pseek 3.4.0__tar.gz → 3.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,10 @@ jobs:
10
10
 
11
11
  runs-on: ubuntu-latest
12
12
 
13
+ concurrency:
14
+ group: pseek-pypi-publish
15
+ cancel-in-progress: false
16
+
13
17
  permissions:
14
18
  contents: read
15
19
 
@@ -51,3 +55,4 @@ jobs:
51
55
  uses: pypa/gh-action-pypi-publish@release/v1
52
56
  with:
53
57
  password: ${{ secrets.PYPI_API_TOKEN }}
58
+ skip-existing: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pseek
3
- Version: 3.4.0
3
+ Version: 3.4.2
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -174,6 +174,26 @@ To search for a query that starts with `-`, use `--` to mark the end of options:
174
174
  psk -- --path
175
175
  ```
176
176
 
177
+ Of course the search query is optional. When no query is provided, Pseek displays the files and directories and file contents within the selected scope.
178
+
179
+ All other filters still apply, including `--glob`, `--depth`, `--size`, ignore rules, and other filtering options.
180
+
181
+ This makes Pseek useful as a flexible alternative to `ls` or `cat`, allowing you to inspect a filtered view of a directory tree and file contents.
182
+
183
+ ```bash
184
+ # List files and directories and file contents
185
+ psk
186
+
187
+ # List only Python files
188
+ psk --ext py
189
+
190
+ # List everything up to depth 2
191
+ psk --depth :2
192
+
193
+ # List everything except the build directory
194
+ psk --exclude build
195
+ ```
196
+
177
197
  ## Command Options
178
198
 
179
199
  | Option | Description |
@@ -309,6 +329,8 @@ psk apple --fuzzy
309
329
 
310
330
  Can match: `appl`, `appel`, `aple`
311
331
 
332
+ > **Note:** To improve performance, highlighting of matches is automatically disabled if the `--fuzzy` flag is enabled and the `--word` flag is disabled.
333
+
312
334
  #### Fuzzy Similarity Threshold
313
335
 
314
336
  ```bash
@@ -339,6 +361,8 @@ Enable:
339
361
  psk '("error" or "warning") and not "debug"' --expr
340
362
  ```
341
363
 
364
+ > **Note:** When using `--expr`, queries are double-quoted and backslashes have special meaning. Ordinary queries use JSON-style escaping, so `\n` and `\t` represent newline and tab characters, respectively. Use `\\n` or `\\t` to search for those literal sequences. Regex queries (`r"..."`) preserve regex escapes, which are interpreted by the regex engine.
365
+
342
366
  ### Supported Operators
343
367
 
344
368
  #### AND
@@ -146,6 +146,26 @@ To search for a query that starts with `-`, use `--` to mark the end of options:
146
146
  psk -- --path
147
147
  ```
148
148
 
149
+ Of course the search query is optional. When no query is provided, Pseek displays the files and directories and file contents within the selected scope.
150
+
151
+ All other filters still apply, including `--glob`, `--depth`, `--size`, ignore rules, and other filtering options.
152
+
153
+ This makes Pseek useful as a flexible alternative to `ls` or `cat`, allowing you to inspect a filtered view of a directory tree and file contents.
154
+
155
+ ```bash
156
+ # List files and directories and file contents
157
+ psk
158
+
159
+ # List only Python files
160
+ psk --ext py
161
+
162
+ # List everything up to depth 2
163
+ psk --depth :2
164
+
165
+ # List everything except the build directory
166
+ psk --exclude build
167
+ ```
168
+
149
169
  ## Command Options
150
170
 
151
171
  | Option | Description |
@@ -281,6 +301,8 @@ psk apple --fuzzy
281
301
 
282
302
  Can match: `appl`, `appel`, `aple`
283
303
 
304
+ > **Note:** To improve performance, highlighting of matches is automatically disabled if the `--fuzzy` flag is enabled and the `--word` flag is disabled.
305
+
284
306
  #### Fuzzy Similarity Threshold
285
307
 
286
308
  ```bash
@@ -311,6 +333,8 @@ Enable:
311
333
  psk '("error" or "warning") and not "debug"' --expr
312
334
  ```
313
335
 
336
+ > **Note:** When using `--expr`, queries are double-quoted and backslashes have special meaning. Ordinary queries use JSON-style escaping, so `\n` and `\t` represent newline and tab characters, respectively. Use `\\n` or `\\t` to search for those literal sequences. Regex queries (`r"..."`) preserve regex escapes, which are interpreted by the regex engine.
337
+
314
338
  ### Supported Operators
315
339
 
316
340
  #### AND
@@ -306,7 +306,7 @@ def check_rar_backend(archive_enabled: bool, tool_path: str, backend: str):
306
306
 
307
307
 
308
308
  @click.command()
309
- @click.argument('query')
309
+ @click.argument('query', required=False)
310
310
  @click.argument('path', type=click.Path(exists=True, file_okay=False, dir_okay=True),
311
311
  default='.', required=False)
312
312
  # Search type options
@@ -1,4 +1,4 @@
1
- import re, click
1
+ import re, click, json
2
2
  from lark import Lark, Transformer
