patch 9.1.0934: hard to view an existing buffer in the preview window

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: #16222

Signed-off-by: Yinzuo Jiang <jiangyinzuo@foxmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt
index 8f347d7..5f0893f 100644
--- a/runtime/doc/indent.txt
+++ b/runtime/doc/indent.txt
@@ -1,4 +1,4 @@
-*indent.txt*    For Vim version 9.1.  Last change: 2024 Nov 12
+*indent.txt*    For Vim version 9.1.  Last change: 2024 Dec 16
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt
index c595d9d..e1f68a0 100644
--- a/runtime/doc/index.txt
+++ b/runtime/doc/index.txt
@@ -1,4 +1,4 @@
-*index.txt*     For Vim version 9.1.  Last change: 2023 Jul 14
+*index.txt*     For Vim version 9.1.  Last change: 2024 Dec 15
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1529,6 +1529,7 @@
 |: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/tags b/runtime/doc/tags
index 9f46c6e..a8b4987 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -3026,6 +3026,8 @@
 :packadd	repeat.txt	/*:packadd*
 :packl	repeat.txt	/*:packl*
 :packloadall	repeat.txt	/*:packloadall*
+:pb	windows.txt	/*:pb*
+:pbuffer	windows.txt	/*:pbuffer*
 :pc	windows.txt	/*:pc*
 :pclose	windows.txt	/*:pclose*
 :pe	if_perl.txt	/*:pe*
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 7691142..bcda3d0 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt*  For Vim version 9.1.  Last change: 2024 Dec 06
+*version9.txt*  For Vim version 9.1.  Last change: 2024 Dec 16
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41661,7 +41661,8 @@
 Commands: ~
 
 |[r| and |]r|		to move the cursor to previous/next rare word
-
+|:pbuffer|		Edit buffer [N] from the buffer list in the preview
+			window
 
 Options: ~
 
diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt
index edb105a..7764072 100644
--- a/runtime/doc/windows.txt
+++ b/runtime/doc/windows.txt
@@ -1,4 +1,4 @@
-*windows.txt*   For Vim version 9.1.  Last change: 2024 Dec 14
+*windows.txt*   For Vim version 9.1.  Last change: 2024 Dec 16
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1005,6 +1005,15 @@
 		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.
+		The notation with single quotes does not work here, `:pbuffer
+		12'345'` uses 12'345 as a buffer name.  Also see |+cmd|.
+
 							*:ped* *:pedit*
 :ped[it][!] [++opt] [+cmd] {file}
 		Edit {file} in the preview window.  The preview window is
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index eea6e82..465311f 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -2,7 +2,7 @@
 " Language:	   Vim script
 " Maintainer:	   Hirohito Higashi <h.east.727 ATMARK gmail.com>
 "	   Doug Kearns <dougkearns@gmail.com>
-" Last Change:	   2024 Oct 08
+" Last Change:	   2024 Dec 15
 " Former Maintainer: Charles E. Campbell
 
 " DO NOT CHANGE DIRECTLY.
@@ -30,9 +30,9 @@
 syn keyword vimCommand contained abo[veleft] abs[tract] al[l] ar[gs] arga[dd] argd[elete] argdo argded[upe] arge[dit] argg[lobal] argl[ocal] argu[ment] as[cii] b[uffer] bN[ext] ba[ll] bad[d] balt bd[elete] bel[owright] bf[irst] bl[ast] bm[odified] bn[ext] bo[tright] bp[revious] br[ewind] brea[k] breaka[dd] breakd[el] breakl[ist] bro[wse] buffers bufd[o] bun[load] bw[ipeout] c[hange] cN[ext] cNf[ile] cabo[ve] cad[dbuffer] cadde[xpr] caddf[ile] caf[ter] cb[uffer] cbe[fore] cbel[ow] cbo[ttom] cc ccl[ose] cd cdo ce[nter] cex[pr] cf[ile] cfd[o] cfir[st] cg[etfile] cgetb[uffer] cgete[xpr] chd[ir] changes che[ckpath] checkt[ime] chi[story] cl[ist] cla[st] clo[se] cle[arjumps] cn[ext] cnew[er] cnf[ile] co[py] col[der] colo[rscheme] com[mand] comc[lear] comp[iler] con[tinue]
 syn keyword vimCommand contained conf[irm] cons[t] cope[n] cp[revious] cpf[ile] cq[uit] cr[ewind] cs[cope] cst[ag] cw[indow] d[elete] delm[arks] deb[ug] debugg[reedy] defc[ompile] defe[r] delf[unction] di[splay] dif[fupdate] diffg[et] diffo[ff] diffp[atch] diffpu[t] diffs[plit] difft[his] dig[raphs] disa[ssemble] dj[ump] dli[st] dr[op] ds[earch] dsp[lit] e[dit] ea[rlier] el[se] em[enu] en[dif] endfo[r] endt[ry] endw[hile] ene[w] ev[al] ex exi[t] exu[sage] f[ile] files filet[ype] filt[er] fin[d] finall[y] fini[sh] fir[st] fix[del] fo[ld] foldc[lose] foldd[oopen] folddoc[losed] foldo[pen] g[lobal] go[to] gr[ep] grepa[dd] gu[i] gv[im] h[elp] helpc[lose] helpf[ind] helpg[rep] helpt[ags] ha[rdcopy] hi[ghlight] hid[e] his[tory] ho[rizontal] ij[ump] il[ist] imp[ort]
 syn keyword vimCommand contained int[ro] is[earch] isp[lit] j[oin] ju[mps] k kee[pmarks] keepj[umps] keepp[atterns] keepa[lt] l[ist] lN[ext] lNf[ile] la[st] lab[ove] lan[guage] lad[dexpr] laddb[uffer] laddf[ile] laf[ter] lat[er] lb[uffer] lbe[fore] lbel[ow] lbo[ttom] lc[d] lch[dir] lcl[ose] lcs[cope] ld[o] le[ft] lefta[bove] lex[pr] leg[acy] lf[ile] lfd[o] lfir[st] lg[etfile] lgetb[uffer] lgete[xpr] lgr[ep] lgrepa[dd] lh[elpgrep] lhi[story] ll lla[st] lli[st] lmak[e] lne[xt] lnew[er] lnf[ile] lo[adview] loc[kmarks] lockv[ar] lol[der] lop[en] lp[revious] lpf[ile] lr[ewind] lt[ag] lua luad[o] luaf[ile] lv[imgrep] lvimgrepa[dd] lw[indow] ls m[ove] ma[rk] mak[e] marks menut[ranslate] mes[sages] mk[exrc] mks[ession] mksp[ell] mkv[imrc] mkvie[w] mod[e] mz[scheme] mzf[ile]
-syn keyword vimCommand contained n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pc[lose] pe[rl] perld[o] ped[it] po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] prof[ile] profd[el] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] py[thon] pyd[o] pyf[ile] py3 py3d[o] python3 py3f[ile] pyx pyxd[o] pythonx pyxf[ile] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redi[r] redr[aw] redraws[tatus] redrawt[abline] reg[isters] res[ize] ret[ab] rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas] sb[uffer]
-syn keyword vimCommand contained sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] sc[riptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] si[malt] sig[n] sil[ent] sla[st] sn[ext] so[urce] sor[t] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] spellra[re] spellu[ndo] spellw[rong] spr[evious] sr[ewind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st] tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] tcl tcld[o] tclf[ile] te[aroff] ter[minal] tf[irst]
-syn keyword vimCommand contained tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] u[ndo] undoj[oin] undol[ist] unh[ide] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim[grep] vimgrepa[dd] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wi[nsize] winc[md] wind[o] winp[os] wn[ext] wp[revious] wq wqa[ll] wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i
+syn keyword vimCommand contained n[ext] nb[key] nbc[lose] nbs[tart] noa[utocmd] noh[lsearch] nos[wapfile] nu[mber] o[pen] ol[dfiles] on[ly] opt[ions] ow[nsyntax] p[rint] pa[ckadd] packl[oadall] pc[lose] pe[rl] perld[o] ped[it] pb[uffer] po[p] pp[op] pre[serve] prev[ious] pro[mptfind] promptr[epl] prof[ile] profd[el] ps[earch] pt[ag] ptN[ext] ptf[irst] ptj[ump] ptl[ast] ptn[ext] ptp[revious] ptr[ewind] pts[elect] pu[t] pw[d] py[thon] pyd[o] pyf[ile] py3 py3d[o] python3 py3f[ile] pyx pyxd[o] pythonx pyxf[ile] q[uit] quita[ll] qa[ll] r[ead] rec[over] red[o] redi[r] redr[aw] redraws[tatus] redrawt[abline] reg[isters] res[ize] ret[ab] rew[ind] ri[ght] rightb[elow] ru[ntime] rub[y] rubyd[o] rubyf[ile] rund[o] rv[iminfo] sN[ext] sa[rgument] sal[l] san[dbox] sav[eas]
+syn keyword vimCommand contained sb[uffer] sbN[ext] sba[ll] sbf[irst] sbl[ast] sbm[odified] sbn[ext] sbp[revious] sbr[ewind] sc[riptnames] scripte[ncoding] scriptv[ersion] scs[cope] setf[iletype] sf[ind] sfir[st] sh[ell] si[malt] sig[n] sil[ent] sla[st] sn[ext] so[urce] sor[t] sp[lit] spe[llgood] spelld[ump] spelli[nfo] spellr[epall] spellra[re] spellu[ndo] spellw[rong] spr[evious] sr[ewind] st[op] sta[g] star[tinsert] startg[replace] startr[eplace] stopi[nsert] stj[ump] sts[elect] sun[hide] sus[pend] sv[iew] sw[apname] synti[me] sync[bind] smi[le] t tN[ext] ta[g] tags tab tabc[lose] tabd[o] tabe[dit] tabf[ind] tabfir[st] tabm[ove] tabl[ast] tabn[ext] tabnew tabo[nly] tabp[revious] tabN[ext] tabr[ewind] tabs tc[d] tch[dir] tcl tcld[o] tclf[ile] te[aroff] ter[minal]
+syn keyword vimCommand contained tf[irst] tj[ump] tl[ast] tn[ext] to[pleft] tp[revious] tr[ewind] try ts[elect] u[ndo] undoj[oin] undol[ist] unh[ide] unlo[ckvar] uns[ilent] up[date] v[global] ve[rsion] verb[ose] vert[ical] vi[sual] vie[w] vim[grep] vimgrepa[dd] vim9[cmd] viu[sage] vne[w] vs[plit] w[rite] wN[ext] wa[ll] wi[nsize] winc[md] wind[o] winp[os] wn[ext] wp[revious] wq wqa[ll] wu[ndo] wv[iminfo] x[it] xa[ll] xr[estore] y[ank] z dl dell delel deletl deletel dp dep delp delep deletp deletep a i
 
 " Lower priority for _new_ to distinguish constructors from the command.
 syn match   vimCommand contained	"\<new\>(\@!"
@@ -43,12 +43,12 @@
 " GEN_SYN_VIM: vimOption normal, START_STR='syn keyword vimOption contained', END_STR='skipwhite nextgroup=vimSetEqual,vimSetMod'
 syn keyword vimOption contained al aleph ari allowrevins ambw ambiwidth arab arabic arshape arabicshape acd autochdir ai autoindent ar autoread asd autoshelldir aw autowrite awa autowriteall bg background bs backspace bk backup bkc backupcopy bdir backupdir bex backupext bsk backupskip bdlay balloondelay beval ballooneval bevalterm balloonevalterm bexpr balloonexpr bo belloff bin binary bomb brk breakat bri breakindent briopt breakindentopt bsdir browsedir bh bufhidden bl buflisted bt buftype cmp casemap cdh cdhome cd cdpath cedit ccv charconvert cin cindent cink cinkeys cino cinoptions cinsd cinscopedecls cinw cinwords cb clipboard ch cmdheight cwh cmdwinheight cc colorcolumn co columns com comments cms commentstring cp compatible cpt complete cfu completefunc skipwhite nextgroup=vimSetEqual,vimSetMod
 syn keyword vimOption contained cia completeitemalign cot completeopt cpp completepopup csl completeslash cocu concealcursor cole conceallevel cf confirm ci copyindent cpo cpoptions cm cryptmethod cspc cscopepathcomp csprg cscopeprg csqf cscopequickfix csre cscoperelative cst cscopetag csto cscopetagorder csverb cscopeverbose crb cursorbind cuc cursorcolumn cul cursorline culopt cursorlineopt debug def define deco delcombine dict dictionary diff dex diffexpr dip diffopt dg digraph dir directory dy display ead eadirection ed edcompatible emo emoji enc encoding eof endoffile eol endofline ea equalalways ep equalprg eb errorbells ef errorfile efm errorformat ek esckeys ei eventignore et expandtab ex exrc fenc fileencoding fencs fileencodings ff fileformat ffs fileformats skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained fic fileignorecase ft filetype fcs fillchars fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert ims imsearch skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable mod modified more mouse skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine rnu relativenumber skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell spc spellcapcheck skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin tf ttyfast ttym ttymouse skipwhite nextgroup=vimSetEqual,vimSetMod
-syn keyword vimOption contained tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained fic fileignorecase ft filetype fcs fillchars ffu findfunc fixeol fixendofline fcl foldclose fdc foldcolumn fen foldenable fde foldexpr fdi foldignore fdl foldlevel fdls foldlevelstart fmr foldmarker fdm foldmethod fml foldminlines fdn foldnestmax fdo foldopen fdt foldtext fex formatexpr flp formatlistpat fo formatoptions fp formatprg fs fsync gd gdefault gfm grepformat gp grepprg gcr guicursor gfn guifont gfs guifontset gfw guifontwide ghr guiheadroom gli guiligatures go guioptions guipty gtl guitablabel gtt guitabtooltip hf helpfile hh helpheight hlg helplang hid hidden hl highlight hi history hk hkmap hkp hkmapp hls hlsearch icon iconstring ic ignorecase imaf imactivatefunc imak imactivatekey imc imcmdline imd imdisable imi iminsert skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained ims imsearch imsf imstatusfunc imst imstyle inc include inex includeexpr is incsearch inde indentexpr indk indentkeys inf infercase im insertmode isf isfname isi isident isk iskeyword isp isprint js joinspaces jop jumpoptions key kmp keymap km keymodel kpc keyprotocol kp keywordprg lmap langmap lm langmenu lnr langnoremap lrm langremap ls laststatus lz lazyredraw lbr linebreak lines lsp linespace lisp lop lispoptions lw lispwords list lcs listchars lpl loadplugins luadll magic mef makeef menc makeencoding mp makeprg mps matchpairs mat matchtime mco maxcombine mfd maxfuncdepth mmd maxmapdepth mm maxmem mmp maxmempattern mmt maxmemtot mis menuitems mopt messagesopt msm mkspellmem ml modeline mle modelineexpr mls modelines ma modifiable skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained mod modified more mouse mousef mousefocus mh mousehide mousem mousemodel mousemev mousemoveevent mouses mouseshape mouset mousetime mzq mzquantum mzschemedll mzschemegcdll nf nrformats nu number nuw numberwidth ofu omnifunc odev opendevice opfunc operatorfunc pp packpath para paragraphs paste pt pastetoggle pex patchexpr pm patchmode pa path perldll pi preserveindent pvh previewheight pvp previewpopup pvw previewwindow pdev printdevice penc printencoding pexpr printexpr pfn printfont pheader printheader pmbcs printmbcharset pmbfn printmbfont popt printoptions prompt ph pumheight pw pumwidth pythondll pythonhome pythonthreedll pythonthreehome pyx pyxversion qftf quickfixtextfunc qe quoteescape ro readonly rdt redrawtime re regexpengine skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained rnu relativenumber remap rop renderoptions report rs restorescreen ri revins rl rightleft rlc rightleftcmd rubydll ru ruler ruf rulerformat rtp runtimepath scr scroll scb scrollbind scf scrollfocus sj scrolljump so scrolloff sbo scrollopt sect sections secure sel selection slm selectmode ssop sessionoptions sh shell shcf shellcmdflag sp shellpipe shq shellquote srr shellredir ssl shellslash stmp shelltemp st shelltype sxe shellxescape sxq shellxquote sr shiftround sw shiftwidth shm shortmess sn shortname sbr showbreak sc showcmd sloc showcmdloc sft showfulltag sm showmatch smd showmode stal showtabline ss sidescroll siso sidescrolloff scl signcolumn scs smartcase si smartindent sta smarttab sms smoothscroll sts softtabstop spell skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained spc spellcapcheck spf spellfile spl spelllang spo spelloptions sps spellsuggest sb splitbelow spk splitkeep spr splitright sol startofline stl statusline su suffixes sua suffixesadd swf swapfile sws swapsync swb switchbuf smc synmaxcol syn syntax tcl tabclose tal tabline tpm tabpagemax ts tabstop tbs tagbsearch tc tagcase tfu tagfunc tl taglength tr tagrelative tag tags tgst tagstack tcldll term tbidi termbidi tenc termencoding tgc termguicolors twk termwinkey twsl termwinscroll tws termwinsize twt termwintype terse ta textauto tx textmode tw textwidth tsr thesaurus tsrfu thesaurusfunc top tildeop to timeout tm timeoutlen title titlelen titleold titlestring tb toolbar tbis toolbariconsize ttimeout ttm ttimeoutlen tbi ttybuiltin skipwhite nextgroup=vimSetEqual,vimSetMod
+syn keyword vimOption contained tf ttyfast ttym ttymouse tsl ttyscroll tty ttytype udir undodir udf undofile ul undolevels ur undoreload uc updatecount ut updatetime vsts varsofttabstop vts vartabstop vbs verbose vfile verbosefile vdir viewdir vop viewoptions vi viminfo vif viminfofile ve virtualedit vb visualbell warn wiv weirdinvert ww whichwrap wc wildchar wcm wildcharm wig wildignore wic wildignorecase wmnu wildmenu wim wildmode wop wildoptions wak winaltkeys wcr wincolor wi window wfb winfixbuf wfh winfixheight wfw winfixwidth wh winheight wmh winminheight wmw winminwidth winptydll wiw winwidth wrap wm wrapmargin ws wrapscan write wa writeany wb writebackup wd writedelay xtermcodes skipwhite nextgroup=vimSetEqual,vimSetMod
 
 " vimOptions: These are the turn-off setting variants {{{2
 " GEN_SYN_VIM: vimOption turn-off, START_STR='syn keyword vimOption contained', END_STR=''
@@ -102,14 +102,14 @@
 " Function Names {{{2
 " GEN_SYN_VIM: vimFuncName, START_STR='syn keyword vimFuncName contained', END_STR=''
 syn keyword vimFuncName contained abs acos add and append appendbufline argc argidx arglistid argv asin assert_beeps assert_equal assert_equalfile assert_exception assert_fails assert_false assert_inrange assert_match assert_nobeep assert_notequal assert_notmatch assert_report assert_true atan atan2 autocmd_add autocmd_delete autocmd_get balloon_gettext balloon_show balloon_split bindtextdomain blob2list browse browsedir bufadd bufexists buflisted bufload bufloaded bufname bufnr bufwinid bufwinnr byte2line byteidx byteidxcomp call ceil ch_canread ch_close ch_close_in ch_evalexpr ch_evalraw ch_getbufnr ch_getjob ch_info ch_log ch_logfile ch_open ch_read ch_readblob ch_readraw ch_sendexpr ch_sendraw ch_setoptions ch_status changenr char2nr charclass charcol charidx
-syn keyword vimFuncName contained chdir cindent clearmatches col complete complete_add complete_check complete_info confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filecopy filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect get getbufinfo getbufline getbufoneline getbufvar getcellwidths getchangelist
-syn keyword vimFuncName contained getchar getcharmod getcharpos getcharsearch getcharstr getcmdcomplpat getcmdcompltype getcmdline getcmdpos getcmdprompt getcmdscreenpos getcmdtype getcmdwintype getcompletion getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv id indent index indexof input inputdialog inputlist
-syn keyword vimFuncName contained inputrestore inputsave inputsecret insert instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode mzeval nextnonblank nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog popup_filter_menu
-syn keyword vimFuncName contained popup_filter_yesno popup_findecho popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf popup_setoptions popup_settext popup_show pow prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove rename repeat resolve
-syn keyword vimFuncName contained reverse round rubyeval screenattr screenchar screenchars screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2float str2list str2nr strcharlen strcharpart
-syn keyword vimFuncName contained strchars strdisplaywidth strftime strgetchar stridx string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput test_garbagecollect_now test_garbagecollect_soon
-syn keyword vimFuncName contained test_getvalue test_gui_event test_ignore_error test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc type typename undofile undotree uniq utf16idx values virtcol virtcol2col visualmode wildmenumode win_execute win_findbuf win_getid win_gettype win_gotoid win_id2tabwin win_id2win win_move_separator win_move_statusline win_screenpos win_splitmove winbufnr wincol windowsversion winheight winlayout winline winnr winrestcmd winrestview winsaveview
-syn keyword vimFuncName contained winwidth wordcount writefile xor
+syn keyword vimFuncName contained chdir cindent clearmatches col complete complete_add complete_check complete_info confirm copy cos cosh count cscope_connection cursor debugbreak deepcopy delete deletebufline did_filetype diff diff_filler diff_hlID digraph_get digraph_getlist digraph_set digraph_setlist echoraw empty environ err_teapot escape eval eventhandler executable execute exepath exists exists_compiled exp expand expandcmd extend extendnew feedkeys filecopy filereadable filewritable filter finddir findfile flatten flattennew float2nr floor fmod fnameescape fnamemodify foldclosed foldclosedend foldlevel foldtext foldtextresult foreach foreground fullcommand funcref function garbagecollect get getbufinfo getbufline getbufoneline getbufvar getcellpixels getcellwidths
+syn keyword vimFuncName contained getchangelist getchar getcharmod getcharpos getcharsearch getcharstr getcmdcomplpat getcmdcompltype getcmdline getcmdpos getcmdprompt getcmdscreenpos getcmdtype getcmdwintype getcompletion getcurpos getcursorcharpos getcwd getenv getfontname getfperm getfsize getftime getftype getimstatus getjumplist getline getloclist getmarklist getmatches getmousepos getmouseshape getpid getpos getqflist getreg getreginfo getregion getregionpos getregtype getscriptinfo gettabinfo gettabvar gettabwinvar gettagstack gettext getwininfo getwinpos getwinposx getwinposy getwinvar glob glob2regpat globpath has has_key haslocaldir hasmapto histadd histdel histget histnr hlID hlexists hlget hlset hostname iconv id indent index indexof input inputdialog
+syn keyword vimFuncName contained inputlist inputrestore inputsave inputsecret insert instanceof interrupt invert isabsolutepath isdirectory isinf islocked isnan items job_getchannel job_info job_setoptions job_start job_status job_stop join js_decode js_encode json_decode json_encode keys keytrans len libcall libcallnr line line2byte lispindent list2blob list2str listener_add listener_flush listener_remove localtime log log10 luaeval map maparg mapcheck maplist mapnew mapset match matchadd matchaddpos matcharg matchbufline matchdelete matchend matchfuzzy matchfuzzypos matchlist matchstr matchstrlist matchstrpos max menu_info min mkdir mode mzeval nextnonblank nr2char or pathshorten perleval popup_atcursor popup_beval popup_clear popup_close popup_create popup_dialog
+syn keyword vimFuncName contained popup_filter_menu popup_filter_yesno popup_findecho popup_findinfo popup_findpreview popup_getoptions popup_getpos popup_hide popup_list popup_locate popup_menu popup_move popup_notification popup_setbuf popup_setoptions popup_settext popup_show pow prevnonblank printf prompt_getprompt prompt_setcallback prompt_setinterrupt prompt_setprompt prop_add prop_add_list prop_clear prop_find prop_list prop_remove prop_type_add prop_type_change prop_type_delete prop_type_get prop_type_list pum_getpos pumvisible py3eval pyeval pyxeval rand range readblob readdir readdirex readfile reduce reg_executing reg_recording reltime reltimefloat reltimestr remote_expr remote_foreground remote_peek remote_read remote_send remote_startserver remove
+syn keyword vimFuncName contained rename repeat resolve reverse round rubyeval screenattr screenchar screenchars screencol screenpos screenrow screenstring search searchcount searchdecl searchpair searchpairpos searchpos server2client serverlist setbufline setbufvar setcellwidths setcharpos setcharsearch setcmdline setcmdpos setcursorcharpos setenv setfperm setline setloclist setmatches setpos setqflist setreg settabvar settabwinvar settagstack setwinvar sha256 shellescape shiftwidth sign_define sign_getdefined sign_getplaced sign_jump sign_place sign_placelist sign_undefine sign_unplace sign_unplacelist simplify sin sinh slice sort sound_clear sound_playevent sound_playfile sound_stop soundfold spellbadword spellsuggest split sqrt srand state str2float str2list
+syn keyword vimFuncName contained str2nr strcharlen strcharpart strchars strdisplaywidth strftime strgetchar stridx string strlen strpart strptime strridx strtrans strutf16len strwidth submatch substitute swapfilelist swapinfo swapname synID synIDattr synIDtrans synconcealed synstack system systemlist tabpagebuflist tabpagenr tabpagewinnr tagfiles taglist tan tanh tempname term_dumpdiff term_dumpload term_dumpwrite term_getaltscreen term_getansicolors term_getattr term_getcursor term_getjob term_getline term_getscrolled term_getsize term_getstatus term_gettitle term_gettty term_list term_scrape term_sendkeys term_setansicolors term_setapi term_setkill term_setrestore term_setsize term_start term_wait terminalprops test_alloc_fail test_autochdir test_feedinput
+syn keyword vimFuncName contained test_garbagecollect_now test_garbagecollect_soon test_getvalue test_gui_event test_ignore_error test_mswin_event test_null_blob test_null_channel test_null_dict test_null_function test_null_job test_null_list test_null_partial test_null_string test_option_not_set test_override test_refcount test_setmouse test_settime test_srand_seed test_unknown test_void timer_info timer_pause timer_start timer_stop timer_stopall tolower toupper tr trim trunc type typename undofile undotree uniq utf16idx values virtcol virtcol2col visualmode wildmenumode win_execute win_findbuf win_getid win_gettype win_gotoid win_id2tabwin win_id2win win_move_separator win_move_statusline win_screenpos win_splitmove winbufnr wincol windowsversion winheight winlayout
+syn keyword vimFuncName contained winline winnr winrestcmd winrestview winsaveview winwidth wordcount writefile xor
 
 "--- syntax here and above generated by mkvimvim ---
 " Special Vim Highlighting (not automatic) {{{1
diff --git a/src/ex_cmdidxs.h b/src/ex_cmdidxs.h
index 658f05e..0b13a6c 100644
--- a/src/ex_cmdidxs.h
+++ b/src/ex_cmdidxs.h
@@ -21,16 +21,16 @@
   /* n */ 308,
   /* o */ 328,
   /* p */ 340,
