feat: Allow overriding actions from mappings (#248)

This commit is contained in:
TJ DeVries
2020-11-16 10:58:30 -05:00
committed by GitHub
parent ad7280e0b9
commit 985856946e
6 changed files with 301 additions and 58 deletions

View File

@@ -6,43 +6,14 @@ local log = require('telescope.log')
local path = require('telescope.path')
local state = require('telescope.state')
local transform_mod = require('telescope.actions.mt').transform_mod
local actions = setmetatable({}, {
__index = function(_, k)
error("Actions does not have a value: " .. tostring(k))
end
})
local action_mt = {
__call = function(t, ...)
local values = {}
for _, v in ipairs(t) do
local result = {v(...)}
for _, res in ipairs(result) do
table.insert(values, res)
end
end
return unpack(values)
end,
__add = function(lhs, rhs)
local new_actions = {}
for _, v in ipairs(lhs) do
table.insert(new_actions, v)
end
for _, v in ipairs(rhs) do
table.insert(new_actions, v)
end
return setmetatable(new_actions, getmetatable(lhs))
end
}
local transform_action = function(a)
return setmetatable({a}, action_mt)
end
--- Get the current picker object for the prompt
function actions.get_current_picker(prompt_bufnr)
return state.get_status(prompt_bufnr).picker
@@ -68,8 +39,8 @@ function actions.add_selection(prompt_bufnr)
end
--- Get the current entry
function actions.get_selected_entry(prompt_bufnr)
return actions.get_current_picker(prompt_bufnr):get_selection()
function actions.get_selected_entry()
return state.get_global_key('selected_entry')
end
function actions.preview_scrolling_up(prompt_bufnr)
@@ -81,7 +52,7 @@ function actions.preview_scrolling_down(prompt_bufnr)
end
-- TODO: It seems sometimes we get bad styling.
local function goto_file_selection(prompt_bufnr, command)
function actions._goto_file_selection(prompt_bufnr, command)
local entry = actions.get_selected_entry(prompt_bufnr)
if not entry then
@@ -95,7 +66,7 @@ local function goto_file_selection(prompt_bufnr, command)
-- TODO: Check for off-by-one
row = entry.row or entry.lnum
col = entry.col
else
elseif not entry.bufnr then
-- TODO: Might want to remove this and force people
-- to put stuff into `filename`
local value = entry.value
@@ -124,11 +95,11 @@ local function goto_file_selection(prompt_bufnr, command)
actions.close(prompt_bufnr)
filename = path.normalize(filename, vim.fn.getcwd())
if entry_bufnr then
vim.cmd(string.format(":%s #%d", command, entry_bufnr))
else
filename = path.normalize(filename, vim.fn.getcwd())
local bufnr = vim.api.nvim_get_current_buf()
if filename ~= vim.api.nvim_buf_get_name(bufnr) then
vim.cmd(string.format(":%s %s", command, filename))
@@ -151,19 +122,19 @@ function actions.center(_)
end
function actions.goto_file_selection_edit(prompt_bufnr)
goto_file_selection(prompt_bufnr, "edit")
actions._goto_file_selection(prompt_bufnr, "edit")
end
function actions.goto_file_selection_split(prompt_bufnr)
goto_file_selection(prompt_bufnr, "new")
actions._goto_file_selection(prompt_bufnr, "new")
end
function actions.goto_file_selection_vsplit(prompt_bufnr)
goto_file_selection(prompt_bufnr, "vnew")
actions._goto_file_selection(prompt_bufnr, "vnew")
end
function actions.goto_file_selection_tabedit(prompt_bufnr)
goto_file_selection(prompt_bufnr, "tabedit")
actions._goto_file_selection(prompt_bufnr, "tabedit")
end
function actions.close_pum(_)
@@ -218,10 +189,9 @@ actions.insert_value = function(prompt_bufnr)
return entry.value
end
for k, v in pairs(actions) do
actions[k] = transform_action(v)
end
actions._transform_action = transform_action
-- ==================================================
-- Transforms modules and sets the corect metatables.
-- ==================================================
actions = transform_mod(actions)
return actions

View File

@@ -0,0 +1,96 @@
local action_mt = {}
action_mt.create = function(mod)
local mt = {
__call = function(t, ...)
local values = {}
for _, v in ipairs(t) do
local func = t._replacements[v] or mod[v]
if t._pre[v] then
t._pre[v](...)
end
local result = {func(...)}
for _, res in ipairs(result) do
table.insert(values, res)
end
if t._post[v] then
t._post[v](...)
end
end
return unpack(values)
end,
__add = function(lhs, rhs)
local new_actions = {}
for _, v in ipairs(lhs) do
table.insert(new_actions, v)
end
for _, v in ipairs(rhs) do
table.insert(new_actions, v)
end
return setmetatable(new_actions, getmetatable(lhs))
end,
_pre = {},
_replacements = {},
_post = {},
}
mt.__index = mt
mt.clear = function()
mt._pre = {}
mt._replacements = {}
mt._post = {}
end
--- Replace the reference to the function with a new one temporarily
function mt:replace(v)
assert(#self == 1, "Cannot replace an already combined action")
local action_name = self[1]
mt._replacements[action_name] = v
end
function mt:enhance(opts)
assert(#self == 1, "Cannot enhance already combined actions")
local action_name = self[1]
if opts.pre then
mt._pre[action_name] = opts.pre
end
if opts.post then
mt._post[action_name] = opts.post
end
end
return mt
end
action_mt.transform = function(k, mt)
return setmetatable({k}, mt)
end
action_mt.transform_mod = function(mod)
local mt = action_mt.create(mod)
local redirect = {}
for k, _ in pairs(mod) do
redirect[k] = action_mt.transform(k, mt)
end
redirect._clear = mt.clear
return redirect
end
return action_mt

View File

@@ -804,12 +804,15 @@ builtin.current_buffer_fuzzy_find = function(opts)
table.insert(lines_with_numbers, {k, v})
end
local bufnr = vim.api.nvim_get_current_buf()
pickers.new(opts, {
prompt_title = 'Current Buffer Fuzzy',
finder = finders.new_table {
results = lines_with_numbers,
entry_maker = function(enumerated_line)
return {
bufnr = bufnr,
display = enumerated_line[2],
ordinal = enumerated_line[2],
@@ -818,17 +821,13 @@ builtin.current_buffer_fuzzy_find = function(opts)
end
},
sorter = sorters.get_generic_fuzzy_sorter(),
attach_mappings = function(prompt_bufnr, map)
local goto_line = function()
local selection = actions.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)
vim.api.nvim_win_set_cursor(0, {selection.lnum, 0})
vim.cmd [[stopinsert]]
end
map('n', '<CR>', goto_line)
map('i', '<CR>', goto_line)
attach_mappings = function(prompt_bufnr)
actions._goto_file_selection:enhance {
post = vim.schedule_wrap(function()
local selection = actions.get_selected_entry(prompt_bufnr)
vim.api.nvim_win_set_cursor(0, {selection.lnum, 0})
end),
}
return true
end

View File

@@ -61,6 +61,9 @@ function Picker:new(opts)
error("layout_strategy and get_window_options are not compatible keys")
end
-- Reset actions for any replaced / enhanced actions.
actions._clear()
local layout_strategy = get_default(opts.layout_strategy, config.values.layout_strategy)
return setmetatable({
@@ -708,6 +711,8 @@ function Picker:set_selection(row)
local status = state.get_status(self.prompt_bufnr)
local results_bufnr = status.results_bufnr
state.set_global_key("selected_entry", entry)
if not vim.api.nvim_buf_is_valid(results_bufnr) then
return
end

View File

@@ -1,12 +1,21 @@
local state = {}
TelescopeGlobalState = TelescopeGlobalState or {}
TelescopeGlobalState.global = TelescopeGlobalState.global or {}
--- Set the status for a particular prompt bufnr
function state.set_status(prompt_bufnr, status)
TelescopeGlobalState[prompt_bufnr] = status
end
function state.set_global_key(key, value)
TelescopeGlobalState.global[key] = value
end
function state.get_global_key(key)
return TelescopeGlobalState.global[key]
end
function state.get_status(prompt_bufnr)
return TelescopeGlobalState[prompt_bufnr] or {}
end