wip: Allow saving picker

This commit is contained in:
TJ DeVries
2021-04-28 11:50:04 -04:00
parent 38765f68db
commit 0ddab4030b
3 changed files with 135 additions and 143 deletions
+24 -48
View File
@@ -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
View File
@@ -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
View File
@@ -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