feat: Add better mapping support
This commit is contained in:
61
lua/telescope/WIP.lua
Normal file
61
lua/telescope/WIP.lua
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
local finders = require('telescope.finders')
|
||||
local previewers = require('telescope.previewers')
|
||||
local pickers = require('telescope.pickers')
|
||||
local sorters = require('telescope.sorters')
|
||||
|
||||
local WIP = {}
|
||||
|
||||
WIP.git_diff = function()
|
||||
local file_picker = pickers.new {
|
||||
previewer = previewers.new_termopen {
|
||||
command = "git diff %s"
|
||||
},
|
||||
}
|
||||
|
||||
file_picker:find {
|
||||
prompt = "Git Diff Viewier",
|
||||
|
||||
finder = finders.new {
|
||||
static = true,
|
||||
|
||||
fn_command = function()
|
||||
return {
|
||||
command = 'git',
|
||||
args = {'ls-files', '-m'}
|
||||
}
|
||||
end,
|
||||
},
|
||||
|
||||
sorter = sorters.get_norcalli_sorter()
|
||||
}
|
||||
end
|
||||
|
||||
-- TODO: Make it so that when you select stuff, it's inserted
|
||||
-- TODO: Make it so the previewer shows the help text.
|
||||
WIP.completion = function()
|
||||
local results = {}
|
||||
for k, v in pairs(vim.api) do
|
||||
table.insert(results, k)
|
||||
end
|
||||
|
||||
local lsp_reference_finder = finders.new {
|
||||
results = results
|
||||
}
|
||||
|
||||
-- local reference_previewer = previewers.qflist
|
||||
local reference_picker = pickers.new {
|
||||
-- previewer = reference_previewer
|
||||
}
|
||||
|
||||
reference_picker:find {
|
||||
prompt = 'LSP References',
|
||||
finder = lsp_reference_finder,
|
||||
sorter = sorters.get_norcalli_sorter(),
|
||||
}
|
||||
end
|
||||
|
||||
-- TODO: Use tree sitter to get "everything" in your current scope / file / etc.
|
||||
-- Fuzzy find ofver it, go to its definition.
|
||||
|
||||
return WIP
|
||||
@@ -1,9 +1,14 @@
|
||||
-- Actions functions that are useful for people creating their own mappings.
|
||||
|
||||
local a = vim.api
|
||||
|
||||
local state = require('telescope.state')
|
||||
|
||||
local actions = {}
|
||||
|
||||
local actions = setmetatable({}, {
|
||||
__index = function(t, k)
|
||||
error("Actions does not have a value: " .. tostring(k))
|
||||
end
|
||||
})
|
||||
|
||||
--- Get the current picker object for the prompt
|
||||
function actions.get_current_picker(prompt_bufnr)
|
||||
@@ -16,10 +21,62 @@ 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
|
||||
|
||||
--- Get the current entry
|
||||
function actions.get_selected_entry(prompt_bufnr)
|
||||
return actions.get_current_picker(prompt_bufnr):get_selection()
|
||||
end
|
||||
|
||||
function actions.goto_file_selection(prompt_bufnr)
|
||||
local picker = actions.get_current_picker(prompt_bufnr)
|
||||
local entry = actions.get_selected_entry(prompt_bufnr)
|
||||
|
||||
if not entry then
|
||||
print("[telescope] Nothing currently selected")
|
||||
return
|
||||
else
|
||||
local value = entry.value
|
||||
if not value then
|
||||
print("Could not do anything with blank line...")
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO: This is not great.
|
||||
if type(value) == "table" then
|
||||
value = entry.display
|
||||
end
|
||||
|
||||
local sections = vim.split(value, ":")
|
||||
|
||||
local filename = sections[1]
|
||||
local row = tonumber(sections[2])
|
||||
local col = tonumber(sections[3])
|
||||
|
||||
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
||||
|
||||
a.nvim_set_current_win(picker.original_win_id or 0)
|
||||
vim.cmd(string.format(":e %s", filename))
|
||||
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
a.nvim_buf_set_option(bufnr, 'buflisted', true)
|
||||
if row and col then
|
||||
a.nvim_win_set_cursor(0, {row, col})
|
||||
end
|
||||
|
||||
vim.cmd [[stopinsert]]
|
||||
end
|
||||
end
|
||||
|
||||
actions.close = function(prompt_bufnr)
|
||||
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
||||
end
|
||||
|
||||
|
||||
return actions
|
||||
|
||||
@@ -18,9 +18,6 @@ builtin.git_files = function(opts)
|
||||
|
||||
local show_preview = ifnil(opts.show_preview, true, opts.show_preview)
|
||||
|
||||
-- TODO: Auto select bottom row
|
||||
-- TODO: filter out results when they don't match at all anymore.
|
||||
|
||||
local file_finder = finders.new {
|
||||
static = true,
|
||||
|
||||
@@ -236,6 +233,4 @@ builtin.grep_string = function(opts)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
|
||||
return builtin
|
||||
|
||||
@@ -149,6 +149,12 @@ finders.new = function(...)
|
||||
return Finder:new(...)
|
||||
end
|
||||
|
||||
-- We should add a few utility functions here...
|
||||
--
|
||||
-- finders.new_job
|
||||
-- finders.new_one_shot_job
|
||||
-- finders.new_table
|
||||
|
||||
finders.Finder = Finder
|
||||
|
||||
return finders
|
||||
|
||||
@@ -1,17 +1,36 @@
|
||||
-- TODO: Customize keymap
|
||||
local a = vim.api
|
||||
|
||||
local actions = require('telescope.actions')
|
||||
local state = require('telescope.state')
|
||||
|
||||
local mappings = {}
|
||||
local keymap = {}
|
||||
|
||||
local keymap_store = {}
|
||||
local keymap_store = setmetatable({}, {
|
||||
__index = function(t, k)
|
||||
rawset(t, k, {})
|
||||
|
||||
return rawget(t, k)
|
||||
end
|
||||
})
|
||||
|
||||
local _mapping_key_id = 0
|
||||
local get_next_id = function()
|
||||
_mapping_key_id = _mapping_key_id + 1
|
||||
return _mapping_key_id
|
||||
end
|
||||
|
||||
local assign_function = function(prompt_bufnr, func)
|
||||
local func_id = get_next_id()
|
||||
|
||||
keymap_store[prompt_bufnr][func_id] = func
|
||||
|
||||
return func_id
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Usage:
|
||||
|
||||
mappings.apply_keymap(42, {
|
||||
normal = {
|
||||
n = {
|
||||
["<leader>x"] = "just do this string",
|
||||
|
||||
["<CR>"] = function(picker, prompt_bufnr)
|
||||
@@ -21,11 +40,49 @@ mappings.apply_keymap(42, {
|
||||
vim.cmd(string.format(":e %s", filename))
|
||||
end,
|
||||
},
|
||||
insert = {
|
||||
|
||||
i = {
|
||||
}
|
||||
})
|
||||
--]]
|
||||
mappings.apply_keymap = function(prompt_bufnr, buffer_keymap)
|
||||
for mode, mode_map in pairs(buffer_keymap) do
|
||||
for key_bind, key_func in pairs(mode_map) do
|
||||
if type(key_func) == "string" then
|
||||
a.nvim_buf_set_keymap(
|
||||
prompt_bufnr,
|
||||
mode,
|
||||
key_bind,
|
||||
key_func,
|
||||
{
|
||||
silent = true
|
||||
}
|
||||
)
|
||||
else
|
||||
local key_id = assign_function(prompt_bufnr, key_func)
|
||||
local prefix = ""
|
||||
if mode == "i" then
|
||||
prefix = "<C-O>"
|
||||
end
|
||||
|
||||
a.nvim_buf_set_keymap(
|
||||
prompt_bufnr,
|
||||
mode,
|
||||
key_bind,
|
||||
string.format(
|
||||
"%s:lua require('telescope.mappings').execute_keymap(%s, %s)<CR>",
|
||||
prefix,
|
||||
prompt_bufnr,
|
||||
key_id
|
||||
),
|
||||
{
|
||||
silent = true
|
||||
}
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vim.cmd(string.format(
|
||||
[[autocmd BufDelete %s :lua require('telescope.mappings').clear(%s)]],
|
||||
@@ -34,95 +91,23 @@ mappings.apply_keymap = function(prompt_bufnr, buffer_keymap)
|
||||
))
|
||||
end
|
||||
|
||||
mappings.execute_keymap = function(prompt_bufnr, keymap_identifier)
|
||||
local key_func = keymap_store[prompt_bufnr][keymap_identifier]
|
||||
|
||||
assert(
|
||||
key_func,
|
||||
string.format(
|
||||
"Unsure of how we got this failure: %s %s",
|
||||
prompt_bufnr,
|
||||
keymap_identifier
|
||||
)
|
||||
)
|
||||
|
||||
key_func(prompt_bufnr)
|
||||
end
|
||||
|
||||
mappings.clear = function(prompt_bufnr)
|
||||
keymap_store[prompt_bufnr] = nil
|
||||
end
|
||||
|
||||
mappings.set_keymap = function(prompt_bufnr, results_bufnr)
|
||||
local function default_mapper(mode, map_key, table_key)
|
||||
a.nvim_buf_set_keymap(
|
||||
prompt_bufnr,
|
||||
mode,
|
||||
map_key,
|
||||
string.format(
|
||||
[[<C-O>:lua __TelescopeMapping(%s, %s, '%s')<CR>]],
|
||||
prompt_bufnr,
|
||||
results_bufnr,
|
||||
table_key
|
||||
),
|
||||
{
|
||||
silent = true,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
default_mapper('i', '<c-n>', 'next_selection')
|
||||
default_mapper('i', '<c-p>', 'previous_selection')
|
||||
default_mapper('i', '<CR>', 'enter')
|
||||
|
||||
default_mapper('n', '<esc>', 'escape')
|
||||
end
|
||||
|
||||
|
||||
function __TelescopeMapping(prompt_bufnr, results_bufnr, characters)
|
||||
if keymap[characters] then
|
||||
keymap[characters](prompt_bufnr, results_bufnr)
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: Refactor this to use shared code.
|
||||
-- TODO: Move from top to bottom, etc.
|
||||
-- TODO: It seems like doing this brings us back to the beginning of the prompt, which is not great.
|
||||
keymap["next_selection"] = function(prompt_bufnr, _)
|
||||
actions.shift_current_selection(prompt_bufnr, 1)
|
||||
end
|
||||
|
||||
keymap["previous_selection"] = function(prompt_bufnr, _)
|
||||
actions.shift_current_selection(prompt_bufnr, -1)
|
||||
end
|
||||
|
||||
keymap["enter"] = function(prompt_bufnr, results_bufnr)
|
||||
local picker = actions.get_current_picker(prompt_bufnr)
|
||||
local entry = actions.get_selected_entry(prompt_bufnr)
|
||||
|
||||
if not entry then
|
||||
print("[telescope] Nothing currently selected")
|
||||
return
|
||||
else
|
||||
local value = entry.value
|
||||
if not value then
|
||||
print("Could not do anything with blank line...")
|
||||
return
|
||||
end
|
||||
|
||||
-- TODO: This is not great.
|
||||
if type(value) == "table" then
|
||||
value = entry.display
|
||||
end
|
||||
|
||||
local sections = vim.split(value, ":")
|
||||
|
||||
local filename = sections[1]
|
||||
local row = tonumber(sections[2])
|
||||
local col = tonumber(sections[3])
|
||||
|
||||
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
||||
|
||||
a.nvim_set_current_win(picker.original_win_id or 0)
|
||||
vim.cmd(string.format(":e %s", filename))
|
||||
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
a.nvim_buf_set_option(bufnr, 'buflisted', true)
|
||||
if row and col then
|
||||
a.nvim_win_set_cursor(0, {row, col})
|
||||
end
|
||||
|
||||
vim.cmd [[stopinsert]]
|
||||
end
|
||||
end
|
||||
|
||||
keymap["escape"] = function(prompt_bufnr)
|
||||
vim.cmd(string.format([[bwipeout! %s]], prompt_bufnr))
|
||||
end
|
||||
|
||||
return mappings
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local a = vim.api
|
||||
local popup = require('popup')
|
||||
|
||||
local actions = require('telescope.actions')
|
||||
local log = require('telescope.log')
|
||||
local mappings = require('telescope.mappings')
|
||||
local state = require('telescope.state')
|
||||
@@ -16,6 +17,18 @@ local pickers = {}
|
||||
|
||||
local ifnil = function(x, was_nil, was_not_nil) if x == nil then return was_nil else return was_not_nil end end
|
||||
|
||||
local default_mappings = {
|
||||
i = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
["<C-p>"] = actions.move_selection_previous,
|
||||
["<CR>"] = actions.goto_file_selection,
|
||||
},
|
||||
|
||||
n = {
|
||||
["<esc>"] = actions.close,
|
||||
},
|
||||
}
|
||||
|
||||
-- Picker takes a function (`get_window_options`) that returns the configurations required for three windows:
|
||||
-- prompt
|
||||
-- results
|
||||
@@ -325,7 +338,8 @@ function Picker:find(opts)
|
||||
finder = finder,
|
||||
})
|
||||
|
||||
mappings.set_keymap(prompt_bufnr, results_bufnr)
|
||||
-- mappings.set_keymap(prompt_bufnr, results_bufnr)
|
||||
mappings.apply_keymap(prompt_bufnr, opts.mappings or default_mappings)
|
||||
|
||||
vim.cmd [[startinsert]]
|
||||
end
|
||||
|
||||
@@ -34,6 +34,27 @@ previewers.new = function(...)
|
||||
return Previewer:new(...)
|
||||
end
|
||||
|
||||
previewers.new_termopen = function(opts)
|
||||
local entry_value = opts.get_value or function(entry)
|
||||
return entry.value
|
||||
end
|
||||
|
||||
local command_string = opts.command
|
||||
|
||||
return previewers.new {
|
||||
preview_fn = function(_, entry, status)
|
||||
local bufnr = vim.api.nvim_create_buf(false, true)
|
||||
|
||||
vim.api.nvim_win_set_buf(status.preview_win, bufnr)
|
||||
|
||||
-- HACK! Requires `termopen` to accept buffer argument.
|
||||
vim.cmd(string.format("noautocmd call win_gotoid(%s)", status.preview_win))
|
||||
vim.fn.termopen(string.format(command_string, entry_value(entry)))
|
||||
vim.cmd(string.format("noautocmd call win_gotoid(%s)", status.prompt_win))
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
previewers.vim_buffer = previewers.new {
|
||||
preview_fn = function(_, entry, status)
|
||||
local value = entry.value
|
||||
|
||||
Reference in New Issue
Block a user