This started out as a small post on how to preview markdown documents in Vim
using makeprg, but somehow I got carried away. More on the markdown thing in
a bit.
When you type :make in Vim, the value of makeprg is executed in
a subprocess. Traditionally this value is set to make, but you can set this
to anything you like. You can see the current value by typing :set makeprg.
When you combine this with Vim’s support for filetype plugins, there’s
a decent amount of value that I think is sometimes overlooked. So this
article is an attempt to explain some of the things you can do with makeprg
and filetype detection.
A filetype plugin is like a global plugin, except that it sets options and defines mappings for the current buffer only.
Using a filetype plugin, we can set makeprg to something useful depending on
the type of a file it happens to be. Adding your own filetype plugin is easy,
just create a file of the form: <filetype>.vim inside the
~/.vim/after/ftplugin directory. The after subdirectory is technically
optional, but I prefer it as it keeps things isolated from other installed
plugins. The after subdirectory is sourced last as Vim initializes itself,
so putting your options there ensures they aren’t clobbered by other plugins.
For a given Vim buffer, you can see the filetype by typing :set ft. Some
people put this information in their statusline, which can be helpful if
you’re writing Vim plugins or just want to make sure things are being detected
correctly.
For example, if I want to define custom settings for the C filetype, I would
create ~/.vim/after/ftplugin/c.vim and put my settings there. Any time
a file of type C is loaded, my settings are applied. We can use this
mechanism to set a custom makeprg for certain filetypes.
I take all of my notes in Markdown, which is nearly plain text with a tiny amount of markup. This allows me to quickly convert my personal notes into decent looking html documentation. It seems to be a regular occurrence that my notes become the initial documentation for the project or subproject that I’m working on. Many wiki’s support Markdown, so it ends up saving me work by just keeping everything in that format.
Even though Markdown’s syntax is very lean and simple, I still end up
forgetting some of it from time to time. I find it useful to generate and
view the HTML output for the buffer that I’m working on periodically to make
sure things look right. This is really easy by setting a custom makeprg for
the markdown filetype.
Robert Gleeson wrote a Vim plugin called Hammer that basically does exactly what I explain here and quite a bit more. It might be perfect for you, but for me it’s much more than I need. I’ve had problems when the version of Ruby on the system is not the same as what Vim was compiled with. Check it out though, you might love it.
All I want is to type :make and have Vim generate an HTML version in /tmp
that I can point my browser to. So I put the following in
~/.vim/after/ftplugin/markdown.vim:
set makeprg=redcarpet\ %\ >/tmp/%<.html
Let’s take a quick look at what’s going on here:
So the above command calls redcarpet on the filename and redirects the
output to /tmp/<filename>.html. That’s it, super simple. Once this
completes, I point my browser to file:/tmp and load the file I’m interested
in.
This same approach can be taken with ReStructured Text by putting the
following in ~/.vim/after/ftplugin/rst.vim:
set makeprg=rst2html.py\ %\ /tmp/%<.html
For C, we could set makeprg to call gcc directly instead of make if
a Makefile is not found in the current working directory. I find this very
helpful when creating a scratch source file to test certain behaviour or
a quick theory. Here’s what the contents of ~/.vim/after/ftplugin/c.vim
might look like:
if !filereadable(expand(“%:p:h”).“/Makefile”)
setlocal makeprg=gcc\ –Wall\ –Wextra\ –o\ %<\ %
endif
Now when you load a file of type C and there is no Makefile, typing :make
will compile your source file into an executable of the same name (minus the
extension). I use this all the time. You could do the same thing for C++ by
changing the filename to cpp.vim and changing gcc to g++.
It would be cool to copy the target filename to the clipboard for easy pasting into the browser’s URL bar.