Mr. Nicky
Mr. Nicky

Reputation: 1659

Is there a way to add custom keyboard shortcuts to Vim for running numerous commands?

I'm having the following issue - whenever I finish writing some C++ code in Vim and want to compile and run it, I have to:

  1. Exit insert mode
  2. Save the file using the command :w
  3. Write :! g++ *.cpp -o programName; ./programName in order to compile and run at once

After inputting the last two commands once, I obviously make use of the upper arrow key on the keyboard to get the last few commands instead of writting them down again and again on future compilations and runs.

But it's still kind of slow to me. So I was wondering if there's some sort of way to maybe create a keyboard shortcut which inputs these last two commands or even does all the three things at once!

Upvotes: 5

Views: 3488

Answers (2)

LycuiD
LycuiD

Reputation: 2575

You can use map to map keys to commands. nmap for normal mode, imap for insert mode etc

map <key> command

the cpp compiling you mentioned should go like:

autocmd FileType cpp nmap <buffer> <F5> :w<bar>!g++ -o %:r % && ./%:r<CR>

Add this command to your vimrc and will compile and run the current cpp file.

FileType cpp- detects the cpp file directly, (no need of manual regex).
nmap- used for mapping key while normal mode.
buffer- for the current buffer (in case of multiple splits).
<F5>- for mapping the 'F5' key.
And the command that executes is: :w | !g++ -o %:r % && ./%:r<CR>

In the above command, % is the file name (with extension), while %:r is the file name(without extension),
<CR> stands for the "Enter" button (Carriage Return)

Upvotes: 10

Ingo Karkat
Ingo Karkat

Reputation: 172540

Speeding up what you've used

If you :set autowrite, Vim will automatically persist the source file before invoking an external command (:!).

You can repeat the last external command via :!! (old vi trick), or / and then repeat the last Ex command via @: (still two keypresses less).

However, this doesn't scale, so you might be better off with a mapping.

Mapping

As this is specific to C++, I would advise you to define a buffer-local mapping, in a filetype plugin:

You can define that for certain filetypes by prepending :autocmd Filetype cpp ..., and put that into your ~/.vimrc. But that gets unwieldy as you add mappings and other settings for various filetypes. Better put the commands into ~/.vim/ftplugin/cpp_mappings.vim. (This requires that you have :filetype plugin on.)

nnoremap <buffer> <F5> :update<Bar>!g++ -o %:r % && ./%:r<CR>

Notes

  • You should use :noremap; it makes the mapping immune to remapping and recursion.
  • :update is a variant of :write that only performs a write if there indeed are unpersisted changes; so, it's slightly more efficient.
  • For the %:r placeholders (that make the mapping independent of the current filename), see :help cmdline-special.

Upvotes: 4

Related Questions