Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 940
Mr. Nicky Avatar asked Oct 11 '16 11:10

Mr. Nicky


People also ask

How do you assign a custom keyboard shortcut to a command?

Use a mouse to assign or remove a keyboard shortcut Go to File > Options > Customize Ribbon. At the bottom of the Customize the Ribbon and keyboard shortcuts pane, select Customize. In the Save changes in box, select the current document name or template that you want to save the keyboard shortcut changes in.

How do I add more hotkeys?

You can add a hotkey to any software or website shortcut on the Desktop. Right-click the desktop shortcut and select Properties from the menu. Click the Shortcut key box and enter a new keyboard shortcut for the program or web page. Just enter a letter there to set up the new hotkey.


2 Answers

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)

like image 147
lycuid Avatar answered Nov 02 '22 23:11

lycuid


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.
like image 41
Ingo Karkat Avatar answered Nov 03 '22 00:11

Ingo Karkat