How to know in a Makefile if `make` is invoked from ViM? - 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.

Related

Can you view the default Vim settings?

I’m starting to learn about creating my own .vimrc file and I keep noticing features that are missing with my custom version that were present in the default setup.
I was wondering if it is possible to view the default settings, so I can compare them to my own and look up all the standard inclusions I don't know to learn more about them.
I searched and couldn’t find an answer online, and if the reason why there isn’t one is that the answer to this question is glaringly obvious, I’m really sorry; I’m still a bit of a noob :p
No worries, it’s a perfectly valid question. Unfortunately, the answer is a bit complicated. First of all, Vim has certain defaults that are documented in the built-in help system.
Some of them are only used when Vi compatibility mode is disabled, and that’s the first customisation most people make:
:set nocompatible
On top of that, many distributions provide their own custom config, for example Debian/Ubuntu comes with /etc/vim/vimrc. To makes things even more confusing, Vim 8 comes with a sane configuration (called default.vim) that only gets applied when ~/.vimrc is not found. Not to mention that NeoVim comes with its own set of defaults.
In practice, I suggest to explicitly set any options you care about to make sure your config is portable between systems and versions of Vim. To see the current value of a given option, use a question mark:
:set showcmd?
To learn more about a given option (including the default value), use Vim’s comprehensive help system:
:help showcmd
Finally, you might want to check my annotated .vimrc for some inspiration, and there is also the vim-sensible plugin that provides some sane defaults most people would agree to.
The easiest way to see “vanilla” Vim options is to start it using:
$ vim -u NONE -N
It will start Vim without any of your customizations or plugins, but still in ‘nocompatible’ mode (i.e., basically, running full-fledged Vim, instead of its stripped down version emulating Vi).
Then, you can execute the following commands:
:set all
:map
:command
:let
:function
:autocmd
to see all options, mappings, commands, variables, functions, and auto-commands, respectively, that are currently in effect. (I cannot promise I haven’t forgotten a customization category.)
Vim also comes with a bunch of basic configurations that is skipped by the -u NONE option, that you can also include while still excluding your .vimrc, by using -u NORC, instead.
Based on #Amadan's answer, I came up with this file (ShowAllDefaults.vim) and command to run it and capture the output.
. In the mean time, learning that, if you have files under ~/.vim, they get executed if you use this:
vim -u ShowAllDefaults.vim -N +q
So the correct way to do it is:
vim -u NONE -N +"source ShowAllDefaults.vim" +q
Contents of ShowAllDefaults.vim:
set verbosefile=/tmp/ShowAllDefaults.log
set all
map
command
let
function
autocmd
I am trying after long time to get familiar with vim also, and I came across this because I had same question.
How I found answer from within vim was to pull up help on defaults and it explained to get defaults along with .vimrc for newer users and also gave the path to default script so you could open it right up in your editor and read & compare it.
I am not going to give my exact path because that might change in different versions, so best to get it from help documents inside vim.

how to clear the screen after exit vim

Sometimes vim will leave something, i.e. press any key to continue, on the terminal and is there any way to return to a clear terminal after exiting vim?
I am new to vim and please tell me exactly what I should do.
Sorry I did not express my idea clear enough the first time. What I actually want to ask is that is there a way to return to a clear terminal after typing :q in vim without further input of commands.
I am using VIM 7.4 in Ubuntu, terminal type is xterm.
Add to your ~/.vimrc:
au VimLeave * :!clear
I use an alias to clear on any exit method including :q, :wqa. (this is for my osx brewed binary, find your own vim binary with which vim)
# .zshrc
alias vim="/usr/local/Cellar/vim/8.0.0094/bin/vim && clear"
There is a way to do more stuffs by editing your .vimrc file
Add this to your .vimrc
command Qc :call ClearAndExit()
function ClearAndExit()
:!clear
:q!
endfunction
use :Qc to quit.... it will clear the screen as well
If Vim is compiled with support for switching xterm-screens, it can do this by default, if you set the t_ti and t_te (Vim usually figures out, to what values this needs to be set by itsself). The gory details are explained at :h xterm-screens (pasted below)
(From comp.editors, by Juergen Weigert, in reply to a question)
:> Another question is that after exiting vim, the screen is left as
it :> was, i.e. the contents of the file I was viewing (editing) was
left on :> the screen. The output from my previous like "ls" were
lost, :> ie. no longer in the scrolling buffer. I know that there is a
way to :> restore the screen after exiting vim or other vi like
editors, :> I just don't know how. Helps are appreciated. Thanks. : :I
imagine someone else can answer this. I assume though that vim and vi
do :the same thing as each other for a given xterm setup.
They not necessarily do the same thing, as this may be a termcap vs.
terminfo problem. You should be aware that there are two databases
for describing attributes of a particular type of terminal: termcap
and terminfo. This can cause differences when the entries differ AND
when of the programs in question one uses terminfo and the other uses
termcap (also see +terminfo).
In your particular problem, you are looking for the control sequences
^[[?47h and ^[[?47l. These switch between xterms alternate and main
screen buffer. As a quick workaround a command sequence like
echo -n "^[[?47h"; vim ... ; echo -n "^[[?47l" may do what you want. (My notation ^[ means the ESC character, further down you'll
see that the databases use \E instead).
On startup, vim echoes the value of the termcap variable ti (terminfo:
smcup) to the terminal. When exiting, it echoes te (terminfo: rmcup).
Thus these two variables are the correct place where the above
mentioned control sequences should go.
Compare your xterm termcap entry (found in /etc/termcap) with your
xterm terminfo entry (retrieved with "infocmp -C xterm"). Both should
contain entries similar to:
:te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:
PS: If you find any difference, someone (your sysadmin?) should better
check
the complete termcap and terminfo database for consistency.
NOTE 1: If you recompile Vim with FEAT_XTERM_SAVE defined in
feature.h, the builtin xterm will include the mentioned "te" and "ti"
entries.
NOTE 2: If you want to disable the screen switching, and you don't
want to change your termcap, you can add these lines to your .vimrc:
:set t_ti= t_te=
Yes. You most certainly can.
Use the UNIX command to clear the screen.
clear
I didn't want to have to use a different command to exit Vim (e.g. :Qc as suggested) by manoj, and the EntangledLoops' .vimrc method didn't work for me.
Inspired by Plato's answer, I found a similar solution by putting the following function in .bashrc:
# Vim exits to clear terminal screen
function vim {
/usr/bin/env vim "$#" && clear
}
Using only vim inside the function was problematic due to the function calling itself recursively and creating an infinite loop, but adding /usr/bin/env eliminates this issue, ignoring the function and executing the first vim in the PATH.

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>

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.

Is vim able to detect the natural language of a file, then load the correct dictionary?

I am using several languages, and currently I am obliged to indicate to vim with which of these the spell check must be done. Is there a way to set up vim so that it automatically detects the correct one? I vaguely remember that in a previous version of vim, when the spell check was not integrated, the vimspell script made this possible.
It would be even better if this could apply not only to a file but also to a portion of a file, since I frequently mix several languages in a single file. Of course, I would like to avoid to load several dictionaries simultaneously.
I don't know if there is a way to autodetect it, but if you put vim:spell:spelllang=foo,bar,baz at the bottom of the file, vim will set the spellchecking languages to foo, bar, and baz when the file is opened. Note that you must put at least one space before that text, or vim will think it's part of the file.
Since vim is missing this feature, I found it useful to define shortcuts like these in .vimrc:
command! Nb :set spelllang=nb
command! En :set spelllang=en

Resources