Sinclair Target

Who Will Maintain Vim? A Demo of Git Who

Mar 18, 2025

Bram Moolenaar, creator and long-time maintainer of the Vim text editor, died in 2023. His death was a great loss. He left behind a piece of software used and beloved by many, as well as some big questions: Who will keep Vim going now that he is gone? Are there other contributors that can take over? Has anyone been working on Vim since he died?

I recently released an open-source command-line tool called git who that can answer some of these questions. I wanted to build the tool because I’ve long been fascinated by what we can learn about a codebase from the metadata in its commit history. The commit history embeds a lot of information, especially about the people behind the codebase. git who surfaces this information. As a Vim user myself, I’m curious to see what git who can tell me about who is working on Vim now. I also hope this example will show how git who can be useful.

In the below code blocks, the tool is invoked as git who, which requires setting up a Git alias. Without the alias, you would invoke it as git-who.

Who Built Vim?

Bram Moolenaar is known for creating Vim, but did other people help him?

To find out, we can clone the Vim repository and then run git who on our local copy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
~/clones/vim$ git who
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│Bram Moolenaar                    1 year ago   16,562│
│Christian Brabandt                15 hr. ago      677│
│zeertzjq                          2 days ago      570│
│Yegappan Lakshmanan               2 weeks ago     453│
│K.Takata                          5 mon. ago      115│
│Doug Kearns                       2 days ago       79│
│glepnir                           16 hr. ago       78│
│Aliaksei Budavei                  16 hr. ago       78│
│LemonBoy                          8 mon. ago       76│
│Ernie Rael                        1 month ago      75│
│...587 more...                                       │
└—————————————————————————————————————————————————————┘

git who returns a listing of the top contributors to the repository ordered by the number of commits each has made. There are almost 600 contributors! But we can also see that Moolenaar has made an order of magnitude more commits than anyone else.

“Number of commits” is not the only metric we might employ to measure contributions to a codebase. We can use the -l flag to list the top contributors ordered by the number of lines they have added or deleted:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
~/clones/vim$ git who -l
┌——————————————————————————————————————————————————————————————————————————————┐
│Author                          Last Edit   Commits   Files        Lines (+/-)│
├——————————————————————————————————————————————————————————————————————————————┤
│Bram Moolenaar                  1 year ago   16,562   4,869     3.5m /    1.7m│
│Yegappan Lakshmanan             2 weeks ago     453     456  106,672 /  54,979│
│Christian Brabandt              16 hr. ago      677     890   51,685 /  30,657│
│Luca Saccarola                  1 week ago       35      64   18,231 /  17,788│
│Doug Kearns                     2 days ago       79     921   25,298 /   9,533│
│JNylson                         6 mon. ago        4       2   17,151 /  17,124│
│RestorerZ                       17 hr. ago       43     240   15,140 /  15,547│
│zeertzjq                        2 days ago      570     593   21,296 /   7,541│
│Aliaksei Budavei                16 hr. ago       78     708   18,009 /   6,215│
│Restorer                        10 mon. ago      28      45   15,165 /   7,457│
│...585 more...                                                                │
└——————————————————————————————————————————————————————————————————————————————┘

Some new columns have appeared. In the last column, we can see that Moolenaar has also contributed an order of magnitude more lines of code to Vim than any other contributor.

