Home | Notes
Modelines

(July 5, 2022)

Today I encountered modelines for the first time! I was reading a snippet of code in Justine Tunney (jart)'s memzoom project that started with some interesting lines:

/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney                              │
│                                                                              │
│ Permission to use, copy, modify, and/or distribute this software for         │
...
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8                                :vi│
╞══════════════════════════════════════════════════════════════════════════════╡
│ Copyright 2020 Justine Alexandra Roberts Tunney                              │
│                                                                              │
│ Permission to use, copy, modify, and/or distribute this software for         │
...

(source)

The -*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*- and vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 lines are definitely not C, and furthermore they're in a comment block. What are they? Based on the tab-width and mode and fenc=utf-8 -type lines, it seems like they are something to do with code formatting.

After a bit of research, it turns out for the vim and vi editors these are called modelines (that's the comment line starting with vi: set...) and for the emacs editor they are called file variables (line starting with -*- mode:c...). They're pretty cool! They can set up per-file indentation rules, tab vs spaces rules, and character encoding (among many other things). This is the kind of thing I would usually rely on a code formatting like clang-format or JuliaFormatter.jl for, but here it's just built into the editor! Also it's a little different because it doesn't format existing programs, just enforces rules while you edit.

Vi(m) and Emacs have different ways to specify what the per-file rules should be, but it looks like you can generally always get them to describe the same behavior. The Emacs file variables need to be on the first line enclosed in a pair of -*-, an the vim modeline just has to be in the first 5 lines of a file, so you can easily have lines for both editors, as Justine has done.

Here's another example of a pair of config lines in the start of a file from the Firefox source code docs:

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */

There are lots of pages online about modelines, but so far I just been reading these ones about vim and emacs.

Pretty neat! I don't use vim or emacs right now (nano and Atom mainly) but this is another reminder that I ought to explore those editors more.