11

I want to perform rubyf action in VIM when I press F5 if the file is of .rb extension. Right now I just have

map <F5> :rubyf % <CR>.

But I also want to interpret scheme files if its .scm or compile tex etc using the same F5. How do I check the file extension and perform the correct binding? How do you guys compile different files in G/VIM?

unj2
  • 52,135
  • 87
  • 247
  • 375

4 Answers4

17

You could create a different autocmd for each file extension. eg:

au BufEnter,BufNew *.rb map <F5> :rubyf % <CR>.

See :help autocmd for info about autocmds.

A better approach for your specific problem would be to map <F5> to always invoke :make % and then have a autocmd that set the makeprg option for each file type (use setlocal when you do this for best results). This wouldn't be for loading ruby into Vim (as you seem to be doing) but instead for invoking an external compiler/interpreter/linter. This is essentially what I do. The nice thing about doing it this way is that Vim can interpret the errors and warnings and automatically jump to the problems in your code. You can also bring up a list of the errors/warnings. See :help quickfix for info about this, as well as the help topics for 'makeprg', :make, :copen and 'errorformat'.

A slight variation on this would be to not use autocmds at all, but instead to have an external script that when given a source filename figures out what to run (ruby, your scheme compiler, pychecker, your C compiler, whatever). Then just set makeprg to always run that script.

Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299
  • Are you sure BufEnter and BufNew are the correct events? BufNew occurs *in the original buffer* every time a new buffer is created (e.g. with `:vsplit` or `:tabedit`), and BufEnter occurs *every time* you switch buffers. Shouldn't this `map` only be called once, upon opening the file? – ban_javascript Nov 16 '22 at 20:46
  • I think `BufRead` and `BufNewFile` (as shown in @Silfverstrom's answer) seem to be better choices. – ban_javascript Nov 16 '22 at 21:09
  • 1
    @ban_javascript Consider the case where you open a .rb file in one buffer, then open a .scm file in another buffer, and then switch back to the first (.rb) buffer. Mappings are global, and without the `BufEnter` event, switching back to the already existing buffer won't cause the mapping to get updated. – Laurence Gonsalves Nov 17 '22 at 00:15
  • @ban_javascript `BufNew` is needed for the case where you create a new unnamed buffer (eg: run vim with no args), and then save it with a name (eg: `:w foo.rb`). `BufNew` is triggered by the rename, but `BufNewFile` is not. – Laurence Gonsalves Nov 17 '22 at 00:16
5

Use filetype plugins.

Create a file ~/.vim/ftplugin/ruby/custom.vim

In that file, put any commands you want included only when the filetype of the current buffer is ruby. They'll be sourced appropriately.

If you want to do the same thing from scheme, create another file ~/.vim/ftplugin/scheme/custom.vim`` and do the same thing.

Each time you load a file in vim, it will detect the filetype, and load all the plugins corresponding to your filetype.

sykora
  • 96,888
  • 11
  • 64
  • 71
4

Autocommands is your friend.
it is defined as followed:
:au[tocmd] [group] {event} {pat} [nested] {cmd}

in your case the following line in .vimrc will do what you want.
autocmd BufRead,BufNewFile *.rb map &lt;F5&gt; :rubyf % &lt;CR&gt;.

for more information se:
http://www.ph.unimelb.edu.au/~ssk/vim/autocmd.html

Silfverstrom
  • 28,292
  • 6
  • 45
  • 57
1

This is answered fairly well in the answers for this question.

Community
  • 1
  • 1
cjs
  • 25,752
  • 9
  • 89
  • 101