Vim Tips Wiki
Register
No edit summary
(Simplify.)
Tag: rollback
(30 intermediate revisions by 19 users not shown)
Line 3: Line 3:
 
|previous=330
 
|previous=330
 
|next=332
 
|next=332
|created=September 22, 2002
+
|created=2002
 
|complexity=basic
 
|complexity=basic
 
|author=
 
|author=
Line 12: Line 12:
 
}}
 
}}
 
Options set in your [[vimrc]] will apply to all files that you edit. You can also set:
 
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 <tt>*.py</tt> files). See [[filetype.vim]] and [[VimTip1510|filetypes]] and an [[VimTip1565|example]].
+
*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).
 
*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==
 
==Examples==
Line 20: Line 22:
 
# vim: set expandtab:
 
# vim: set expandtab:
 
</pre>
 
</pre>
  +
The space between the comment opening and <code>vim:</code> 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 <code>modelines</code> variable; see {{help|'modelines'}}. By default, it is set to 5 lines.
In a Python file, the '<tt>#</tt>' starts a comment so the modeline is not interpreted by Python.
 
   
 
The following examples show some alternatives that could be in a C file:
 
The following examples show some alternatives that could be in a C file:
Line 35: Line 38:
 
</pre>
 
</pre>
   
With "<tt>set</tt>", the modeline ends at the first colon not following a backslash. Without "<tt>set</tt>", no text can follow the options, so for example, the following is invalid:
+
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:
 
<pre>
 
<pre>
 
Error E518: Unknown option: */
 
Error E518: Unknown option: */
Line 42: Line 45:
   
 
==Adding a modeline==
 
==Adding a modeline==
With the following in your [[vimrc]] and the default leader key, you could type <tt>\ml</tt> to add a modeline based on your current settings:
+
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>
 
<pre>
 
" Append modeline after last line in buffer.
 
" Append modeline after last line in buffer.
" Use substitute() (not printf()) to handle '%%s' modeline in LaTeX files.
+
" Use substitute() instead of printf() to handle '%%s' modeline in LaTeX
  +
" files.
 
function! AppendModeline()
 
function! AppendModeline()
  +
let l:modeline = printf(" vim: set ts=%d sw=%d tw=%d %set :",
let save_cursor = getpos('.')
 
let append = ' vim: set ts='.&tabstop.' sw='.&shiftwidth.' tw='.&textwidth.': '
+
\ &tabstop, &shiftwidth, &textwidth, &expandtab ? '' : 'no')
$put =substitute(&commentstring, '%s', append, '')
+
let l:modeline = substitute(&commentstring, "%s", l:modeline, "")
call setpos('.', save_cursor)
+
call append(line("$"), l:modeline)
 
endfunction
 
endfunction
 
nnoremap <silent> <Leader>ml :call AppendModeline()<CR>
 
nnoremap <silent> <Leader>ml :call AppendModeline()<CR>
Line 57: Line 61:
 
In a C file, you would get a modeline like this:
 
In a C file, you would get a modeline like this:
 
<pre>
 
<pre>
/* vim: set ts=8 sw=4 tw=0: */
+
/* vim: set ts=8 sw=4 tw=0 noet : */
 
</pre>
 
</pre>
   
Line 69: Line 73:
 
vim:ff=unix ts=4 ss=4
 
vim:ff=unix ts=4 ss=4
 
vim60:fdm=marker
 
vim60:fdm=marker
  +
</pre>
  +
  +
==Enabling modelines==
  +
Vim executes a modeline only if all of the following apply:
  +
*'modeline' is set to "modeline" (not "nomodeline")
  +
*'modelines' is set to a positive integer (not "0")
  +
*You are not root.
  +
  +
Enter the following to see the current settings and, if not the default, where they were last set.
  +
<pre>
  +
:verbose set modeline? modelines?
  +
</pre>
  +
  +
Debian, Ubuntu, Gentoo, OSX, etc. by default disable modelines for security reasons. To enable modelines, edit your vimrc file (for example, in Vim enter <code>:e $MYVIMRC</code>) and check you have lines like the following.
  +
<pre>
  +
set modeline
  +
set modelines=5
 
</pre>
 
</pre>
   
Line 86: Line 107:
 
This mechanism can be extended to 'let' &ndash; see {{script|id=83}}.
 
This mechanism can be extended to 'let' &ndash; see {{script|id=83}}.
   
See {{script|id=1876}}
+
See {{script|id=1876}} - securemodelines
  +
----
   
  +
How is it that the modeline:
  +
<code>vim: noai:ts=4:sw=4</code>
  +
is used as an example of correct modeline usage and then used as an error example (when describing use of 'set') right afterwards?
  +
:Because, if you are using the <code>set:</code> syntax, then the modeline ends on the first <code>:</code> character it finds. Thus, you can include the modeline in <code>/* ... */</code> style comments. When you are *not* using the <code>set:</code> syntax, then the modeline always continues to the end of the line. Any text at all in the line will be considered part of the modeline. Therefore you cannot use <code>/* ... */</code> style comments, you must use <code>//</code> style comments. --[[User:Fritzophrenic|Fritzophrenic]] ([[User talk:Fritzophrenic|talk]]) 18:11, February 5, 2015 (UTC)
 
----
 
----

Revision as of 00:38, 9 February 2015

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

Vim executes a modeline only if all of the following apply:

  • 'modeline' is set to "modeline" (not "nomodeline")
  • 'modelines' is set to a positive integer (not "0")
  • You are not root.

Enter the following to see the current settings and, if not the default, where they were last set.

:verbose set modeline? modelines?

Debian, Ubuntu, Gentoo, OSX, etc. by default disable modelines for security reasons. To enable modelines, edit your vimrc file (for example, in Vim enter :e $MYVIMRC) and check you have lines like the following.

set modeline
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 is it that the modeline: vim: noai:ts=4:sw=4 is used as an example of correct modeline usage and then used as an error example (when describing use of 'set') right afterwards?

Because, if you are using the set: syntax, then the modeline ends on the first : character it finds. Thus, you can include the modeline in /* ... */ style comments. When you are *not* using the set: syntax, then the modeline always continues to the end of the line. Any text at all in the line will be considered part of the modeline. Therefore you cannot use /* ... */ style comments, you must use // style comments. --Fritzophrenic (talk) 18:11, February 5, 2015 (UTC)