vim command to map keys to command that maps keys - vim

Background: I'm using this mapping map ,r :! bundle exec ruby %<CR> all the time to easily run test file I'm currently editing. However I also do:
map ,t :! bundle exec ruby test/integration/some_integration_test.rb<CR>
so that I can run this particular integration test with two key strokes while working on some other file. It has hard-coded path, when I move to some other area of the application I type above command with another integration test file path.
How to make a command that creates such mapping automatically?
map ,T :map ,t :! bundle exec ruby %<CR> won't work because it doesn't expand % while creating the mapping, so ,t will always run current file (while I want it to run file I was editing at the time of creating the mapping).
[EDIT]:
Slightly adjusted solution from the answer:
nnoremap ,r :! bundle exec ruby %<CR>
nnoremap ,T :let g:testfile = expand('%:p')
nnoremap ,t :! bundle exec ruby <C-r><C-r>=g:testfile<CR><CR>
,r always runs file under cursor
,T saves current file path under in a variable for running later
,t runs file path stored previously

Just save the current file name (best with a full absolute path to be immune against changes to the current directory; the :p modifier does that) in a variable, and insert the variable instead of % via <C-r>:
:noremap ,r :let g:testfile = expand('%:p')<Bar>! bundle exec ruby %<CR>
:noremap ,t :! bundle exec ruby <C-r><C-r>=g:testfile<CR><CR>
PS: I used :noremap, because that is generally safer and should be the first choice unless you really need remapping to occur.

execute ":nnoremap ,t :! bundle exec ruby ".shellescape(expand('%:p'))."<CR>"
creates a ,t mapping that will execute your test on what is the current file at the time of execution.
But each time you do that you'll lose the previous ,t. I'm not sure that's what you want to do.

Related

How to put current filename in vim commands in .vimrc

i want to create a shortcut to run typescript in vim how can i access the filename in .vimrc
i want to run short scripts.
nmap <leader>r :! ts-node current-file<return>
First try %, as this gets substituted by the file name (as explained in :help :!):
nmap <Leader>r :! ts-node %<CR>
But if the file name contains whitespaces or special characters, you might see some errors. In that case, you need to escape the file name as follows:
nmap <Leader>r :execute '!ts-node ' . shellescape(expand("%"))<CR>
You're strongly adviced to read :h cmdline.txt, section 6 :h cmdline-special from top down to bottom.
nnoremap <leader>r :!ts-node %:S<CR>

How do I automatically re-load a file that gets modified by a bang (!) commandin Vim?

I have set up a line of vimscript in my .vimrc file to pretty print JavaScript files:
nnoremap <leader>p :!js-beautify -r -j %<cr>
I want to just automatically reload the file instead of being prompted when vim comes back from the shell, is that possible? Thanks.
:! can be used a) to execute arbitrary shell commands or b) as a filter.
You are using it to run js-beautify against the file associated with the current buffer with the following consequences:
You are forced to exit Vim.
The file is modified outside of Vim so you get a prompt asking you if you want to reload or not.
Hence the many seemingly pointless <CR>.
What you actually want is to run js-beautify as a filter against the current buffer, which doesn't require you to exit Vim or press <CR>:
nnoremap <leader>p :%!js-beautify -f - -j<cr>
the special range % represents the whole buffer, it's the range on which we want to apply our filter
-f - passes the content of the buffer via stdin
That's it: no <CR>, no prompt, no mess.
As a bonus, here is a custom command from my config (I didn't want a mapping for that):
command! -buffer -range=% Format execute <line1> . "," . <line2> . "!js-beautify -f - -j -B -s " . &shiftwidth
edit
You can use context marks to return the cursor to its initial position:
nnoremap <leader>p m`:%!js-beautify -f - -j<CR>``
As the help for :! notes:
Vim redraws the screen after the command is finished,
because it may have printed any text. This requires a
hit-enter prompt, so that you can read any messages.
To avoid this use:
:silent !{cmd}
The screen is not redrawn then, thus you have to use
CTRL-L or ":redraw!" if the command did display
something.
So if you wanted to use the :redraw! approach, for example, you could do this using something like
nnoremap <leader>p :silent !js-beautify -r -j %<cr>:e!<cr>:redraw!<cr>

Can I shorten :pyf P:\Computer Applications\Python\pi.py?

To use Vim/Python like a calculator one option is executing the following command in gVim:
:pyf[ile] P:\Computer Applications\Python\pi.py
I intend on storing all my py files in the directory P:\Computer Applications\Python\. Can I add something to my _vimrc file so that in the future gVim knows where all my python files are stored and all I need to write is the following?
:pyf[ile] pi.py
Why not use a mapping?
nnoremap <Leader>p :pyf P:\Computer Applications\Python\
You can then press \p (in normal mode) to get the :pyf P:\Computer Applications\Python\ prefix.
References
Mapleader
:noremap
Normal mode

compile c++ project using vim

I a new vim user, so i am trying to modify vim in order to fit to my needs.
Let's say that i have the project/main.cpp and project/build. Where inside the project/build when i do "make -j5 install" my project is being build and installed correctly. But when i am trying to do that inside from the vim it doesn't work. Here is the code which i use....
map <F5> :call BuildGitRepo()<cr>
function! BuildGitRepo()
:cd %:p:h
let currentFileDir = :pw
:cd currentFileDir
:cd "build"
:!make -j5 install
endfunction
Vim script from a vimrc file functions a bit differently from the Vim window. Commands that begin with : become native in vim script, meaning that you don't need the colon. Also, using local variables is a bit different - you need to use exec.
Finally, you can't capture the output of : commands without buffer redirection, but you can use the getcwd() function to get the current working directory. But it looks like you're cding to the current file's directory twice, so I've made that a bit simpler.
Here's a version of your function that should work in a vimrc file:
map <F5> :call BuildGitRepo()<cr>
function! BuildGitRepo()
exec "cd " . expand("%:p:h") ."/build"
!make -j5 install
endfunction

Vim — running external command bound to F5 inserts result in source

I'm currently developing a webapp that need a "compilation" phase to be tested. For this, I have a simple shell script, which is designed to run from a precise directory.
So in Vim, when I enter command mode and issue this, it works:
:lcd /my/script/directory
:!./build debug
My build script writes some logs in the command window, everything is fine, and tells me to press return to go back editing my stuff. Fine.
Now I'd like to bind this to F5 to speed things up. In my ~/.vimrc, I have added this:
map <F5> :lcd /my/script/directory<CR>! ./build debug<CR>
But after source'ing my ~/.vimrc, when I press F5, my script runs correctly... but strangely Vim replaces the current line I'm on with the output of the script. The same if I do map <silent> <F5> …
If i change ./build debug with a simple ls, the problem arises too. The output of the ls is inserted in my current document, overwriting the current line.
Does anybody know where the problem comes from? I really need to see the output of my build script, so there's no way I could just add a "undo" command after my bind, that would simply erase the inserted output of my command.
FWIW, I'm running MacVim snapshot 63 on OSX 10.7.2, but it also occurs when I use the plain old command-line vim (v7.3) from iTerm2 (1.0.0.20111020).
Try
map <silent> <F5> :lcd /my/script/directory \| !./build debug<CR>
The escaped pipe is here to chain commands.
Use a colon before !, like:
map <F5> :lcd /my/script/directory<CR>:! ./build debug<CR>

Resources