Skip to content

Instantly share code, notes, and snippets.

@mmktomato
Last active November 4, 2021 01:16
Show Gist options
  • Save mmktomato/eb77f6ef6a007e7fd880430390a7dbef to your computer and use it in GitHub Desktop.
Save mmktomato/eb77f6ef6a007e7fd880430390a7dbef to your computer and use it in GitHub Desktop.
This is a note about making a Vim plugin, while I was working on https://github.com/mmktomato/open-backlog-issue.vim .

How to make a Vim plugin

This is a note about making a Vim plugin, while I was working on open-backlog-issue.vim. This document is based on Vim 8.2.

Directory structure

(root)
  |- autoload
    |- myplugin.vim
  |- plugin
    |- myplugin.vim
  |- doc
    |- myplugin.txt

autoload

autoload directory has files about plugin itself. This directory includes core logics of the plugin. This directory has to have a file that has the same name of the plugin. It's lazily loaded when Vim requires the plugin codes.

plugin

plugin directory has files about commands, key mappings, all other initializers. This directory has to have a file that has the same name of the plugin. Vim requires it when loading the plugin.

doc

doc directory has help files. These files should formatted as a help file.

A rule between file name and function name.

You may want to call a function in autoload files from plugin files. The function has to have the name separating # corresponding to directory structure.

" autoload/foo/bar/myplugin.vim - Define the function.
function! foo#bar#myplugin#myfn() abort
endfunction

" plugin/foo/bar/myplugin.vim - Call the function.
command! MyFn call foo#bar#myplugin#myfn()

<Plug> in a key mapping.

This is not related to vim-plug 😇

<Plug> is not mapped to any keys. You can use it if you want to define a key mapping that is open to the users.

" plugin/foo/bar/myplugin.vim - Define the key mapping.
nnoremap <Plug>(myplugin-myfn) :call foo#bar#myplugin#myfn()<CR>

" A user's .vimrc
nmap gm <Plug>(myplugin-myfn)

As the above example says, <Plug>(myplugin-myfn) is a key mapping. You can safely change internal function names unless you change the key mapping (<Plug>(myplugin-myfn)). It won't break users' .vimrc if they upgrade your plugin.

Detect a dependent plugin

Your plugin may depend on other plugins. You may want to force users to install them. Here is the example to check other plugins are installed or not.

if globpath(&rtp, 'plugin/otherplugin.vim') == ''
    " The dependent plugin is not installed.
    return
endif

Writing unit test

There are many many many many many testing frameworks for Vim plugin. However, vim-themis looks handy.

  • You can install vim-themis easily because it's a vim plugin.
  • You can run tests by calling a shell command.
  • You can write tests in basic vim script style or RSpec style.
  • You can use basic (and enough) assertion functions.
  • You can test plugin's script-local functions from test code.

Of course I recommend to look for other frameworks. I hope you can find your best one or create the best one ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment