feat: Action improvements (#472)

* feat: replace_map

* feat: Add action_set and action_state

* fix: Move all actions.get_ to action_state.get_

* fix: replace all internal references of _goto_file_selection_edit

* feat: add some docs

* fix: lint

* feat: actions.select

* remove mentions and usage of goto_file_selection APIs

* feat: special case attach_mappings to be overridable and defaultable

* Having goto_file_selection mappings will cause a error

as well as replacing deprecated goto_file_selection methodes

For config and replacing use this instead:
- actions.select_default
- actions.select_horizonal
- actions.select_vertical
- actions.select_tab

Only replacing:
- actions.set.edit -- for replacing all select functions

* adds actions.state.select_key_to_edit_key

Co-authored-by: Simon Hauser <Simon-Hauser@outlook.de>
This commit is contained in:
TJ DeVries
2021-02-22 11:30:57 -05:00
committed by GitHub
parent 1c5e42a6a5
commit d7c02e3b52
16 changed files with 785 additions and 459 deletions

View File

@@ -1,6 +1,7 @@
local make_entry = require('telescope.make_entry')
local actions = require('telescope.actions')
local action_state = require('telescope.actions.state')
local finders = require('telescope.finders')
local previewers = require('telescope.previewers')
local pickers = require('telescope.pickers')
@@ -70,7 +71,7 @@ WIP.reloader = function(opts)
attach_mappings = function(prompt_bufnr, map)
local reload_package = function()
local selection = actions.get_selected_entry(prompt_bufnr)
local selection = action_state.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)

View File

