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

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.

Related

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

Can I write a script to tell me which files are currently being edited in vim?

I'm using tmux with many windows, and I frequently lose track of which files I'm editing in vim. I'd like to have another shell open that runs a script that tells me the paths of files that vim is currently editing.
I'm running Mac OS.
The way I would tackle the problem is to query all remote Vim processes for their opened buffers. You can use Vim's clientserver functionality for that. The GVIM server names are usually sequentially named: GVIM, GVIM1, ...; for terminal Vim, you'd have to name them with the --servername argument (e.g. via a shell alias).
You can then query the list of open files via the --remote-expr argument. A simple expression to loop over all listed buffers (like what the :ls command shows) is:
map(filter(range(1, bufnr('$')), 'buflisted(v:val) && ! empty(bufname(v:val))'), 'bufname(v:val)')
As you can see, it's a bit involved and might affect your workflow of launching Vim. Think hard whether you really need this!
That I know of there is no way to get every open vim buffer from an external process. Instead of using separate tmux layouts and a separate instance of vim to edit multiple files, you could have one instance of vim and edit multiple separate files using :split and :tabnew. Then in that vim instance you can use :ls to see the paths of all open files relative to the current working directory. :pwd also works.
If this isn't your style and you'd still like to use vim in separate layouts, you can use ps to see the arguments to each vim process and check the cwd of these processes. Something like:
paste <(pgrep vim | xargs pwdx) <(pgrep vim | xargs ps -o %a | sed 1d)
Note that if you use multiple buffers in vim the above won't quite work because it will only list the arguments given to each vim command and not list the actual buffers.
You could tweak around with the piped commands ps -eF | grep vim for your script.
At the end of each line, of the result, you'll see you the different processes dealing with anything related to 'vim'. Therefore you'll find which files are currently being edited by vim('vim foo.txt' for instance), as well as 'grep vim' that was being active to get this result. To have a pretty output, you'd have to filter all of these with a script.
I hope this will help you.

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

what is the load order of scripts when you start up vim?

If you start up vim with something like this:
vim -S myscript.vim file.txt
What is the load order of scripts? Does myscript.vim get loaded after or before ~/.vimrc.
If you pass in vimscript commands to vim directly on the command line, when do they get executed relative to sourced and default vimscripts?
I believe vimrc is always first. You can run :scriptnames to get a list of sourced scripts in order in which they were first sourced in your Vim instance.
The help entry is way too long to post here, but it lists the order of everything that vim does at initialization. See :help initialization.
The answer is myscript.vim gets loaded dead last.
The vim -V option is a lifesaver here. (Capital -V, because -v starts in vi mode.) Just ran across it, after searching further since although the other answers answered your question, they don't show what wasn't sourced because it wasn't found. If I could send it back in time, I'd save myself a lot of time banging my head against strace output.
This will not only show you all of the scriptnames that it did source in order, but also all of the scriptnames that it would have sourced if they existed in order. So, you can discover what files you can create to load at the appropriate time.
$ vim -V
Adding it to your vim arguments easily answers the question.
$ vim -V -S myscript.vim file.txt
It shows myscript.vim as dead last.
It prints a ton, and winds up at a "Press ENTER or type command to continue" prompt, which lets you step through Autocommands.

Resources