diff options
| author | TJ DeVries <devries.timothyj@gmail.com> | 2020-08-31 16:44:47 -0400 |
|---|---|---|
| committer | TJ DeVries <devries.timothyj@gmail.com> | 2020-08-31 17:32:31 -0400 |
| commit | e38589f265a276d431113efcef6fdb157120ce68 (patch) | |
| tree | bd3203a976f3e349875184f03d3199d79fb7303f /lua/telescope/_private/NGRam.lua | |
| parent | 0af8a911b4b5d3eefa6518a804ddadefefd65e19 (diff) | |
feat: Combine configuration into picker.new()
Diffstat (limited to 'lua/telescope/_private/NGRam.lua')
| -rw-r--r-- | lua/telescope/_private/NGRam.lua | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/lua/telescope/_private/NGRam.lua b/lua/telescope/_private/NGRam.lua new file mode 100644 index 0000000..15006c6 --- /dev/null +++ b/lua/telescope/_private/NGRam.lua @@ -0,0 +1,109 @@ +local NGram = {} +NGram.__index = NGram + +function NGram:new(opts) + -- TODO: Add padding + opts = opts or {} + return setmetatable({ + N = opts.N or 2, + split = opts.split or "/", + _depth = 5, + _grams = setmetatable({}, utils.default_table_mt) + }, self) +end + +local min = math.min + +function NGram:_split(word) + local word_len = #word + + local result = {} + for i = 1, word_len - 1 do + -- for j = i + (self.N - 1), min(i + self._depth - 1, word_len) do + -- table.insert(result, string.sub(word, i, j)) + -- end + table.insert(result, string.sub(word, i, i + self.N - 1)) + end + + return result +end + +-- local function pairsByKeys (t, f) +-- local a = {} +-- for n in pairs(t) do table.insert(a, n) end +-- table.sort(a, f) +-- local i = 0 -- iterator variable +-- local iter = function () -- iterator function +-- i = i + 1 +-- if a[i] == nil then return nil +-- else return a[i], t[a[i]] +-- end +-- end +-- return iter +-- end + +function NGram:add(word) + local split_word = self:_split(word) + + for _, k in ipairs(split_word) do + local counts = self._grams[k] + if counts[word] == nil then + counts[word] = 0 + end + + counts[word] = counts[word] + 1 + end +end + +function NGram:_items_sharing_ngrams(query) + local split_query = self:_split(query) + + -- Matched string to number of N-grams shared with the query string. + local shared = {} + + local remaining = {} + + for _, ngram in ipairs(split_query) do + remaining = {} + for match, count in pairs(self._grams[ngram] or {}) do + remaining[match] = remaining[match] or count + + if remaining[match] > 0 then + remaining[match] = remaining[match] - 1 + shared[match] = (shared[match] or 0) + 1 + end + end + end + + return shared +end + +function NGram:search(query, show_values) + local sharing_ngrams = self:_items_sharing_ngrams(query) + + local results = {} + for name, count in pairs(sharing_ngrams) do + local allgrams = #query + #name - (2 * self.N) - count + 2 + table.insert(results, {name, count / allgrams}) + end + + table.sort(results, function(left, right) + return left[2] > right[2] + end) + + if not show_values then + for k, v in ipairs(results) do + results[k] = v[1] + end + end + + return results +end + +function NGram:find(query) + return self:search(query)[1] +end + +function NGram:score(query) + return (self:search(query, true)[1] or {})[2] or 0 +end |
