mirror of
https://github.com/zoriya/telescope.nvim.git
synced 2026-06-02 02:55:40 +00:00
wip: Allow saving picker
This commit is contained in:
@@ -21,50 +21,10 @@ local transform_mod = require('telescope.actions.mt').transform_mod
|
||||
|
||||
local actions = setmetatable({}, {
|
||||
__index = function(_, 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
|
||||
})
|
||||
|
||||
-- TODO(conni2461): Remove deprecated messages
|
||||
local action_is_deprecated = function(name, err)
|
||||
local messager = err and error or log.info
|
||||
|
||||
return messager(
|
||||
string.format("`actions.%s()` is deprecated."
|
||||
.. "Use require('telescope.actions.state').%s() instead",
|
||||
name,
|
||||
name
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
function actions.get_selected_entry()
|
||||
-- TODO(1.0): Remove
|
||||
action_is_deprecated("get_selected_entry")
|
||||
return action_state.get_selected_entry()
|
||||
end
|
||||
|
||||
function actions.get_current_line()
|
||||
-- TODO(1.0): Remove
|
||||
action_is_deprecated("get_current_line")
|
||||
return action_state.get_current_line()
|
||||
end
|
||||
|
||||
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
|
||||
---@param prompt_bufnr number: The prompt bufnr
|
||||
function actions.move_selection_next(prompt_bufnr)
|
||||
@@ -155,6 +115,17 @@ function actions.center(_)
|
||||
vim.cmd(':normal! zz')
|
||||
end
|
||||
|
||||
function actions.select_multi_default(prompt_bufnr)
|
||||
local picker = action_state.get_current_picker(prompt_bufnr)
|
||||
local manager = picker.manager
|
||||
|
||||
for entry in manager:iter() do
|
||||
action_set.select(entry)
|
||||
end
|
||||
|
||||
actions.close(prompt_bufnr)
|
||||
end
|
||||
|
||||
function actions.select_default(prompt_bufnr)
|
||||
return action_set.select(prompt_bufnr, "default")
|
||||
end
|
||||
@@ -197,31 +168,36 @@ function actions.close_pum(_)
|
||||
end
|
||||
|
||||
actions._close = function(prompt_bufnr, keepinsert)
|
||||
log.warn("Closing:", 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
|
||||
|
||||
if picker.previewer then
|
||||
picker.previewer:teardown()
|
||||
end
|
||||
-- TODO: I don't think I want this here, because it will get cleared
|
||||
-- when we do a NEW picker.
|
||||
-- picker:teardown()
|
||||
|
||||
actions.close_pum(prompt_bufnr)
|
||||
if not keepinsert then
|
||||
vim.cmd [[stopinsert]]
|
||||
end
|
||||
|
||||
vim.api.nvim_win_close(prompt_win, true)
|
||||
if prompt_win and a.nvim_win_is_valid(prompt_win) then
|
||||
vim.api.nvim_win_close(prompt_win, true)
|
||||
pcall(a.nvim_set_current_win, original_win_id)
|
||||
end
|
||||
|
||||
pcall(vim.cmd, string.format([[silent bdelete! %s]], prompt_bufnr))
|
||||
pcall(a.nvim_set_current_win, original_win_id)
|
||||
if prompt_bufnr and a.nvim_buf_is_valid(prompt_bufnr) then
|
||||
pcall(a.nvim_buf_delete, prompt_bufnr, { force = true })
|
||||
end
|
||||
end
|
||||
|
||||
function actions.close(prompt_bufnr)
|
||||
actions._close(prompt_bufnr, false)
|
||||
end
|
||||
|
||||
actions.edit_command_line = function(prompt_bufnr)
|
||||
local entry = action_state.get_selected_entry(prompt_bufnr)
|
||||
actions.edit_command_line = function(prompt_bufnr, entry)
|
||||
entry = entry or action_state.get_selected_entry(prompt_bufnr)
|
||||
actions.close(prompt_bufnr)
|
||||
a.nvim_feedkeys(a.nvim_replace_termcodes(":" .. entry.value , true, false, true), "t", true)
|
||||
end
|
||||
|
||||
+85
-84
@@ -1,3 +1,5 @@
|
||||
require('telescope')
|
||||
|
||||
local a = vim.api
|
||||
local popup = require('popup')
|
||||
|
||||
@@ -8,8 +10,6 @@ local async = async_lib.async
|
||||
local await = async_lib.await
|
||||
local channel = async_util.channel
|
||||
|
||||
require('telescope')
|
||||
|
||||
local actions = require('telescope.actions')
|
||||
local action_set = require('telescope.actions.set')
|
||||
local config = require('telescope.config')
|
||||
@@ -281,6 +281,8 @@ function Picker:_next_find_id()
|
||||
end
|
||||
|
||||
function Picker:find()
|
||||
state.set_current_picker(self)
|
||||
|
||||
self:close_existing_pickers()
|
||||
self:reset_selection()
|
||||
|
||||
@@ -421,21 +423,7 @@ function Picker:find()
|
||||
end)
|
||||
|
||||
-- Register attach
|
||||
vim.api.nvim_buf_attach(prompt_bufnr, false, {
|
||||
on_lines = tx.send,
|
||||
on_detach = function()
|
||||
-- TODO: Can we add a "cleanup" / "teardown" function that completely removes these.
|
||||
self.finder = nil
|
||||
self.previewer = nil
|
||||
self.sorter = nil
|
||||
self.manager = nil
|
||||
|
||||
self.closed = true
|
||||
|
||||
-- TODO: Should we actually do this?
|
||||
collectgarbage(); collectgarbage()
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_buf_attach(prompt_bufnr, false, { on_lines = tx.send })
|
||||
|
||||
if self.sorter then self.sorter:_init() end
|
||||
async_lib.run(main_loop())
|
||||
@@ -492,56 +480,6 @@ function Picker:hide_preview()
|
||||
end
|
||||
|
||||
|
||||
function Picker.close_windows(status)
|
||||
local prompt_win = status.prompt_win
|
||||
local results_win = status.results_win
|
||||
local preview_win = status.preview_win
|
||||
|
||||
local prompt_border_win = status.prompt_border_win
|
||||
local results_border_win = status.results_border_win
|
||||
local preview_border_win = status.preview_border_win
|
||||
|
||||
local function del_win(name, win_id, force, bdelete)
|
||||
if not vim.api.nvim_win_is_valid(win_id) then
|
||||
return
|
||||
end
|
||||
|
||||
local bufnr = vim.api.nvim_win_get_buf(win_id)
|
||||
if bdelete
|
||||
and vim.api.nvim_buf_is_valid(bufnr)
|
||||
and not vim.api.nvim_buf_get_option(bufnr, 'buflisted') then
|
||||
vim.cmd(string.format("silent! bdelete! %s", bufnr))
|
||||
end
|
||||
|
||||
if not vim.api.nvim_win_is_valid(win_id) then
|
||||
return
|
||||
end
|
||||
|
||||
if not pcall(vim.api.nvim_win_close, win_id, force) then
|
||||
log.trace("Unable to close window: ", name, "/", win_id)
|
||||
end
|
||||
end
|
||||
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
del_win("results_win", results_win, true, true)
|
||||
del_win("preview_win", preview_win, true, true)
|
||||
|
||||
del_win("prompt_border_win", prompt_border_win, true, true)
|
||||
del_win("results_border_win", results_border_win, true, true)
|
||||
del_win("preview_border_win", preview_border_win, true, true)
|
||||
|
||||
-- vim.cmd(string.format("bdelete! %s", status.prompt_bufnr))
|
||||
|
||||
-- Major hack?? Why do I have to od this.
|
||||
-- Probably because we're currently IN the buffer.
|
||||
-- Should wait to do this until after we're done.
|
||||
vim.defer_fn(function()
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
end, 10)
|
||||
|
||||
state.clear_status(status.prompt_bufnr)
|
||||
end
|
||||
|
||||
function Picker:get_selection()
|
||||
return self._selection_entry
|
||||
end
|
||||
@@ -872,9 +810,16 @@ function Picker:_on_complete()
|
||||
end
|
||||
end
|
||||
|
||||
--- TODO: Can we remove this?
|
||||
function Picker:close_existing_pickers()
|
||||
for _, prompt_bufnr in ipairs(state.get_existing_prompts()) do
|
||||
pcall(actions.close, prompt_bufnr)
|
||||
error("Shouldn't happen -- close_existing_pickers: " .. tostring(prompt_bufnr))
|
||||
-- pcall(actions.close, prompt_bufnr)
|
||||
-- local prompt_picker = (state.get_status(prompt_bufnr) or {}).picker
|
||||
-- if prompt_picker then
|
||||
-- log.warn("Tearing down picker...")
|
||||
-- prompt_picker:teardown()
|
||||
-- end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1036,21 +981,6 @@ pickers.new = function(opts, defaults)
|
||||
return Picker:new(result)
|
||||
end
|
||||
|
||||
function pickers.on_close_prompt(prompt_bufnr)
|
||||
local status = state.get_status(prompt_bufnr)
|
||||
local picker = status.picker
|
||||
|
||||
if picker.sorter then
|
||||
picker.sorter:_destroy()
|
||||
end
|
||||
|
||||
if picker.previewer then
|
||||
picker.previewer:teardown()
|
||||
end
|
||||
|
||||
picker.close_windows(status)
|
||||
end
|
||||
|
||||
--- Get the prompt text without the prompt prefix.
|
||||
function Picker:_get_prompt()
|
||||
return vim.api.nvim_buf_get_lines(self.prompt_bufnr, 0, 1, false)[1]:sub(#self.prompt_prefix + 1)
|
||||
@@ -1060,7 +990,78 @@ function Picker:_reset_highlights()
|
||||
self.highlighter:clear_display()
|
||||
end
|
||||
|
||||
function pickers.on_close_prompt(prompt_bufnr)
|
||||
pickers.close_windows(state.get_status(prompt_bufnr))
|
||||
end
|
||||
|
||||
function pickers.close_windows(status)
|
||||
local prompt_win = status.prompt_win
|
||||
local results_win = status.results_win
|
||||
local preview_win = status.preview_win
|
||||
|
||||
local prompt_border_win = status.prompt_border_win
|
||||
local results_border_win = status.results_border_win
|
||||
local preview_border_win = status.preview_border_win
|
||||
|
||||
local function del_win(name, win_id, force, bdelete)
|
||||
if not vim.api.nvim_win_is_valid(win_id) then
|
||||
return
|
||||
end
|
||||
|
||||
local bufnr = vim.api.nvim_win_get_buf(win_id)
|
||||
if bdelete
|
||||
and vim.api.nvim_buf_is_valid(bufnr)
|
||||
and not vim.api.nvim_buf_get_option(bufnr, 'buflisted') then
|
||||
a.nvim_buf_delete(bufnr, { force = true })
|
||||
end
|
||||
|
||||
if not vim.api.nvim_win_is_valid(win_id) then
|
||||
return
|
||||
end
|
||||
|
||||
if not pcall(vim.api.nvim_win_close, win_id, force) then
|
||||
log.trace("Unable to close window: ", name, "/", win_id)
|
||||
end
|
||||
end
|
||||
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
del_win("results_win", results_win, true, true)
|
||||
del_win("preview_win", preview_win, true, true)
|
||||
|
||||
del_win("prompt_border_win", prompt_border_win, true, true)
|
||||
del_win("results_border_win", results_border_win, true, true)
|
||||
del_win("preview_border_win", preview_border_win, true, true)
|
||||
|
||||
-- Major hack?? Why do I have to od this.
|
||||
-- Probably because we're currently IN the buffer.
|
||||
-- Should wait to do this until after we're done.
|
||||
vim.defer_fn(function()
|
||||
del_win("prompt_win", prompt_win, true)
|
||||
end, 10)
|
||||
|
||||
state.clear_status(status.prompt_bufnr)
|
||||
end
|
||||
|
||||
|
||||
function Picker:teardown()
|
||||
log.warn("CLEARING PICKER NOW")
|
||||
|
||||
if self.sorter then
|
||||
self.sorter:_destroy()
|
||||
end
|
||||
|
||||
if self.previewer then
|
||||
self.previewer:teardown()
|
||||
end
|
||||
|
||||
for k, _ in pairs(self) do
|
||||
self[k] = nil
|
||||
end
|
||||
|
||||
collectgarbage()
|
||||
collectgarbage()
|
||||
end
|
||||
|
||||
pickers._Picker = Picker
|
||||
|
||||
|
||||
return pickers
|
||||
|
||||
+26
-11
@@ -1,23 +1,38 @@
|
||||
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
|
||||
_TelescopeGlobalState = _TelescopeGlobalState or {}
|
||||
_TelescopeGlobalState.global = _TelescopeGlobalState.global or {}
|
||||
_TelescopeGlobalState.prompt = _TelescopeGlobalState.prompt or {}
|
||||
|
||||
function state.set_global_key(key, value)
|
||||
TelescopeGlobalState.global[key] = value
|
||||
_TelescopeGlobalState.global[key] = value
|
||||
end
|
||||
|
||||
function state.get_global_key(key)
|
||||
return TelescopeGlobalState.global[key]
|
||||
return _TelescopeGlobalState.global[key]
|
||||
end
|
||||
|
||||
function state.set_current_picker(picker)
|
||||
local old_picker = state.get_current_picker()
|
||||
if old_picker then
|
||||
old_picker:teardown()
|
||||
old_picker = nil
|
||||
end
|
||||
|
||||
state.set_global_key('picker', picker)
|
||||
end
|
||||
|
||||
function state.get_current_picker()
|
||||
return state.get_global_key('picker')
|
||||
end
|
||||
|
||||
--- Set the status for a particular prompt bufnr
|
||||
function state.set_status(prompt_bufnr, status)
|
||||
_TelescopeGlobalState.prompt[prompt_bufnr] = status
|
||||
end
|
||||
|
||||
function state.get_status(prompt_bufnr)
|
||||
return TelescopeGlobalState[prompt_bufnr] or {}
|
||||
return _TelescopeGlobalState.prompt[prompt_bufnr] or {}
|
||||
end
|
||||
|
||||
function state.clear_status(prompt_bufnr)
|
||||
@@ -25,7 +40,7 @@ function state.clear_status(prompt_bufnr)
|
||||
end
|
||||
|
||||
function state.get_existing_prompts()
|
||||
return vim.tbl_keys(TelescopeGlobalState)
|
||||
return vim.tbl_keys(_TelescopeGlobalState.prompt)
|
||||
end
|
||||
|
||||
return state
|
||||
|
||||
Reference in New Issue
Block a user