@@ -3,162 +3,134 @@
local a = vim.api
local log = require('telescope.log')
local path = require('telescope.path')
local state = require('telescope.state')
local utils = require('telescope.utils')
local action_state = require('telescope.actions.state')
local action_set = require('telescope.actions.set')
local transform_mod = require('telescope.actions.mt').transform_mod
local actions = setmetatable({}, {
__index = function(_, k)
error("Actions does not have a value: " .. tostring(k))
-- TODO(conni2461): Remove deprecated messages
if k:find('goto_file_selection') then
error("`" .. k .. "` is removed and no longer usable. " ..
"Use `require('telescope.actions').select_` instead. Take a look at developers.md for more Information.")
elseif k == '_goto_file_selection' then
error("`_goto_file_selection` is deprecated and no longer replaceable. " ..
"Use `require('telescope.actions.set').edit` instead. Take a look at developers.md for more Information.")
end
error("Key does not exist for 'telescope.actions': " .. tostring(k))
end
})
--- Get the current picker object for the prompt
function actions.get_current_picker(prompt_bufnr)
return state.get_status(prompt_bufnr).picker
end
-- TODO(conni2461): Remove deprecated messages
local action_is_deprecated = function(name, err)
local messager = err and error or log.info
--- Move the current selection of a picker {change} rows.
--- Handles not overflowing / underflowing the list.
function actions.shift_current_selection(prompt_bufnr, change)
actions.get_current_picker(prompt_bufnr):move_selection(change)
end
function actions.move_selection_next(prompt_bufnr)
actions.shift_current_selection(prompt_bufnr, 1)
end
function actions.move_selection_previous(prompt_bufnr)
actions.shift_current_selection(prompt_bufnr, -1)
end
function actions.add_selection(prompt_bufnr)
local current_picker = actions.get_current_picker(prompt_bufnr)
current_picker:add_selection(current_picker:get_selection_row())
end
function actions.remove_selection(prompt_bufnr)
local current_picker = actions.get_current_picker(prompt_bufnr)
current_picker:remove_selection(current_picker:get_selection_row())
end
function actions.toggle_selection(prompt_bufnr)
local current_picker = actions.get_current_picker(prompt_bufnr)
current_picker:toggle_selection(current_picker:get_selection_row())
return messager(
string.format("`actions.%s()` is deprecated."
.. "Use require('telescope.actions.state').%s() instead",
name,
name
)
)
end
--- Get the current entry
function actions.get_selected_entry()
return state.get_global_key('selected_entry')
-- TODO(1.0): Remove
action_is_deprecated("get_selected_entry")
return action_state.get_selected_entry()
end
function actions.get_current_line()
return state.get_global_key('current_line')
-- TODO(1.0): Remove
action_is_deprecated("get_current_line")
return action_state.get_current_line()
end
--- Get the current picker object for the prompt
function actions.get_current_picker(prompt_bufnr)
-- TODO(1.0): Remove
action_is_deprecated("get_current_picker")
return action_state.get_current_picker(prompt_bufnr)
end
--- Move the selection to the next entry
function actions.move_selection_next(prompt_bufnr)
action_set.shift_selection(prompt_bufnr, 1)
end
--- Move the selection to the previous entry
function actions.move_selection_previous(prompt_bufnr)
action_set.shift_selection(prompt_bufnr, -1)
end
function actions.add_selection(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:add_selection(current_picker:get_selection_row())
end
function actions.remove_selection(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:remove_selection(current_picker:get_selection_row())
end
function actions.toggle_selection(prompt_bufnr)
local current_picker = action_state.get_current_picker(prompt_bufnr)
current_picker:toggle_selection(current_picker:get_selection_row())
end
function actions.preview_scrolling_up(prompt_bufnr)
actions.get_current_picker(prompt_bufnr).previewer:scroll_fn(-30)
-- TODO: Make number configurable.
action_state.get_current_picker(prompt_bufnr).previewer:scroll_fn(-30)
end
function actions.preview_scrolling_down(prompt_bufnr)
actions.get_current_picker(prompt_bufnr).previewer:scroll_fn(30)
end
-- TODO: It seems sometimes we get bad styling.
function actions._goto_file_selection(prompt_bufnr, command)
local entry = actions.get_selected_entry(prompt_bufnr)
if not entry then
print("[telescope] Nothing currently selected")
return
else
local filename, row, col
if entry.filename then
filename = entry.path or entry.filename
-- TODO: Check for off-by-one
row = entry.row or entry.lnum
col = entry.col
elseif not entry.bufnr then
-- TODO: Might want to remove this and force people
-- to put stuff into `filename`
local value = entry.value
if not value then
print("Could not do anything with blank line...")
return
end
if type(value) == "table" then
value = entry.display
end
local sections = vim.split(value, ":")
filename = sections[1]
row = tonumber(sections[2])
col = tonumber(sections[3])
end
local preview_win = state.get_status(prompt_bufnr).preview_win
if preview_win then
a.nvim_win_set_config(preview_win, {style = ''})
end
local entry_bufnr = entry.bufnr
actions.close(prompt_bufnr)
if entry_bufnr then
if command == 'edit' then
vim.cmd(string.format(":buffer %d", entry_bufnr))
elseif command == 'new' then
vim.cmd(string.format(":sbuffer %d", entry_bufnr))
elseif command == 'vnew' then
vim.cmd(string.format(":vert sbuffer %d", entry_bufnr))
elseif command == 'tabedit' then
vim.cmd(string.format(":tab sb %d", entry_bufnr))
end
else
filename = path.normalize(vim.fn.fnameescape(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))
bufnr = vim.api.nvim_get_current_buf()
a.nvim_buf_set_option(bufnr, "buflisted", true)
end
if row and col then
local ok, err_msg = pcall(a.nvim_win_set_cursor, 0, {row, col})
if not ok then
log.debug("Failed to move to cursor:", err_msg, row, col)
end
end
end
vim.api.nvim_command("doautocmd filetypedetect BufRead " .. vim.fn.fnameescape(filename))
end
-- TODO: Make number configurable.
action_state.get_current_picker(prompt_bufnr).previewer:scroll_fn(30)
end
function actions.center(_)
vim.cmd(':normal! zz')
end
function actions.goto_file_selection_edit(prompt_bufnr)
actions._goto_file_selection(prompt_bufnr, "edit")
function actions.select_default(prompt_bufnr)
return action_set.select(prompt_bufnr, "default")
end
function actions.goto_file_selection_split(prompt_bufnr)
actions._goto_file_selection(prompt_bufnr, "new")
function actions.select_horizontal(prompt_bufnr)
return action_set.select(prompt_bufnr, "horizontal")
end
function actions.goto_file_selection_vsplit(prompt_bufnr)
actions._goto_file_selection(prompt_bufnr, "vnew")
function actions.select_vertical(prompt_bufnr)
return action_set.select(prompt_bufnr, "vertical")
end
function actions.goto_file_selection_tabedit(prompt_bufnr)
actions._goto_file_selection(prompt_bufnr, "tabedit")
function actions.select_tab(prompt_bufnr)
return action_set.select(prompt_bufnr, "tab")
end
-- TODO: consider adding float!
-- https://github.com/nvim-telescope/telescope.nvim/issues/365
function actions.file_edit(prompt_bufnr)
return action_set.edit(prompt_bufnr, "edit")
end
function actions.file_split(prompt_bufnr)
return action_set.edit(prompt_bufnr, "new")
end
function actions.file_vsplit(prompt_bufnr)
return action_set.edit(prompt_bufnr, "vnew")
end
function actions.file_tab(prompt_bufnr)
return action_set.edit(prompt_bufnr, "tabedit")
end
function actions.close_pum(_)
@@ -168,7 +140,7 @@ function actions.close_pum(_)
end
local do_close = function(prompt_bufnr, keepinsert)
local picker = actions.get_current_picker(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
local prompt_win = state.get_status(prompt_bufnr).prompt_win
local original_win_id = picker.original_win_id
@@ -192,7 +164,7 @@ function actions.close(prompt_bufnr)
end
actions.set_command_line = function(prompt_bufnr)
local entry = actions.get_selected_entry(prompt_bufnr)
local entry = action_state.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)
vim.fn.histadd("cmd", entry.value)
@@ -200,8 +172,8 @@ actions.set_command_line = function(prompt_bufnr)
end
actions.edit_register = function(prompt_bufnr)
local entry = actions.get_selected_entry(prompt_bufnr)
local picker = actions.get_current_picker(prompt_bufnr)
local entry = action_state.get_selected_entry(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
vim.fn.inputsave()
local updated_value = vim.fn.input("Edit [" .. entry.value .. "] ", entry.content)
@@ -222,7 +194,7 @@ actions.edit_register = function(prompt_bufnr)
end
actions.paste_register = function(prompt_bufnr)
local entry = actions.get_selected_entry(prompt_bufnr)
local entry = action_state.get_selected_entry(prompt_bufnr)
actions.close(prompt_bufnr)
@@ -239,21 +211,21 @@ actions.paste_register = function(prompt_bufnr)
end
actions.run_builtin = function(prompt_bufnr)
local entry = actions.get_selected_entry(prompt_bufnr)
local entry = action_state.get_selected_entry(prompt_bufnr)
do_close(prompt_bufnr, true)
require('telescope.builtin')[entry.text]()
end
actions.insert_symbol = function(prompt_bufnr)
local selection = actions.get_selected_entry()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.api.nvim_put({selection.value[1]}, '', true, true)
end
-- TODO: Think about how to do this.
actions.insert_value = function(prompt_bufnr)
local entry = actions.get_selected_entry(prompt_bufnr)
local entry = action_state.get_selected_entry(prompt_bufnr)
vim.schedule(function()
actions.close(prompt_bufnr)
@@ -263,15 +235,15 @@ actions.insert_value = function(prompt_bufnr)
end
actions.git_checkout = function(prompt_bufnr)
local cwd = actions.get_current_picker(prompt_bufnr).cwd
local selection = actions.get_selected_entry()
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
utils.get_os_command_output({ 'git', 'checkout', selection.value }, cwd)
end
actions.git_staging_toggle = function(prompt_bufnr)
local cwd = actions.get_current_picker(prompt_bufnr).cwd
local selection = actions.get_selected_entry()
local cwd = action_state.get_current_picker(prompt_bufnr).cwd
local selection = action_state.get_selected_entry()
-- If parts of the file are staged and unstaged at the same time, stage
-- changes. Else toggle between staged and unstaged if the file is tracked,
@@ -296,7 +268,7 @@ local entry_to_qf = function(entry)
end
actions.send_selected_to_qflist = function(prompt_bufnr)
local picker = actions.get_current_picker(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
local qf_entries = {}
for entry in pairs(picker.multi_select) do
@@ -309,7 +281,7 @@ actions.send_selected_to_qflist = function(prompt_bufnr)
end
actions.send_to_qflist = function(prompt_bufnr)
local picker = actions.get_current_picker(prompt_bufnr)
local picker = action_state.get_current_picker(prompt_bufnr)
local manager = picker.manager
local qf_entries = {}

View File

@@ -1,23 +1,41 @@
local action_mt = {}
--- Checks all replacement combinations to determine which function to run.
--- If no replacement can be found, then it will run the original function
local run_replace_or_original = function(replacements, original_func, ...)
for _, replacement_map in ipairs(replacements or {}) do
for condition, replacement in pairs(replacement_map) do
if condition == true or condition(...) then
return replacement(...)
end
end
end
return original_func(...)
end
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](...)
for _, action_name in ipairs(t) do
if t._pre[action_name] then
t._pre[action_name](...)
end
local result = {func(...)}
local result = {
run_replace_or_original(
t._replacements[action_name],
mod[action_name],
...
)
}
for _, res in ipairs(result) do
table.insert(values, res)
end
if t._post[v] then
t._post[v](...)
if t._post[action_name] then
t._post[action_name](...)
end
end
@@ -54,8 +72,33 @@ action_mt.create = function(mod)
function mt:replace(v)
assert(#self == 1, "Cannot replace an already combined action")
return self:replace_map { [true] = v }
end
function mt:replace_if(condition, replacement)
assert(#self == 1, "Cannot replace an already combined action")
return self:replace_map { [condition] = replacement }
end
--- Replace table with
-- Example:
--
-- actions.select:replace_map {
-- [function() return filetype == 'lua' end] = actions.file_split,
-- [function() return filetype == 'other' end] = actions.file_split_edit,
-- }
function mt:replace_map(tbl)
assert(#self == 1, "Cannot replace an already combined action")
local action_name = self[1]
mt._replacements[action_name] = v
if not mt._replacements[action_name] then
mt._replacements[action_name] = {}
end
table.insert(mt._replacements[action_name], 1, tbl)
return self
end
function mt:enhance(opts)
@@ -69,6 +112,8 @@ action_mt.create = function(mod)
if opts.post then
mt._post[action_name] = opts.post
end
return self
end
return mt
@@ -81,7 +126,9 @@ end
action_mt.transform_mod = function(mod)
local mt = action_mt.create(mod)
local redirect = {}
-- Pass the metatable of the module if applicable.
-- This allows for custom errors, lookups, etc.
local redirect = setmetatable({}, getmetatable(mod) or {})
for k, _ in pairs(mod) do
redirect[k] = action_mt.transform(k, mt)

View File

@@ -0,0 +1,125 @@
local a = vim.api
local log = require('telescope.log')
local path = require('telescope.path')
local state = require('telescope.state')
local action_state = require('telescope.actions.state')
local transform_mod = require('telescope.actions.mt').transform_mod
--- Telescope action sets are used to provide an interface for managing
--- actions that all primarily do the same thing, but with slight tweaks.
---
--- For example, when editing files you may want it in the current split,
--- a vertical split, etc. Instead of making users have to overwrite EACH
--- of those every time they want to change this behavior, they can instead
--- replace the `set` itself and then it will work great and they're done.
local set = setmetatable({}, {
__index = function(_, k)
error("'telescope.actions.set' does not have a value: " .. tostring(k))
end
})
--- Move the current selection of a picker {change} rows.
--- Handles not overflowing / underflowing the list.
---@param prompt_bufnr number: The prompt bufnr
---@param change number: The amount to shift the selection by
set.shift_selection = function(prompt_bufnr, change)
action_state.get_current_picker(prompt_bufnr):move_selection(change)
end
--- Select the current entry. This is the action set to overwrite common
--- actions by the user.
---
--- By default maps to editing a file.
---@param prompt_bufnr number: The prompt bufnr
---@param type string: The type of selection to make
-- Valid types include: "default", "horizontal", "vertical", "tabedit"
set.select = function(prompt_bufnr, type)
return set.edit(prompt_bufnr, action_state.select_key_to_edit_key(type))
end
--- Edit a file based on the current selection.
---@param prompt_bufnr number: The prompt bufnr
---@param command string: The command to use to open the file.
-- Valid commands include: "edit", "new", "vedit", "tabedit"
set.edit = function(prompt_bufnr, command)
local entry = action_state.get_selected_entry()
if not entry then
print("[telescope] Nothing currently selected")
return
else
local filename, row, col
if entry.filename then
filename = entry.path or entry.filename
-- TODO: Check for off-by-one
row = entry.row or entry.lnum
col = entry.col
elseif not entry.bufnr then
-- TODO: Might want to remove this and force people
-- to put stuff into `filename`
local value = entry.value
if not value then
print("Could not do anything with blank line...")
return
end
if type(value) == "table" then
value = entry.display
end
local sections = vim.split(value, ":")
filename = sections[1]
row = tonumber(sections[2])
col = tonumber(sections[3])
end
local preview_win = state.get_status(prompt_bufnr).preview_win
if preview_win then
a.nvim_win_set_config(preview_win, {style = ''})
end
local entry_bufnr = entry.bufnr
require('telescope.actions').close(prompt_bufnr)
if entry_bufnr then
if command == 'edit' then
vim.cmd(string.format(":buffer %d", entry_bufnr))
elseif command == 'new' then
vim.cmd(string.format(":sbuffer %d", entry_bufnr))
elseif command == 'vnew' then
vim.cmd(string.format(":vert sbuffer %d", entry_bufnr))
elseif command == 'tabedit' then
vim.cmd(string.format(":tab sb %d", entry_bufnr))
end
else
filename = path.normalize(vim.fn.fnameescape(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))
bufnr = vim.api.nvim_get_current_buf()
a.nvim_buf_set_option(bufnr, "buflisted", true)
end
if row and col then
local ok, err_msg = pcall(a.nvim_win_set_cursor, 0, {row, col})
if not ok then
log.debug("Failed to move to cursor:", err_msg, row, col)
end
end
end
vim.api.nvim_command("doautocmd filetypedetect BufRead " .. vim.fn.fnameescape(filename))
end
end
-- ==================================================
-- Transforms modules and sets the corect metatables.
-- ==================================================
set = transform_mod(set)
return set

View File

@@ -0,0 +1,30 @@
local global_state = require('telescope.state')
local action_state = {}
--- Get the current entry
function action_state.get_selected_entry()
return global_state.get_global_key('selected_entry')
end
--- Gets the current line
function action_state.get_current_line()
return global_state.get_global_key('current_line')
end
--- Gets the current picker
function action_state.get_current_picker(prompt_bufnr)
return global_state.get_status(prompt_bufnr).picker
end
local select_to_edit_map = {
default = "edit",
horizontal = "new",
vertical = "vnew",
tab = "tabedit",
}
function action_state.select_key_to_edit_key(type)
return select_to_edit_map[type]
end
return action_state

View File

@@ -1,4 +1,5 @@
local actions = require('telescope.actions')
local action_state = require('telescope.actions.state')
local action_set = require('telescope.actions.set')
local finders = require('telescope.finders')
local make_entry = require('telescope.make_entry')
local pickers = require('telescope.pickers')
@@ -256,9 +257,9 @@ files.current_buffer_fuzzy_find = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function()
actions._goto_file_selection:enhance {
action_set.select:enhance {
post = function()
local selection = actions.get_selected_entry()
local selection = action_state.get_selected_entry()
vim.api.nvim_win_set_cursor(0, {selection.lnum, 0})
end,
}
@@ -292,9 +293,9 @@ files.tags = function(opts)
previewer = previewers.ctags.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function()
actions._goto_file_selection:enhance {
action_set.select:enhance {
post = function()
local selection = actions.get_selected_entry()
local selection = action_set.get_selected_entry()
if selection.scode then
local scode = string.gsub(selection.scode, '[$]$', '')

View File

@@ -47,7 +47,7 @@ git.commits = function(opts)
previewer = previewers.git_commit_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.goto_file_selection_edit:replace(actions.git_checkout)
actions.select_default:replace(actions.git_checkout)
return true
end
}):find()
@@ -67,7 +67,7 @@ git.bcommits = function(opts)
previewer = previewers.git_commit_diff.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.goto_file_selection_edit:replace(actions.git_checkout)
actions.select_default:replace(actions.git_checkout)
return true
end
}):find()
@@ -101,7 +101,7 @@ git.branches = function(opts)
previewer = previewers.git_branch_log.new(opts),
sorter = conf.file_sorter(opts),
attach_mappings = function()
actions.goto_file_selection_edit:replace(actions.git_checkout)
actions.select_default:replace(actions.git_checkout)
return true
end
}):find()

View File

@@ -1,4 +1,6 @@
local actions = require('telescope.actions')
local action_set = require('telescope.actions.set')
local action_state = require('telescope.actions.state')
local finders = require('telescope.finders')
local make_entry = require('telescope.make_entry')
local path = require('telescope.path')
@@ -47,7 +49,7 @@ internal.builtin = function(opts)
previewer = previewers.builtin.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function(_)
actions.goto_file_selection_edit:replace(actions.run_builtin)
actions.select_default:replace(actions.run_builtin)
return true
end
}):find()
@@ -82,8 +84,8 @@ internal.planets = function(opts)
previewer = previewers.cat.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
print("Enjoy astronomy! You viewed:", selection.display)
@@ -137,7 +139,7 @@ internal.symbols = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(_)
actions.goto_file_selection_edit:replace(actions.insert_symbol)
actions.select_default:replace(actions.insert_symbol)
return true
end
}):find()
@@ -168,8 +170,8 @@ internal.commands = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
local val = selection.value
local cmd = string.format([[:%s ]], val.name)
@@ -285,8 +287,8 @@ internal.vim_options = function(opts)
-- previewer = previewers.help.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function()
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
local esc = ""
if vim.fn.mode() == "i" then
@@ -411,14 +413,14 @@ internal.help_tags = function(opts)
previewer = previewers.help.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions._goto_file_selection:replace(function(_, cmd)
local selection = actions.get_selected_entry()
action_set.select:replace(function(_, cmd)
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
if cmd == 'edit' or cmd == 'new' then
if cmd == 'default' or cmd == 'horizontal' then
vim.cmd('help ' .. selection.value)
elseif cmd == 'vnew' then
elseif cmd == 'vertical' then
vim.cmd('vert bo help ' .. selection.value)
elseif cmd == 'tabedit' then
elseif cmd == 'tab' then
vim.cmd('tab help ' .. selection.value)
end
end)
@@ -443,16 +445,16 @@ internal.man_pages = function(opts)
previewer = previewers.man.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions._goto_file_selection:replace(function(_, cmd)
local selection = actions.get_selected_entry()
action_set.select:replace(function(_, cmd)
local selection = action_state.get_selected_entry()
local args = selection.section .. ' ' .. selection.value
actions.close(prompt_bufnr)
if cmd == 'edit' or cmd == 'new' then
if cmd == 'default' or cmd == 'horizontal' then
vim.cmd('Man ' .. args)
elseif cmd == 'vnew' then
elseif cmd == 'vertical' then
vim.cmd('vert bo Man ' .. args)
elseif cmd == 'tabedit' then
elseif cmd == 'tab' then
vim.cmd('tab Man ' .. args)
end
end)
@@ -487,8 +489,8 @@ internal.reloader = function(opts)
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
require('plenary.reload').reload_module(selection.value)
@@ -566,8 +568,8 @@ internal.colorscheme = function(opts)
-- TODO: better preview?
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.cmd("colorscheme " .. selection.value)
@@ -618,7 +620,7 @@ internal.registers = function(opts)
-- use levenshtein as n-gram doesn't support <2 char matches
sorter = sorters.get_levenshtein_sorter(),
attach_mappings = function(_, map)
actions.goto_file_selection_edit:replace(actions.paste_register)
actions.select_default:replace(actions.paste_register)
map('i', '<C-e>', actions.edit_register)
return true
@@ -657,8 +659,8 @@ internal.keymaps = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
vim.api.nvim_feedkeys(
vim.api.nvim_replace_termcodes(selection.value.lhs, true, false, true),
"t", true)
@@ -679,8 +681,8 @@ internal.filetypes = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.cmd('setfiletype ' .. selection[1])
end)
@@ -700,8 +702,8 @@ internal.highlights = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.cmd('hi ' .. selection.value)
end)
@@ -791,10 +793,10 @@ internal.autocommands = function(opts)
previewer = previewers.autocommands.new(opts),
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions._goto_file_selection:replace(function(_, vim_cmd)
local selection = actions.get_selected_entry()
action_set.select:replace(function(_, type)
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.cmd(vim_cmd .. ' ' .. selection.value)
vim.cmd(action_state.select_key_to_edit_key(type) .. ' ' .. selection.value)
end)
return true
@@ -815,8 +817,8 @@ internal.spell_suggest = function(opts)
},
sorter = conf.generic_sorter(opts),
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
vim.cmd('normal! ciw' .. selection[1])
vim.cmd('stopinsert')

