make from within vim - 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

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

How can I use neovim to automate generating pdfs from Rmarkdown?

I have been wanting to create a sort of live preview effect when writing Rmarkdown in neovim. I've looked at various plugins that claim to help with this but I have not been able to get any of them working (even after installing them properly. I'm not sure if it's a vim vs neovim thing).
The closest I have come to this is using entr from the terminal before I begin editing my rmd document, but to do this I'd have to manually enter the command:
echo [file] | entr echo "require(rmarkdown); render('[file]')" | R --vanilla
every time I turn on my computer and for every single file I decide to work on that day.
I've attempted to create various autocmds in my init.vim, but those either don't work at all, don't work the way I would like (i.e vim hangs every time it runs the autocommand, even when running silently), or produce errors.
Is there something wrong I'm doing when writing my autocmds or is there a better method overall I can use to get live previews working?
What I usually do when working with markdown files in Vim is create a temporary autocmd to recompile my pdf using pandoc and then send a SIGHUP to mupdf to reload the file.
Being in your markdown file, run this:
:au! BufWritePost <buffer> silent !pandoc % -o your.pdf && pkill -HUP mupdf
This assumes mupdf is already running in the background showing your.pdf.
If you want it more permanently, you could add the autocmd to your .vimrc, though you have to make sure to just set it up for Rmarkdown files. Then the only step you need to do is open mupdf once.

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

How to compile from gVim on Windows with GCC from Cygwin and then run the program?

I've been working at this all morning and I still can't find a way to easily bind a key to compile my program from the Windows version of gVim using the Cygwin GCC, and then run it. I'm kind of a novice to Bash scripting, and I haven't been able to make it create the .exe in the home directory (C:/cygwin/home) and then run it.
What I have so far:
map <F4> :call CompileRunGcc()<CR>
func! CompileRunGcc()
exec "w"
exec "!gcc /home/%:t && cd C:/cygwin/home && ./a.exe"
endfun
This would work all well and good, except that when I go to the home directory, the a.exe is not there. Compiling using gcc from the bash script .bat in cygwin works fine... but not from gVim.
Thanks for all help in advance.
check this plugin.
it seems to be what you want.
I haven't tested it though.
For mono-files projects, you don't need any makefile. Thus, as long as gcc and make are in your $PATH, and you are in the directory where the current source file comes from, you "just" have to type:
:update
:make
If your program has no error, a simple !./%< will do.
Otherwise, you may then have to execute a :copen to see compilation errors. If you have any, you'll notice some pathnames in *nix format. Unfortunately (g)vim-win32 is unable to understand them. That where my old cygwin compiler plugin skeept told you about comes into play. In order to support any compilation-like program (and not just make), it evolved into BuildToolsWrapper -- its installation will require lh-vim-lib, and may be a few other plugins of mine (system_tools, searchinruntime).
With it, just do once a :BTW add cygwin before you play with :make, or even :Make that BTW defines. This new command will do a :update! before calling :make with a automagically determined target. NB: BTW maps Make and the execution of the current project executable to <F7>and to <C-F5>.
PS: if you have have several files in your project, define a Makefile, and play with :make, that's all.
PPS: you may also be interested into cyg-wrapper.sh that helps to correctly open gvim-win32 from cygwin shell.
Basically, when gcc runs it produces binary right in the working directory. If you want to place the output binary in a different directory you have to pass the -o options. So the command should be either of these:
exec "!gcc -o C:/cygwin/home/a.exe /home/%:t && cd C:/cygwin/home && ./a.exe"
exec "!cd C:/cygwin/home && gcc /home/%:t && ./a.exe"

Resources