Dmytrii Nagirniak
Dmytrii Nagirniak

Reputation: 24108

File completion when mapping commands in VIM

I often create a temporary mapping to do something on a particular file.

Typical example is this:

:map <leader>f :w<cr>:! bundle exec cucumber features/account/sign_in.feature:41<cr>

I want the file features/account/sign_in.feature to be autocompleted from the current directory.

This should simply save the current file and shell out on <leader>f to run the command.

It allows me to easily work on a piece of code not thinking about jumping to a particular file and run it.

The problem is that creating such a binding is cumbersome and error prone.

VIM doesn't allow completing the file name when mapping. Also using % is totally different ( I want to map to a file statically).

What is a better way of doing it?

Thanks.

Upvotes: 3

Views: 251

Answers (2)

holygeek
holygeek

Reputation: 16195

I don't know the answer but if I were you I'd use cabbr:

:cabbr fas features/account/sign_in.features:

Or something like that. It's not autocomplete, but it sure does reduce the number of keystrokes you need.

Another alternative is to create a function mapped from a user command that accepts an argument that creates the mapping. If I remember it correctly you can customize the user command completion so that might work.

Update: yes you can customize user command. See :help user-command

Something like this should get you started:

command -complete=file_in_path -nargs=1 Map call CreateMap(expand('<args>'))

function CreateMap(filename)
    exec 'map <leader>f :w<cr>:! bundle exec cucumber ' . a:filename . ':41<cr>'
endfun

Once you do that, ensure that you 'path' setting includes the current directory ".", or if you want to make it search recursively "./**". Then you can use the Map user command like this:

:Map fea<tab>ac<tab>

Upvotes: 1

sehe
sehe

Reputation: 393674

Allthough I think your question should be made a lot clearer, here are some hints:

:nnoremap <leader>f :w<bar>!exec "bundle exec cucumber " . expand('%') . ":" . line('.')<CR>

Will correctly save and insert current filename/line number in the command

Also, you will want to know about the autowrite option:

:se autowrite

Lastly, I usually employ makeprg for this kind of purpose:

:let &makeprg="bundle exec cucumber %"

This has the added benefit of working with quickfix commands (:copen, :colder, :cnewer) and (given a correct makef) also jumping to error lines

Upvotes: 4

Related Questions