Vim Send a Word under Cursor to External command - vim

I am trying to send a Word under to an external command. I did some digging, yet cannot have a working solution. I learned about using <cword> but I can't seem to pass the current word to the external command.
Here is my command:
nmap <silent> <F8> :!start test.exe s/\(<c-r>=expand("<cword>")<cr>\)/
All it does is gets the current word under the cursor and pass it to test.exe. Can some one please help.
Update
Here is what I am trying to achieve. I have function name in the code.
a = 0
b = 1
c = add_function(a,b)
I would like to use word under cursor to pass add_function to the custom executable I have. So that it will launch test.exe, and pass the following:
open, 'add_function'
I tried the above vim command, but it does work.

I'm not sure what the problem with your mapping is as such, if I remove the <silent> I get in my cmdline:
:!start test.exe s/\(WORD\)/
Which may be what you want? It doesn't send because you didn't add a <Cr> to the end (and doesn't show in the commandline because of the <silent>)...
nnoremap <silent> <F8> :!start test.exe s/\(<c-r>=expand("<cword>")<cr>\)/<CR>
If this isn't what you want, and if adding s/\(..\)/ isn't intentional, then lets start over by trying to get the simplest working mapping by just just echo-ing the current word in Vim:
nnoremap <F8> :echo shellescape(expand('<cword>'))<Cr>
Then expand that to run the external echo command:
nnoremap <F8> :execute ':!echo ' . shellescape(expand('<cword>'))<Cr>
Then expand that to run your start text.exe:
nnoremap <F8> :execute ':!start test.exe' . shellescape(expand('<cword>'))<Cr>
And finally add the <silent>:
nnoremap <silent> <F8> :execute ':!start test.exe' . shellescape(expand('<cword>'))<Cr>

Add one more "cr" to run external program
nmap <silent><F8> :!start test.exe s/\(<c-r>=expand("<cword>")<cr><cr>\)/
End it would be better to rewrite it into
nnoremap <silent><F8> :!start test.exe %s/\(<c-r>=expand("<cword>")<cr><cr>\)/

Related

Hitting ENTER on quickfix error jumps to an empty buffer

I'm using GVim 8.1 on Windows 10 with no external plugins.
I have the following set up in my .gvimrc file:
let g:build_file_abs_path = fnamemodify(findfile("windows-build.bat", ";."), ":p:h")
" This build script is a basic wrapper for 'clang.exe file.c -o file.exe' style invocation
let &makeprg=g:build_file_abs_path . "\\windows-build.bat"
nnoremap <silent> <C-B> :cd <C-R>=g:build_file_abs_path<CR> <bar> make! <bar> copen <bar> redraw <bar> cd -<CR>
Now, this automatically opens a quickfix window with the correct compiler output. However, when I press ENTER over the error, the cursor jumps to the buffer for the affected file, yet it is completely blank with a single line. Furthermore, this occurs as I use :cn and :cp commands inside the quickfix window. e.g:
Images showing these two states:
before
after
Please note that:
:verbose nmap <CR> returns no mappings, so there is not conflict there.
I would appreciate it if someone could provide some insight as to how to avoid the buffer becoming empty and actually jump to the error in the appropriate file. Many thanks.
Thanks to Christian Brabandt's comment, I was able to solve the issue. I was misunderstanding the distinction between the working directories of vim and the build script. I made the following changes:
let &makeprg="cd " . g:build_file_abs_path . " && windows-build.bat"
nnoremap <silent> <C-B> :make! <bar> copen <bar> redraw <CR>

What is wrong with this line? nnoremap <C-[> :execute "normal! A{{{\<Esc>"<CR>

I am trying to add this to my vimrc but I am getting problems one it inserts {{{ at the beginning of my vimrc whenever I open it and also it apparently has 'c' in the regiser as the last pressed key so it deletes the first 2 lines when I press j
And when I run the command it complains that
"A{{{\ is missing a quotation mark and is not a command.
This gave me tip. map execute command vim
You don't need use :execute "normal! ..." if you are using nnoremap. This will work.
nnoremap <C-[> A{{{<Esc><CR>

Vimscript: one command is not calling the other

I have the following code in my vimrc file:
" move line to end of file and add a timestamp
noremap ,d ddGp,t
" append a timestamp to the end of the line
nnoremap ,t A <Esc>"=strftime("%H:%M")<CR>p
In the above code, ,t works when called by itself. However, when called by ,d the ,t command does nothing. The rest of the ,d command functions as expected. Why is this? How do I fix it?
,d is marked as nore which turns recursive mappings off, and thus fails to recognize ,t as a command. Thank you FDinoff for the answer.
More info:
What is the difference between the remap, noremap, nnoremap and vnoremap mapping commands in vim?

use search in "browse oldfiles" list?

Is there a way to search the list of recently used file in Vim? The list can be displayed using
browse old
but / does not work. I am aware of some plugins (e.g. MRU) but would prefer to not use a plugin.
Here's a short scriptlet that opens the file list in a scratch buffer. As a bonus, it defines a local <Enter> mapping to :edit the current file. With this, you can search with all built-in commands like /:
:new +setl\ buftype=nofile | 0put =v:oldfiles | nnoremap <buffer> <CR> :e <C-r>=getline('.')<CR><CR>
If you really want to avoid a plugin:
:new The old files will be printed into this buffer
:redir #X where X is a temporary register`
:silent echo(v:oldfiles) 'Silent' is there to not actually print onto your screen
:redir END
"Xp paste the temporary register
(optional) Do some regex-fu to put each file on its own line.
Put the above into a function and voila. Also :help redir
It's actually not very hard to write a simple (simplistic?) MRU command with completion that works like :edit or :split:
" this is our 'main' function: it couldn't be simpler
function! MRU(arg)
execute 'edit ' . a:arg
endfunction
" the completion function, again it's very simple
function! MRUComplete(ArgLead, CmdLine, CursorPos)
return filter(copy(v:oldfiles), 'v:val =~ a:ArgLead')
endfunction
" the actual command
" it accepts only one argument
" it's set to use the function above for completion
command! -nargs=1 -complete=customlist,MRUComplete MRU call MRU(<f-args>)
Here is a .vimrc version of code above. Just add following lines to .vimrc and map to desired keys (in my case it is 'o). In addition define patterns to remove "junk" files. Also cursor is placed at the top for convenience.
Most hard thing is to map an Enter inside nested nmap. ^V is the result of doubled Ctrl-V. ^R is the result of Ctrl-V+Ctrl-R. ^M is the result of Ctrl-V+Enter. You need manually repeat those symbols - not just Copy/Paste. Spent hours to understand this magic - so I'm glad to share. This technology lets you add own macroses in .vimrc.
" Browse Old Files
nnoremap <silent> 'o :enew<CR>:set buftype=nofile<CR>:set nobuflisted<CR>:exe "0put =v:oldfiles"<CR>:nmap <buffer> ^V^V^M :e ^V^V^R=getline('.')^V^V^M^V^V^M<CR>:g/\v(stdout\|nerd\|fugitive)/d<CR>:0<CR>
This is my take on Ingo's answer above for my .vimrc:
Opens the old files in either a vertical split or tab, then maps enter to open file under cursor! magic!
" open old files list and map enter to open line
" vertical split
noremap <leader>vv :vnew +setl\ buftype=nofile <bar> 0put =v:oldfiles <bar> nnoremap <lt>buffer> <lt>CR> :e <lt>C-r>=getline('.')<lt>CR><lt>CR><CR><CR>
" in new tab
noremap <leader>vt :tabnew +setl\ buftype=nofile <bar> 0put =v:oldfiles <bar> nnoremap <lt>buffer> <lt>CR> :e <lt>C-r>=getline('.')<lt>CR><lt>CR <CR><CR>

Extend a vim command

How can I extend a command in vim?
I want to do it in two situations,
After a :diffget or :diffput I always want to run a :diffupdate
After a :NERDTreeToggle I want to run a <C-w>=
I am unaware of any autocmd events that would be triggered for your scenarios. However a few custom mappings might be helpful.
You can change the default dp and do mappings to also do a :diffupdate
nnoremap dp dp:diffupdate<cr>
nnoremap do do:diffupdate<cr>
Note there are times where you cannot use dp and/or do and must use :diffput/:diffget. In these cases I would suggest you create a commands like so:
command! -nargs=? -range=1 -bar Diffput <line1>,<line2>diffput <args>|diffupdate
command! -nargs=? -range=1 -bar Diffget <line1>,<line2>diffget <args>|diffupdate
Or you can just map :diffupdate
nnoremap <f8> :diffupdate<cr>
NERDTree
nnoremap <leader>N :NERDTreeToggle<cr><c-w>=
Maybe you can have a look to the vim macro. It is probably suitable for what you want to do :).
Create your own custom function in VimScript in your .vimrc that wraps several commands.
Here's one I use to launch a Clojure Repl in a buffer using several plugins:
fun! LeinCMD()
execute 'ConqueTerm lein repl'
execute 'set syntax=clojure'
execute 'normal! i'
endf
command! Repl call LeinCMD()
I then call this command with :Repl (note that your custom commands must always start with an uppercase letter).
Source: Automate running several vim commands and keystrokes

Resources