Skip to content

Commit 89163a3

Browse files
committed
fix: add cross-platform support for grep context lines parsing
- Add support for Linux/Unix grep context line format (path-linenum-content) - Maintain backward compatibility with Windows and standard formats - Support both dash and tab separators in context lines - Handle absolute and relative paths uniformly - Add proper error handling to prevent crashes on malformed lines Fixes #34
1 parent f82c823 commit 89163a3

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

src/code_index_mcp/search/base.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,35 @@ def parse_search_output(output: str, base_path: str) -> Dict[str, List[Tuple[int
3333
if not line.strip():
3434
continue
3535
try:
36-
# Handle Windows paths which might have a drive letter, e.g., C:
36+
# Try to parse as a matched line first (format: path:linenum:content)
3737
parts = line.split(':', 2)
38-
if sys.platform == "win32" and len(parts[0]) == 1 and parts[1].startswith('\\'):
39-
# Re-join drive letter with the rest of the path
38+
39+
# Check if this might be a context line (format: path-linenum-content)
40+
# Context lines use '-' as separator in grep/ag output
41+
if len(parts) < 3 and '-' in line:
42+
# Try to parse as context line
43+
# Match pattern: path-linenum-content or path-linenum-\tcontent
44+
match = re.match(r'^(.*?)-(\d+)[-\t](.*)$', line)
45+
if match:
46+
file_path_abs = match.group(1)
47+
line_number_str = match.group(2)
48+
content = match.group(3)
49+
else:
50+
# If regex doesn't match, skip this line
51+
continue
52+
elif sys.platform == "win32" and len(parts) >= 3 and len(parts[0]) == 1 and parts[1].startswith('\\'):
53+
# Handle Windows paths with drive letter (e.g., C:\path\file.txt)
4054
file_path_abs = f"{parts[0]}:{parts[1]}"
4155
line_number_str = parts[2].split(':', 1)[0]
42-
content = parts[2].split(':', 1)[1]
43-
else:
56+
content = parts[2].split(':', 1)[1] if ':' in parts[2] else parts[2]
57+
elif len(parts) >= 3:
58+
# Standard format: path:linenum:content
4459
file_path_abs = parts[0]
4560
line_number_str = parts[1]
4661
content = parts[2]
62+
else:
63+
# Line doesn't match any expected format
64+
continue
4765

4866
line_number = int(line_number_str)
4967

0 commit comments

Comments
 (0)