@@ -7,18 +7,76 @@ local rpath = require 'workspace.require-path'
77local jumpSource = require ' core.jump-source'
88local wssymbol = require ' core.workspace-symbol'
99
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 )
1164 -- 先按照顺序排序
65+ -- Sort in order first
66+ local simularity_cache = {} --- @type table<string,number>
1267 table.sort (results , function (a , b )
1368 local u1 = guide .getUri (a .target )
1469 local u2 = guide .getUri (b .target )
1570 if u1 == u2 then
1671 return a .target .start < b .target .start
1772 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 ]
1976 end
2077 end )
2178 -- 如果2个结果处于嵌套状态,则取范围小的那个
79+ -- If two results are nested, take the one with the smaller range
2280 local lf , lu
2381 for i = # results , 1 , - 1 do
2482 local res = results [i ].target
@@ -141,7 +199,7 @@ return function (uri, offset)
141199 local results = {}
142200 local uris = checkRequire (source )
143201 if uris then
144- for i , uri in ipairs (uris ) do
202+ for _ , uri in ipairs (uris ) do
145203 results [# results + 1 ] = {
146204 uri = uri ,
147205 source = source ,
@@ -230,7 +288,7 @@ return function (uri, offset)
230288 return nil
231289 end
232290
233- sortResults (results )
291+ sortResults (results , uri )
234292 jumpSource (results )
235293
236294 return results
0 commit comments