Run code directly from Gvim with a keybinding - vim

I am looking for a way to run the most used programming languages (python, c, c++, etc)
With a keybinding. A plugin would be preferred.
Thank you

Scripting languages (e.g. python):
To run the current python script with a shortcut (for example F1):
For Windows, add the following line to your _vimrc:
autocmd FileType python nmap <silent> <buffer> <F1> :silent up<CR>:silent <C-r>=!cmd /k python <C-r>=expand("%:p")<CR><CR>
For this to run correctly, python directory should be added to your %Path%.
If python scripts (*.py) are associated with python.exe, no need to call python then the script as an argument, as the script can be called directly.
For Linux, add the following line to your .vimrc:
autocmd FileType python nmap <silent> <buffer> <F1> :silent up<CR>:silent <C-r>=!python <C-r>=expand("%:p")<CR> &<CR>
Compiled languages (e.g. C):
Map a shortcut to compile the file:
autocmd FileType c nmap <buffer> <F1> :up<CR>:!gcc <C-r>=expand("%:p")<CR> -o <C-r>=expand("%:p:r")<CR><CR>
And map another shortcut to run the resulting executable:
autocmd FileType c nmap <silent> <buffer> <S-F1> :silent <C-r>=!<C-r>=expand("%:p:r")<CR> &<CR>

Related

how to keybind shortcuts with vim autocmd FileType?

I have these lines in my vimrc file:
autocmd FileType js nnoremap <F5> :! node % <CR>
autocmd FileType cpp nnoremap <F5> :! g++ % -o %.out && ./%.out <CR>
autocmd FileType py nnoremap <F5> :! python % <CR>
Problem: compiling and running cpp files with F5 works normally, but js and py files can't run, I think the shortcut is not being executed at all.
The name of vim's filetype for python is "python", not "py". See also this answer. Similarily, it's "javascript", not "js". However, "cpp" is fine.
So the first and third lines should be:
autocmd FileType javascript nnoremap :! node %
autocmd FileType python nnoremap :! python %

Vimrc autocmd runs command instead of mapping

