cleanup!: Remove prompt buffer implementation for ui.input
The `prompt_buffer = true` option will no longer function. The only input modal implementation will use a normal scratch buffer.
This commit is contained in:
parent
0ad4d1e6b9
commit
f487c89b56
|
@ -1,11 +1,3 @@
|
|||
func! dressing#prompt_confirm(text) abort
|
||||
call luaeval("require('dressing.input').confirm(_A)", a:text)
|
||||
endfunc
|
||||
|
||||
func! dressing#prompt_cancel() abort
|
||||
lua require('dressing.input').confirm()
|
||||
endfunc
|
||||
|
||||
function! dressing#fzf_run(labels, options, window) abort
|
||||
call fzf#run({
|
||||
\ 'source': a:labels,
|
||||
|
|
|
@ -119,21 +119,6 @@ dressing.get_config() *dressing_get_config()
|
|||
}
|
||||
})
|
||||
|
||||
===============================================================================
|
||||
*dressing-prompt*
|
||||
Vim has a mechanism that is built for getting input from the user: the
|
||||
|prompt-buffer|. This is a specific |buftype| and comes with a lot of special
|
||||
handling within vim. Neovim 0.6 and earlier has some bugs with the prompt
|
||||
buffer (see https://github.com/stevearc/dressing.nvim/issues/2 and
|
||||
https://github.com/neovim/neovim/issues/13715). For this reason, the default
|
||||
implementation of |vim.ui.input| does NOT use the prompt buffer, and instead
|
||||
mimics its behavior through other means. If you don't mind the bugs, or if
|
||||
you're on a version of Neovim after 0.6 (nightly has the fixes now), you can
|
||||
pass `prompt_buffer = true` to use that implementation.
|
||||
|
||||
There are slight visual differences in where the "prompt" text in placed, but
|
||||
otherwise they should be functionally identical.
|
||||
|
||||
===============================================================================
|
||||
*dressing-format*
|
||||
Sometimes you may wish to change how choices are displayed for
|
||||
|
|
1
doc/tags
1
doc/tags
|
@ -2,7 +2,6 @@ Dressing dressing.txt /*Dressing*
|
|||
dressing dressing.txt /*dressing*
|
||||
dressing-configuration dressing.txt /*dressing-configuration*
|
||||
dressing-format dressing.txt /*dressing-format*
|
||||
dressing-prompt dressing.txt /*dressing-prompt*
|
||||
dressing.nvim dressing.txt /*dressing.nvim*
|
||||
dressing.txt dressing.txt /*dressing.txt*
|
||||
dressing_get_config() dressing.txt /*dressing_get_config()*
|
||||
|
|
|
@ -4,16 +4,6 @@ local M = {}
|
|||
|
||||
M.setup = function(opts)
|
||||
config.update(opts)
|
||||
-- Wait until vim has fully started up before we show deprecation warnings
|
||||
vim.defer_fn(function()
|
||||
if config.input.prompt_buffer then
|
||||
vim.notify(
|
||||
"dressing.nvim option 'input.prompt_buffer = true' is deprecated and will be removed in a future version. If you want it to continue to be supported please file an issue with your use case: https://github.com/stevearc/dressing.nvim/issues/new",
|
||||
vim.log.levels.WARN,
|
||||
{}
|
||||
)
|
||||
end
|
||||
end, 100)
|
||||
end
|
||||
|
||||
local original_input
|
||||
|
|
|
@ -15,7 +15,7 @@ local function close_completion_window()
|
|||
end
|
||||
end
|
||||
|
||||
M.confirm = function(text)
|
||||
local function confirm(text)
|
||||
if not context.on_confirm then
|
||||
return
|
||||
end
|
||||
|
@ -41,13 +41,13 @@ M.confirm = function(text)
|
|||
end, 5)
|
||||
end
|
||||
|
||||
M.confirm_non_prompt = function()
|
||||
M.confirm = function()
|
||||
local text = vim.api.nvim_buf_get_lines(0, 0, 1, true)[1]
|
||||
M.confirm(text)
|
||||
confirm(text)
|
||||
end
|
||||
|
||||
M.close = function()
|
||||
M.confirm()
|
||||
confirm()
|
||||
end
|
||||
|
||||
M.highlight = function()
|
||||
|
@ -88,11 +88,7 @@ M.completefunc = function(findstart, base)
|
|||
return findstart == 1 and 0 or {}
|
||||
end
|
||||
if findstart == 1 then
|
||||
if global_config.input.prompt_buffer then
|
||||
return vim.api.nvim_strwidth(context.opts.prompt)
|
||||
else
|
||||
return 0
|
||||
end
|
||||
return 0
|
||||
else
|
||||
local completion = context.opts.completion
|
||||
local pieces = split(completion, ",")
|
||||
|
@ -140,12 +136,7 @@ setmetatable(M, {
|
|||
|
||||
-- Create or update the window
|
||||
local prompt = opts.prompt or config.default_prompt
|
||||
local width
|
||||
if config.prompt_buffer then
|
||||
width = util.calculate_width(config.prefer_width + vim.api.nvim_strwidth(prompt), config)
|
||||
else
|
||||
width = util.calculate_width(config.prefer_width, config)
|
||||
end
|
||||
local width = util.calculate_width(config.prefer_width, config)
|
||||
local winopt = {
|
||||
relative = config.relative,
|
||||
anchor = config.anchor,
|
||||
|
@ -187,27 +178,17 @@ setmetatable(M, {
|
|||
vim.api.nvim_buf_set_keymap(bufnr, "i", "<Esc>", close_rhs, keyopts)
|
||||
end
|
||||
|
||||
if config.prompt_buffer then
|
||||
vim.api.nvim_buf_set_option(bufnr, "buftype", "prompt")
|
||||
vim.fn.prompt_setprompt(bufnr, prompt)
|
||||
-- Would prefer to use v:lua directly here, but it doesn't work :(
|
||||
vim.fn.prompt_setcallback(bufnr, "dressing#prompt_confirm")
|
||||
vim.fn.prompt_setinterrupt(bufnr, "dressing#prompt_cancel")
|
||||
else
|
||||
local confirm_rhs = "<cmd>lua require('dressing.input').confirm_non_prompt()<CR>"
|
||||
-- If we're not using the prompt buffer, we need to put the prompt into a
|
||||
-- separate title window that will appear in the input window border
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "i", "<C-c>", close_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "i", "<CR>", confirm_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "n", "<CR>", confirm_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, { opts.default or "" })
|
||||
-- Disable nvim-cmp if installed
|
||||
local ok, cmp = pcall(require, "cmp")
|
||||
if ok then
|
||||
cmp.setup.buffer({ enabled = false })
|
||||
end
|
||||
util.add_title_to_win(winid, string.gsub(prompt, "^%s*(.-)%s*$", "%1"), { align = "left" })
|
||||
local confirm_rhs = "<cmd>lua require('dressing.input').confirm()<CR>"
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "i", "<C-c>", close_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "i", "<CR>", confirm_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, "n", "<CR>", confirm_rhs, keyopts)
|
||||
vim.api.nvim_buf_set_lines(bufnr, 0, -1, true, { opts.default or "" })
|
||||
-- Disable nvim-cmp if installed
|
||||
local ok, cmp = pcall(require, "cmp")
|
||||
if ok then
|
||||
cmp.setup.buffer({ enabled = false })
|
||||
end
|
||||
util.add_title_to_win(winid, string.gsub(prompt, "^%s*(.-)%s*$", "%1"), { align = "left" })
|
||||
|
||||
vim.cmd([[
|
||||
aug DressingHighlight
|
||||
|
@ -237,10 +218,6 @@ setmetatable(M, {
|
|||
]])
|
||||
|
||||
vim.cmd("startinsert!")
|
||||
if opts.default and config.prompt_buffer then
|
||||
vim.api.nvim_feedkeys(opts.default, "n", false)
|
||||
end
|
||||
|
||||
close_completion_window()
|
||||
M.highlight()
|
||||
end,
|
||||
|
|
|
@ -17,133 +17,121 @@ local function run_input(keys, opts)
|
|||
return rx()
|
||||
end
|
||||
|
||||
for _, prompt_buffer in ipairs({ true, false }) do
|
||||
a.describe(
|
||||
string.format("input (%s)", prompt_buffer and "prompt buffer" or "normal floatwin"),
|
||||
function()
|
||||
before_each(function()
|
||||
dressing.patch()
|
||||
dressing.setup({
|
||||
input = {
|
||||
prompt_buffer = prompt_buffer,
|
||||
},
|
||||
})
|
||||
end)
|
||||
a.describe("input modal", function()
|
||||
before_each(function()
|
||||
dressing.patch()
|
||||
dressing.setup()
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
-- Clean up all floating windows so one test failure doesn't cascade
|
||||
for _, winid in ipairs(vim.api.nvim_list_wins()) do
|
||||
if vim.api.nvim_win_get_config(winid).relative ~= "" then
|
||||
vim.api.nvim_win_close(winid, true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
after_each(function()
|
||||
-- Clean up all floating windows so one test failure doesn't cascade
|
||||
for _, winid in ipairs(vim.api.nvim_list_wins()) do
|
||||
if vim.api.nvim_win_get_config(winid).relative ~= "" then
|
||||
vim.api.nvim_win_close(winid, true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
a.it("accepts input", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<CR>",
|
||||
})
|
||||
assert(ret == "my text", string.format("Got '%s' expected 'my text'", ret))
|
||||
end)
|
||||
a.it("accepts input", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<CR>",
|
||||
})
|
||||
assert(ret == "my text", string.format("Got '%s' expected 'my text'", ret))
|
||||
end)
|
||||
|
||||
a.it("Cancels input on <C-c>", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<C-c>",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
a.it("Cancels input on <C-c>", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<C-c>",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
|
||||
a.it("cancels input when leaving the window", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
}, {
|
||||
after_fn = function()
|
||||
vim.cmd([[wincmd p]])
|
||||
end,
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
a.it("cancels input when leaving the window", function()
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
}, {
|
||||
after_fn = function()
|
||||
vim.cmd([[wincmd p]])
|
||||
end,
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
|
||||
a.it("cancels on <Esc> when insert_only = true", function()
|
||||
require("dressing.config").input.insert_only = true
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<Esc>",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
a.it("cancels on <Esc> when insert_only = true", function()
|
||||
require("dressing.config").input.insert_only = true
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<Esc>",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
|
||||
a.it("does not cancel on <Esc> when insert_only = false", function()
|
||||
require("dressing.config").input.insert_only = false
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<Esc>",
|
||||
"<CR>",
|
||||
})
|
||||
assert(ret == "my text", string.format("Got '%s' expected 'my text'", ret))
|
||||
end)
|
||||
a.it("does not cancel on <Esc> when insert_only = false", function()
|
||||
require("dressing.config").input.insert_only = false
|
||||
local ret = run_input({
|
||||
"my text",
|
||||
"<Esc>",
|
||||
"<CR>",
|
||||
})
|
||||
assert(ret == "my text", string.format("Got '%s' expected 'my text'", ret))
|
||||
end)
|
||||
|
||||
a.it("cancels first callback if second input is opened", function()
|
||||
local tx, rx = channel.oneshot()
|
||||
vim.ui.input({}, tx)
|
||||
util.feedkeys({
|
||||
"i", -- HACK have to do this because :startinsert doesn't work in tests,
|
||||
"my text",
|
||||
})
|
||||
vim.ui.input({}, function() end)
|
||||
local ret = rx()
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
a.it("cancels first callback if second input is opened", function()
|
||||
local tx, rx = channel.oneshot()
|
||||
vim.ui.input({}, tx)
|
||||
util.feedkeys({
|
||||
"i", -- HACK have to do this because :startinsert doesn't work in tests,
|
||||
"my text",
|
||||
})
|
||||
vim.ui.input({}, function() end)
|
||||
local ret = rx()
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
end)
|
||||
|
||||
-- TODO can't get this working in the prompt buffer test
|
||||
if not prompt_buffer then
|
||||
a.it("supports completion", function()
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
vim.cmd([[
|
||||
a.it("supports completion", function()
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
vim.cmd([[
|
||||
function! CustomComplete(arglead, cmdline, cursorpos)
|
||||
return "first\nsecond\nthird"
|
||||
endfunction
|
||||
]])
|
||||
local ret = run_input({
|
||||
"<Tab><Tab><C-n><CR>", -- Using tab twice to test both versions of the mapping
|
||||
}, {
|
||||
completion = "custom,CustomComplete",
|
||||
})
|
||||
assert(ret == "second", string.format("Got '%s' expected 'second'", ret))
|
||||
assert(vim.fn.pumvisible() == 0, "Popup menu should not be visible after leaving modal")
|
||||
end)
|
||||
local ret = run_input({
|
||||
"<Tab><Tab><C-n><CR>", -- Using tab twice to test both versions of the mapping
|
||||
}, {
|
||||
completion = "custom,CustomComplete",
|
||||
})
|
||||
assert(ret == "second", string.format("Got '%s' expected 'second'", ret))
|
||||
assert(vim.fn.pumvisible() == 0, "Popup menu should not be visible after leaving modal")
|
||||
end)
|
||||
|
||||
a.it("can cancel out when popup menu is open", function()
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
local ret = run_input({
|
||||
"<Tab>",
|
||||
"<C-c>",
|
||||
}, {
|
||||
completion = "command",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
assert(vim.fn.pumvisible() == 0, "Popup menu should not be visible after leaving modal")
|
||||
end)
|
||||
a.it("can cancel out when popup menu is open", function()
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
local ret = run_input({
|
||||
"<Tab>",
|
||||
"<C-c>",
|
||||
}, {
|
||||
completion = "command",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
assert(vim.fn.pumvisible() == 0, "Popup menu should not be visible after leaving modal")
|
||||
end)
|
||||
|
||||
a.it("doesn't delete text in original buffer", function()
|
||||
-- This is a regression test for weird behavior I was seeing with the
|
||||
-- completion popup menu
|
||||
vim.api.nvim_buf_set_lines(0, 0, 1, true, { "some text" })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 4 })
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
local ret = run_input({
|
||||
"<Tab>",
|
||||
"<C-c>",
|
||||
}, {
|
||||
completion = "command",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
local line = vim.api.nvim_buf_get_lines(0, 0, 1, true)[1]
|
||||
assert(line == "some text", "Doing <C-c> with popup menu open deleted buffer text o.0")
|
||||
end)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
a.it("doesn't delete text in original buffer", function()
|
||||
-- This is a regression test for weird behavior I was seeing with the
|
||||
-- completion popup menu
|
||||
vim.api.nvim_buf_set_lines(0, 0, 1, true, { "some text" })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 4 })
|
||||
vim.opt.completeopt = { "menu", "menuone", "noselect" }
|
||||
local ret = run_input({
|
||||
"<Tab>",
|
||||
"<C-c>",
|
||||
}, {
|
||||
completion = "command",
|
||||
})
|
||||
assert(ret == nil, string.format("Got '%s' expected nil", ret))
|
||||
local line = vim.api.nvim_buf_get_lines(0, 0, 1, true)[1]
|
||||
assert(line == "some text", "Doing <C-c> with popup menu open deleted buffer text o.0")
|
||||
end)
|
||||
end)
|
||||
|
|
Loading…
Reference in New Issue