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

a2a2fe841e

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>
This commit is contained in:
zeertzjq 2024-12-17 11:34:30 +08:00 committed by GitHub
parent 15153c4cd5
commit b03e790cdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 216 additions and 37 deletions

View File

@ -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

View File

@ -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

View File

@ -1946,6 +1946,12 @@ M.cmds = {
addr_type = 'ADDR_NONE',
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),

View File

@ -4501,6 +4501,12 @@ static void ex_bunload(exarg_T *eap)
/// :[N]buffer [N] to buffer N
/// :[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);
@ -7002,14 +7008,35 @@ static void ex_ptag(exarg_T *eap)
static void ex_pedit(exarg_T *eap)
{
win_T *curwin_save = curwin;
// Open the preview window or popup and make it the current window.
g_do_tagpreview = (int)p_pvh;
prepare_tagpreview(true);
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);
}
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);

View File

@ -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([[

View File

@ -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()

View File

@ -15,14 +15,7 @@ func Test_Psearch()
bwipe
endfunc
func Test_window_preview()
CheckFeature quickfix
" Open a preview window
pedit Xa
call assert_equal(2, winnr('$'))
call assert_equal(0, &previewwindow)
func s:goto_preview_and_close()
" Go to the preview window
wincmd P
call assert_equal(1, &previewwindow)
@ -36,6 +29,46 @@ func Test_window_preview()
call assert_fails('wincmd P', 'E441:')
endfunc
func Test_window_preview()
CheckFeature quickfix
" Open a preview window
pedit Xa
call assert_equal(2, winnr('$'))
call assert_equal(0, &previewwindow)
call s:goto_preview_and_close()
endfunc
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 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()
CheckFeature quickfix

View File

@ -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'.

View File

@ -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

View File

@ -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()