Vim: Sorting (BibTeX) Bibliography Files

Keeping BibTeX’s .bib files properly sorted.  Keywords: #vim #bibtex #bibliography #sorting

Suppose you have a BibTeX .bib file, with content formatted along the following lines:

@book{Mumford:Technics,
  title     = "Technics And Civilization",
  author    = "Lewis Mumford",
  address   = "New York",
  publisher = "Harcourt Brace Jovanovich",
  year      = "1963"
}
@book{Horkeimer:EOR,
  title     = "Eclipse Of Reason",
  author    = "M. Horkeimer",
  address   = "New York",
  publisher = "Seabury",
  year      = "1974"
}

With just two entries it is dead easy to keep the file sorted by the alphanumeric sorting of the bibliographic keys (Mumford:Technics and Horkeimer:EOR in the case of our snippet). However, as the file grows, having the file so sorted, becomes both increasingly desirable, and decreasingly easy to achieve/maintain—if one does such a task by hand, that is. Because with the following normal mode map, getting the file sorted is dead simple: just press S. The entire file will be sorted by bibliographic key (ascending, ignoring case differences), and the cursor will be left on the line starting with @ that corresponds to the entry over the lines of which the cursor was initially (i.e., before the sorting).

nnoremap S $?@<CR>f{lvf,h"8y:%s/}\@<!\n/XXXXLBXXXX<CR>:sort i /^@[a-z]\+{/<CR>
:%s/XXXXLBXXXX/\r/g<CR>:execute '/'.@8<CR>

Beware! The map consists only of ONE LINE; it is split into two for readability. Here is how it works:

  1. First, we want to select the reference key for the entry on the lines of which the cursor is currently at. For this, we move the cursor to the end of the line it is at now, and then search backwards for @—which leaves the cursor on top of that @. Then we search forward for {, and yank into registry 8 the text between { and ,—which is the sought reference key.

  2. Next, we replace every newline (line break) that does NOT come after a } with the special string XXXXLBXXXX—this effectively joins each bibliographical entry into a single line. (Note there is nothing special about this string; it just has to be something that will never show up in a .bib file.)

  3. Then we sort the file: the regular expression selects what is to be ignored; i.e., sorting starts after the text that the regexp matches, which is to say it starts at bibliographic key.

  4. Lastly, we replace the special string with a newline (\r)—i.e., we undo the joining—and do a search for the reference key in register 8: this moves the cursor back to reference we were originally on, which after sorting may have been moved to a different position.

Simple enough, right? If applied to the bibliographical snippet above, both entries will reverse position—feel free to give it a try.

November 16, 2025. Got feedback? See the contact page.