3

I've been going through learn vim the hard way and am currently adding abbreviations via autocmd.

I've added the following to my .vimrc

augroup outputs
    autocmd!
    autocmd FileType php        :iabbrev <buffer> sout echo "";
    autocmd FileType javascript :iabbrev <buffer> sout console.log();<esc>hi
augroup END

which works, but only for new files. If I edit an existing .js or .php file it uses a cached version(I'm assuming) of the command before I editted it.

I was under the impression autocmd! would clear any existing commands. I've also tried adding abclear or running :abclear neither of which are allowing changes to the abbreviations to work on existing files.

Additonal troubleshooting: if I run :abbreviate on an existing file it shows the older version of the abbreviation. However, doing :abclear or :unabbreviate sout does not remove the entry on :abbreviate

1 Answer 1

2

If I edit an existing .js or .php file it uses a cached version(I'm assuming) of the command before I editted it. I was under the impression autocmd! would clear any existing commands.

autocmd! will clear the autocmds in the current augroup, but it will not undo any abbreviation, command, mapping, match, option they installed.

To install your buffer-local abbreviation via your autocmd, you can:

  • reload the buffer by executing :e
  • reassign the value of the 'filetype' option by executing :let &ft=&ft
  • apply your autocmd manually by executing :doautocmd outputs filetype

Additonal troubleshooting: if I run :abbreviate on an existing file it shows the older version of the abbreviation. However, doing :abclear or :unabbreviate sout does not remove the entry on :abbreviate

:abclear, and :unabbreviate, will remove global abbreviations.
If you want to remove the buffer-local ones instead, you should use the <buffer> argument:

" remove all buffer-local abbreviations
:abclear <buffer>

" remove all buffer-local abbreviations in insert mode only (but not in command-line mode)
:iabclear <buffer>

" remove all the 'sout' buffer-local abbreviations
:unabbreviate <buffer> sout

" remove the 'sout' buffer-local abbreviation in insert mode only
:iunabbrev <buffer> sout

If you don't want the rhs of your abbreviation to be affected by mappings, use the non-recursive version of :iabbrev, i.e. :inoreabbrev.


In the abbreviations table printed by :abbreviate, you can check whether an abbreviation is local to a buffer and whether its rhs can be remapped by looking at the symbol(s) between the lhs and rhs.
If you can read @, it means the abbreviation is local to the buffer.
If you can read *, it means the rhs of the abbreviation can't be remapped.


You could also move your abbreviations in filetype plugins.
For javascript, you could use ~/.vim/after/ftplugin/javascript.vim and for php ~/.vim/after/ftplugin/php.vim.

In a filetype plugin, you don't need autocmds anymore, you can write your abbreviations directly:

inoreabbrev <buffer> sout echo "";
inoreabbrev <buffer> sout console.log();<esc>hi

Also, it would allow you to make Vim remove the abbreviations automatically if you changed the filetype of your buffer.
To do that, you would need to include a command such as :iunabbrev in b:undo_ftplugin (see :h undo_ftplugin):

let b:undo_ftplugin = get(b:, 'undo_ftplugin', '')
    \ .(empty(get(b:, 'undo_ftplugin', '')) ? '' : '|')
    \ ."
    \   exe 'iuna <buffer> sout'
    \ | exe 'iuna <buffer> ...'
    \ | ...
    \ "
1
  • 1
    File type plugins look like exactly what I'm looking for. Thanks!
    – kalenpw
    Oct 17, 2018 at 22:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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