Tagbar plugin works in vim but not neovim - vim

I have the tagbar plugin working perfectly in vim but no tags are displayed in neovim.
When I use TagbarDebug from within both, I can see that the ctags output is fine when run from vim, but from neovim, tagbardebug.log.ctags_out just has the following line:
^[[31;01m'^[[39;00m^[[31;01m/usr/local/bin/ctags-f---format=2--excmd=pattern--fields=nksSaf--extra=--file-scope=yes--sort=no--append=no-V--language-force=python--python-kinds=icfmv/var/folders/_z/tz5sb8jd6mj41gj2gn8qvhhr0000gn/T/nvimoU8Oxr/1.py^[[39;00m^[[31;01m'^[[39;00m
From tagbardebug.log, I can see that ctags is called slightly differently between the two. From within vim, the log has:
Calling shell to execute: "('/usr/local/bin/ctags' '-f' '-' '--format=2' '--excmd=pattern' '--fields=nksSaf' '--extra=' '--file-scope=yes' '--sort=no' '--append=no' '-V' '--language-force=python' '--python-kinds=icfmv' '/var/folders/_z/tz5sb8jd6mj41gj2gn8qvhhr0000gn/T/v0jhgoR/4.py') >/var/folders/_z/tz5sb8jd6mj41gj2gn8qvhhr0000gn/T/v0jhgoR/5 2>&1"
but from neovim, the equivalent line is:
Executing command: "'/Users/owen/miniconda3/bin/xonsh' '-c' ''/usr/local/bin/ctags' '-f' '-' '--format=2' '--excmd=pattern' '--fields=nksSaf' '--extra=' '--file-scope=yes' '--sort=no' '--append=no' '-V' '--language-force=python' '--python-kinds=icfmv' '/var/folders/_z/tz5..."
The difference appears to be how ctags is being called - vim calls it directly but neovim calls the shell executable and passes the -c argument. However, if I run the command used by neovim from the command line, it works fine.
I've tried setting tagbar_ctags_bin, but that made no difference.
Any clues as to where else I need to dig?

My guess is that xonsh makes some assumptions about being connected to a terminal, which is true in terminal Vim but not gVim nor Neovim (which invokes commands using pipes).
Try setting shell* options to their default values:
:set shell& shellcmdflag& shellpipe& shellquote& shellredir& shellxquote& shellxescape&
(Or simply remove the lines in your config that set those options.)
The difference appears to be how ctags is being called - vim calls it directly but neovim calls the shell executable and passes the -c argument
No, that's just a difference in log output. Vim also uses the 'shell' option and 'shellcmdflag' options (which is hinted by its log message: Calling shell to execute...).

Related

Vim makeprg make environment variable expansion

This is bothering me more than it should and has me completely stumped. I feel like like finding the answer will have some good learning opportunities so hopefully it's relevant.
I do embedded C development with Vim and have a setup for hobbyist stuff with Arduino (using Arduino Makefile). I use :make with some shortcuts with build projects.
An external define resolves the Arduino Makefile root directory in the project level Makefile: 'ARDMK_DIR=/usr/local/opt/arduino-mk'. This is define as an export in my shell (zsh). This is where it gets weird:
Using make at the shell prompt the project builds fine:
make -d
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `/usr/local/opt/arduino-mk/Arduino.mk' (search path) (no ~ expansion)...
However using :make in Vim the define becomes something from an old install:
:make
This program built for i386-apple-darwin11.3.0
Reading makefiles...
Reading makefile `Makefile'...
Reading makefile `/usr/local/Cellar/arduino-mk/1.5.2/Arduino.mk' (search path) (no ~ expansion)...
Makefile:24: /usr/local/Cellar/arduino-mk/1.5.2/Arduino.mk: No such file or directory
I cannot for the life of me find where ARDMK_DIR is being re-defined to '/usr/local/Cellar/arduino-mk/1.5.2'. Things I have tried:
setlocal makeprg=echo\ $ARDMK_DIR\ &&\ make\ -d\: echo comes back with my shell define (/usr/local/opt/arduino-mk), but make fails with the error above!!
:echo $ARDMK_DIR: again returns my shell define.
ag my home directory for ARDMK_DIR, the only place it is defined is in my shell exports. Did since for my root directory to and same thing. Same thing for $VIMRUNTIME
Even vim-disptach works fine calling the same makeprg?!
Re-define ARDMK_DIR in the project Makefile. Everything builds find as expected. I don't want to do this however as I compile with different systems.
The same vim config works on other macOS and Linux systems with expected behaviour.
Some where between echo and the actual execution of make, ARDMK_DIR is being re-defined. Why and can anyone think of a way of finding out where and solving this?
Zsh has multiple init files that are sourced. The file .zshenv is always sourced, when the shell starts and the file .zshrc is only sourced when the shell is started in interactive mode.
If you define the variable ARDMK_DIR with different values in .zshenv and in .zshrc, the value from .zshrc will be used when you work interactive with the shell (entering commands, starting Vim, ...).
But when Vim starts a command it will start a non-interactive shell. In that case only the file .zshenv will be sourced, so you get the value from that file.
One question left:
Why did the following command first echo the correct value, but make uses the wrong?
:setlocal makeprg=echo\ $ARDMK_DIR\ &&\ make\ -d\
For testing, I started Vim under strace. Then :
:set makeprg=echo\ $EDITOR
:make
In the strace file I found the following line:
execve("/usr/bin/zsh", ["/usr/bin/zsh", "-c", "echo vi 2>&1| tee /tmp/vdxR5DH/"...], [/* 86 vars */]) = 0
As you can see, Vim executes echo vi, so it already expanded the environment variable $EDITOR to its value before calling the shell.
So the answer to the above question is, that the echo command echos the text, that Vim inserted into the command line while the make command gets the the variable value from the environment. As it is a non-interactive shell, it is the value from .zshenv.

make from within vim

I am using gvim for coding c++. Since my program involves cmake, my sources are located in a different directory than my build.
How can I still invoke :make from within vim so that the correct make file within the build directory is found?
how can I then subsequently start my application with the very same command line style and one keystroke?
TD;LR: just assign 'cd "compi/dir" && make $*' to &makeprg (with :let) and run :make youroptionaltarget -j 4.
In another Q/A, I've already criticised the :!make approach. This is what we had to do 20-ish years ago with vi. Vim has introduced integrated compilation through quickfix mode. Please learn vim way to compile code.
In CMake case, we can indeed compile with cmake --someoption compil/dir. I use it when I compile with VC++ compiler, piloted by CMake, from vim. The rest of the time, I'd rather avoid it as it messes compiler outputs by prepending each line with number>, which breaks vim quickfix feature. Unfortunately there is no neat way to ignore this noise by tweaking &errorformat. So far I postprocess cmake and ctest outputs to remove ^\d+>.
So. What can, and shall, we really do? We should take advantage of vim quickfix feature. This is done by tweaking &makeprg and &efm options. In your case, the first one should be enough. Use it to change directory and execute make. And finally compile with :make and navigate errors with :cn, :cp, :cc, etc.
If you want also to compile in background, you'll need a plugin that knows how to compile in background in a directory which is not the current one. This is where I advertise my build-tool-wrappers plugin that provides these features and a few more CMake related features.
PS: It's also possible to use make (and ninja) -c parameter.
The easiest solution I came up with is the following:
:! (cd /path/to/your/cmake/build/directory; make)
To execute the program at the same time, you can append commands with ; or &&:
:! (cd /path/to/your/cmake/build/directory; make && ./myProgram)
In this page, you can find a tutorial how to bind this in order to do this in one key stroke.
Explanation:
In vim, you can execute any command with :! command (for instance, :! ls).
With (cd [...]; [...]), you specify that the execution directory is different by creating a subshell and changing to this directory in the subshell.
You can use the following:
autocmd filetype cpp nnoremap <F8> :w<CR> :!clear<CR> :!make && ./%<<CR>
This will allow you to Compile/Run C++ using Makefile with <F8> and clear console

How to set iterm2 Badge from vim?

I want to call the function iterm2_set_user_var VARIABE VALUE from vim/neovim using call system(). However, I get the following.
zsh:1: command not found: iterm2_set_user_var
shell returned 127
This is already done in node.js: How to exec script to set iterm2 Badge from nodejs?
I'm guessing you've defined iterm2_set_user_var as a shell function in your zsh config somewhere. Vim doesn't invoke a login shell with the system function. I think you have two options:
Change shellcmdflag to force a login shell by adding l to the flags currently there. This would affect all :! commands in vim as well.
Define iterm2_set_user_var as an executable somewhere in your $PATH.
Either should work fine.

How do I use Vim with Rebar

Trying to get up and running Vim + Rebar.
Separately they work but not together. What I want to achieve is to run eunit without leaving the Vim.
I guess this is doable with following plugin https://github.com/mbbx6spp/vim-rebar . Unfortunately is very poorly documented.
How do I run my tests quickly, see the output, code and once again.
All your feedback will be appreciated.
I don't know how to integrate rebar into vim, but perhaps you could try tmux? This works for me. In one window I keep opened vim, another window i use as compilation/attach session to erlang node.
One quick way to get out of Vim is to suspend it with Ctrl+z, run your commands, and then foreground it again with fg afterwards. Works at least on bash in Os X and Ubuntu Linux.
You can also run command line commands with :! <command name> directly from Vim, e.g. :! ls.
Yet another way is to use screen, with one window running vim and another still on the command line.
The best solution I've found is to use a Makefile in my project. Since vim is capable of running shell commands, you can call make & have it use your makefile. Then map these shell commands to shortcuts of your choosing.
For example, my Makefile has the following:
test:
$(REBAR) skip_deps=true eunit
In my .vimrc:
command MakeErlangTest !make test
nmap <leader>r :MakeErlangTest<CR>

Calling command from `-c` command line argument doesn't work in Vim

I'm using the Fugitive plugin.
It has a command(?) Git! which executes a command and opens the result in a new buffer.
Example:
:Git! diff --cached
I have a function which calls this, and does some other things after that.
And I have this command declaration:
command! Hello execute ":Git! diff"
If I run :Hello from within vim, it works as it should. But when I run vim -c Hello, it throws this error:
Not an editor command :Git! diff
How can I do this?
(PS: How can I make this error message to stay until I press ? It appears for about a second and disappears.)
The reason is that Fugitive only defines its commands for buffers whose files are under Git version control. Precisely, the code in plugin/fugitive.vim only sets up autocmds that detect files under Git control, and only then defines buffer-local commands.
So at least you need to pass a Git-controlled file to your Vim invocation. If that still doesn't work, try explicitly triggering the detection via
:doautocmd User Fugitive

Resources