-  /* q */ 380,
-  /* r */ 383,
-  /* s */ 403,
-  /* t */ 473,
-  /* u */ 520,
-  /* v */ 531,
-  /* w */ 552,
-  /* x */ 566,
-  /* y */ 576,
-  /* z */ 577
+  /* q */ 381,
+  /* r */ 384,
+  /* s */ 404,
+  /* t */ 474,
+  /* u */ 521,
+  /* v */ 532,
+  /* w */ 553,
+  /* x */ 567,
+  /* y */ 577,
+  /* z */ 578
 };
 
 /*
@@ -56,7 +56,7 @@
   /* m */ {  1,  0,  0,  0,  7,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16 },
   /* n */ {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  5,  8, 10,  0,  0,  0,  0,  0, 17,  0,  0,  0,  0,  0 },
   /* o */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  5,  0,  0,  0,  0,  0,  0,  9,  0, 11,  0,  0,  0 },
-  /* p */ {  1,  0,  3,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9,  0,  0, 16, 17, 26,  0, 28,  0, 29,  0 },
+  /* p */ {  1,  3,  4,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, 10,  0,  0, 17, 18, 27,  0, 29,  0, 30,  0 },
   /* q */ {  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
   /* r */ {  0,  0,  0,  0,  0,  0,  0,  0, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 14, 19,  0,  0,  0,  0 },
   /* s */ {  2,  6, 15,  0, 19, 23,  0, 25, 26,  0,  0, 29, 31, 35, 39, 41,  0, 50,  0, 51,  0, 64, 65,  0, 66,  0 },
@@ -69,4 +69,4 @@
   /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
 };
 
