I already have this in my vimrc:
set shell=powershell
set shellcmdflag=-command
Now I want to pass powershell the path of the current file so it can run it. I tried this:
nnoremap <C-q> :! expand('%:p')<cr>
And here is what I see in powershell:
powershell -command " expand('\\path\to\my\file....
Obviously this doesn't work because I've that darn expand() in there. How can I pass just the full path of the current file to my shell?
Also, before anyone says something I have my own mapping I use for visual block which is why I'm re-mapping <C-q>
The special characters like % (:help cmdline-special) are automatically expanded by Vim "at places where a file name can be used" (to quote from the help). This includes the :! command, so the following is enough:
nnoremap <C-q> :! %:p<CR>
Now, if you wanted to do more complex mangling than the :p, there would be two options:
Using :execute: nnoremap <C-q> :execute '!' expand('%:p')<CR>
Using <C-R> with the expression register: nnoremap <C-q> :! <C-r>=expand('%:p')<CR><CR>
How about just using %:p
nnoremap <C-q> :!%:p<CR>
Related
I am new to vim and I'm using it to type up my latex documents. I work on Windows, and have defined this map in my vimrc file:
autocmd FileType tex inoremap ,lc <Esc>:w! \| !latexmk -pdf -pv %<CR>
When latexmk is ran, it opens up a cmd window and then the PDF viewer window. However, it doesn't close the cmd window, which I then have to close by pressing any key. Is there any way to define my map such that it closes the command line and opens up my PDF? I thought something like
autocmd FileType tex inoremap ,lc <Esc>:w! \| !latexmk -pdf %<CR> \| !latexmk -pv %<CR>
could work, but turns out it doesn't.
You can try:
autocmd FileType tex inoremap ,lc <Esc>:w! \| !latexmk -pdf -pv %<CR> \| call feedkeys(' ')<CR>
The feedkeys() simulates the press of the given key(s), in occurence the space key, which should close the command message for you.
Additional advices
As you are new to Vim, you may be interested by some additional advices I want to share to improve your above code:
You can add the <buffer> argument to your mapping:
autocmd FileType tex inoremap <buffer> ,lc ...
It will map your shortkey only for latex buffers. Without it, once a latex file is loaded, every buffer and window will interpret your mapping, which is not what you want I guess.
You can create a dedicated function in order to perform the job you want: it will improve readability and make it easier to modify. Indeed, your autocommand line is becoming quite long to read, and it might be still longer if you wanted to add more features.
So you could transform your code into something like this:
autocmd FileType tex inoremap <buffer> ,lc <Esc>:call MakeLatex()<CR>
function MakeLatex()
w!
!latexmk -pdf -pv %
call feedkeys(' ')
endf
Depending of what exact behaviour you want for your mapping, you could replace <esc> by <c-o> in your mapping.
This way, you can stay in Insert mode after having typed your shortcut:
autocmd FileType tex inoremap <buffer> ,lc <C-O>:call MakeLatex()<CR>
The last thing to improve (imho) would be to put all of this into a separate ftplugin file. This way you can separate features that you only want for Latex files, and make it easier to add even more filetype-based features.
In order to do this, go to your vim home directory (it should be something like ~/.vim or ~/vimfiles on Windows) and create the file <YOUR_VIM_DIR>/ftplugin/tex.vim; this file will be loaded each time you will want to edit a latex file, without the need of any autocmd FileType tex. Then put the following code into this file:
inoremap <buffer> ,lc <c-o>:MakeLatex<cr>
command! -buffer MakeLatex call s:make_latex()
function s:make_latex()
w!
!latexmk -pdf -pv %
call feedkeys(' ')
endf
It is a slightly improved version compared to the above one, because now, everything is local to the buffer or to the script. In the previous version, the MakeLatex() function scope was global to Vim, while it was not needed outside of Latex files. With this version, s:make_latex() is local to the script, and the MakeLatex command is local to the buffer, so the scope of commands/functions is really limited to Latex files only.
Hope this can be useful, happy vimming;
I have configured <F5> to use the Windows start command, but trying to use the command line option "/wait" confuses VIM so that the command is not found anymore.
Here my old mapping:
noremap <F5> :w<CR>:!start "%:p"<CR>
I changed the mapping to:
nnoremap <F5> :w<CR>:!start /wait "%:p"<CR>
Using the later cause the following error:
E371: command not found
But why "command not found", the command is still "start", isn't it?
Thanks in advance!
Vim implement :!start command it-self since Vim must handle background command correctly. And it doesn't have /wait option. See :help :!start.
Using "start" stops Vim switching to another screen, opening a new console,
or waiting for the program to complete; it indicates that you are running a
program that does not affect the files you are editing. Programs begun
with :!start do not get passed Vim's open file handles, which means they do
not have to be closed before Vim.
To avoid this special treatment, use ":! start".
:nnoremap <F5> :w<CR>:! start /wait %:p<CR>
FYI: original start command doesn't require double-quote for argument.
I tried to map <Alt+D> to <Ctrl+D> by adding the below line to .vimrc, but it doesn't work. I checked the .vimrc is loaded by Vim.
map <Alt-D> <C-D>
Is there any error in this mapping?
To Mac users out there: for mapping ALT+hjkl, use instead the real character generated (find out which character using the combination while in INSERT mode), for example with my keyboard I get:
<ALT+j> ==> ª
<ALT+k> ==> º
and so on.
Solution found here on StackOverflow.
I used this to move lines up and down with ALT+k\j, using this on my .vimrc:
nnoremap ª :m .+1<CR>==
nnoremap º :m .-2<CR>==
inoremap ª <Esc>:m .+1<CR>==gi
inoremap º <Esc>:m .-2<CR>==gi
vnoremap ª :m '>+1<CR>gv=gv
vnoremap º :m '<-2<CR>gv=gv
as explained here.
Hope it's useful, enjoy Vim :)
ADDENDUM BY Dylan_Larkin (2019): For this to work on a Mac, "Use Option as Meta Key" must be turned OFF in Terminal->Preferences->Keyboard
UPDATE 09/2021
I recently switched from a "British" keyboard to "ABC - Extended" and noticed this configuration doesn't work as expected.
As an alternative, I mapped the <up> and <down> keys to do the same operation (which, I guess, also solves most of the complexity explained in other answers of this very question):
nnoremap <down> :m .+1<CR>==
nnoremap <up> :m .-2<CR>==
inoremap <down> <Esc>:m .+1<CR>==gi
inoremap <up> <Esc>:m .-2<CR>==gi
vnoremap <down> :m '>+1<CR>gv=gv
vnoremap <up> :m '<-2<CR>gv=gv
This is also a great way for beginners to rewire the habit of using the arrows and instead learn the much more efficient Vim motion way to move around the code. ;)
You can complete your transition mapping <left> and <right> to quickly move between tabs with:
nnoremap <left> gT
nnoremap <right> gt
Or whatever you fancy (even a brutal <NOP>, like I did at the beginning of my journey).
:help key-notation describes what format needs to be used to map different keys. In the case of alt, you can use either <A- or <M-. So your mapping would be
map <M-d> <C-d>
I'd also recommend using the nore variant of :map (e.g., noremap) unless you explicitly want to allow the right-hand side to be re-evaluated for mappings.
I'm not sure is "possible" anymore. Please read the update below.
Yes, you can even in terminal vim, but there's no real catch all answer. You basically have to follow two steps:
Make sure the <M-d> notation exists, and map exactly what your terminal inputs (^[ is the escape character):
$ cat
^[d
$
" in your .vimrc
execute "set <M-d>=\ed"
" you have to use double quotes!
Map something to your newly "created" combination:
noremap <M-d> :echo "m-d works!"<cr>
Understanding how it works, you can expand this "trick" to other "strange" combinations, for instance, I'm using termite, and vim doesn't recognize <S-F1>, using cat I get ^[[1;2P. Then, in my vimrc I do: execute "set <S-F1>=\e[1;2P", and then I can map it to anything.
Note: I don't know why, but for some people using \<Esc> works instead of \e.
Update (february 2016)
Depending on the terminfo your terminal runs, maybe you could... in most terminals, "alt + h", for example, is mapped to ^[h, which is: "escape + h". So it could overwrite keys. I've just tried (again) and it seems to work, but I believe it's a very buggy and error prone implementation.
Nevertheless, for the brave enough, here's an experimental plugin:
https://github.com/vim-utils/vim-alt-mappings
https://github.com/drmikehenry/vim-fixkey
Map Alt Key in Vim on Mac OSx:
Start by viewing the key code your terminal is sending to vim:
$ sed -n l
^[[1;9D
In the above example, I ran the command and pressed Alt + Left.
The ^[[1;9D is the escaped sequence being sent to vim, so we can user that for our mapping.
map <Esc>[1;9D
Use:
map <A-D> <C-D>
See :help key-notation.
My Terminal would produce ^[x commands (e.g. for alt-x). What got it to work inside Vim was this small script from vim.wikia.com:
for i in range(97,122)
let c = nr2char(i)
exec "map \e".c." <M-".c.">"
exec "map! \e".c." <M-".c.">"
endfor
Add to .vimrc to fix all alt key mappings.
as a follow up to Bruno's answer for Mac users, try making sure your option key is mapped to Esc+.
This will give you the "normal" behavior of the option (A) key in Vim.
For example, in iterm2, this option can be found under Preferences > Profiles > Keys:
Your terminal might not transmit "properly" the Alt-D. You can use C-V to actually get the actual escape sequence send to Vim and use it to create your mapping. Ie, edit your .vimrc
and replace the actual by typing the following sequence "C-V Alt-D" so you'll have the correct escape sequence in your vimrc. That won't work if your terminal doesn't send anything to vim.
Find out key mapping by putting following command in your vim editor
:help key-notation
It will display all the key mapping.
In my ubuntu system for Alt it is <M-...>. It is possible for your version mapping might be different. If you too have same mapping then following should work.
map <M-D> <C-D>
Hello after no good solution after years of testing all the above on mac, I kept searching.
Here is my solution:
To create a combination keystroke including Alt you have to declare the combination in the preference > keyboard and use that combination in the vim setup file (check use option as meta key).
The output must be an unusual character (no a for example) so that you're not overriding a regular character.
In the example below you should be able to quite vim with ALT-Up.
vim setting:
mac setting:
I'm trying to learn VIM editor , and I'm going to test some small code
for ruby
here is question..
When I compile and launch my small ruby code,
Command-mode,
:!ruby %
Or Open another terminal,
$ruby filename.rb
I did ,
but.. its really stressful and I cannot focus....
Is there any magical things?? ,
config .vimrc file then make a hot-key
or... make some script by rubyself...??
You can use :!! to repeat the last :!{cmd}.
You can type :!ruby % once, and then run :!!, which can of course be mapped to a key like:
nnoremap <F8> :!!<CR>
Or to write and run it (saves typing :w):
nnoremap <F8> :w<CR>:!!<CR>
This is a flexible solution, since you can replace :!ruby % with anything else (e.g. :!coffee -c %, :!python %, etc.).
If your vim distribution has ruby support, can be confirmed using vim --version |grep ruby, Then
nnoremap <F9> :rubyfile %<CR>
This is will be more faster as this does not invoke an external command using !ruby and hence no shell launch. More details at :help ruby.
Another way to complete the work irrespective of ruby support.
Your vim distribution will come with $VIMRUNTIME/compiler/ruby.vim for compiler setting. If so, you can set it :compiler ruby for ruby files in your vimrc.
This will allow you to just do make to accomplish what you are doing. But output looks somewhat clumsy.
Hence, Having a some keybinding will help
nnoremap <f9> :make<CR> :copen<CR>
This will open a quickfix for error. You can just press F9 or any other key that you have mapped.
You might also like to review quickfix commands at :help quickfix
You can try doing this to your .vimrc. It's not exactly sophisticated, but may be good enough for your needs:
" Run current file as Ruby program
nnoremap <C-r> :!ruby %<CR>
I've enabled the following mappings in my init.vim:
tnoremap <Esc> <C-\><C-n>
tnoremap <C-h> <C-\><C-n><C-w>h
tnoremap <C-j> <C-\><C-n><C-w>j
tnoremap <C-k> <C-\><C-n><C-w>k
tnoremap <C-l> <C-\><C-n><C-w>l
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
These greatly improve windows navigation in Vim.
However, I've noticed that C-h does not work as expected when executed in terminal buffer. Trying this on a usual terminal session results in Backspace action. So probably it seems to be one of these alternative key combinations, like C-i for Tab or C-[ for Esc. But is there any way to make C-h work in Neovim's terminal session as per my bindings?
Thanks!
This issue has already been extensively debated here. Original Vim does not rely on terminfo and includes its own patch for correct handling of C-h sequences. Neovim does look at terminfo though.
Briefly, the fix is executing these commands in the shell:
infocmp $TERM | sed 's/kbs=^[hH]/kbs=\\177/' > $TERM.ti
tic $TERM.ti