summaryrefslogtreecommitdiff
path: root/lua/telescope/sorters.lua
diff options
context:
space:
mode:
authorTJ DeVries <devries.timothyj@gmail.com>2020-08-24 12:31:57 -0400
committerTJ DeVries <devries.timothyj@gmail.com>2020-08-24 12:31:57 -0400
commit1995ca53f38bb89f58a25b523cac59a07c09a0b8 (patch)
treea170df7448d40ba9f1ddf307cb5849ceb5697905 /lua/telescope/sorters.lua
parentcfddae42f59eacbd792a8853be089f4711bbf4ba (diff)
Add fuzzy git file finderZ
Diffstat (limited to 'lua/telescope/sorters.lua')
-rw-r--r--lua/telescope/sorters.lua78
1 files changed, 78 insertions, 0 deletions
diff --git a/lua/telescope/sorters.lua b/lua/telescope/sorters.lua
index 0299c91..d09b53b 100644
--- a/lua/telescope/sorters.lua
+++ b/lua/telescope/sorters.lua
@@ -1,3 +1,5 @@
+local ceil = math.ceil
+
local log = require('telescope.log')
local util = require('telescope.utils')
@@ -70,4 +72,80 @@ sorters.get_levenshtein_sorter = function()
}
end
+sorters.get_norcalli_sorter = function()
+ local ngramlen = 2
+
+ local cached_ngrams = {}
+
+ local function overlapping_ngrams(s, n)
+ if cached_ngrams[s] and cached_ngrams[s][n] then
+ return cached_ngrams[s][n]
+ end
+
+ local R = {}
+ for i = 1, s:len() - n + 1 do
+ R[#R+1] = s:sub(i, i+n-1)
+ end
+
+ if not cached_ngrams[s] then
+ cached_ngrams[s] = {}
+ end
+
+ cached_ngrams[s][n] = R
+
+ return R
+ end
+
+ return Sorter:new {
+ scoring_function = function(_, prompt, line)
+ if prompt == 0 or #prompt < ngramlen then
+ return 0
+ end
+
+ local prompt_ngrams = overlapping_ngrams(prompt, ngramlen)
+
+ local prompt_lower = prompt:lower()
+ local line_lower = line:lower()
+
+ local N = #prompt
+
+ local contains_string = line_lower:find(prompt_lower, 1, true)
+
+ local consecutive_matches = 0
+ local previous_match_index = 0
+ local match_count = 0
+
+ for i = 1, #prompt_ngrams do
+ local match_start = line_lower:find(prompt_ngrams[i], 1, true)
+ if match_start then
+ match_count = match_count + 1
+ if match_start > previous_match_index then
+ consecutive_matches = consecutive_matches + 1
+ end
+
+ previous_match_index = match_start
+ end
+ end
+
+ -- TODO: Copied from ashkan.
+ local denominator = (
+ (10 * match_count / #prompt_ngrams)
+ -- biases for shorter strings
+ -- TODO(ashkan): this can bias towards repeated finds of the same
+ -- subpattern with overlapping_ngrams
+ + 3 * match_count * ngramlen / #line
+ + consecutive_matches
+ + N / (contains_string or (2 * #line))
+ -- + 30/(c1 or 2*N)
+ )
+
+ if denominator == 0 or denominator ~= denominator then
+ return -1
+ end
+
+ return 1 / denominator
+ end
+ }
+end
+
return sorters