-static const int command_count = 594;
+static const int command_count = 595;
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 25f6914..dc5da0a 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -1145,6 +1145,9 @@
 EXCMD(CMD_packloadall,	"packloadall",	ex_packloadall,
 	EX_BANG|EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
 	ADDR_NONE),
+EXCMD(CMD_pbuffer,	"pbuffer",	ex_pbuffer,
+	EX_BANG|EX_RANGE|EX_BUFNAME|EX_BUFUNL|EX_COUNT|EX_EXTRA|EX_CMDARG|EX_TRLBAR,
+	ADDR_BUFFERS),
 EXCMD(CMD_pclose,	"pclose",	ex_pclose,
 	EX_BANG|EX_TRLBAR,
 	ADDR_NONE),
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 859dc85..d516755 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -36,6 +36,7 @@
 static void	ex_doautocmd(exarg_T *eap);
 static void	ex_bunload(exarg_T *eap);
 static void	ex_buffer(exarg_T *eap);
+static void	do_exbuffer(exarg_T *eap);
 static void	ex_bmodified(exarg_T *eap);
 static void	ex_bnext(exarg_T *eap);
 static void	ex_bprevious(exarg_T *eap);
@@ -101,10 +102,14 @@
 static void	ex_pclose(exarg_T *eap);
 static void	ex_ptag(exarg_T *eap);
 static void	ex_pedit(exarg_T *eap);
