4

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?

  • I think you want <C-w>o? (also see: How to “full screen” browse Vim help?). – Martin Tournoij Jun 26 '15 at 15:08
  • 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
3

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.