9

I can't seem to find this answer anywhere, but I'm sure it's because I don't know the terms to search for.

I'm currently working in a mixed shop, with my developers using a mix of emacs, vim, Notepad++, and whatever you call the alleged text editor that is part of Aginity.

As you can imagine there are also great differences in opinion as to how to indent code (both spaces v.s. tabs, and how many spaces/tabs). Being a support guy I take no position on this, other than PLEASE FOR THE LOVE OF GHOD PICK ONE. I especially hate inconsistency inside a single file (???)

Vim has this feature called "modeline magic" (http://vim.wikia.com/wiki/Modeline_magic) that lets me put:

# vim: expandtab copyindent preserveindent softtabstop=0 shiftwidth=4 tabstop=4 filetype=py

"near" the top or bottom of a file and it tells vim to, well, you can follow that. (note for those who don't follow the link, the first character is a file-type dependent comment. In C++ it might be /* ... */ or //. SQL would be -- etc.

Surely Emacs has some sort of equivalent?

EDITED TO ADD:

Emacs and Vim mean something utterly different by "modeline" and "mode-line". Being a Unix Admin pretending to be a developer, I'm asking about the vim definition.

If I'm just missing the obvious search terms, that would be cool too. (The tag is...probably wrong. If someone could make it more better, that would be good.) Basil Fixored it. Thanks Basil.

Petro
  • 193
  • 1
  • 4
  • 2
    IIUC you're looking for [file variables](https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html). In my experience, though, others usually find these too intrusive in collaborative projects; often a more convenient alternative is to use [directory variables](https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html). – Basil Oct 31 '17 at 22:21
  • I think the file variables is what I'm looking for, because I can put the vim modeline on line three or at the bottom. Directory variables won't work because vim doesn't support such a creature. Optimally we would have company/corporate standards to direct such things and they'd issue me a taser for the miscreants who dared flaunt THE MAN. But no such luck. – Petro Oct 31 '17 at 22:38
  • 2
    Perhaps http://editorconfig.org/ would be of interest to the entire team? – phils Oct 31 '17 at 22:40
  • 1
    (Note that this vim "mode-line" apparently has nothing to do with what Emacs calls the mode-line.) – Drew Nov 01 '17 at 03:20
  • @phils GENIUS. Will be implementing shortly and tasering developers until they comply or I get tired. THANKS. – Petro Nov 01 '17 at 23:00
  • @drew, yeah, figured that out already. Should have noted it in the question. – Petro Nov 01 '17 at 23:00

2 Answers2

14

What you're looking for are File Variables, specifically you want to look at Specifying File Variables in the Emacs Manual.

There are two ways to specify File Variables. The more "modeline magic like" of the two requires you to surround your variable list with with -*- characters. An example combining emacs and vim functionality could look like:

/* -*- mode: c++; -*- vim: set ft=cpp: */

But, a single line could get unwieldy quickly. As a matter of personal convention, I use two separate lines:

;; -*- mode: lisp; fill-column: 75; -*-
;; vim: ft=lisp cc=75

Note: depending on how your vim was compiled, you may have to configure vim to read the modeline on line #2. You can do this with modeline and modlines in your ~/.vimrc:

set modeline
set modelines=2
nega
  • 3,091
  • 15
  • 21
  • Why `-*-` ? Is this some formal agreement between vi and Emacs users? Or a polyglot hack? – mcandre May 03 '23 at 18:50
  • @mcandre `-*-` has nothing to do with vim. it is an emacs convention only. vim doesnt recognize or process it. – nega May 03 '23 at 18:59
7

File variables

The equivalent of Vi modelines in Emacs is file variables. As is often the case, the purpose of the feature is the same, but there are differences in the implementation details.

The basic syntax of Emacs file variables is a block delimited by -*- characters which must be on the first line of the file. Within this block, assignments of the form variable:value are separated by semicolons.

# -*-indent-tabs-mode: nil; fill-column: 70 -*-
# vim:expandtab:textwidth=70:

As an exception. if the first line starts with #! then file local variables may be specified on the second file.) Independently, if you only want to specify the major mode, you can leave out the mode: part.

#!/usr/bin/env modified-python
# -*-python-*- vim:ft=py:

If you want to specify a lot of variables, or if you don't want to put the settings on the first line, you can put them near the end of the file, in a local variables list. A local variables list starts with a line containing the exact substring Local Variables: and ends with a line containing End:. All the lines from Local Variables: to End: must start and end with the same prefix and suffix (typically to make them comment lines). The intermediate lines contain one file variable assignment per line. The block must start within the last 3000 characters of the file.

# Local Variables:
# indent-tabs-mode: nil
# fill-column: 78
# End:

Directory variables

If you have a lot of files that require similar settings, then instead of putting the same settings in each file, you can put them in a directory local variables file. This file is called .dir-locals.el. Emacs looks for it in the directory containing the files, and if it doesn't find one, it tries parent directories recursively, so you can put a .dir-locals.el file at the top of your tree. A .dir-locals file might look like this, with two settings that apply to every file and two that apply to C files (overriding the default, in the case of indent-tabs-mode):

((nil . ((indent-tabs-mode . nil)
         (fill-column . 78)))
 (c-mode . ((c-file-style . linux)
            (indent-tabs-mode . t))))

Which variables can be file variables?

Only variables declared as safe should appear in file or directory variables lists. If a file or directory variables list contains an unsafe variable, Emacs will ask for confirmation when opening the file.

EditorConfig

File variables take care of Emacs and Vi(m), but they won't help users of other editors. You can set a few basics through EditorConfig. A lot of editors have EditorConfig plugins (Emacs: install the editorconfig package from ELPA; Vim: EditorConfig plugin; Notepad++: EditorConfig plugin), though they are usually not installed by default. EditorConfig only supports a few basic settings, but the nice thing is that they are specified in an editor-independent format.