+static void	ex_pbuffer(exarg_T *eap);
+static void	prepare_preview_window(void);
+static void	back_to_current_window(win_T *curwin_save);
 #else
 # define ex_pclose		ex_ni
 # define ex_ptag		ex_ni
 # define ex_pedit		ex_ni
+# define ex_pbuffer		ex_ni
 #endif
 static void	ex_hide(exarg_T *eap);
 static void	ex_exit(exarg_T *eap);
@@ -5734,6 +5739,15 @@
 {
     if (ERROR_IF_ANY_POPUP_WINDOW)
 	return;
+    do_exbuffer(eap);
+}
+
+/*
+ * ":buffer" command and alike.
+ */
+    static void
+do_exbuffer(exarg_T *eap)
+{
     if (*eap->arg)
 	eap->errmsg = ex_errmsg(e_trailing_characters_str, eap->arg);
     else
@@ -9437,17 +9451,43 @@
 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)
+{
     if (ERROR_IF_ANY_POPUP_WINDOW)
 	return;
 
     // Open the preview window or popup and make it the current window.
     g_do_tagpreview = p_pvh;
     prepare_tagpreview(TRUE, TRUE, FALSE);
+}
 
-    // 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
diff --git a/src/testdir/dumps/Test_popup_and_previewwindow_pbuffer.dump b/src/testdir/dumps/Test_popup_and_previewwindow_pbuffer.dump
new file mode 100644
index 0000000..0eab2a6
--- /dev/null
+++ b/src/testdir/dumps/Test_popup_and_previewwindow_pbuffer.dump
@@ -0,0 +1,20 @@
+|a+0&#ffffff0|b|0| @71
+|a|b|1| @71
+|a|b|2| @71
+|a|b|3| @71
+|a|b|4| @71
+|a|b|5| @71
+|a|b|6| @71
+|a|b|7| @71
+|a|b|8| @71
+|a+0#0000001#e0e0e08|b|0| @11| +0#0000000#0000001|e+1&#ffffff0|w|]|[|+|]| @34|1|,|1| @11|T|o|p
+|a+0#0000001#ffd7ff255|b|1| @11| +0#0000000#0000001| +0&#ffffff0@58
+|a+0#0000001#ffd7ff255|b|2| @11| +0#0000000#0000001| +0&#ffffff0@58
+|a+0#0000001#ffd7ff255|b|3| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58
+|a+0#0000001#ffd7ff255|b|4| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58
+|a+0#0000001#ffd7ff255|b|5| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58
+|a|b|0> @71
+|~+0#4040ff13&| @73
+|~| @73
+|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1@1|,|1| @10|B|o|t
+|-+2&&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |1|0| +0#0000000&@26
diff --git a/src/testdir/dumps/Test_popup_and_previewwindow_01.dump b/src/testdir/dumps/Test_popup_and_previewwindow_pedit.dump
similarity index 100%
rename from src/testdir/dumps/Test_popup_and_previewwindow_01.dump
rename to src/testdir/dumps/Test_popup_and_previewwindow_pedit.dump
diff --git a/src/testdir/dumps/Test_pum_preview_pbuffer_1.dump b/src/testdir/dumps/Test_pum_preview_pbuffer_1.dump
new file mode 100644
index 0000000..ae02ce5
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_preview_pbuffer_1.dump
@@ -0,0 +1,12 @@
+|o+0&#ffffff0|n|e| |o|t|h|e|r> @65
+|╔+0#0000001#ffd7ff255|═@1| +0&#e0e0e08|o|t|h|e|r| @9|═+0&#ffd7ff255@21|X| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|c|e| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|l|y| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|f@1| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|n|e| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|c+0#af5f00255&|a|l@1| +0#0000001&|s+0#00e0e07&|y|s|t|e|m|(+0#e000e06&|'+0#e000002&|e|c|h|o| |h|e|l@1|o|'|)+0#e000e06&| +0#0000001&@14|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|"+0#0000e05&| |t|h|e| |e|n|d| +0#0000001&@30|║| +0#4040ff13#ffffff0@32
+|╚+0#0000001#ffd7ff255|═@39|⇲| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |5| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_pum_preview_pbuffer_2.dump b/src/testdir/dumps/Test_pum_preview_pbuffer_2.dump
new file mode 100644
index 0000000..e83929f
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_preview_pbuffer_2.dump
@@ -0,0 +1,12 @@
+|o+0&#ffffff0|n|e| |o|n|c|e> @66
+|╔+0#0000001#ffd7ff255|═@1| |o|t|h|e|r| @9|═@21|X| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001#e0e0e08|o|n|c|e| @10| +0&#ffd7ff255@21|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|l|y| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|f@1| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|n|e| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|c+0#af5f00255&|a|l@1| +0#0000001&|s+0#00e0e07&|y|s|t|e|m|(+0#e000e06&|'+0#e000002&|e|c|h|o| |h|e|l@1|o|'|)+0#e000e06&| +0#0000001&@14|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|"+0#0000e05&| |t|h|e| |e|n|d| +0#0000001&@30|║| +0#4040ff13#ffffff0@32
+|╚+0#0000001#ffd7ff255|═@39|⇲| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |2| |o|f| |5| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_pum_preview_pbuffer_3.dump b/src/testdir/dumps/Test_pum_preview_pbuffer_3.dump
new file mode 100644
index 0000000..fde2104
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_preview_pbuffer_3.dump
@@ -0,0 +1,12 @@
+|o+0&#ffffff0|n|e| |o|n|l|y> @66
+|╔+0#0000001#ffd7ff255|═@1| |o|t|h|e|r| @9|═@21|X| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|c|e| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001#e0e0e08|o|n|l|y| @10| +0&#ffd7ff255@21|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|f@1| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|n|e| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|c+0#af5f00255&|a|l@1| +0#0000001&|s+0#00e0e07&|y|s|t|e|m|(+0#e000e06&|'+0#e000002&|e|c|h|o| |h|e|l@1|o|'|)+0#e000e06&| +0#0000001&@14|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|"+0#0000e05&| |t|h|e| |e|n|d| +0#0000001&@30|║| +0#4040ff13#ffffff0@32
+|╚+0#0000001#ffd7ff255|═@39|⇲| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |3| |o|f| |5| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_pum_preview_pbuffer_4.dump b/src/testdir/dumps/Test_pum_preview_pbuffer_4.dump
new file mode 100644
index 0000000..dee2b55
--- /dev/null
+++ b/src/testdir/dumps/Test_pum_preview_pbuffer_4.dump
@@ -0,0 +1,12 @@
+|o+0&#ffffff0|n|e| |o|f@1> @67
+|╔+0#0000001#ffd7ff255|═@1| |o|t|h|e|r| @9|═@21|X| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|c|e| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|l+0#af5f00255&|e| +0#0000001&|o|n|l|y| @32|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001#e0e0e08|o|f@1| @11| +0&#ffd7ff255@21|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|e+0#af5f00255&|c| +0#0000001&|o|n|e| @33|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|c+0#af5f00255&|a|l@1| +0#0000001&|s+0#00e0e07&|y|s|t|e|m|(+0#e000e06&|'+0#e000002&|e|c|h|o| |h|e|l@1|o|'|)+0#e000e06&| +0#0000001&@14|║| +0#0000000#ffffff0@32
+|║+0#0000001#ffd7ff255|"+0#0000e05&| |t|h|e| |e|n|d| +0#0000001&@30|║| +0#4040ff13#ffffff0@32
+|╚+0#0000001#ffd7ff255|═@39|⇲| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|-+2#0000000&@1| |K|e|y|w|o|r|d| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |4| |o|f| |5| +0#0000000&@33
diff --git a/src/testdir/dumps/Test_pum_preview_1.dump b/src/testdir/dumps/Test_pum_preview_pedit_1.dump
similarity index 100%
rename from src/testdir/dumps/Test_pum_preview_1.dump
rename to src/testdir/dumps/Test_pum_preview_pedit_1.dump
diff --git a/src/testdir/dumps/Test_pum_preview_2.dump b/src/testdir/dumps/Test_pum_preview_pedit_2.dump
similarity index 100%
rename from src/testdir/dumps/Test_pum_preview_2.dump
rename to src/testdir/dumps/Test_pum_preview_pedit_2.dump
diff --git a/src/testdir/dumps/Test_pum_preview_3.dump b/src/testdir/dumps/Test_pum_preview_pedit_3.dump
similarity index 100%
rename from src/testdir/dumps/Test_pum_preview_3.dump
rename to src/testdir/dumps/Test_pum_preview_pedit_3.dump
diff --git a/src/testdir/dumps/Test_pum_preview_4.dump b/src/testdir/dumps/Test_pum_preview_pedit_4.dump
similarity index 100%
rename from src/testdir/dumps/Test_pum_preview_4.dump
rename to src/testdir/dumps/Test_pum_preview_pedit_4.dump
diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim
index d5e6e31..69228e1 100644
--- a/src/testdir/test_popup.vim
+++ b/src/testdir/test_popup.vim
@@ -748,17 +748,11 @@
   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', 'D')
