Skip to content

Commit 4db0d73

Browse files
authored
Merge pull request #62 from zerochae/fix/windows-path-parsing
fix: resolve Windows path parsing issue in ripgrep results
2 parents 7d4630f + 12e8591 commit 4db0d73

3 files changed

Lines changed: 130 additions & 6 deletions

File tree

lua/endpoint/core/Framework.lua

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,18 @@ function Framework:_parse_result_line(result_line)
202202
return {}
203203
end
204204

205-
-- Parse ripgrep output format: file:line:col:content
206-
local source_file_path, source_line_number, source_column_position, line_content =
207-
result_line:match "([^:]+):(%d+):(%d+):(.*)"
208-
if not source_file_path or not source_line_number or not source_column_position or not line_content then
205+
-- Use rg util to parse result line (handles Windows and Unix paths)
206+
local rg_util = require "endpoint.utils.rg"
207+
local parsed = rg_util.parse_result_line(result_line)
208+
209+
if not parsed then
209210
return {}
210211
end
211212

212-
local line_num = tonumber(source_line_number) or 1
213-
local col_pos = tonumber(source_column_position) or 1
213+
local source_file_path = parsed.file_path
214+
local line_num = parsed.line_number
215+
local col_pos = parsed.column
216+
local line_content = parsed.content
214217

215218
local endpoints = {}
216219
if self.parser then

lua/endpoint/utils/rg.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,39 @@ M.common_file_patterns = {
6868
react = { "**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx" },
6969
}
7070

71+
-- Parse ripgrep result line into components
72+
-- Handles both Unix and Windows paths
73+
-- Format: file:line:col:content
74+
function M.parse_result_line(result_line)
75+
if not result_line or result_line == "" then
76+
return nil
77+
end
78+
79+
-- Try to parse ripgrep output: file:line:col:content
80+
-- Need to handle Windows paths like C:\path\file.java:10:5:content
81+
-- And Unix paths like /path/file.java:10:5:content
82+
83+
-- Match pattern that handles Windows drive letters (C:) and Unix paths
84+
local file_path, line_number, column, content
85+
86+
-- Try Windows path first (C:\...:line:col:content)
87+
if result_line:match "^[A-Z]:" then
88+
file_path, line_number, column, content = result_line:match "^([A-Z]:[^:]+):(%d+):(%d+):(.*)$"
89+
else
90+
-- Unix path (/...:line:col:content)
91+
file_path, line_number, column, content = result_line:match "^([^:]+):(%d+):(%d+):(.*)$"
92+
end
93+
94+
if not file_path or not line_number or not column or not content then
95+
return nil
96+
end
97+
98+
return {
99+
file_path = file_path,
100+
line_number = tonumber(line_number),
101+
column = tonumber(column),
102+
content = content,
103+
}
104+
end
105+
71106
return M

tests/spec/rg_util_spec.lua

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
local rg_util = require "endpoint.utils.rg"
2+
3+
describe("Ripgrep Utility", function()
4+
describe("parse_result_line", function()
5+
it("should parse Unix path correctly", function()
6+
local line = "/home/user/project/src/Controller.java:10:5:@GetMapping"
7+
local result = rg_util.parse_result_line(line)
8+
9+
assert.is_not_nil(result)
10+
assert.equals("/home/user/project/src/Controller.java", result.file_path)
11+
assert.equals(10, result.line_number)
12+
assert.equals(5, result.column)
13+
assert.equals("@GetMapping", result.content)
14+
end)
15+
16+
it("should parse Windows path correctly", function()
17+
local line = "C:\\Users\\user\\project\\src\\Controller.java:10:5:@GetMapping"
18+
local result = rg_util.parse_result_line(line)
19+
20+
assert.is_not_nil(result)
21+
assert.equals("C:\\Users\\user\\project\\src\\Controller.java", result.file_path)
22+
assert.equals(10, result.line_number)
23+
assert.equals(5, result.column)
24+
assert.equals("@GetMapping", result.content)
25+
end)
26+
27+
it("should parse Windows path with forward slashes", function()
28+
local line = "C:/Users/user/project/src/Controller.java:10:5:@GetMapping"
29+
local result = rg_util.parse_result_line(line)
30+
31+
assert.is_not_nil(result)
32+
assert.equals("C:/Users/user/project/src/Controller.java", result.file_path)
33+
assert.equals(10, result.line_number)
34+
assert.equals(5, result.column)
35+
assert.equals("@GetMapping", result.content)
36+
end)
37+
38+
it("should handle content with colons", function()
39+
local line = "/path/to/file.ts:15:8:@Query(() => User, { name: 'user' })"
40+
local result = rg_util.parse_result_line(line)
41+
42+
assert.is_not_nil(result)
43+
assert.equals("/path/to/file.ts", result.file_path)
44+
assert.equals(15, result.line_number)
45+
assert.equals(8, result.column)
46+
assert.equals("@Query(() => User, { name: 'user' })", result.content)
47+
end)
48+
49+
it("should handle Windows path with content containing colons", function()
50+
local line = "D:\\project\\app\\resolver.ts:20:10:@Mutation(() => User, { description: 'test' })"
51+
local result = rg_util.parse_result_line(line)
52+
53+
assert.is_not_nil(result)
54+
assert.equals("D:\\project\\app\\resolver.ts", result.file_path)
55+
assert.equals(20, result.line_number)
56+
assert.equals(10, result.column)
57+
assert.equals("@Mutation(() => User, { description: 'test' })", result.content)
58+
end)
59+
60+
it("should return nil for empty line", function()
61+
local result = rg_util.parse_result_line("")
62+
assert.is_nil(result)
63+
end)
64+
65+
it("should return nil for nil input", function()
66+
local result = rg_util.parse_result_line(nil)
67+
assert.is_nil(result)
68+
end)
69+
70+
it("should return nil for malformed line", function()
71+
local result = rg_util.parse_result_line("invalid line format")
72+
assert.is_nil(result)
73+
end)
74+
75+
it("should handle relative paths", function()
76+
local line = "src/controllers/user.controller.ts:25:3:@Get('/users')"
77+
local result = rg_util.parse_result_line(line)
78+
79+
assert.is_not_nil(result)
80+
assert.equals("src/controllers/user.controller.ts", result.file_path)
81+
assert.equals(25, result.line_number)
82+
assert.equals(3, result.column)
83+
assert.equals("@Get('/users')", result.content)
84+
end)
85+
end)
86+
end)

0 commit comments

Comments
 (0)