vim run make through screen - vim

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.

Related

How to save changes in vim parameters

I would like to change some vim parameters so I can see the spaces+eol, and set the tabulations as 4 spaces. I found a few commands that allow me to do that but i have to type the commands every time I wanna use them. Is there a way so save them so they stay even when I close vim?
Put those commands in a vimrc file. Vim loads this on startup and runs the commands in it, as if you had typed them in.
See also: https://vi.stackexchange.com/questions/13398/are-there-any-comprehensive-docs-for-vimrc

How to execute a list of vim commands on a text file?

I have a text that's around 1000 lines long, and I have a bunch of vim commands I want to apply to it. Lots of regex find-and-replace stuff. For example:
:%s/^[^\$\$]/def
:%s/\$\$/
%s/='/ = ['
I could copy and paste those commands one by one, but that's work I'll have to do again every time I receive a new version of this file. I'm wondering if there's a way to save a long list of commands that I can then apply to the file? Thanks!
registers
You can put them all into a register, either by typing those commands in a scratch buffer and then yanking into a register, or via explicit assignment:
:let #a = "%s///\n%s///"
Then, execute via :#a
Depending on your Vim configuration, the register contents may persist across sessions (cp. :help viminfo), but you must be careful to not override them.
scripts
A longer-lasting and more scalable solution is putting the commands into a separate script file, ideally with a .vim extension. You can put them anywhere (except ~/.vim/plugin, unless you want them executed automatically), and then run them via
:source /path/to/script.vim
custom commands
If you need a set of commands very often, you can give them a name and turn them into a custom command:
:command! MyCommands %s/// | %s///
Put this into your ~/.vimrc, or (if it's filetype-specific), make it a :help ftplugin.
Normally, you can run vim command from the shell using
vim -c YourCommandHere

vim redirect output to quickfix

Is it possible to redirect an output of a command to the quick fix window?
The command I am running is
:!java %:r
and was hoping the output would go into the quickfix window
I would suggest one of two options: configure makeprg to run java like you want, or create a mapping or command to populate the quickfix list without changing anything else.
Option 1: Using makeprg and compiler plugins
I would generally set the makeprg option for this, as others have said. It's not a hack, that's exactly what the makeprg option is for.
The only problem is if you have another build script you want to run as well. A more general solution is to create a simple compiler plugin. For instance, somewhere on your runtimepath, you can create a file under compiler/java.vim and set it to something like this:
if exists("current_compiler")
finish
endif
let current_compiler = "java"
CompilerSet makeprg=java
Now when you're working with java, you can do :compiler java and then your makeprg will be set as desired in the current window. If you want to use it for all windows, use :compiler! java, with a bang. Not all compiler plugins set the makeprg option, but you can always reset it with :set makeprg&. Try :help write-compiler-plugin for more information.
Option 2: Create a command to do it
Alternatively, you can also use cexpr to populate the quickfix list. For instance:
:cexpr system('java ' . shellescape(expand('%:r')))
The expand is necessary to expand the '%:r' in an expression, and shellescape escapes it so it can be used as an argument to a shell command. Then the string 'java ' is prepended to the escaped path and the result is invoked as a shell command by system. The output from this command is used to load the quickfix list.
The nice thing about this is that it doesn't change makeprg or any other settings, but still lets you easily populate the quickfix list. Of course, you'll probably want to map this or define a custom command for it.
Please note that the quickfix window is for specific output (e.g. of compiler or syntax checker tools) which includes references (i.e. line and column numbers) to the current buffer. There's a lot of infrastructure around this: 'makeprg', 'errorformat', etc., usually bundled into a compiler plugin.
Though you can redirect arbitrary output into the quickfix window, it provides little benefit (and has the downside of clobbering 'makeprg') over reading the output of an external program into a new scratch buffer, e.g. like this:
:new|0read !java #:r
Try this:
set makeprg=java
make %:r
It's a bit of hack, and of course assumes you aren't already using makeprg for your actual build script.
I mapped leader + j + r to run my java code and display it in the quickfix window by doing
map <leader>jr :set makeprg=java <CR>:make %:r<CR>:copen<CR>

How to know in a Makefile if `make` is invoked from ViM?

In short, I need to know in a Makefile whether `make is being invoked from ViM or not. Is there a certain variable (such as ENVIRONMENT or something), that ViM would set to a specific value?.
The reason I need this is the following:
If called from bash, I could do all sorts of wonderful stuff for user (or myself), such as giving messages as to which subsystem is being built and highlighting errors and warnings.
The problem is however that, when called from ViM, the error messages already get captured and introducing \x1b commands (for color) makes the messages incomprehensible to ViM. What I want to do is basically disable coloring when :make is issued in ViM.
Even though I'd rather have the Makefile resolve it, I am open to other solutions.
I'd either tell the makefile explicitly that you don't want colouring, or filter it out.
If you try to guess inside the makefile, it's liable to break when you use a different editor, or shell, or tweak your environment.
My preference would be to just filter out the non-printable characters:
:set makeprg=make\ $*\ \\\|filter
since this doesn't require explicit workarounds in the makefile. However, the required filter itself is non-trivial: see for example this question on unix.stackexchange.
Alternatively, as already suggested, the easiest way to tell your makefile explicitly is to add a variable to your invocation:
:set makeprg=make\ NO_COLOUR=1
or whatever (make should be the current value of makeprg).
.
Inside Vim, you can set environment variables that are inherited by opened shells; e.g.
:let $INSIDE_VIM = 1
If this is just about :make, you can manipulate the 'makeprg' that determines what is invoked:
:set makeprg=export\ INSIDE_VIM=1;make
If you're just concerned about the escape sequences for coloring, you could just set $TERM to something that doesn't understand colors (dumb maybe?) and if the coloring isn't hard-coded (which unfortunately is a big if in many tools), it should obey the terminal setting and not print the escape sequences.
You can alter your vim binding to SOURCE="vim" make, so in your makefile the $$SOURCE variable is set to "vim".
Edit: I see you are in fact not using bindings in vim, you can use them with the following line in your .vimrc (or /etc/vimrc) like this:
:nmap <F5> <CR>SOURCE="vim" :make<CR>
This will bind F5 to what you want
You could check MYVIMRCor VIMRUNTIME environment variables. On my GNU/Linux distribution, SHLVL value is 1 from bash and 2 when make is invoked from within vim.

is there a way to see output of previous ":! g++ %" without rerunning?

When coding, I like to check the code by running :! g++ %. I map the command to <F5>. sometimes it takes a while to compile and I want to see the errors without spending time recompiling. Also, sometimes I want to compare the new output to previous one.
Is there a way to see the previous output of :! ...?
Provided you have g++ configured with makeprg, you can use :copen to reopen the last list of errors from the :make command.
set makeprg=g++\ %
Then, to compile, use
:make
When the compile completes, any errors will be listed in the quickfix window, which can (assuming errorformat is correctly configured) be used to jump to the lines on which errors occur. This usually works out of the box for C/C++.
If you dismiss the quickfix window, retrieve the last error list with
:copen
Review :help quickfix and :help makeprg for full gory details on how this works.
If you are using Vim from the terminal just suspend vim with Ctrl+z.
This will send you back to your terminal. You should see the commands that you just ran via :!. To get back to vim issue the fg. Note: This maybe different depending upon your shell.
:sh starts you a shell within Vim. If you're using Vim in a terminal, this switches back to what's known as the "primary buffer", which means that you see the history from the terminal before you started Vim, as well as any of the :! commands you ran in Vim.
You can get back to your Vim session with Ctrl-d.
Michael gave you the right answer: :makeis the way to go. The old :!compilation-command is to be forgotten. Vi is, well, ... history.
Now to clarify : you'd almost never have to tweak &makeprg. The default value is the one you want to use, unless:
you're using something else to compile (ant, ...)
you want to compile a mono file program, and you don't want write a Makefile, and you're under mingw whose gnumake installation s*cks (all other installations of gnumake do permit to transform foo.c/cpp into foo(.exe) without having to write any single Makefile)
you want to play with the compilation directory, or with things that can't be injected through $CXXFLAGS, $LDFLAGS, $CFLAGS, etc.

Resources