So far we have been implicitly using the table subcommand of git who. (We could have written that last command as git who table -l.) We can use another subcommand, hist, to get a sense of how the top contributor has changed over time:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
~/clones/vim$ git who hist
2004 ┤ #                                     Bram Moolenaar (46)
2005 ┤ #########                             Bram Moolenaar (578)
2006 ┤ #######                               Bram Moolenaar (428)
2007 ┤ ######                                Bram Moolenaar (392)
2008 ┤ #####                                 Bram Moolenaar (318)
2009 ┤ ####                                  Bram Moolenaar (249)
2010 ┤ ##########                            Bram Moolenaar (636)
2011 ┤ #####                                 Bram Moolenaar (317)
2012 ┤ #######                               Bram Moolenaar (400)
2013 ┤ ############                          Bram Moolenaar (797)
2014 ┤ ########                              Bram Moolenaar (466)
2015 ┤ ########                              Bram Moolenaar (493)
2016 ┤ ########################              Bram Moolenaar (1,574)
2017 ┤ #####################                 Bram Moolenaar (1,335)
2018 ┤ ##################                    Bram Moolenaar (1,135)
2019 ┤ #############################         Bram Moolenaar (1,875)
2020 ┤ ##################################    Bram Moolenaar (2,236)
2021 ┤ #####################------           Bram Moolenaar (1,395)
2022 ┤ #########################-----------  Bram Moolenaar (1,636)
2023 ┤ ####------------------                Bram Moolenaar (256)
2024 ┤ ######----------------------          Christian Brabandt (363)
2025 ┤ ##----                                Christian Brabandt (67)