3
3
  from .utils import compile_regex
4
4
  from rapidfuzz import fuzz
@@ -139,6 +139,19 @@ PREFIXED_STRING: /(r|c|w|f|rc|cr|cw|wc|cf|fc|wf|fw|cwf|cfw|wcf|wfc|fcw|fwc)"([^"
139
139
  QUERY_PARSER = Lark(query_grammar, parser='lalr')
140
140
 
141
141
 
142
+ def decode_expr_string(token: str, regex: bool = False) -> str:
143
+ """
144
+ Decode a quoted expression string.
145
+
146
+ Normal strings use JSON-style escaping.
147
+ """
148
+ if not regex:
149
+ return json.loads(token)
150
+
151
+ # Keep regex escapes such as \b, \d, and \w intact
152
+ return token[1:-1]
153
+
154
+
142
155
  class TreeToExpr(Transformer):
143
156
  """Transform parsed tree into expression tree (ExprNode subclasses)"""
144
157
  def __init__(self, fuzzy_level):
@@ -147,7 +160,7 @@ class TreeToExpr(Transformer):
147
160
 
148
161
  def string(self, s):
149
162
  """ Match normal quoted string: "foo" """
150
- term = s[0][1:-1] # Remove surrounding quotes (e.g., "foo" -> foo)
163
+ term = decode_expr_string(str(s[0]))
151
164
  return TermNode(
152
165
  term,
153
166
  False,
@@ -158,13 +171,19 @@ class TreeToExpr(Transformer):
158
171
  )
159
172
 
160
173
  def prefixed_string(self, s):
174
+ """Transform a prefixed search term"""
161
175
  text = str(s[0]) # e.g., 'rc"pattern"'
162
- prefix = text.split('"', 1)[0].lower()
163
- content = text.split('"', 1)[1][:-1]
176
+
177
+ quote_index = text.index('"')
178
+ prefix = text[:quote_index].lower()
179
+ quoted = text[quote_index:]
180
+
181
+ is_regex = 'r' in prefix
182
+ content = decode_expr_string(quoted, is_regex)
164
183
 
165
184
  return TermNode(
166
185
  content,
167
- regex='r' in prefix,
186
+ regex=is_regex,
168
187
  whole_word='w' in prefix,
169
188
  case_sensitive='c' in prefix,
170
189
  fuzzy='f' in prefix,
@@ -187,6 +206,9 @@ def parse_query_expression(config) -> ExprNode:
187
206
  If expr is False, treat the whole query as a single term.
188
207
  """
189
208
 
209
+ if config.query is None:
210
+ return None
211
+
190
212
  if not config.expr:
191
213
  return TermNode(
192
214
  config.query,
@@ -352,6 +374,9 @@ def evaluate_with_matches(
352
374
  def find_matches(expr: ExprNode, text: str, num: int = 0) -> list[tuple[int, int]]:
353
375
  """Find spans that contribute to a successful expression"""
354
376
 
377
+ if expr is None:
378
+ return []
379
+
355
380
  matched, matches = evaluate_with_matches(expr, text, num)
356
381
  # Remove duplicate ranges
357
382
  return list(dict.fromkeys(matches)) if matched else []
@@ -61,7 +61,7 @@ def search_file_and_dir(config, matches: dict, pattern, p: Path,
61
61
  None
62
62
  )
63
63
 
64
- if match_type and pattern.evaluate(p.name):
64
+ if match_type and (pattern is None or pattern.evaluate(p.name)):
65
65
  # Find matched query in the name
66
66
  name_matches = find_matches(
67
67
  pattern,
@@ -102,7 +102,7 @@ def search_file_and_dir(config, matches: dict, pattern, p: Path,
102
102
  None
103
103
  )
104
104
 
105
- if arc_match_type and pattern.evaluate(name.name):
105
+ if arc_match_type and (pattern is None or pattern.evaluate(name.name)):
106
106
  name_matches = find_matches(
107
107
  pattern,
108
108
  name.name,
@@ -231,7 +231,7 @@ def search_content(config, matches: dict, pattern, binary_pattern,
231
231
 
232
232
  collector = ContextCollector(config.context)
233
233
  for num, line in enumerate(decoded_content.splitlines(), 1):
234
- matched = pattern.evaluate(line)
234
+ matched = pattern is None or pattern.evaluate(line)
235
235
 
236
236
  if config.paths_only and matched:
237
237
  add_result(
@@ -285,7 +285,7 @@ def search_content(config, matches: dict, pattern, binary_pattern,
285
285
  # Skip lines that can't be decoded
286
286
  continue
287
287
 
288
- matched = pattern.evaluate(line_decoded)
288
+ matched = pattern is None or pattern.evaluate(line_decoded)
289
289
 
290
290
  # Avoid searching through the entire file content if the paths-only flag is True
291
291
  if config.paths_only and matched:
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "pseek"
7
- version = "3.4.0"
7
+ version = "3.4.2"
8
8
  description = "Pseek is a Python CLI toolkit to search files, folders, and text"
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes