4

When writing a Vim help file, it's often useful to set the filetype to help to show syntax highlighting and such. But I find this annoying to work with when editing the document due to the "concealed" characters; my cursor behaves in "strange" ways and I often remove the concealed characters by accident.

I now set the filetype to text before editing, and setting it back again to help when I want to check if my changed are valid.

I would like to do this automatically. I know I can do:

autocmd InsertEnter *.txt setlocal filetype=txt
autocmd InsertLeave *.txt setlocal filetype=help

But how can I do this only for help files and not other .txt files?

7

Asked: Setting the filetype

The autocommands in the question are a good start, and with 2 extra pieces of knowledge we can finish it:

  • You can define autocommands everywhere. autocmd and augroup are "just" regular Vim commands, not special syntax or keywords. So defining an autocmd from within an autocmd is perfectly fine.

  • You can define autocommands to be buffer-local (see: :help autocmd-buffer-local).

Armed with this information, the solution is fairly easy:

augroup help_start
    autocmd!
    autocmd FileType help call SetHelpFiletype()
augroup end

fun! SetHelpFiletype()
    augroup help_insert
        autocmd!
        autocmd InsertEnter <buffer> setlocal filetype=txt
        autocmd InsertLeave <buffer> setlocal filetype=help
    augroup end
endfun

I used a function here since nesting multiple augroups inline does seem to be problematic (the first augroup end seems to end both groups; you can opt to not use an augroup for the inner autocmds, but this can lead to them being executed multiple times after reloading the vimrc file).

You will need a modeline which sets the filetype. It's pretty much standard to add a modeline to the end of Vim help files, so this is probably already present:

vim:tw=78:ts=8:ft=help:norl

Better: configuring concealed characters

There is another (probably better) way to solve this problem: by showing the concealed characters in insert mode.

The ftplugin for help files does:

setlocal conceallevel=2 concealcursor=nc

conceallevel=2 tells Vim to actual conceal characters which are marked as such, but concealcursor=nc tells Vim to conceal the characters only in normal and cmdline mode.

However, this still confusing:

  1. The characters don't show up very clearly as they are still hidden due to the syntax highlighting:

    :highlight helpBar
    helpBar        xxx links to Ignore
    
    :highlight Ignore
    Ignore         xxx ctermfg=15 guifg=bg
    

    15 is white, which is my terminal's background colour (this always matches your terminal's background colour).

  2. Only the characters for the current line show up. This can be considered both a feature and a bug, but I don't like it.

We can fix this with:

  1. Use :highlight clear Ignore. This will clear the syntax highlighting for the Ignore group.

  2. Tell Vim to set conceallevel to 0 (always show all concealed characters) when entering insert mode.

Putting this together, we end up with:

augroup help_start
    autocmd!
    autocmd FileType help call SetHelpFiletype()
augroup end

fun! SetHelpFiletype()
    augroup help_insert
        autocmd!
        autocmd InsertEnter <buffer> setlocal conceallevel=0 | highlight clear Ignore
        autocmd InsertLeave <buffer> setlocal conceallevel=2
    augroup end
endfun

This will show the formatting characters, and still shows the syntax highlighting in insert mode. In normal mode, it will show the help file as the user sees it when reading it.

This method is also also a bit faster than setting the filetype since Vim doesn't have to source a bunch of filetype/syntax files.

Preview split

(With thanks to @PeterRincker's comment).

conceallevel is a window local setting. This means you can easily use splits. One for editing with set conceallevel=0 and the other window with the default set conceallevel=2.

This is especially useful in combination with How can I get both splits to scroll left or right at the same time?.

You can create a command to show a "preview split" like so:

command! HelpPreview setlocal scrollbind | split | setlocal conceallevel=0 | highlight clear Ignore
  • 3
    'conceallevel' is a window local setting. This means you can easily use splits. One for editing with set conceallevel=0 and the other window with the default ( set conceallevel=2). – Peter Rincker Jun 25 '15 at 17:20
1

Try this

autocmd InsertEnter *.txt if &buftype == 'help' | setlocal filetype=txt | endif
autocmd InsertLeave *.txt if &buftype == 'help' | setlocal filetype=help | endif

Or:

autocmd InsertEnter *.txt if &filetype == 'help' | setlocal filetype=txt | endif
autocmd InsertLeave *.txt if &filetype == 'help' | setlocal filetype=help | endif

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.