View File

@@ -1,4 +1,5 @@
local actions = require('telescope.actions')
local action_state = require('telescope.actions.state')
local finders = require('telescope.finders')
local make_entry = require('telescope.make_entry')
local pickers = require('telescope.pickers')
@@ -116,8 +117,8 @@ lsp.code_actions = function(opts)
end
},
attach_mappings = function(prompt_bufnr)
actions.goto_file_selection_edit:replace(function()
local selection = actions.get_selected_entry()
actions.select_default:replace(function()
local selection = action_state.get_selected_entry()
actions.close(prompt_bufnr)
local val = selection.value

View File

@@ -87,7 +87,7 @@ function config.set_defaults(defaults)
-- Otherwise, just set the mapping to the function that you want it to be.
--
-- ...,
-- ["<C-i>"] = actions.goto_file_selection_split
-- ["<C-i>"] = actions.select_default
-- ...,
--
set("mappings", {})

View File

@@ -16,10 +16,10 @@ mappings.default_mappings = config.values.default_mappings or {
["<Down>"] = actions.move_selection_next,
["<Up>"] = actions.move_selection_previous,
["<CR>"] = actions.goto_file_selection_edit + actions.center,
["<C-x>"] = actions.goto_file_selection_split,
["<C-v>"] = actions.goto_file_selection_vsplit,
["<C-t>"] = actions.goto_file_selection_tabedit,
["<CR>"] = actions.select_default + actions.center,
["<C-x>"] = actions.select_horizontal,
["<C-v>"] = actions.select_vertical,
["<C-t>"] = actions.select_tab,
["<C-u>"] = actions.preview_scrolling_up,
["<C-d>"] = actions.preview_scrolling_down,
@@ -30,10 +30,10 @@ mappings.default_mappings = config.values.default_mappings or {
n = {
["<esc>"] = actions.close,
["<CR>"] = actions.goto_file_selection_edit + actions.center,
["<C-x>"] = actions.goto_file_selection_split,
["<C-v>"] = actions.goto_file_selection_vsplit,
["<C-t>"] = actions.goto_file_selection_tabedit,
["<CR>"] = actions.select_default + actions.center,
["<C-x>"] = actions.select_horizontal,
["<C-v>"] = actions.select_vertical,
["<C-t>"] = actions.select_tab,
-- TODO: This would be weird if we switch the ordering.
["j"] = actions.move_selection_next,
@@ -153,8 +153,19 @@ mappings.apply_keymap = function(prompt_bufnr, attach_mappings, buffer_keymap)
telescope_map(prompt_bufnr, mode, key_bind, key_func, opts)
end
if attach_mappings and not attach_mappings(prompt_bufnr, map) then
return
if attach_mappings then
local attach_results = attach_mappings(prompt_bufnr, map)
if attach_results == nil then
error(
"Attach mappings must always return a value. `true` means use default mappings, "
.. "`false` means only use attached mappings"
)
end
if not attach_results then
return
end
end
for mode, mode_map in pairs(buffer_keymap or {}) do

View File

@@ -4,6 +4,7 @@ local popup = require('popup')
require('telescope')
local actions = require('telescope.actions')
local action_set = require('telescope.actions.set')
local config = require('telescope.config')
local debounce = require('telescope.debounce')
local resolve = require('telescope.config.resolve')
@@ -21,25 +22,6 @@ local EntryManager = require('telescope.entry_manager')
local get_default = utils.get_default
-- TODO: Make this work with deep extend I think.
local extend = function(opts, defaults)
local result = {}
for k, v in pairs(opts or {}) do
assert(type(k) == 'string', "Should be string, opts")
result[k] = v
end
for k, v in pairs(defaults or {}) do
if result[k] == nil then
assert(type(k) == 'string', "Should be string, defaults")
result[k] = v
end
end
return result
end
local ns_telescope_matching = a.nvim_create_namespace('telescope_matching')
local ns_telescope_prompt = a.nvim_create_namespace('telescope_prompt')
local ns_telescope_prompt_prefix = a.nvim_create_namespace('telescope_prompt_prefix')
@@ -62,7 +44,10 @@ function Picker:new(opts)
end
-- Reset actions for any replaced / enhanced actions.
-- TODO: Think about how we could remember to NOT have to do this...
-- I almost forgot once already, cause I'm not smart enough to always do it.
actions._clear()
action_set._clear()
local layout_strategy = get_default(opts.layout_strategy, config.values.layout_strategy)
@@ -1016,7 +1001,31 @@ end
pickers.new = function(opts, defaults)
return Picker:new(extend(opts, defaults))
local result = {}
for k, v in pairs(opts or {}) do
assert(type(k) == 'string', "Should be string, opts")
result[k] = v
end
for k, v in pairs(defaults or {}) do
if result[k] == nil then
assert(type(k) == 'string', "Should be string, defaults")
result[k] = v
else
-- For attach mappings, we want people to be able to pass in another function
-- and apply their mappings after we've applied our defaults.
if k == 'attach_mappings' then
local opt_value = result[k]
result[k] = function(...)
v(...)
return opt_value(...)
end
end
end
end
return Picker:new(result)
end
function pickers.on_close_prompt(prompt_bufnr)