8

Some time ago I found an interesting trick on Damian Conway's vimrc which allows to open help files in new tabs instead of split windows. The code is the following:

"Only apply to .txt files...
augroup HelpInTabs
    autocmd!
    autocmd BufEnter  *.txt   call HelpInNewTab()
augroup END

"Only apply to help files...
function! HelpInNewTab ()
    if &buftype == 'help' && g:help_in_tabs
        "Convert the help window to a tab...
        execute "normal \<C-W>T"
    endif
endfunction

Of course this piece of code works well but I'd like to improve it: I feel that opening the help file into a new tab isn't that convenient and I rather open it into a new buffer and give the focus on this buffer.

So I'm looking for a command which would replace this line:

execute "normal \<C-W>T"

and more precisely <C-W>T to turn the window into a new buffer instead of a new tab.

Unfortunately, I could find anything which could help me in the documentation. So is it possible? And if it is, how can I do it?

statox
  • 49,782
  • 19
  • 148
  • 225
  • Erf how could have I not find this? (Maybe this question should be marked as duplicate actually) That's exactly what I want thanks. But is it normal that when I'm on an help buffer, I do :bn to go back to my previous buffer that close the help buffer (it doesn't appear anymore in :ls)? – statox Jun 26 '15 at 15:15
  • @Carpetsmoker: I just accepted Peter's answer, but could you make your solution an answer? It is what I was looking for on the beginning and it solve my problem so I think that is worth an answer :) – statox Jun 29 '15 at 15:59

2 Answers2

7

We can open help in the current window by set buftype=help and then using the :help command.

We have the following problems:

  • restore the 'buftype' value of the previous buffer, #, in the success case
  • restore the 'buftype' value of the current buffer, %, in the error case
  • let the :h error message through correctly

The :h command like so many of Vim's command will set v:errmsg when an error messages occurs. This means we can detect the error message. However this will give a "stack trace" when used inside of a function. We can overcome this by suppressing the error via :silent!. Now we can check v:errmsg and restore 'buftype' correctly.

Since you still want to keep the error message we will use :execute in the :command definition and have the function return the failed help command.

Below is the resulting code (Put this in your vimrc file):

function! s:help(subject)
  let buftype = &buftype
  let &buftype = 'help'
  let v:errmsg = ''
  let cmd = "help " . a:subject
  silent! execute  cmd
  if v:errmsg != ''
    let &buftype = buftype
    return cmd
  else
    call setbufvar('#', '&buftype', buftype)
  endif
endfunction
command! -nargs=? -bar -complete=help H execute <SID>help(<q-args>)

This creates the :H command which behave just like :h except open in the same window.

Thoughts

  • You may want to look into something like cmdallias.vim to make this command easier to type
  • Maybe instead of all this trouble just promote the help window to its own tab via <c-w>T (my preference)
  • the technique will need to be adjusted to take into consideration if there is a different a window with buftype=help already open

More help

:h 'buftype'
:h :h
:h :silent
:h v:errmsg
:h :exe
Peter Rincker
  • 15,854
  • 1
  • 36
  • 45
  • Thanks for your answer and sorry for my late comment! First: your method seems to be more reliable than mine combined with the comment of CarpetSmoker (using <C-w>o) but I haven't tested it yet in full depth. Secondly I have a question: with you method just like with mine, the help buffer seems to disapear (just like I described it in the comment on my question), is it an expected behavior? And if so is it possible to get rid of it so I can open an help buffer and then switch between it and my others buffers? – statox Jun 29 '15 at 15:14
  • Help buffers are unlisted so they do not show up in :ls or navigable via simple :bn/:bp commands. To see unlisted buffers do :ls!. Now if you use <c-^>/<c-6> you can easily switch between the current buffer and the alternative buffer. I remap this command to backspace via nnoremap <bs> <c-^> to make switching easier. If you really want to switch between the buffers you can do set buflisted around line 7 of the function, but that will clutter up your buffer list. – Peter Rincker Jun 29 '15 at 15:40
  • I think the <c-^>/<c-6> trick is what I was looking for, and I'll probably remap it too because on my azerty keyboard it's absolutely not convenient. Thank you for these additionnal informations! – statox Jun 29 '15 at 15:56
  • 1
    You can also do :tab help <topic> to make it open in a new tab. – mattb Sep 15 '22 at 23:26
0

The Vim 9.0 tips.txt help file contains a section on this topic. See:

:help help-curwin
jeberle
  • 101
  • 2