I want to add a hotkey to my vim to run my python files, so I have added the following line to my vimrc:
autocmd FileType python map <F5> :w|!python3 %
But on opening the file instead of running autocmd, it runs python with my file.
For me this seems no different from what many tutorials suggest on using autocmd and map, so I'd like to know what exactly is happening here instead of the behavior I expect.
Your :map command ends at the command separator |; the remainder is already executed when the :autocmd runs. You need to escape it (\|), or better use the special <Bar> character:
autocmd FileType python nnoremap <buffer> <F5> :w<Bar>!python3 %<CR>
Cp. :help map_bar. Also, you should use :noremap; it makes the mapping immune to remapping and recursion. And (as #PeterRincker suggested), make the mapping buffer-local, so that it only applies to Python buffers).
Your :autocmd FileType approach is fine for a few mappings, but it doesn't scale well. If you have :filetype plugin on in your ~/.vimrc, you can factor our your mappings into a separate script ~/.vim/ftplugin/python_mappings.vim.

VIM: why do these bindings work only sometimes?

I've got these bindings in my .vimrc. They work most of the time, but sometimes they don't: they will just save the file but not run it.
Then I go into insert mode and exit it back to normal mode, and they work again. What could be the problem?
Thanks!
autocmd FileType python map <C-k> :write <CR> :! python % <CR>
autocmd FileType lisp map <C-k> :write <CR> :! clisp % <CR>
autocmd FileType scala map <C-k> :write <CR> :! scala % <CR>
There are many topics to discuss here so with out further ado:
Mappings
Your current mappings map <c-k> ... will only work in normal, visual, and operator-pending modes. However executing your mappings in visual mode or operator-pending modes would save the buffer with only a range of lines (read not good). I suggest you make your mappings for normal mode only.
Two general rules of thumb:
Always supply a mode like n for normal.
Always use noremp instead of map unless you are mapping to a <Plug> mapping.
So one of your mappings might look something similar to this:
nnoremap <c-k> :w<cr>:!python %<cr>
For more information:
:h :map-modes
:h map-overview
:h :nore
:h map-listing
:h map-verbose
Filetype based mappings
You need to do 2 things:
Create a mapping local to a specific buffer by using the <buffer> option for noremap.
Load the mappings for just a specific filetype.
This can be done via an autocmd and FileType event in your .vimrc like so:
autocmd FileType python nnoremap <buffer> <c-k> :w<cr>:!python %:p<cr>
The other way option is by creating a filetype plugin. (see :h ftplugin for more details)
A simple example is do create a file named, ~/.vim/ftplugin/python.vim and place your mappings inside like so:
nnoremap <buffer> <c-k> :w<cr>:!python %:p<cr>
I personally lean more towards the ftplugin approach but having a everything in your .vimrc file can be nice.
For more help see:
:h :au
:h FileType
:h map-local
:h ftplugin
:make
A more vim like way of doing this would be to use :make. (Assuming you want to lint vs execute your current buffer)
:make will execute the 'makeprg'. It defaults to make which is great of C projects
After running :make the quickfix list will be contain any errors.
Set your compiler via the :compiler command.
Extra parameter can be passed like so :make foo-command
Current filename can be represented by %. e.g. :make %
Often people set do :complier/'makeprg' in side of ftplugins e.g. ~/.vim/ftplugin/perl.vim or autocmd's e.g. autocmd FileType perl compiler perl.
Fop more help see:
:h :make
:h 'makeprg'
:h :compiler
:h c_%
quickfix list
Use :cnext and :cprev to move between your errors.
:copen to open up the quickfix list in a window (:cclose to close)
:cwindow to open quickfix list window only if there are errors
May want to use better mappings for :cnext and friends. I suggest Tim Pope's unimpaired plugin
For more help see the following:
:h quickfix
:h :cnext
:h :cope
Alternatives to using :make
Just use <c-z> to suspend vim and run your build system. (Cons: loose out on the quickfix list)
Use :! to compile. (Same cons as suspending) e.g. :!make
Syntastic is a syntax checking system that checks files on save
Ale (Asynchronous Lint Engine) is a plugin for providing linting in NeoVim and Vim 8 while you edit your text files
Dispatch can be used to run things in the background. Great for test suites
May want to consider terminal multiplexers like tmux or screen.
SingleComplile tries and takes some of the work out of using :make
Conclusion
Personally I would install ALE as this removes the need for your mappings. It is also a great idea to learn how to use the location (or quickfix) list. When you are ready to get your hands dirty then you can learn and use :make.
tl;dr
Install ALE.
The space inserted between <CR> and : could lead to errors, because this space is really entered during the execution of the mapping.
With :noremap or :nnoremap (which should be used most of the times, as Peter Rincker wrote in his answer), it wouldn't be a big problem, since it only would move the cursor one char to the right (see :h <space>).
But with :map, it could trigger a custom mapping (or a partial one).
Then, instead of:
autocmd FileType python map <C-k> :write <CR> :! python % <CR>
the following would be better:
autocmd FileType python map <C-k> :write <CR>:! python % <CR>
and this one, really better:
autocmd FileType python nnoremap <C-k> :write <CR>:! python % <CR>

Is there a better way to map command call based on filetype [duplicate]

This question already has answers here:
Vim inoremap for specific filetypes
(5 answers)
Closed 8 years ago.
I'm new to vim after switching from Notepad and Notepad++, but I've been using it exclusively for the past four months. In my .vimrc I have a command that automatically changes the command call based on file extensions. For example, if I'm editing an R file, I can press <F5> and vim executes !Rscript %:p<cr>, but if I switch to a python file and press <F5>, vim executes !python %:p<cr>. I accomplish this by putting the following in my .vimrc:
autocmd BufRead *.R noremap <F5> :!Rscript %:p<cr>
autocmd BufRead *.pl noremap <F5> :!perl %:p<cr>
autocmd BufRead *.py noremap <F5> :!python %:p<cr>
I'm wondering if this is the "proper" vim way to execute it based on the command call. I know some of python files I work with do not have a *.py extension, and so the setting is useless in this case.
You need to do 2 things:
Create a mapping local to a specific buffer by using the <buffer> option for noremap.
Load the mappings for just a specific filetype.
This can be done via an autocmd and FileType event in your .vimrc like so:
autocmd FileType perl noremap <buffer> <F5> :!perl %:p<cr>
The other way option is by creating a filetype plugin. (see :h ftplugin for more details)
A simple example is do create a file named, ~/.vim/ftplugin/perl.vim and place your mappings inside like so:
nnoremap <buffer> <F5> :!perl %:p<cr>
I personally lean more towards the ftplugin approach but having a everything in your .vimrc file can be nice.
For more help see:
:h :au
:h FileType
:h map-local
:h ftplugin
if you have BufRead *.py, the autocommand was trigger only when it is loading a *.py buffer/file.
vim has filetype detection mechanism.
Vim can detect the type of file that is edited. This is done by
checking the file name and sometimes by inspecting the contents of the
file for specific text.
you should switch :filetype on
and use FileType event in your autocmd.

Change the mapping of F5 on the basis of specific file type

The current mapping of my F5 key is:
imap <F5> <esc>:w\|!python %<CR>
Now I want that if I'm editing any python file (it will be better if it also recognizes file other than standard .py format like .pyd etc) then this mapping works as it is. But, if I edit a Java file it is mapped to something like:
imap <F5> <esc>:w\|!javac %<CR>
And when I'm editing any .c or .cpp file then F5 is mapped to this:
imap <F5> <esc>:w\|!make %<CR>
I have no idea how to proceed.
There are problems with both given answer and original mapping. First of all, for buffer-local mappings there is *map <buffer>. Second, with <buffer> you don’t need to use BufEnter events and can instead use Filetype which are launched only once. Third, you have one error (2.), one potential problem (1.) and one place that can be optimized in original mappings:
you should not be using imap, it makes it very easy to accidentally break old mappings when adding new ones
!python % will break once file contain a special symbol (space, semicolon, quot, dollar, …)
using :update instead of :write avoids useless writes in some cases
My variant:
autocmd Filetype c,cpp inoremap <buffer> <F5> <C-o>:update<Bar>execute '!make '.shellescape(expand('%:r'), 1)<CR>
autocmd Filetype python inoremap <buffer> <F5> <C-o>:update<Bar>execute '!python '.shellescape(#%, 1)<CR>
autocmd Filetype java inoremap <buffer> <F5> <C-o>:update<Bar>execute '!javac '.shellescape(#%, 1)<CR>
Try this:
au BufEnter *.py map <F5> <esc>:w\|!python %<CR>
au BufEnter *.java imap <F5> <esc>:w\|!javac %<CR>
au BufEnter *.c, *.cpp imap <F5> <esc>:w\|!make %<CR>
I'm not 100% sure about the comma separated file types, trying to verify...
The vim docs are usually pretty nasty to try to figure out how to use commands, but these should help get you started:
:h BufEnter
:h :autocmd
Note: You may have to restart vim for these changes to overwrite the current autocommand groups.

Resources