vimautocmd

How do you set an autocmd to take effect when filetype is none?


In Vim, I want to have a certain mapping set only if and only if the filetype is markdown, text, or none (ie NULL). Specifying "none" is the hard part.

The command below works if :set filetype? returns filetype=markdown or filetype=text. But if :set filetype? returns filetype= (shows as none in my status line) it does not work.

autocmd FileType markdown,text,none  nnoremap <leader>f :%! cat<CR>

What is the correct way to to specify filetype is not set? In other words this mapping should be defined only when filetype is not set (or is text or markdown). On any other filetype the mapping should be undefined.

NB: the mapping is contrived because it is not the interesting part of the question.


Solution

  • Here's one way:

    autocmd FileType markdown,text nnoremap <buffer> <leader>f :1,$! cat
    autocmd BufNewFile,BufRead * if empty(&filetype) | execute 'nnoremap <buffer> <leader>f :1,$! cat' | endif
    

    As the FileType event is not triggered when no filetype is detected, you have to use the original filetype detection events, and check for an empty filetype. Put those lines after :filetype on in your ~/.vimrc, so that the autocmd ordering is right.

    Note that the code in your question still defines global mappings (after one of your filetypes is loaded); you need to add <buffer> to make those mappings truly local. (And to be 100% correct use <LocalLeader>, though most users don't have a separate key defined for that.)

    If you're fine with a global mapping, you could also get rid of all the autocmds and just perform the filetype check (if that's really necessary; I don't see a bad behavior with other filetypes for your example) at runtime, e.g. with :help :map-expr:

    nnoremap <expr> <leader>f index(['markdown', 'text', ''], &filetype) == -1 ? '': ':1,$! cat')
    

    Postscript