Calling command from `-c` command line argument doesn't work in Vim - 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

Related

Tagbar plugin works in vim but not neovim

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...).

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

Vim - Cannot reenter Vim after executing gcc inside Vim

I am having an really annoying issue with Vim. I am learning C and everytime I invoke :!gcc something.c -o something, Vim would exit to shell outputting whatever gcc outputs. However, from here, I cannot go back to Vim. If I press ctrl-D or type exit, the terminal just says "Stopped vim something.c". However, now when I try to type "Vim something.c" again, Vim would give an error saying the file is in swap or something and that it is already opened in another session.
How do I fix this?
You want to create a makefile to help you compile and report back your errors to vim. You can do this in C and C++.
You will make a file called 'makefile' in the same dir as the file you are making. You can execute that file in vim or in the terminal and it will act the same.
You call the makefile by typing in 'make' and ':make' in vim.
More documentation
https://www.cs.swarthmore.edu/~newhall/unixhelp/howto_makefiles.html#C

In vimscript, is there any events triggered by the internal commands?

for example,
in command mode, if I type ":cd /Home"
A events can be triggered by the cd command and I can get the path of the destination directory (/Home) of the command.
something like:
autocmd cd * : echo "blabla"
Unfortunately not. You'll find the entire event list at :help autocmd-events. I see the following options:
If it's just the :cd command, you could create an override :Cd command that triggers your additional functionality after delegating to the original :cd. To avoid having to type the uppercase :Cd, you can use cmdalias.vim - Create aliases for Vim commands. I would prefer this approach.
Though there's no hook for Ex commands, you could intercept all interactively entered commands by hooking into :cmap <CR> and using getcmdline(), but that requires parsing by yourself and the global hook doesn't play well with other plugins / configurations.
As the effects of :cd can be observed with getcwd(), you could hook into other regular events such as CursorHold,CursorMoved, if you live with a small delay.

Execute an open default editor command inside vim

I am trying to make a habit of never leaving my gvim, not even for executing commands in the terminal. This works fine with :!<command>. However if this command wants to open default editor (vim) it ironically does not work from gvim (it works from command line vim). Example:
:!git commit
error: Terminal is dumb, but EDITOR unset
Please supply the message using either -m or -F option.
I can run:
:!git commit -m "message"
But I like the vim window when I am inspecting files and write commit messages. Is it possible to make the commit window appear in gvim as with command line vim?
As an alternative to shelling out using :! command, you may want to try Tim Pope's Fugitive plugin. Quote from documentation:
I'm not going to lie to you; fugitive.vim may very well be the best
Git wrapper of all time.
Once installed you can simply run the :Gcommit command and the commit buffer will be opened up.
Over at Drew Neil's Vimcasts he a series on using Fugitive that is worth a look:
The Fugitive Series - a retrospective - overview of series
Fugitive.vim - a complement to command line git - specific screencast using :Gcommit
Git commit checks for the environment value $EDITOR in order to decide which editor it should to open to type the commit messages unless the messages has been specified using the -m optin on the commandline.
Use:
:!EDITOR=vim git commit
This will set the $EDITOR environment var to vim.
Further explanation:
(from man git-commit)
The editor used to edit the commit log message will be chosen from the
GIT_EDITOR environment variable, the core.editor configuration
variable, the VISUAL environment variable, or the EDITOR environment
variable (in that order). See git-var(1) for details.
This means beside from setting environment values you can use git config to specify the editor. (I would do so)
git config core.editor vim
If you once done so than git commit will not check the $EDITOR env var anymore.

Resources