git who gives us a lot of information here. For each year, we are shown who made the most commits in that year and how many commits that person made. The bar graph gives us a sense of how the number of commits varies from year to year. In some years, the top contributor only contributes a fraction of the total number of commits made that year; you can see that in 2023, for example, Moolenaar’s commits (represented by #) do not fill the entire bar. The remaining portion of the bar (represented by -) accounts for commits made by contributors not named “Bram Moolenaar.”

In most of the above years, Moolenaar appears to have been the only contributor to Vim. It was only after 2023 that Christian Brabandt became the top contributor. From what I can understand, Brabandt has inherited leadership of the Vim project. It is interesting to see this succession borne out in the commit history.

Still, it is clear that Vim was a solo project for most of its existence. And this timeline only goes back to the beginning of Vim’s Git commit history. Vim was initially released in 1991, well before Linus Torvalds created Git. Other people might have contributed to Vim before it was put under Git version control. But from what we can see in the Git history, Moolenaar left large shoes to fill.

We can confirm that other contributors began committing to the Vim repo only recently using the --nauthor flag (for “not author”) to exclude Moolenaar from the timeline:

1
2
3
4
5
6
7
8
~/clones/vim$ git who hist --nauthor "Bram Moolenaar"
2019 ┤ #                                     Christian Brabandt (1)
2020 ┤ #                                     Jay Sitter (1)
2021 ┤ ##-----                               Yegappan Lakshmanan (87)
2022 ┤ ###------------                       zeertzjq (148)
2023 ┤ ####-------------------               Christian Brabandt (193)
2024 ┤ ########----------------------------  Christian Brabandt (363)
2025 ┤ ##------                              Christian Brabandt (67)

The timeline now begins only in 2019, when Brabandt made the first non-Moolenaar commit. Surprisingly, before 2023, Brabandt was not the top contributor even among people not named “Bram Moolenaar.” (Though keep in mind that “number of commits” is only one possible metric we could choose, and further that no metric can capture how much someone has contributed to a project in a holistic sense.)

Who Is Working On Vim Now?

Moolenaar died on August 3rd, 2023. We can see who has contributed since then using the --since flag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
~/clones/vim$ git who --since "August 3rd, 2023"
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│Christian Brabandt                1 day ago       610│
│zeertzjq                          2 days ago      334│
│Yegappan Lakshmanan               2 weeks ago     214│
│glepnir                           1 day ago        78│
│Aliaksei Budavei                  1 day ago        78│
│Doug Kearns                       2 days ago       76│
│Wu, Zhenyu                        1 month ago      70│
│dkearns                           9 mon. ago       67│
│Ken Takata                        2 mon. ago       64│
│Ernie Rael                        1 month ago      63│
│...427 more...                                       │
└—————————————————————————————————————————————————————┘

I am reassured by the large number of contributors I see here. Moolenaar may have been more or less synonymous with Vim, but it looks like there are many people who have stepped up to make significant contributions in his absence.

We could also look at the contributors to the v9.1 release, the most recent version of Vim (as of this writing) and also the first release after Moolenaar’s passing:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
~/clones/vim$ git who v9.0.0000..v9.1.0
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│Bram Moolenaar                    1 year ago    1,062│
│zeertzjq                          1 year ago      234│
│Christian Brabandt                1 year ago      203│
│Yegappan Lakshmanan               1 year ago      177│
│K.Takata                          1 year ago       56│
│Philip H                          1 year ago       45│
│Luuk van Baal                     1 year ago       44│
│Yee Cheng Chin                    1 year ago       43│
│Ernie Rael                        1 year ago       42│
│Amaan Qureshi                     1 year ago       31│
│...253 more...                                       │
└—————————————————————————————————————————————————————┘

We can see here that the minor-number release, while an accomplishment, still included much work by Moolenaar. The real test will be the v9.2 release.

Who are Christian Brabandt, zeertzjq, and Yegappan Lakshmanan? These three seem to be the main contributors maintaining Vim now. We aren’t going to do any investigation into their personal or professional lives, but we certainly can look at who they are within the Vim codebase.

Who Is Contributing What?

git who has a third subcommand that we’ve not seen yet, called tree. The tree subcommand prints out the files in the Git working tree, along with an annotation for each file showing the one author that has contributed the “most” to that file according to a chosen metric.

One simple invocation of git who tree can show us who has edited each file most recently. This should yield the same information as can be viewed on Github when you browse a repository. We use the -m flag to pick the author who last modified each file. The -d flag limits the depth of the tree.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
~/clones/vim$ git who tree -d 1 -m
./............................Christian Brabandt (1 day ago)
├── .github/..................Jonathan (1 day ago)
├── READMEdir/................Nir Lichtman (5 mon. ago)
├── ci/.......................Christ van Willegen (3 weeks ago)
├── lang/.....................Rafael Fontenelle (2 weeks ago)
├── nsis/.....................Rafael Fontenelle (2 weeks ago)
├── pixmaps/..................Bram Moolenaar (3 yr. ago)
├── runtime/..................Christian Brabandt (1 day ago)
├── src/......................Christian Brabandt (1 day ago)
├── tools/....................RestorerZ (1 month ago)
├── .appveyor.yml.............RestorerZ (1 year ago)
├── .cirrus.yml...............Philip H. (3 mon. ago)
├── .clang-format.............Luca Saccarola (3 mon. ago)
├── .codecov.yml..............dundargoc (1 year ago)
├── .editorconfig.............Maxim Kim (1 week ago)
├── .git-blame-ignore-revs
├── .gitattributes............Bram Moolenaar (5 yr. ago)
├── .gitignore................Eisuke Kawashima (1 week ago)
├── .hgignore.................Eisuke Kawashima (1 week ago)
├── CONTRIBUTING.md...........RestorerZ (1 month ago)
├── Filelist..................RestorerZ (1 day ago)
├── LICENSE
├── Makefile..................Aliaksei Budavei (1 day ago)
├── README.md.................Patrick Brinich-Langlois (9 mon. ago)
├── README.txt................Patrick Brinich-Langlois (9 mon. ago)
├── README_VIM9.md............Bram Moolenaar (2 yr. ago)
├── SECURITY.md
├── configure.................Bram Moolenaar (5 yr. ago)
├── uninstall.txt.............Martin Tournoij (2 yr. ago)
├── vimtutor.bat..............RestorerZ (3 mon. ago)
└── vimtutor.com..............Bram Moolenaar (9 yr. ago)

We can see what our trio of top contributors have been working on since the v9.1 release using a more complicated invocation. Here we filter to particular authors using the --author flag and leave out the -m flag to go back to ranking authors by number of commits (the default):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
~/clones/vim$ git who tree --author "zeertzjq" --author "Christian Brabandt" --author "Yegappan Lakshmanan" -d 1 v9.1.0..
./............................Christian Brabandt (424)
├── .github/..................Christian Brabandt (10)
├── READMEdir/................zeertzjq (1)
├── nsis/.....................Christian Brabandt (2)
├── runtime/..................Christian Brabandt (241)
├── src/......................zeertzjq (219)
├── .git-blame-ignore-revs
├── CONTRIBUTING.md
├── Filelist
├── Makefile
└── README.md

An interesting observation we can make here is that Brabandt seems to have specialized in maintaining Vim’s runtime files (mostly VimScript code), while zeertzjq seems to have specialized in maintaining the editor core (written in C).

Also note that our tree has been truncated and most of the files that appeared in it above no longer appear. This is because git who tree only includes files in the tree that were edited by a commit in the provided revision range. In this case we limited the command to commits occurring after the v9.1 release.

The output of git who tree, since it only shows a single “winner” for each file node, can be misleading. We can sanity check our conclusion about what Brabandt and zeertzjq are working on using the table subcommand on the src directory:

1
2
3
4
5
6
7
8
~/clones/vim$ git who --author "zeertzjq" --author "Christian Brabandt" --author "Yegappan Lakshmanan" v9.1.0.. src/
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│zeertzjq                          3 days ago      219│
│Christian Brabandt                1 day ago       206│
│Yegappan Lakshmanan               2 weeks ago     106│
└—————————————————————————————————————————————————————┘

This reveals that while zeertzjq has made more commits affecting files under the src directory than Brabandt, Brabandt has not been far behind. So maybe a better conclusion is that both Brabandt and zeertzjq are committing to the editor core, but Brabandt seems to be taking the lead on maintaining the runtime files:

1
2
3
4
5
6
7
8
~/clones/vim$ git who --author "zeertzjq" --author "Christian Brabandt" --author "Yegappan Lakshmanan" v9.1.0.. runtime/
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│Christian Brabandt                1 day ago       241│
│zeertzjq                          3 days ago       73│
│Yegappan Lakshmanan               4 weeks ago      35│
└—————————————————————————————————————————————————————┘

What of Lakshmanan? We can filter just for him to make sure his contributions appear:

1
2
3
4
5
~/clones/vim$ git who tree --author "Yegappan Lakshmanan" -d 1 v9.1.0..
./..............Yegappan Lakshmanan (114)
├── runtime/....Yegappan Lakshmanan (35)
├── src/........Yegappan Lakshmanan (106)
└── Filelist

He has contributed to both the runtime and src directories, but has made fewer commits than his peers and so his name did not appear earlier.

We can dive deeper and get a sense for all of the changes Lakshmanan has made since the v9.1 release. In this next invocation, we are increasing the depth of the tree, showing lines changed/added rather than number of commits, and finally passing the -a flag to force git who to annotate every file. (git who will by default remove some redundant annotations to reduce visual noise.)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
~/clones/vim$ git who tree -l -a -d 2 --author "Yegappan Lakshmanan" v9.1.0..
./...........................Yegappan Lakshmanan (22,033 / 8,176)
├── runtime/.................Yegappan Lakshmanan (2,836 / 404)
│   ├── autoload/............Yegappan Lakshmanan (219 / 0)
│   ├── doc/.................Yegappan Lakshmanan (977 / 232)
│   ├── ftplugin/............Yegappan Lakshmanan (45 / 0)
│   ├── pack/................Yegappan Lakshmanan (183 / 169)
│   ├── plugin/..............Yegappan Lakshmanan (6 / 0)
│   ├── syntax/..............Yegappan Lakshmanan (93 / 0)
│   ├── tutor/...............Yegappan Lakshmanan (1,307 / 0)
│   ├── defaults.vim.........Yegappan Lakshmanan (3 / 3)
│   └── filetype.vim.........Yegappan Lakshmanan (3 / 0)
├── src/.....................Yegappan Lakshmanan (19,191 / 7,772)
│   ├── proto/...............Yegappan Lakshmanan (49 / 25)
│   ├── testdir/.............Yegappan Lakshmanan (8,936 / 2,292)
│   ├── Make_ami.mak.........Yegappan Lakshmanan (1 / 0)
│   ├── Make_cyg_ming.mak....Yegappan Lakshmanan (1 / 0)
│   ├── Make_mvc.mak.........Yegappan Lakshmanan (4 / 0)
│   ├── Make_vms.mms.........Yegappan Lakshmanan (6 / 0)
│   ├── Makefile.............Yegappan Lakshmanan (17 / 2)
│   ├── README.md............Yegappan Lakshmanan (1 / 0)
│   ├── buffer.c.............Yegappan Lakshmanan (3 / 1)
│   ├── charset.c............Yegappan Lakshmanan (11 / 0)
│   ├── cmdexpand.c..........Yegappan Lakshmanan (27 / 18)
│   ├── dict.c...............Yegappan Lakshmanan (27 / 0)
│   ├── diff.c...............Yegappan Lakshmanan (284 / 37)
│   ├── digraph.c............Yegappan Lakshmanan (2 / 5)
│   ├── errors.h.............Yegappan Lakshmanan (60 / 14)
│   ├── eval.c...............Yegappan Lakshmanan (2,240 / 2,339)
│   ├── evalbuffer.c.........Yegappan Lakshmanan (2 / 0)
│   ├── evalfunc.c...........Yegappan Lakshmanan (526 / 43)
│   ├── evalvars.c...........Yegappan Lakshmanan (80 / 18)
│   ├── ex_cmds.h............Yegappan Lakshmanan (5 / 5)
│   ├── ex_docmd.c...........Yegappan Lakshmanan (310 / 80)
│   ├── ex_getln.c...........Yegappan Lakshmanan (7 / 7)
│   ├── fileio.c.............Yegappan Lakshmanan (1 / 1)
│   ├── filepath.c...........Yegappan Lakshmanan (29 / 27)
│   ├── gc.c.................Yegappan Lakshmanan (783 / 0)
│   ├── globals.h............Yegappan Lakshmanan (9 / 1)
│   ├── if_cscope.c..........Yegappan Lakshmanan (2 / 2)
│   ├── list.c...............Yegappan Lakshmanan (24 / 0)
│   ├── mbyte.c..............Yegappan Lakshmanan (12 / 1)
│   ├── misc1.c..............Yegappan Lakshmanan (11 / 11)
│   ├── option.c.............Yegappan Lakshmanan (87 / 22)
│   ├── option.h.............Yegappan Lakshmanan (6 / 2)
│   ├── optiondefs.h.........Yegappan Lakshmanan (15 / 4)
│   ├── optionstr.c..........Yegappan Lakshmanan (14 / 9)
│   ├── proto.h..............Yegappan Lakshmanan (1 / 0)
│   ├── scriptfile.c.........Yegappan Lakshmanan (12 / 5)
│   ├── strings.c............Yegappan Lakshmanan (290 / 57)
│   ├── structs.h............Yegappan Lakshmanan (28 / 6)
│   ├── terminal.c...........Yegappan Lakshmanan (9 / 2)
│   ├── testing.c............Yegappan Lakshmanan (11 / 2)
│   ├── typval.c.............Yegappan Lakshmanan (25 / 3)
│   ├── undo.c...............Yegappan Lakshmanan (1 / 1)
│   ├── usercmd.c............Yegappan Lakshmanan (2 / 2)
│   ├── userfunc.c...........Yegappan Lakshmanan (212 / 95)
│   ├── version.c............Yegappan Lakshmanan (215 / 1)
│   ├── vim.h................Yegappan Lakshmanan (8 / 4)
│   ├── vim9.h...............Yegappan Lakshmanan (11 / 1)
│   ├── vim9class.c..........Yegappan Lakshmanan (1,009 / 196)
│   ├── vim9cmds.c...........Yegappan Lakshmanan (11 / 5)
│   ├── vim9compile.c........Yegappan Lakshmanan (2,548 / 1,750)
│   ├── vim9execute.c........Yegappan Lakshmanan (269 / 66)
│   ├── vim9expr.c...........Yegappan Lakshmanan (96 / 41)
│   ├── vim9instr.c..........Yegappan Lakshmanan (27 / 5)
│   ├── vim9script.c.........Yegappan Lakshmanan (17 / 8)
│   ├── vim9type.c...........Yegappan Lakshmanan (796 / 555)
│   └── viminfo.c............Yegappan Lakshmanan (1 / 1)
└── Filelist.................Yegappan Lakshmanan (6 / 0)

With this increased granularity, we can see that Lakshmanan seems to have made some big contributions to vim tutor (the tutorial program) and also to eval.c and vim9compile.c, two important-sounding files! Lakshmanan also contributed many lines of code under the src/testdir directory, but it’s hard to know without further exploration if those were substantive changes or something like a bulk change to a test fixture.

To Vim or Neovim

In recent years, a competitor to Vim called Neovim has emerged. Part of the reason Neovim forked from Vim in the first place was that the organization of the Vim project made it hard for new contributors to get involved. Fans of Neovim argue that Neovim has a healthier ecosystem of contributors and plugin authors than the original Vim and that therefore Neovim will be the version of Vim with more features and better maintenance going forward.

As we have seen, Vim has many active contributors and has opened up to a wider group in the last couple years. Work is continuing on the project led by what appears to be a core group of three contributors. Speaking for myself, I trust these contributors to keep Vim going strong, though it will be interesting to see how the v9.2 release (the first one without any contributions from Moolenaar) will come together.

All that said, are Neovim fans right when they say that Neovim has more support from the open-source community? I meant to leave this as an exercise for the reader, but my curiosity has gotten the best of me.

We can very easily see how Neovim compares using git who:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
~/clones/neovim$ git who
┌—————————————————————————————————————————————————————┐
│Author                            Last Edit   Commits│
├—————————————————————————————————————————————————————┤
│zeertzjq                          13 hr. ago    4,175│
│Justin M. Keyes                   10 hr. ago    2,411│
│Jan Edmund Lazo                   3 yr. ago     2,258│
│ZyX                               5 yr. ago     1,421│
│Christian Clason                  1 day ago     1,318│
│bfredl                            1 week ago    1,167│
│dundargoc                         2 weeks ago   1,126│
│James McCoy                       2 weeks ago     838│
│Thiago de Arruda                  8 yr. ago       742│
│Lewis Russell                     1 week ago      615│
│...1,211 more...                                     │
└—————————————————————————————————————————————————————┘

Immediately we can see that there are many more total contributors to Neovim, and also that there seems to be a wider group of people who have made significant contributions. There’s also a spicy finding here—it appears zeertzjq is the top contributor to Neovim! One wonders if most of his contributions to base Vim are in support of Neovim somehow… which would mean that, at least if we’re trying to evaluate how much momentum the project has on its own, Vim arguably has just two main contributors and not three.

The output of git who hist for the Neovim repository is also revealing. But that one I do leave as an exercise to the reader. Download git who and give it a spin!

Correction

Reddit user y-c-c pointed out to me that the above analysis of Vim’s commit history is misleading because for many years Moolenaar gave credit to contributors in the commit message of patches he committed. So, during the many years where it looks like Moolenaar was the sole contributor, there were in fact other people contributing to Vim—it’s just that all of their changes were introduced to the repo via a commit from Moolenaar.

Typically, a situation like this would be handled in Git by setting the commit author to the person who wrote the patch and the commit committer to the person actually making the commit. git who uses the author field. Still, everybody is entitled to use their tools their own way; it’s also possible this convention didn’t exist when Moolenaar first migrated Vim to Git. The fault is my own for not spot checking the commit history to see how the Vim project did things. Vim has had more external contributors (and has had them for far longer) than I represent above.

I think this blog post still serves as an accurate demonstration of git who—of both its power and major weaknesses! Let this be a warning to anybody that would use git who too credulously. Please don’t use it to do something silly like evaluate your employees.