mirror of
https://github.com/neovim/neovim.git
synced 2025-11-21 09:36:29 +00:00
feat(prompt): multiline prompt input #33371
Problem: Cannot enter multiline prompts in a buftype=prompt buffer. Solution: - Support shift+enter (`<s-enter>`) to start a new line in the prompt. - Pasting multiline text via OS paste, clipboard, "xp, etc. - A/I in editable region works as usual. - i/a/A/I outside of editable region moves cursor to end of current prompt. - Support undo/redo in prompt buffer. - Support o/O in prompt buffer. - Expose prompt location as `':` mark.
This commit is contained in:
@@ -3,6 +3,7 @@ local n = require('test.functional.testnvim')()
|
||||
local Screen = require('test.functional.ui.screen')
|
||||
|
||||
local feed = n.feed
|
||||
local fn = n.call
|
||||
local source = n.source
|
||||
local clear = n.clear
|
||||
local command = n.command
|
||||
@@ -31,7 +32,7 @@ describe('prompt buffer', function()
|
||||
close
|
||||
else
|
||||
" Add the output above the current prompt.
|
||||
call append(line("$") - 1, 'Command: "' . a:text . '"')
|
||||
call append(line("$") - 1, split('Command: "' . a:text . '"', '\n'))
|
||||
" Reset &modified to allow the buffer to be closed.
|
||||
set nomodified
|
||||
call timer_start(20, {id -> TimerFunc(a:text)})
|
||||
@@ -40,7 +41,7 @@ describe('prompt buffer', function()
|
||||
|
||||
func TimerFunc(text)
|
||||
" Add the output above the current prompt.
|
||||
call append(line("$") - 1, 'Result: "' . a:text .'"')
|
||||
call append(line("$") - 1, split('Result: "' . a:text .'"', '\n'))
|
||||
" Reset &modified to allow the buffer to be closed.
|
||||
set nomodified
|
||||
endfunc
|
||||
@@ -245,4 +246,280 @@ describe('prompt buffer', function()
|
||||
Leave
|
||||
Close]])
|
||||
end)
|
||||
|
||||
it('can insert mutli line text', function()
|
||||
source_script()
|
||||
feed('line 1<s-cr>line 2<s-cr>line 3')
|
||||
screen:expect([[
|
||||
cmd: line 1 |
|
||||
line 2 |
|
||||
line 3^ |
|
||||
{1:~ }|
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<cr>')
|
||||
-- submiting multiline text works
|
||||
screen:expect([[
|
||||
Result: "line 1 |
|
||||
line 2 |
|
||||
line 3" |
|
||||
cmd: ^ |
|
||||
{3:[Prompt] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can paste multiline text', function()
|
||||
source_script()
|
||||
fn('setreg', 'a', 'line 1\nline 2\nline 3')
|
||||
feed('<esc>"ap')
|
||||
screen:expect([[
|
||||
cmd: ^line 1 |
|
||||
line 2 |
|
||||
line 3 |
|
||||
{1:~ }|
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
feed('i<cr>')
|
||||
screen:expect([[
|
||||
Result: "line 1 |
|
||||
line 2 |
|
||||
line 3" |
|
||||
cmd: ^ |
|
||||
{3:[Prompt] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('undo works for current prompt', function()
|
||||
source_script()
|
||||
-- text editiing alowed in current prompt
|
||||
feed('tests-initial<esc>')
|
||||
feed('bimiddle-<esc>')
|
||||
screen:expect([[
|
||||
cmd: tests-middle^-initial|
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
|
||||
feed('Fdx')
|
||||
screen:expect([[
|
||||
cmd: tests-mid^le-initial |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
|
||||
-- can undo edits until prompt has been submitted
|
||||
feed('u')
|
||||
screen:expect([[
|
||||
cmd: tests-mid^dle-initial|
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
1 change; {MATCH:.*} |
|
||||
]])
|
||||
|
||||
feed('u')
|
||||
screen:expect([[
|
||||
cmd: tests-^initial |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
1 change; {MATCH:.*} |
|
||||
]])
|
||||
|
||||
feed('i<cr><esc>')
|
||||
screen:expect([[
|
||||
cmd: tests-initial |
|
||||
Command: "tests-initial" |
|
||||
Result: "tests-initial" |
|
||||
cmd:^ |
|
||||
{3:[Prompt] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
|
||||
-- after submit undo does nothing
|
||||
feed('u')
|
||||
screen:expect([[
|
||||
cmd: tests-initial |
|
||||
Command: "tests-initial" |
|
||||
cmd:^ |
|
||||
{1:~ }|
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
1 line {MATCH:.*} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('o/O can create new lines', function()
|
||||
source_script()
|
||||
feed('line 1<s-cr>line 2<s-cr>line 3')
|
||||
screen:expect([[
|
||||
cmd: line 1 |
|
||||
line 2 |
|
||||
line 3^ |
|
||||
{1:~ }|
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<esc>koafter')
|
||||
|
||||
screen:expect([[
|
||||
cmd: line 1 |
|
||||
line 2 |
|
||||
after^ |
|
||||
line 3 |
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<esc>kObefore')
|
||||
|
||||
screen:expect([[
|
||||
cmd: line 1 |
|
||||
before^ |
|
||||
line 2 |
|
||||
after |
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<cr>')
|
||||
screen:expect([[
|
||||
line 2 |
|
||||
after |
|
||||
line 3" |
|
||||
cmd: ^ |
|
||||
{3:[Prompt] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('line 4<s-cr>line 5')
|
||||
|
||||
feed('<esc>k0oafter prompt')
|
||||
screen:expect([[
|
||||
after |
|
||||
line 3" |
|
||||
cmd: line 4 |
|
||||
after prompt^ |
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<esc>k0Oat prompt')
|
||||
screen:expect([[
|
||||
after |
|
||||
line 3" |
|
||||
cmd: at prompt^ |
|
||||
line 4 |
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<cr>')
|
||||
screen:expect([[
|
||||
line 4 |
|
||||
after prompt |
|
||||
line 5" |
|
||||
cmd: ^ |
|
||||
{3:[Prompt] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('deleting prompt adds it back on insert', function()
|
||||
source_script()
|
||||
feed('asdf')
|
||||
screen:expect([[
|
||||
cmd: asdf^ |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<esc>ddi')
|
||||
screen:expect([[
|
||||
cmd: ^ |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('asdf')
|
||||
screen:expect([[
|
||||
cmd: asdf^ |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
|
||||
feed('<esc>cc')
|
||||
screen:expect([[
|
||||
cmd: ^ |
|
||||
{1:~ }|*3
|
||||
{3:[Prompt] [+] }|
|
||||
other buffer |
|
||||
{1:~ }|*3
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
end)
|
||||
|
||||
it(': mark follows current prompt', function()
|
||||
source_script()
|
||||
feed('asdf')
|
||||
eq({ 1, 1 }, api.nvim_buf_get_mark(0, ':'))
|
||||
feed('<cr>')
|
||||
eq({ 3, 1 }, api.nvim_buf_get_mark(0, ':'))
|
||||
end)
|
||||
|
||||
it(': mark only available in prompt buffer', function()
|
||||
source_script()
|
||||
feed('asdf')
|
||||
eq({ 1, 1 }, api.nvim_buf_get_mark(0, ':'))
|
||||
source('set buftype=')
|
||||
eq(false, pcall(api.nvim_buf_get_mark, 0, ':'))
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user