+  call writefile(a:lines, 'Xscript', 'D')
   let buf = RunVimInTerminal('-S Xscript', {})
 
   " wait for the script to finish
@@ -768,12 +762,32 @@
   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)
 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()
   CheckFunction balloon_split
 
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 23f318f..d345b3e 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1106,6 +1106,7 @@
   call assert_fails('call win_execute(winid, "next")', 'E994:')
   call assert_fails('call win_execute(winid, "rewind")', 'E994:')
   call assert_fails('call win_execute(winid, "pedit filename")', 'E994:')
+  call assert_fails('call win_execute(winid, "pbuffer filename")', 'E994:')
   call assert_fails('call win_execute(winid, "buf")', 'E994:')
   call assert_fails('call win_execute(winid, "bnext")', 'E994:')
   call assert_fails('call win_execute(winid, "bprev")', 'E994:')
@@ -3457,7 +3458,7 @@
   call StopVimInTerminal(buf)
 endfunc
 
-func Test_previewpopup_pum()
+func s:run_preview_popuppum(preview_lines, dumpfile_name)
   CheckScreendump
   CheckFeature quickfix
 
@@ -3471,30 +3472,43 @@
   END
   call writefile(lines, 'XpreviewText.vim', 'D')
 
-  let lines =<< trim END
-      call setline(1, ['one', 'two', 'three', 'other', 'once', 'only', 'off'])
-      set previewpopup=height:6,width:40
-      pedit XpreviewText.vim
-  END
-  call writefile(lines, 'XtestPreviewPum', 'D')
+  call writefile(a:preview_lines, 'XtestPreviewPum', 'D')
   let buf = RunVimInTerminal('-S XtestPreviewPum', #{rows: 12})
 
   call term_sendkeys(buf, "A o\<C-N>")
-  call VerifyScreenDump(buf, 'Test_pum_preview_1', {})
+  call VerifyScreenDump(buf, 'Test_pum_preview_' . a:dumpfile_name . '_1', {})
 
   call term_sendkeys(buf, "\<C-N>")
-  call VerifyScreenDump(buf, 'Test_pum_preview_2', {})
+  call VerifyScreenDump(buf, 'Test_pum_preview_' . a:dumpfile_name . '_2', {})
 
   call term_sendkeys(buf, "\<C-N>")
-  call VerifyScreenDump(buf, 'Test_pum_preview_3', {})
+  call VerifyScreenDump(buf, 'Test_pum_preview_' . a:dumpfile_name . '_3', {})
 
   call term_sendkeys(buf, "\<C-N>")
-  call VerifyScreenDump(buf, 'Test_pum_preview_4', {})
+  call VerifyScreenDump(buf, 'Test_pum_preview_' . a:dumpfile_name . '_4', {})
 
   call term_sendkeys(buf, "\<Esc>")
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_previewpopup_pum_pedit()
+  let lines =<< trim END
+      call setline(1, ['one', 'two', 'three', 'other', 'once', 'only', 'off'])
+      set previewpopup=height:6,width:40
+      pedit XpreviewText.vim
+  END
+  call s:run_preview_popuppum(lines, 'pedit')
+endfunc
+
+func Test_previewpopup_pum_pbuffer()
+  let lines =<< trim END
+      call setline(1, ['one', 'two', 'three', 'other', 'once', 'only', 'off'])
+      set previewpopup=height:6,width:40
+      badd XpreviewText.vim
+      exe bufnr('$') . 'pbuffer'
+  END
+  call s:run_preview_popuppum(lines, 'pbuffer')
+endfunc
 
 func Get_popupmenu_lines()
   let lines =<< trim END
diff --git a/src/testdir/test_preview.vim b/src/testdir/test_preview.vim
index 3d13d99..0df1a90 100644
--- a/src/testdir/test_preview.vim
+++ b/src/testdir/test_preview.vim
@@ -15,14 +15,7 @@
   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 @@
   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
 
diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim
index 22fd78c..73c3bee 100644
--- a/src/testdir/test_statusline.vim
+++ b/src/testdir/test_statusline.vim
@@ -220,6 +220,10 @@
   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/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 51ae7e6..900bf8a 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -2044,16 +2044,27 @@
   v9.CheckScriptFailureList(lines, ["E1356:", "E1405:"])
 enddef
 
+def s:check_previewpopup(expected_title: string)
+  var id = popup_findpreview()
+  assert_notequal(id, 0)
+  assert_match(expected_title, popup_getoptions(id).title)
+  popup_clear()
+  bw Xppfile
+  set previewpopup&
+enddef
+
 " Test for the 'previewpopup' option
 def Test_previewpopup()
   set previewpopup=height:10,width:60
   pedit Xppfile
-  var id = popup_findpreview()
-  assert_notequal(id, 0)
-  assert_match('Xppfile', popup_getoptions(id).title)
-  popup_clear()
-  bw Xppfile
-  set previewpopup&
+  s:check_previewpopup('Xppfile')
+enddef
+
+def Test_previewpopup_pbuffer()
+  set previewpopup=height:10,width:60
+  edit Xppfile
+  pbuffer
+  s:check_previewpopup('')
 enddef
 
 def Test_syntax_enable_clear()
diff --git a/src/testdir/test_window_cmd.vim b/src/testdir/test_window_cmd.vim
index 75b37ec..b6381a3 100644
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -1258,6 +1258,7 @@
 
     " Preview window
     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
diff --git a/src/testdir/test_winfixbuf.vim b/src/testdir/test_winfixbuf.vim
index 3cec4ed..2d4eaf6 100644
--- a/src/testdir/test_winfixbuf.vim
+++ b/src/testdir/test_winfixbuf.vim
@@ -2545,6 +2545,18 @@
   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()
diff --git a/src/version.c b/src/version.c
index 1cfe99d..f8cee6d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    934,
+/**/
     933,
 /**/
     932,