Use last arguments from vim's :make command - vim

I have a one key mapping to build my project.
noremap <F5> :make<CR>
This works great. However I sometimes am building a only a piece of the project. In this case I use the command :make smaller_part to build just that piece. I'd also like a one key mapping for this use case as well.
noremap <S-F5> :make last_arguments()<CR>
Is this possible? A last_arguments() function isn't required. It's just how I imagine the solution would look. The important part is I hit one key and it runs :make with the arguments that I gave it last time.

I use
map <f2> :wa<cr>:Make <Up>
to run make with the last arguments
by the way
command -nargs=* Make write | make <args> | cwindow 6
is the Make.

I don't know whether you can programmatically retrieve the last line from the command history, or specific arguments on it. I expect you can, but I don't know how to do it offhand.
But what are the constraints here? If you'll allow your initial invocation of make to call a function you've defined, say :MyMake(smaller_part), then that can save the smaller_part in a variable and you can define a Remake() function that will call make on the target saved in that variable.
Is that solution acceptable to you? Or must the original invocation be of the form :make smaller_part?

What if you wrap the :make command in a couple commands of your own? One command runs make with whatever argument you supplied (possibly none). It also stores the argument in a variable. Then you map this command to <F5>. The other command runs make with the argument stored in your variable (again, if any). You map this command to <S-F5>. I think the vim command for defining your own commands like this is Command.

Related

How to write buffer contents to external program and put the output into the quickfix window?

So I know you can pipe the current buffer contents to an external program with w!sometool and I know you can use cexpr to display e.g. a variable's contents to the quickfix window, but I can't work out how to do both at the same time.
Basically, I want to do the following:
:cexpr w!sometool --stdin
But I can't figure out how to get vim to treat the part after cexpr as a vim command to run.
I already have errorformat set to match the output.
Alternatively, if there's a way to use the makeprg system to run makeprg in tha same way (current unsaved buffer contents to stdin), that would be fine too.
Well, the point is that in VimScript commands and expressions are different things. So you cannot simply do that composition of command1 command2 command3 like with the expressions. (Yes, there exists :w !sometool, but this is not two commands pasted together, but rather a single command with a unique syntax).
So you must execute :cexpr some_expr, and not :cexpr some_command. This can be achieved by using function system() (or systemlist()), as any function call (without the preceding command :call) is an expression in VimScript:
:cexpr system('sometool', bufnr())

Add Keybinding to ./program

I recently dumped all ide's and decided to program solely with vim. So far it works good, but I have a minor annoyance. Everytime I want to run my recently compiled program, I have to write
:!./myProgramExecutable
I could do this in my .vimrc:
nmap <key> :!./myProgramExecutable<CR>
but that would only work for executables of that name. Is there a way to generalize this command for my current project in CMakeLists.txt for example? (or another way to find the correct name)
If the program name can be derived from the current buffer's path and/or name, you can use :help filename-modifiers in the command execution.
However, if it's okay for you to specify the program name once, a neat trick is that :!! repeats the last :! command with the same arguments. If you bind that to a key, you have a quick way to re-execute it.
Oh, and if you're working with Makefiles or similar, why not create a target (always with the same name) that executes the program; you can then do that from Vim via :make run, for instance.

Vim: Issue normal-mode commands in user-defined command

I'm certain this will have been asked somewhere, but I can't for the life of me find it, and it's not in the Defining command-line commands section of the Vim documentation.
I want to create a user-defined command which will insert the word foo before the current word.
(Note: I want it to be a function because I don't trust myself to remember yet another shortcut key. I know how to do it with noremap...)
In my .vimrc I add:
command AddFoo bifoo<esc>w
But when I type :AddFoo I get Not an editor command: bifoow.
Is it possible to have a function which issues normal mode commands?
The :normal Ex command allows to issue arbitrary normal mode commands.
command AddFoo normal! bifoo<esc>w
If you want to interpolate expressions etc., you need to use :execute; I'll just show your example again with the use of :help key-notation:
command AddFoo execute "normal! bifoo\<esc>w"
The ! after :normal prevents the use of custom mappings, like :noremap (vs :map).
Please make sure you get the difference between a command and a function.
The right hand side of a command definition is supposed to be at least one Ex command like write or bnext:
command! Foo update | tabnext
You can call a function:
command! Bar call Bar()
or execute a normal mode macro:
command! Baz normal ciw"<C-r>""
See :help :normal.
Should be simple to get what you want, you just need to switch to normal mode to make your changes:
command AddFoo normal bifoo<esc>w

vim run make through screen

Due to some complicated environmental variables required, I have chosen to run Make through GNU screen. Using the screen vim plugin, I have the following setup in my .vimrc:
map <Leader>mm :call ScreenShellSend("cd ".expand("%:p:h")." && make 2>&1 | tee /path/to/errorfile") <CR>
Roughly translated, this will run make in the current working directory through an existing screen session with all of the required environment variables preset. I can then see the output of that command in a separate terminal window.
My question is, assuming I output the results of make to a text file, how do I tell automate the vim make process to:
A.) set make to use a vimscript function, i.e. call SreenShellSend() instead of an external program.
B.) set errorfile to /path/to/errorfile
Unfortunately, you cannot set 'makeprg' to a Vim function or command, it has to be a shell program. (I wish for an enhancement that treats commands starting with a colon as Vim commands, similar to the :help exception in 'keywordprg', but haven't come around to implementing this.)
There are workarounds, though. One is to use vim --remote-send as 'makeprg' and use this other temporary Vim instance to call back into the original Vim. What I do though is overriding the :make command through the cmdalias.vim plugin for those buffers. That alias then simply :calls my function.
Once you're able to invoke a Vim function, setting the 'errorfile' is just a matter of putting a function wrapper around ScreenShellSend() and setting it in there.

Run terminal command from VIM?

I wish to write a function which I can add to my .vimrc file that will call a terminal command, and then bind it to <leader>u.
I cant seem to get it to work tho. I believe that I can use the system() function, but there is very little documentation available and I cant seem to get it to work.
The terminal command in question is 'git push origin master'.
I know that there are plugins available for git but I am not looking for any of these, just a simple function to bind a terminal command to a key combination.
function gitPush()
system("git push origin master")
endfunction
:nmap <leader>u :call gitPush()
I know this is waaay out, but vim doesnt seem to want to make documentation very available.
Ty
function GitPush()
!git push origin master
endfunction
Is the way to run a command in a subshell.
EDIT: User defined functions must begin with a capital letter too ;)
Why do you use call to call your own function and fail to use it for builtin? It is one of three errors, other was mentioned by #Richo: user-defined function must either start with a capital or with b:, w:, t: (note that neither of these are local functions), g:, s: (only inside scripts, and you will have to replace s: with <SID> in mappings), even \w: (for example, function _:foo() works) or with {filename_without_extension}# (if filename matches \w+.vim). If it is anonymous function:
let dict={}
function dict["foo"]()
endfunction
function dict.bar()
endfunction
it also does not require to start with a capital. So the correct solution is:
function g:gitPush()
call system("git push origin master")
endfunction
nnoremap <leader>u :call g:gitPush()<CR>
Third error is omitting <CR>. I changed nmap to nnoremap because it is good to use nore where possible. Having : at the start of the command does not hurt and is not an error, but I just do not write it: it is required in normal mode mappings to start command mode, but not inside scripts.

Resources