sponsor Vim development Vim logo Vim Book Ad

Vim Development

Most active development happens on the vim-dev maillist. Subscribe if you want to get involved, see here.

To see the known bugs and next things to work on, use the Vim help:

  :help todo

There is also an issue tracker here.

Making changes to Vim

Since Vims source code is hosted at code.google.com and managed by mercurial it is most easiest to use mercurial (and the distributed mercurial queues) for developing and bugfixing Vim.

Mercurial queues (mq) is an extension to mercurial, that allows to maintain patches on top of an existing mercurial repository (that are commited on top of the repository) and they can be refreshed, reordered and removed thus making the changes mutable (as opposed to the immutable commits in the repository). This allows for a flexible development (but is not strictly necessary for creating patches).

Make sure, you have mercurial installed (On Debian, you can use apt-get install mercurial to have it installed).

1. Clone the repository

~/code $ hg clone https://code.google.com/p/vim
This will checkout the Vim source code into ~/code/vim

To make developing easier, I recommend to enable the mq extension. For that edit the hgrc config file and enable the mq extension. Also make sure, you are using git extended diff mode.

~/code/vim $ vim .hg/hgrc
[extensions]
mq=

[diff]
git = True

2. Create a new patch

2.1 Simple case

For single changes you can simply make your changes, to all files in the repository. When you are done, you can create a patch using hg diff.

~/code/vim $ [edit files]
~/code/vim $ hg diff > fix_annoying_bug.diff
Now send your patch file (fix_annoying_bug.diff) to the vim_dev list (but see below).

If you are trying to change several things, it might be easier to use the mq extension for handling those patches independently.

2.2 Using the Mq extension

Let's say you want to add some new fancy feature to your local copy of Vim. First start by creating a new empty patch.

~/code/vim/src $ hg qnew my_fancy_feature
Now go ahead and make the changes to the source code as needed. Once you are finished, you must "refresh" your top-level patch. Do this by
~/code/vim/src $ hg qrefresh
All changes that have been accumulated to the current repository will be stored in the current top level patch and the repository will be clean again. Note, how hg diff does not notice any changes anymore.

Once you develop, you might notice a small bug (or even a typo), that needs to be fixed but does not belong to the current work of adding your fancy feature. So you save your work, refresh the current patch and fix that small bug with a new patch:

~/code/vim $ hg qrefresh
~/code/vim $ hg qpop
popping my_fancy_feature
patch queue now empty
~/code/vim $ hg qnew fix_typo
[... fix bug ...]
~/code/vim $ hg qrefresh
Now you can extract that patch and send it to the vim-dev mailinglist to have the patch reviewed and put into the todo list of Bram (but see below):
~/code/vim $ hg qdiff > $(hg qtop).diff
... send patch to Bram, continue working on your new feature
~/code/vim $ hg qpush
applying my_fancy_feature
now at: my_fancy_feature
As you work on your new patch, you might want to add another feature, that you think is missing. So go ahead and create a new patch.

As you create patches you'll start creating a patch queue, each patch being applied on the result of the previous patch. To move between those patches, you can use the qpush (push next patch on the stack) and qpop commands (remove current patch from stack and continue working on the previous patch).

It is dangerous to pull changes from the central vim repository and update your working copy at the same time (-u flag), while there are still patches applied. Instead, make sure to pop all patches, update the repository and push your patches again:

~/code/vim $ hg qpop -a
popping my_fancy_feature
patch queue now empty
~/code/vim $ hg pull -u
~/code/vim $ hg qpush my_fancy_feature
After the last step, you might need to fix merge conflicts, that happened because of changes to the Vim repository and your patch changing the same file. If you have changed the patch, you need to qrefresh your patch, so it will apply cleanly on top of the changes to the Vim repository.

Before publishing your patches

A few comments to help have your patch be easily accepted:
  • Make sure your patch actually works
  • The code should be readable
  • Simple things first, don't try to fix everything in one single patch but rather create several small patches (This allows for easier review)
  • Make sure the all tests still pass (make test) and if possible add new tests for your feature/bugfix (look into src/testdir directory for existing tests and extend them if possible). For newly created testfiles, give it meaningful names.
  • Try hard not to break anything (compile with different features, test, watch out for warnings (uncomment #FLAGS = -g -DDEBUG -Wall -Wshadow -Wmissing-prototypes in the src directory Makefile. Yes this could be the first patch in your patch queue)
  • test your patch by running under valgrind and make sure, it doesn't leak memory.
  • Document your changes (also update the runtime documentation that comes with Vim and any related vim script e.g. optwin.vim, syntax or filetype plugins).
  • Try to follow the adivses given in develop.txt (:h develop.txt)
  • Come up with a good usecase for your new feature (e.g. make Bram want to include your feature ;))
  • If possible try not to introduce new options ;)
  • After publishing your patches

  • When you send out your patch and don't get immediate feedback, don't despair. Bram is overloaded with work so just be patient. Usually your patch will be included into the todo list (:h todo.txt) and will be included into Vim eventually.
  • React to feedback and try to fix all mentioned issues. Beware, discussions might wander away from your original topic you originally adressed, don't let that scare you away!
  • While the patch is pending, update the Vim repository as new patches are sent out, keep your patch in sync and fix merge conflicts that may occur. After a reasonable time, resend your resynced patch again.
  • MQ commands

    When the mq extension is enabled, mercurial enables several new commands, all starting with q Here are some useful commands:

    hg qpush (push next patch on the stack)
    hg qpop (pop patch from the stack)
    hg qnew (create new empty patch in the stack)
    hg qimport (import existing patch as new mq patch)
    hg qrefresh (update current parent with the changes in the work tree)
    hg qdiff (displays the diff between the work tree and the current patch)
    hg qtop (displays the name of the current changeset)
    hg qseries (displays the list of patches available)
    hg qdelete (deletes an unapplied patch from the queue. Can not be restored)

    Caution:

  • Don't use MQ in a repository anyone might pull from (unless you hide your mq changesets away using the secret phase).
  • Create new patches from a clean working tree (changes will otherwise be contained into that new patch which might be undesired).
  • before pulling in new changes into the repository make sure to pop all current patches (e.g. do hg qpop -a; hg fetch; hg qpush -a)
  • Thanks to Christian Brabandt for writing the original version of this text. If you have suggestions for improvement of this page please send a message to the vim-dev maillist.


    If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
    Questions about Vim should go to the maillist. Help Bram help Uganda.
       
    SourceForge.net Logo