@@ -7,18 +7,76 @@ local rpath = require 'workspace.require-path'
7
7
local jumpSource = require ' core.jump-source'
8
8
local wssymbol = require ' core.workspace-symbol'
9
9
10
- local function sortResults (results )
10
+ --- @param s string
11
+ --- @return string[]
12
+ local function split (s )
13
+ local r = {}
14
+ s :gsub (' [^/]+' , function (w )
15
+ r [# r + 1 ] = w :gsub (" ~1" , " /" ):gsub (" ~0" , " ~" )
16
+ end )
17
+ return r
18
+ end
19
+
20
+ --- Returns the Levenshtein distance between the two given string arrays
21
+ --- @param a string[]
22
+ --- @param b string[]
23
+ --- @return number
24
+ local function levenshteinDistance (a , b )
25
+ local a_len , b_len = # a , # b
26
+ local matrix = {} --- @type integer[][]
27
+
28
+ -- Initialize the matrix
29
+ for i = 1 , a_len + 1 do
30
+ matrix [i ] = { [1 ] = i }
31
+ end
32
+
33
+ for j = 1 , b_len + 1 do
34
+ matrix [1 ][j ] = j
35
+ end
36
+
37
+ -- Compute the Levenshtein distance
38
+ for i = 1 , a_len do
39
+ for j = 1 , b_len do
40
+ local cost = (a [i ] == b [j ]) and 0 or 1
41
+ matrix [i + 1 ][j + 1 ] =
42
+ math.min (matrix [i ][j + 1 ] + 1 , matrix [i + 1 ][j ] + 1 , matrix [i ][j ] + cost )
43
+ end
44
+ end
45
+
46
+ -- Return the Levenshtein distance
47
+ return matrix [a_len + 1 ][b_len + 1 ]
48
+ end
49
+
50
+ --- @param path1 string
51
+ --- @param path2 string
52
+ --- @return number
53
+ local function pathSimilarityRatio (path1 , path2 )
54
+ if path1 == path2 then
55
+ return 0
56
+ end
57
+ local parts1 = split (path1 )
58
+ local parts2 = split (path2 )
59
+ local distance = levenshteinDistance (parts1 , parts2 )
60
+ return distance * 2 / (# parts1 + # parts2 )
61
+ end
62
+
63
+ local function sortResults (results , uri )
11
64
-- 先按照顺序排序
65
+ -- Sort in order first
66
+ local simularity_cache = {} --- @type table<string,number>
12
67
table.sort (results , function (a , b )
13
68
local u1 = guide .getUri (a .target )
14
69
local u2 = guide .getUri (b .target )
15
70
if u1 == u2 then
16
71
return a .target .start < b .target .start
17
72
else
18
- return u1 < u2
73
+ simularity_cache [u1 ] = simularity_cache [u1 ] or pathSimilarityRatio (uri , u1 )
74
+ simularity_cache [u2 ] = simularity_cache [u2 ] or pathSimilarityRatio (uri , u2 )
75
+ return simularity_cache [u1 ] < simularity_cache [u2 ]
19
76
end
20
77
end )
21
78
-- 如果2个结果处于嵌套状态,则取范围小的那个
79
+ -- If two results are nested, take the one with the smaller range
22
80
local lf , lu
23
81
for i = # results , 1 , - 1 do
24
82
local res = results [i ].target
@@ -141,7 +199,7 @@ return function (uri, offset)
141
199
local results = {}
142
200
local uris = checkRequire (source )
143
201
if uris then
144
- for i , uri in ipairs (uris ) do
202
+ for _ , uri in ipairs (uris ) do
145
203
results [# results + 1 ] = {
146
204
uri = uri ,
147
205
source = source ,
@@ -230,7 +288,7 @@ return function (uri, offset)
230
288
return nil
231
289
end
232
290
233
- sortResults (results )
291
+ sortResults (results , uri )
234
292
jumpSource (results )
235
293
236
294
return results
0 commit comments