Merge PR #533: fix: use regex for search output parsing to handle Windows drive-letter paths
Authored by Himess. Replaces split(':', 2) with regex that optionally
captures Windows drive-letter prefix in rg/grep output parsing. Fixes
search_files returning zero results on Windows where paths like
C:\path\file.py:42:content were misparsed by naive colon splitting.
No behavior change on Unix/Mac.
This commit is contained in:
commit
2285615010
1 changed files with 39 additions and 42 deletions
|
|
@ -962,37 +962,35 @@ class ShellFileOperations(FileOperations):
|
||||||
# rg match lines: "file:lineno:content" (colon separator)
|
# rg match lines: "file:lineno:content" (colon separator)
|
||||||
# rg context lines: "file-lineno-content" (dash separator)
|
# rg context lines: "file-lineno-content" (dash separator)
|
||||||
# rg group seps: "--"
|
# rg group seps: "--"
|
||||||
|
# Note: on Windows, paths contain drive letters (e.g. C:\path),
|
||||||
|
# so naive split(":") breaks. Use regex to handle both platforms.
|
||||||
|
_match_re = re.compile(r'^([A-Za-z]:)?(.*?):(\d+):(.*)$')
|
||||||
|
_ctx_re = re.compile(r'^([A-Za-z]:)?(.*?)-(\d+)-(.*)$')
|
||||||
matches = []
|
matches = []
|
||||||
for line in result.stdout.strip().split('\n'):
|
for line in result.stdout.strip().split('\n'):
|
||||||
if not line or line == "--":
|
if not line or line == "--":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Try match line first (colon-separated: file:line:content)
|
# Try match line first (colon-separated: file:line:content)
|
||||||
parts = line.split(':', 2)
|
m = _match_re.match(line)
|
||||||
if len(parts) >= 3:
|
if m:
|
||||||
try:
|
matches.append(SearchMatch(
|
||||||
matches.append(SearchMatch(
|
path=(m.group(1) or '') + m.group(2),
|
||||||
path=parts[0],
|
line_number=int(m.group(3)),
|
||||||
line_number=int(parts[1]),
|
content=m.group(4)[:500]
|
||||||
content=parts[2][:500]
|
))
|
||||||
))
|
continue
|
||||||
continue
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Try context line (dash-separated: file-line-content)
|
# Try context line (dash-separated: file-line-content)
|
||||||
# Only attempt if context was requested to avoid false positives
|
# Only attempt if context was requested to avoid false positives
|
||||||
if context > 0:
|
if context > 0:
|
||||||
parts = line.split('-', 2)
|
m = _ctx_re.match(line)
|
||||||
if len(parts) >= 3:
|
if m:
|
||||||
try:
|
matches.append(SearchMatch(
|
||||||
matches.append(SearchMatch(
|
path=(m.group(1) or '') + m.group(2),
|
||||||
path=parts[0],
|
line_number=int(m.group(3)),
|
||||||
line_number=int(parts[1]),
|
content=m.group(4)[:500]
|
||||||
content=parts[2][:500]
|
))
|
||||||
))
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
total = len(matches)
|
total = len(matches)
|
||||||
page = matches[offset:offset + limit]
|
page = matches[offset:offset + limit]
|
||||||
|
|
@ -1059,34 +1057,33 @@ class ShellFileOperations(FileOperations):
|
||||||
# grep match lines: "file:lineno:content" (colon)
|
# grep match lines: "file:lineno:content" (colon)
|
||||||
# grep context lines: "file-lineno-content" (dash)
|
# grep context lines: "file-lineno-content" (dash)
|
||||||
# grep group seps: "--"
|
# grep group seps: "--"
|
||||||
|
# Note: on Windows, paths contain drive letters (e.g. C:\path),
|
||||||
|
# so naive split(":") breaks. Use regex to handle both platforms.
|
||||||
|
_match_re = re.compile(r'^([A-Za-z]:)?(.*?):(\d+):(.*)$')
|
||||||
|
_ctx_re = re.compile(r'^([A-Za-z]:)?(.*?)-(\d+)-(.*)$')
|
||||||
matches = []
|
matches = []
|
||||||
for line in result.stdout.strip().split('\n'):
|
for line in result.stdout.strip().split('\n'):
|
||||||
if not line or line == "--":
|
if not line or line == "--":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
parts = line.split(':', 2)
|
m = _match_re.match(line)
|
||||||
if len(parts) >= 3:
|
if m:
|
||||||
try:
|
matches.append(SearchMatch(
|
||||||
matches.append(SearchMatch(
|
path=(m.group(1) or '') + m.group(2),
|
||||||
path=parts[0],
|
line_number=int(m.group(3)),
|
||||||
line_number=int(parts[1]),
|
content=m.group(4)[:500]
|
||||||
content=parts[2][:500]
|
))
|
||||||
))
|
continue
|
||||||
continue
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if context > 0:
|
if context > 0:
|
||||||
parts = line.split('-', 2)
|
m = _ctx_re.match(line)
|
||||||
if len(parts) >= 3:
|
if m:
|
||||||
try:
|
matches.append(SearchMatch(
|
||||||
matches.append(SearchMatch(
|
path=(m.group(1) or '') + m.group(2),
|
||||||
path=parts[0],
|
line_number=int(m.group(3)),
|
||||||
line_number=int(parts[1]),
|
content=m.group(4)[:500]
|
||||||
content=parts[2][:500]
|
))
|
||||||
))
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
total = len(matches)
|
total = len(matches)
|
||||||
page = matches[offset:offset + limit]
|
page = matches[offset:offset + limit]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue