Vim Tips Wiki
No edit summary
(Enabling modelines)
(36 intermediate revisions by 22 users not shown)
Line 1: Line 1:
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=331
 
|id=331
 
|previous=330
 
|previous=330
 
|next=332
 
|next=332
|created=September 22, 2002
+
|created=2002
 
|complexity=basic
 
|complexity=basic
|author=Alex A. Naanou
+
|author=
|version=5.7
+
|version=6.0
 
|rating=154/50
 
|rating=154/50
  +
|category1=
  +
|category2=
 
}}
 
}}
  +
Options set in your [[vimrc]] will apply to all files that you edit. You can also set:
One of the things about Vim that are both quite simple yet very useful is that you can store by-file settings... That is each file can contain settings specific to it. This thing is called a modeline {{help|modeline}}. Though this is limited only to the 'set' command arguments, you can store quite a lot local file settings like the indent type, folding method and so on.
 
  +
*Different options for all files of a certain type (for example, all <code>*.py</code> files). See [[filetype.vim]] and [[VimTip1510|filetypes]] and an [[VimTip1565|example]].
  +
*Different options for a particular file using modelines (this tip).
   
  +
Note that the 'modeline' option must be set in order to take advantage of this tip. This option is set by default for Vim running in nocompatible mode, but some notable distributions of Vim disable this option in the system vimrc for security. In addition, it is off by default when editing as root. See {{help|'modeline'}} for more information.
The syntax is as follows:
 
  +
  +
==Examples==
  +
For example, in a particular file you may want each tab character that you type to be expanded to spaces. To achieve this, put the following modeline near the top or the bottom of that file:
 
<pre>
 
<pre>
// vim:set ts=4 sw=4 nowrap:
+
# vim: set expandtab:
 
</pre>
 
</pre>
  +
The space between the comment opening and <code>vim:</code> is required, otherwise the modeline will not be recognized.
or
 
  +
  +
The modeline cannot be anywhere in the file: it must be in the first or last few lines. The exact location where vim checks for the modeline is controlled by the <code>modelines</code> variable; see {{help|'modelines'}}. By default, it is set to 5 lines.
  +
  +
The following examples show some alternatives that could be in a C file:
 
<pre>
 
<pre>
/* vim:noai:ts=2:sw=4: */
+
// vim: noai:ts=4:sw=4
  +
-or-
  +
/* vim: noai:ts=4:sw=4
  +
*/
  +
-or-
  +
/* vim: set noai ts=4 sw=4: */
  +
-or-
  +
/* vim: set fdm=expr fde=getline(v\:lnum)=~'{'?'>1'\:'1': */
 
</pre>
 
</pre>
   
  +
With "<code>set</code>", the modeline ends at the first colon not following a backslash. Without "<code>set</code>", no text can follow the options, so for example, the following is invalid:
The modelines can be contained in comments so as to not interfere with the file syntax (shown here for C/C++). These lines are read by Vim when it loads the file, and they can either be in the first or last 5 lines (by default).
 
 
<pre>
  +
Error E518: Unknown option: */
  +
/* vim: noai:ts=4:sw=4 */
 
</pre>
   
  +
==Adding a modeline==
Please note that the second modeline syntax (the one using "se[t]") _must_ be colon terminated, while the first (plain) one _may_.
 
  +
With the following in your [[vimrc]] and the default leader key, you could type <code>\ml</code> to add a modeline based on your current settings:
 
<pre>
 
" Append modeline after last line in buffer.
  +
" Use substitute() instead of printf() to handle '%%s' modeline in LaTeX
  +
" files.
 
function! AppendModeline()
  +
let l:modeline = printf(" vim: set ts=%d sw=%d tw=%d %set :",
  +
\ &tabstop, &shiftwidth, &textwidth, &expandtab ? '' : 'no')
  +
let l:modeline = substitute(&commentstring, "%s", l:modeline, "")
  +
call append(line("$"), l:modeline)
 
endfunction
 
nnoremap <silent> <Leader>ml :call AppendModeline()<CR>
 
</pre>
   
  +
In a C file, you would get a modeline like this:
==Comments==
 
Speaking of modelines I find it handy to have a very primitive menu entry to insert my normal modeline for me:
 
 
<pre>
 
<pre>
  +
/* vim: set ts=8 sw=4 tw=0 noet : */
amenu Fe&amp;ral's.Insert\ a\ Vim\ modeline &lt;Esc&gt;&lt;Esc&gt;ggOvim:ff=unix ts=4 ss=4&lt;CR&gt;vim60:fdm=marker&lt;esc&gt;gg
 
 
</pre>
 
</pre>
   
  +
Alternatively, you could use a simple menu entry, for example:
This will net you a (I think proper) modeline at the start of the file like so:
 
  +
<pre>
 
amenu Edit.Insert\ &modeline <C-\><C-N>ggOvim:ff=unix ts=4 ss=4<CR>vim60:fdm=marker<Esc>
  +
</pre>
  +
  +
Choosing the menu item would insert two modelines like this:
 
<pre>
 
<pre>
 
vim:ff=unix ts=4 ss=4
 
vim:ff=unix ts=4 ss=4
Line 37: Line 75:
 
</pre>
 
</pre>
   
  +
== Enabling modelines ==
----
 
  +
This mechanism can be extended to 'let'. Cf. for instance: {{script|id=83}}.
 
  +
The modelines are executed by vim *only* if *all three* of
  +
"modeline" is set to "modeline" (not "nomodeline"),
  +
and
  +
"modelines" is set to some positive integer (not "0"),
  +
and
  +
you are not root.
  +
  +
type
  +
:verbose set modeline?
  +
and
  +
:verbose set modelines?
  +
to get the current settings and, if not the default, where it was last set.
  +
  +
Debian, Ubuntu, Gentoo, OSX, etc. by default disable modelines "for security reasons".<ref>
  +
[http://superuser.com/questions/323712/modeline-not-work-in-vim]
  +
[https://wiki.python.org/moin/Vim]
  +
[http://unix.stackexchange.com/questions/19875/setting-vim-filetype-with-modeline-not-working-as-expected]
  +
</ref>
  +
  +
To enable modelines in Debian and Ubuntu -- which by default set "modeline" to "nomodeline", but leave "modelines" at the default of "5" --
  +
at the command prompt type
  +
  +
vim ~/.vimrc
  +
  +
and make sure it has the line
  +
  +
set modeline
  +
  +
To enable modelines in OSX -- which by default sets "modelines" to 0, but leaves "modeline" at the default of "modeline" --
  +
at the command prompt type
  +
  +
vim ~/.vimrc
  +
  +
and make sure it has the line
  +
  +
set modelines=5
  +
  +
  +
  +
==Security==
  +
{{Todo}}
  +
*Need note on security implications of modelines and reference to alternatives.
  +
*Text other than "vim:" can be recognised as a modeline.
  +
*Google "vim modeline vulnerability" (without quotes) for information.
  +
  +
==References==
  +
*{{help|auto-setting}}
  +
*{{help|modeline}}
  +
*{{help|'modeline'}} determines whether to look for modelines
  +
*{{help|'modelines'}} number of lines checked to find each modeline
  +
 
==Comments==
 
This mechanism can be extended to 'let' &ndash; see {{script|id=83}}.
   
  +
See {{script|id=1876}} - securemodelines
 
----
 
----
  +
How can we make this page more discoverable? New users may have seen a comment at the top of a file, with vim settings in it, but they don't know that this is called a 'modeline'. They may search for something like ''"set options in a comment"'' and we should return this page. <small>--Preceding [[Vim Tips Wiki:Quick reference|unsigned]] comment added by [[User:Chopp3r|Chopp3r]] 00:19, November 26, 2013</small>
  +
:I made a redirect, see [[Set options in a comment]]. Clicking that link will go to this page, and at the top will be a small link saying "(Redirected from [http://vim.wikia.com/wiki/Set_options_in_a_comment?redirect=no Set options in a comment])". Clicking that will go to the actual redirect page, which you can edit to see the idea. The search engine takes some time (a day or two?) to update its indices, but after that searching for "set options in a comment" should go directly here. It should help Google find that as well. In practice it is difficult anticipating what people might search for, but your suggested text is very reasonable so a redirect is worthwhile. [[User:JohnBeckett|JohnBeckett]] ([[User talk:JohnBeckett|talk]]) 09:10, November 26, 2013 (UTC)
  +
::I just tried "vim set options in a comment" (without quotes) in Google, and this page was #3, behind Stackoverflow at #1 and #2. It's hard to improve on #3, but we'll see what happens in a few days. [[User:JohnBeckett|JohnBeckett]] ([[User talk:JohnBeckett|talk]]) 09:12, November 26, 2013 (UTC)
   
 
----
It is also possible to append a modeline using the file type's comment string:
 
<pre>
 
function! InsertModeline()
 
" save the old position
 
let l:pos = line( '.' ).' | normal! '.virtcol( '.' ).'|'
 
" insert the modeline at the end of the buffer
 
execute "normal Go" . printf(&commentstring, "vim: ts=".tabstop." sw=".&shiftwidth." tw=".&textwidth.": " )
 
" restore the old position
 
exe l:pos
 
endif
 
endfunction
 
</pre>
 
Then one may create a mapping such as:
 
<pre>
 
nnoremap <silent> <LocalLeader>ml :call InsertModeline()<CR>
 
</pre>
 

Revision as of 02:46, 4 September 2014

Tip 331 Printable Monobook Previous Next

created 2002 · complexity basic · version 6.0


Options set in your vimrc will apply to all files that you edit. You can also set:

  • Different options for all files of a certain type (for example, all *.py files). See filetype.vim and filetypes and an example.
  • Different options for a particular file using modelines (this tip).

Note that the 'modeline' option must be set in order to take advantage of this tip. This option is set by default for Vim running in nocompatible mode, but some notable distributions of Vim disable this option in the system vimrc for security. In addition, it is off by default when editing as root. See :help 'modeline' for more information.

Examples

For example, in a particular file you may want each tab character that you type to be expanded to spaces. To achieve this, put the following modeline near the top or the bottom of that file:

# vim: set expandtab:

The space between the comment opening and vim: is required, otherwise the modeline will not be recognized.

The modeline cannot be anywhere in the file: it must be in the first or last few lines. The exact location where vim checks for the modeline is controlled by the modelines variable; see :help 'modelines'. By default, it is set to 5 lines.

The following examples show some alternatives that could be in a C file:

// vim: noai:ts=4:sw=4
   -or-
/* vim: noai:ts=4:sw=4
*/
   -or-
/* vim: set noai ts=4 sw=4: */
   -or-
/* vim: set fdm=expr fde=getline(v\:lnum)=~'{'?'>1'\:'1': */

With "set", the modeline ends at the first colon not following a backslash. Without "set", no text can follow the options, so for example, the following is invalid:

Error E518: Unknown option: */
/* vim: noai:ts=4:sw=4 */

Adding a modeline

With the following in your vimrc and the default leader key, you could type \ml to add a modeline based on your current settings:

" Append modeline after last line in buffer.
" Use substitute() instead of printf() to handle '%%s' modeline in LaTeX
" files.
function! AppendModeline()
  let l:modeline = printf(" vim: set ts=%d sw=%d tw=%d %set :",
        \ &tabstop, &shiftwidth, &textwidth, &expandtab ? '' : 'no')
  let l:modeline = substitute(&commentstring, "%s", l:modeline, "")
  call append(line("$"), l:modeline)
endfunction
nnoremap <silent> <Leader>ml :call AppendModeline()<CR>

In a C file, you would get a modeline like this:

/* vim: set ts=8 sw=4 tw=0 noet : */

Alternatively, you could use a simple menu entry, for example:

amenu Edit.Insert\ &modeline <C-\><C-N>ggOvim:ff=unix ts=4 ss=4<CR>vim60:fdm=marker<Esc>

Choosing the menu item would insert two modelines like this:

vim:ff=unix ts=4 ss=4
vim60:fdm=marker

Enabling modelines

The modelines are executed by vim *only* if *all three* of "modeline" is set to "modeline" (not "nomodeline"), and "modelines" is set to some positive integer (not "0"), and you are not root.

type

   :verbose set modeline?

and

   :verbose set modelines?

to get the current settings and, if not the default, where it was last set.

Debian, Ubuntu, Gentoo, OSX, etc. by default disable modelines "for security reasons".[1]

To enable modelines in Debian and Ubuntu -- which by default set "modeline" to "nomodeline", but leave "modelines" at the default of "5" -- at the command prompt type

   vim ~/.vimrc

and make sure it has the line

   set modeline

To enable modelines in OSX -- which by default sets "modelines" to 0, but leaves "modeline" at the default of "modeline" -- at the command prompt type

   vim ~/.vimrc

and make sure it has the line

   set modelines=5


Security

 TO DO 

  • Need note on security implications of modelines and reference to alternatives.
  • Text other than "vim:" can be recognised as a modeline.
  • Google "vim modeline vulnerability" (without quotes) for information.

References

Comments

This mechanism can be extended to 'let' – see script#83.

See script#1876 - securemodelines


How can we make this page more discoverable? New users may have seen a comment at the top of a file, with vim settings in it, but they don't know that this is called a 'modeline'. They may search for something like "set options in a comment" and we should return this page. --Preceding unsigned comment added by Chopp3r 00:19, November 26, 2013

I made a redirect, see Set options in a comment. Clicking that link will go to this page, and at the top will be a small link saying "(Redirected from Set options in a comment)". Clicking that will go to the actual redirect page, which you can edit to see the idea. The search engine takes some time (a day or two?) to update its indices, but after that searching for "set options in a comment" should go directly here. It should help Google find that as well. In practice it is difficult anticipating what people might search for, but your suggested text is very reasonable so a redirect is worthwhile. JohnBeckett (talk) 09:10, November 26, 2013 (UTC)
I just tried "vim set options in a comment" (without quotes) in Google, and this page was #3, behind Stackoverflow at #1 and #2. It's hard to improve on #3, but we'll see what happens in a few days. JohnBeckett (talk) 09:12, November 26, 2013 (UTC)