我不太了解 vim 脚本,仅足以修补我的 vimrc。所以我正在寻求有人的帮助来了解这里可以做什么。
我使用 vim 帮助页面“tips.txt”、标签“help-curwin”中的
HelpCurWin
命令。该命令旨在在当前窗口中打开给定的帮助页面,而不是打开新的拆分。这部分工作正常。这是代码:
" Command to open help page in current window.
command -bar -nargs=? -complete=help HelpCurwin
\ execute s:HelpCurwin(<q-args>)
let s:did_open_help = v:false
function s:HelpCurwin(subject) abort
let mods = 'silent noautocmd keepalt'
if !s:did_open_help
execute mods .. ' help'
execute mods .. ' helpclose'
let s:did_open_help = v:true
endif
if !getcompletion(a:subject, 'help')->empty()
execute mods .. ' edit ' .. &helpfile
endif
return 'help ' .. a:subject
endfunction
这是与 nvim 文档略有不同的版本(我都尝试过):
" Command to open help page in current window.
command -bar -nargs=? -complete=help HelpCurwin
\ execute s:HelpCurwin(<q-args>)
let s:did_open_help = v:false
function s:HelpCurwin(subject) abort
let mods = 'silent noautocmd keepalt'
if !s:did_open_help
execute mods .. ' help'
execute mods .. ' helpclose'
let s:did_open_help = v:true
endif
" Fix from nvim documentation.
if !empty(getcompletion(a:subject, 'help'))
execute mods .. ' edit ' .. &helpfile
endif
return 'help ' .. a:subject
endfunction
正如我所说,在当前窗口中打开帮助页面的主要目标已经实现,但是,我注意到有 3 个副作用:
:HelpCurwin
,“help.txt”页面也会被列为常规缓冲区,并且不会获得语法突出显示(即使文件类型设置正确)。这些不是关键问题,但它困扰着我,如果有人能帮助我解决它,我将不胜感激,或者,如果不可能,请向我解释原因。
编辑:我忘记指出我个人主要在垂直分割窗口中使用此功能,因此我希望主要针对该用例来改进它。
这是我想出的一个解决方案,它比推荐的解决方案稍微简单一点(IMO),并且不会遇到污染缓冲区列表的问题。
" Open help in the current window with :Help
command! -bar -nargs=? -complete=help Help call s:HelpHere(<q-args>)
function! s:HelpHere(subject) abort
" remember the state of the windows
let l:window_id = win_getid()
let l:window_width = winwidth(0)
let l:num_windows = winnr('$')
" open the help window
execute 'help ' .. a:subject
" close the original window if a new help window was opened, and
" if it should have opened immediately above the original window
if l:num_windows < winnr('$') && (l:num_windows == 1 || l:window_width >= 80)
call win_execute(l:window_id, 'close')
endif
endfunction
新的
:Help
命令由函数s:HelpHere
实现。该函数只是将其参数传递给标准 :help
命令,然后如果 :help
创建了新窗口,则关闭原始窗口。
大多数时候,这会模拟在调用
:Help
的窗口中打开帮助窗口。
但是,如果从狭窄窗口调用标准
:help
命令,那么它将在可能的几个垂直分割窗口之上创建一个新窗口,因此关闭原始窗口并不能模拟我们想要的效果。在这种情况下,我的 :Help
命令不会关闭原始窗口,而只是保留 :help
的默认行为。
无论窗口宽度如何,这个似乎都可以工作,并且还支持多个帮助窗口,在现有帮助窗口中第一次打开后没有
:help
:
" uses current window for help buffer, replacing the active buffer,
" rather than making a new window, as vim normally does
"
" note: untested when tabs are in use
command -nargs=? -complete=help Help call s:Help(<q-args>)
function s:Help(subject) abort
let l:helpbufs = []
for w in getwininfo()
if getbufvar(w.bufnr, '&buftype') == 'help'
call setbufvar(w.bufnr, '&buftype', 'nowrite')
call add(l:helpbufs, w.bufnr)
endif
endfor
execute 'help ' . a:subject
let l:helpbufnum = bufnr()
execute 'helpclose'
execute 'buffer ' . l:helpbufnum
for n in l:helpbufs
call setbufvar(n, '&buftype', 'help')
endfor
endfunction
它打开帮助缓冲区,并让 vim 像往常一样分割。保存缓冲区编号后,我们
:helpclose
它。这将返回到之前的布局。帮助缓冲区将保留,但不列出。所以我们可以在原始窗口中按数字编辑该缓冲区。
如果您只需要一个帮助窗口,只需删除前后的
for
循环即可。如果有的话,Vim 将在现有窗口中打开 buftype == 'help'
。
您可能还希望使其能够与原始小写字母
:help
和 :h
一起使用:
" make :help and :h commands run our :Help rather than builtin
" (really it just replaces the command in realtime whilst typing)
"
function HelpAbbrev(arg) abort
let pat = '^' . a:arg
return getcmdtype() == ":" && getcmdline() =~ pat ? 'Help' : a:arg
endfunction
cnoreabbrev <expr> h HelpAbbrev('h')
cnoreabbrev <expr> help HelpAbbrev('help')