mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-02-03 16:10:05 +08:00
149 lines
4.0 KiB
Lua
149 lines
4.0 KiB
Lua
|
local fzf = require "fzf_lib"
|
||
|
local sorters = require "telescope.sorters"
|
||
|
|
||
|
local case_enum = setmetatable({
|
||
|
["smart_case"] = 0,
|
||
|
["ignore_case"] = 1,
|
||
|
["respect_case"] = 2,
|
||
|
}, {
|
||
|
__index = function(_, k)
|
||
|
error(string.format("%s is not a valid case mode", k))
|
||
|
end,
|
||
|
__newindex = function()
|
||
|
error "Don't set new things"
|
||
|
end,
|
||
|
})
|
||
|
|
||
|
local get_fzf_sorter = function(opts)
|
||
|
local case_mode = case_enum[opts.case_mode]
|
||
|
local fuzzy_mode = opts.fuzzy == nil and true or opts.fuzzy
|
||
|
local post_or = false
|
||
|
local post_inv = false
|
||
|
local post_escape = false
|
||
|
|
||
|
local get_struct = function(self, prompt)
|
||
|
local struct = self.state.prompt_cache[prompt]
|
||
|
if not struct then
|
||
|
struct = fzf.parse_pattern(prompt, case_mode, fuzzy_mode)
|
||
|
self.state.prompt_cache[prompt] = struct
|
||
|
end
|
||
|
return struct
|
||
|
end
|
||
|
|
||
|
local clear_filter_fun = function(self, prompt)
|
||
|
local filter = "^(" .. self._delimiter .. "(%S+)" .. "[" .. self._delimiter .. "%s]" .. ")"
|
||
|
local matched = prompt:match(filter)
|
||
|
|
||
|
if matched == nil then
|
||
|
return prompt
|
||
|
end
|
||
|
return prompt:sub(#matched + 1, -1)
|
||
|
end
|
||
|
|
||
|
return sorters.Sorter:new {
|
||
|
init = function(self)
|
||
|
self.state.slab = fzf.allocate_slab()
|
||
|
self.state.prompt_cache = {}
|
||
|
|
||
|
if self.filter_function then
|
||
|
self.__highlight_prefilter = clear_filter_fun
|
||
|
end
|
||
|
end,
|
||
|
destroy = function(self)
|
||
|
for _, v in pairs(self.state.prompt_cache) do
|
||
|
fzf.free_pattern(v)
|
||
|
end
|
||
|
self.state.prompt_cache = {}
|
||
|
if self.state.slab ~= nil then
|
||
|
fzf.free_slab(self.state.slab)
|
||
|
self.state.slab = nil
|
||
|
end
|
||
|
end,
|
||
|
start = function(self, prompt)
|
||
|
local last = prompt:sub(-1, -1)
|
||
|
|
||
|
if last == "|" then
|
||
|
self._discard_state.filtered = {}
|
||
|
post_or = true
|
||
|
elseif last == " " and post_or then
|
||
|
self._discard_state.filtered = {}
|
||
|
elseif post_or then
|
||
|
self._discard_state.filtered = {}
|
||
|
post_or = false
|
||
|
else
|
||
|
post_or = false
|
||
|
end
|
||
|
|
||
|
if last == "\\" and not post_escape then
|
||
|
self._discard_state.filtered = {}
|
||
|
post_escape = true
|
||
|
else
|
||
|
self._discard_state.filtered = {}
|
||
|
post_escape = false
|
||
|
end
|
||
|
|
||
|
if last == "!" and not post_inv then
|
||
|
post_inv = true
|
||
|
self._discard_state.filtered = {}
|
||
|
elseif post_inv then
|
||
|
self._discard_state.filtered = {}
|
||
|
elseif post_inv and " " then
|
||
|
post_inv = false
|
||
|
end
|
||
|
end,
|
||
|
discard = true,
|
||
|
scoring_function = function(self, prompt, line)
|
||
|
local obj = get_struct(self, prompt)
|
||
|
local score = fzf.get_score(line, obj, self.state.slab)
|
||
|
if score == 0 then
|
||
|
return -1
|
||
|
else
|
||
|
return 1 / score
|
||
|
end
|
||
|
end,
|
||
|
highlighter = function(self, prompt, display)
|
||
|
if self.__highlight_prefilter then
|
||
|
prompt = self:__highlight_prefilter(prompt)
|
||
|
end
|
||
|
return fzf.get_pos(display, get_struct(self, prompt), self.state.slab)
|
||
|
end,
|
||
|
}
|
||
|
end
|
||
|
|
||
|
local fast_extend = function(opts, conf)
|
||
|
local ret = {}
|
||
|
ret.case_mode = vim.F.if_nil(opts.case_mode, conf.case_mode)
|
||
|
ret.fuzzy = vim.F.if_nil(opts.fuzzy, conf.fuzzy)
|
||
|
return ret
|
||
|
end
|
||
|
|
||
|
return require("telescope").register_extension {
|
||
|
setup = function(ext_config, config)
|
||
|
local override_file = vim.F.if_nil(ext_config.override_file_sorter, true)
|
||
|
local override_generic = vim.F.if_nil(ext_config.override_generic_sorter, true)
|
||
|
|
||
|
local conf = {}
|
||
|
conf.case_mode = vim.F.if_nil(ext_config.case_mode, "smart_case")
|
||
|
conf.fuzzy = vim.F.if_nil(ext_config.fuzzy, true)
|
||
|
|
||
|
if override_file then
|
||
|
config.file_sorter = function(opts)
|
||
|
opts = opts or {}
|
||
|
return get_fzf_sorter(fast_extend(opts, conf))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if override_generic then
|
||
|
config.generic_sorter = function(opts)
|
||
|
opts = opts or {}
|
||
|
return get_fzf_sorter(fast_extend(opts, conf))
|
||
|
end
|
||
|
end
|
||
|
end,
|
||
|
exports = {
|
||
|
native_fzf_sorter = function(opts)
|
||
|
return get_fzf_sorter(opts or { case_mode = "smart_case", fuzzy = true })
|
||
|
end,
|
||
|
},
|
||
|
}
|