aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-12-17 11:34:30 +0800
committerGitHub <noreply@github.com>2024-12-17 03:34:30 +0000
commitb03e790cddd19b57fa91f4fbfcc30c28f3c173bf (patch)
tree9a6841d79d079ab0a052c0d72aa3bb9138033a1c
parent15153c4cd5319652bcdcd608fe5d4f0fa1eb9419 (diff)
downloadrneovim-b03e790cddd19b57fa91f4fbfcc30c28f3c173bf.tar.gz
rneovim-b03e790cddd19b57fa91f4fbfcc30c28f3c173bf.tar.bz2
rneovim-b03e790cddd19b57fa91f4fbfcc30c28f3c173bf.zip
vim-patch:9.1.0934: hard to view an existing buffer in the preview window (#31605)
Problem: hard to view an existing buffer in the preview window Solution: add the :pbuffer command (Yinzuo Jiang) Similar as `:pedit` and `:buffer` command. `:pbuffer` edits buffer [N] from the buffer list in the preview window. `:pbuffer` can also open special buffer, for example terminal buffer. closes: vim/vim#16222 https://github.com/vim/vim/commit/a2a2fe841ed2efdbb1f8055f752a3a4d0988ae9d Cherry-pick Test_popup_and_previewwindow_dump() changes from patch 9.0.0625. Cherry-pick Run_noroom_for_newwindow_test() changes from patches 8.2.0432 and 9.0.0363. Co-authored-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
-rw-r--r--runtime/doc/index.txt1
-rw-r--r--runtime/doc/windows.txt7
-rw-r--r--src/nvim/ex_cmds.lua6
-rw-r--r--src/nvim/ex_docmd.c33
-rw-r--r--test/functional/ui/popupmenu_spec.lua75
-rw-r--r--test/old/testdir/test_popup.vim33
-rw-r--r--test/old/testdir/test_preview.vim47
-rw-r--r--test/old/testdir/test_statusline.vim4
-rw-r--r--test/old/testdir/test_window_cmd.vim31
-rw-r--r--test/old/testdir/test_winfixbuf.vim12
10 files changed, 214 insertions, 35 deletions
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index d81d59c56f..0182123a12 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1472,6 +1472,7 @@ tag command action ~
|:ownsyntax| :ow[nsyntax] set new local syntax highlight for this window
|:packadd| :pa[ckadd] add a plugin from 'packpath'
|:packloadall| :packl[oadall] load all packages under 'packpath'
+|:pbuffer| :pb[uffer] edit buffer in the preview window
|:pclose| :pc[lose] close preview window
|:pedit| :ped[it] edit file in the preview window
|:perl| :pe[rl] execute perl command
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index a6e5984c82..d3c58a28a4 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -978,6 +978,13 @@ CTRL-W g } *CTRL-W_g}*
it. Make the new Preview window (if required) N high. If N is
not given, 'previewheight' is used.
+ *:pb* *:pbuffer*
+:[N]pb[uffer][!] [+cmd] [N]
+ Edit buffer [N] from the buffer list in the preview window.
+ If [N] is not given, the current buffer remains being edited.
+ See |:buffer-!| for [!]. This will also edit a buffer that is
+ not in the buffer list, without setting the 'buflisted' flag.
+
*:ped* *:pedit*
:ped[it][!] [++opt] [+cmd] {file}
Edit {file} in the preview window. The preview window is
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index c8574c805c..0cdc397e9c 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -1947,6 +1947,12 @@ M.cmds = {
func = 'ex_packloadall',
},
{
+ command = 'pbuffer',
+ flags = bit.bor(BANG, RANGE, BUFNAME, BUFUNL, COUNT, EXTRA, CMDARG, TRLBAR),
+ addr_type = 'ADDR_BUFFERS',
+ func = 'ex_pbuffer',
+ },
+ {
command = 'pclose',
flags = bit.bor(BANG, TRLBAR),
addr_type = 'ADDR_NONE',
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index b32a8b867f..052bf3b9f7 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -4502,6 +4502,12 @@ static void ex_bunload(exarg_T *eap)
/// :[N]sbuffer [N] to buffer N
static void ex_buffer(exarg_T *eap)
{
+ do_exbuffer(eap);
+}
+
+/// ":buffer" command and alike.
+static void do_exbuffer(exarg_T *eap)
+{
if (*eap->arg) {
eap->errmsg = ex_errmsg(e_trailing_arg, eap->arg);
} else {
@@ -7002,14 +7008,35 @@ static void ex_ptag(exarg_T *eap)
static void ex_pedit(exarg_T *eap)
{
win_T *curwin_save = curwin;
+ prepare_preview_window();
+
+ // Edit the file.
+ do_exedit(eap, NULL);
+
+ back_to_current_window(curwin_save);
+}
+
+/// ":pbuffer"
+static void ex_pbuffer(exarg_T *eap)
+{
+ win_T *curwin_save = curwin;
+ prepare_preview_window();
+
+ // Go to the buffer.
+ do_exbuffer(eap);
+ back_to_current_window(curwin_save);
+}
+
+static void prepare_preview_window(void)
+{
// Open the preview window or popup and make it the current window.
g_do_tagpreview = (int)p_pvh;
prepare_tagpreview(true);
+}
- // Edit the file.
- do_exedit(eap, NULL);
-
+static void back_to_current_window(win_T *curwin_save)
+{
if (curwin != curwin_save && win_valid(curwin_save)) {
// Return cursor to where we were
validate_cursor(curwin);
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index a4bf602e57..beb3ae385c 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -1542,6 +1542,81 @@ describe('builtin popupmenu', function()
end)
if not multigrid then
+ describe('popup and preview window do not overlap', function()
+ before_each(function()
+ screen:try_resize(53, 20)
+ end)
+
+ -- oldtest: Test_popup_and_previewwindow_dump_pedit()
+ it('with :pedit', function()
+ exec([[
+ set previewheight=9
+ silent! pedit
+ call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
+ exec "norm! G\<C-E>\<C-E>"
+ ]])
+ feed('o')
+ n.poke_eventloop()
+ feed('<C-X><C-N>')
+ screen:expect([[
+ ab0 |
+ ab1 |
+ ab2 |
+ ab3 |
+ ab4 |
+ ab5 |
+ ab6 |
+ ab7 |
+ ab8 |
+ {s:ab0 }{c: }{3:ew][+] }|
+ {n:ab1 }{c: } |
+ {n:ab2 }{c: } |
+ {n:ab3 }{c: } |
+ {n:ab4 }{s: } |
+ {n:ab5 }{s: } |
+ {n:ab6 }{s: } |
+ ab0^ |
+ {1:~ }|
+ {4:[No Name] [+] }|
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 10} |
+ ]])
+ end)
+
+ -- oldtest: Test_popup_and_previewwindow_dump_pbuffer()
+ it('with :pbuffer', function()
+ exec([[
+ set previewheight=9
+ silent! pbuffer
+ call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
+ exec "norm! G\<C-E>\<C-E>\<C-E>"
+ ]])
+ feed('o')
+ n.poke_eventloop()
+ feed('<C-X><C-N>')
+ screen:expect([[
+ ab0 |
+ ab1 |
+ ab2 |
+ ab3 |
+ ab4 |
+ ab5 |
+ ab6 |
+ ab7 |
+ ab8 |
+ {s:ab0 }{c: }{3:ew][+] }|
+ {n:ab1 }{c: } |
+ {n:ab2 }{c: } |
+ {n:ab3 }{s: } |
+ {n:ab4 }{s: } |
+ {n:ab5 }{s: } |
+ ab0^ |
+ {1:~ }|*2
+ {4:[No Name] [+] }|
+ {2:-- Keyword Local completion (^N^P) }{5:match 1 of 10} |
+ ]])
+ end)
+ end)
+
-- oldtest: Test_pum_with_preview_win()
it('preview window opened during completion', function()
exec([[
diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim
index 33e86678c8..a24e133ce6 100644
--- a/test/old/testdir/test_popup.vim
+++ b/test/old/testdir/test_popup.vim
@@ -748,17 +748,11 @@ func Test_popup_and_preview_autocommand()
bw!
endfunc
-func Test_popup_and_previewwindow_dump()
+func s:run_popup_and_previewwindow_dump(lines, dumpfile)
CheckScreendump
CheckFeature quickfix
- let lines =<< trim END
- set previewheight=9
- silent! pedit
- call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
- exec "norm! G\<C-E>\<C-E>"
- END
- call writefile(lines, 'Xscript')
+ call writefile(a:lines, 'Xscript', 'D')
let buf = RunVimInTerminal('-S Xscript', {})
" wait for the script to finish
@@ -768,11 +762,30 @@ func Test_popup_and_previewwindow_dump()
call term_sendkeys(buf, "o")
call TermWait(buf, 50)
call term_sendkeys(buf, "\<C-X>\<C-N>")
- call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {})
+ call VerifyScreenDump(buf, a:dumpfile, {})
call term_sendkeys(buf, "\<Esc>u")
call StopVimInTerminal(buf)
- call delete('Xscript')
+endfunc
+
+func Test_popup_and_previewwindow_dump_pedit()
+ let lines =<< trim END
+ set previewheight=9
+ silent! pedit
+ call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
+ exec "norm! G\<C-E>\<C-E>"
+ END
+ call s:run_popup_and_previewwindow_dump(lines, 'Test_popup_and_previewwindow_pedit')
+endfunc
+
+func Test_popup_and_previewwindow_dump_pbuffer()
+ let lines =<< trim END
+ set previewheight=9
+ silent! pbuffer
+ call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
+ exec "norm! G\<C-E>\<C-E>\<C-E>"
+ END
+ call s:run_popup_and_previewwindow_dump(lines, 'Test_popup_and_previewwindow_pbuffer')
endfunc
func Test_balloon_split()
diff --git a/test/old/testdir/test_preview.vim b/test/old/testdir/test_preview.vim
index b7b908e761..d24b09b7d2 100644
--- a/test/old/testdir/test_preview.vim
+++ b/test/old/testdir/test_preview.vim
@@ -15,6 +15,20 @@ func Test_Psearch()
bwipe
endfunc
+func s:goto_preview_and_close()
+ " Go to the preview window
+ wincmd P
+ call assert_equal(1, &previewwindow)
+ call assert_equal('preview', win_gettype())
+
+ " Close preview window
+ wincmd z
+ call assert_equal(1, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ call assert_fails('wincmd P', 'E441:')
+endfunc
+
func Test_window_preview()
CheckFeature quickfix
@@ -23,17 +37,36 @@ func Test_window_preview()
call assert_equal(2, winnr('$'))
call assert_equal(0, &previewwindow)
- " Go to the preview window
- wincmd P
- call assert_equal(1, &previewwindow)
- call assert_equal('preview', win_gettype())
+ call s:goto_preview_and_close()
+endfunc
- " Close preview window
- wincmd z
+func Test_window_preview_from_pbuffer()
+ CheckFeature quickfix
+
+ call writefile(['/* some C code */'], 'Xpreview.c', 'D')
+ edit Xpreview.c
+ const buf_num = bufnr('%')
+ enew
call assert_equal(1, winnr('$'))
+ exe 'pbuffer ' . buf_num
+ call assert_equal(2, winnr('$'))
call assert_equal(0, &previewwindow)
- call assert_fails('wincmd P', 'E441:')
+ call s:goto_preview_and_close()
+endfunc
+
+func Test_window_preview_terminal()
+ CheckFeature quickfix
+ " CheckFeature terminal
+
+ term " ++curwin
+ const buf_num = bufnr('$')
+ call assert_equal(1, winnr('$'))
+ exe 'pbuffer' . buf_num
+ call assert_equal(2, winnr('$'))
+ call assert_equal(0, &previewwindow)
+
+ call s:goto_preview_and_close()
endfunc
func Test_window_preview_from_help()
diff --git a/test/old/testdir/test_statusline.vim b/test/old/testdir/test_statusline.vim
index c8162ced07..c9f79dfef7 100644
--- a/test/old/testdir/test_statusline.vim
+++ b/test/old/testdir/test_statusline.vim
@@ -220,6 +220,10 @@ func Test_statusline()
wincmd j
call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
pclose
+ pbuffer
+ wincmd j
+ call assert_match('^\[Preview\],PRV\s*$', s:get_statusline())
+ pclose
" %y: Type of file in the buffer, e.g., "[vim]". See 'filetype'.
" %Y: Type of file in the buffer, e.g., ",VIM". See 'filetype'.
diff --git a/test/old/testdir/test_window_cmd.vim b/test/old/testdir/test_window_cmd.vim
index e173aa1e73..343bc9fd83 100644
--- a/test/old/testdir/test_window_cmd.vim
+++ b/test/old/testdir/test_window_cmd.vim
@@ -1185,20 +1185,20 @@ func Run_noroom_for_newwindow_test(dir_arg)
let dir = (a:dir_arg == 'v') ? 'vert ' : ''
" Open as many windows as possible
- for i in range(500)
+ while v:true
try
exe dir . 'new'
catch /E36:/
break
endtry
- endfor
+ endwhile
- call writefile(['first', 'second', 'third'], 'Xfile1')
- call writefile([], 'Xfile2')
- call writefile([], 'Xfile3')
+ call writefile(['first', 'second', 'third'], 'Xnorfile1')
+ call writefile([], 'Xnorfile2')
+ call writefile([], 'Xnorfile3')
" Argument list related commands
- args Xfile1 Xfile2 Xfile3
+ args Xnorfile1 Xnorfile2 Xnorfile3
next
for cmd in ['sargument 2', 'snext', 'sprevious', 'sNext', 'srewind',
\ 'sfirst', 'slast']
@@ -1209,13 +1209,13 @@ func Run_noroom_for_newwindow_test(dir_arg)
" Buffer related commands
set modified
hide enew
- for cmd in ['sbuffer Xfile1', 'sbnext', 'sbprevious', 'sbNext', 'sbrewind',
+ for cmd in ['sbuffer Xnorfile1', 'sbnext', 'sbprevious', 'sbNext', 'sbrewind',
\ 'sbfirst', 'sblast', 'sball', 'sbmodified', 'sunhide']
call assert_fails(dir .. cmd, 'E36:')
endfor
" Window related commands
- for cmd in ['split', 'split Xfile2', 'new', 'new Xfile3', 'sview Xfile1',
+ for cmd in ['split', 'split Xnorfile2', 'new', 'new Xnorfile3', 'sview Xnorfile1',
\ 'sfind runtest.vim']
call assert_fails(dir .. cmd, 'E36:')
endfor
@@ -1238,7 +1238,8 @@ func Run_noroom_for_newwindow_test(dir_arg)
call assert_fails(dir .. 'lopen', 'E36:')
" Preview window
- call assert_fails(dir .. 'pedit Xfile2', 'E36:')
+ call assert_fails(dir .. 'pedit Xnorfile2', 'E36:')
+ call assert_fails(dir .. 'pbuffer', 'E36:')
call setline(1, 'abc')
call assert_fails(dir .. 'psearch abc', 'E36:')
endif
@@ -1246,15 +1247,15 @@ func Run_noroom_for_newwindow_test(dir_arg)
" Window commands (CTRL-W ^ and CTRL-W f)
if a:dir_arg == 'h'
call assert_fails('call feedkeys("\<C-W>^", "xt")', 'E36:')
- call setline(1, 'Xfile1')
+ call setline(1, 'Xnorfile1')
call assert_fails('call feedkeys("gg\<C-W>f", "xt")', 'E36:')
endif
enew!
" Tag commands (:stag, :stselect and :stjump)
call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
- \ "second\tXfile1\t2",
- \ "third\tXfile1\t3",],
+ \ "second\tXnorfile1\t2",
+ \ "third\tXnorfile1\t3",],
\ 'Xtags')
set tags=Xtags
call assert_fails(dir .. 'stag second', 'E36:')
@@ -1276,9 +1277,9 @@ func Run_noroom_for_newwindow_test(dir_arg)
endif
%bwipe!
- call delete('Xfile1')
- call delete('Xfile2')
- call delete('Xfile3')
+ call delete('Xnorfile1')
+ call delete('Xnorfile2')
+ call delete('Xnorfile3')
only
endfunc
diff --git a/test/old/testdir/test_winfixbuf.vim b/test/old/testdir/test_winfixbuf.vim
index cc8ff86fa1..f7986fdda3 100644
--- a/test/old/testdir/test_winfixbuf.vim
+++ b/test/old/testdir/test_winfixbuf.vim
@@ -2545,6 +2545,18 @@ func Test_pedit()
call assert_equal(l:other, bufnr())
endfunc
+" Allow :pbuffer because, unlike :buffer, it uses a separate window
+func Test_pbuffer()
+ call s:reset_all_buffers()
+
+ let l:other = s:make_buffer_pairs()
+
+ exe 'pbuffer ' . l:other
+
+ execute "normal \<C-w>w"
+ call assert_equal(l:other, bufnr())
+endfunc
+
" Fail :pop but :pop! is allowed
func Test_pop()
call s:reset_all_buffers()