]> ruderich.org/simon Gitweb - config/dotfiles.git/blob - vim/vim/plugin/securemodelines.vim
vcs: gitconfig: sort tags as version numbers
[config/dotfiles.git] / vim / vim / plugin / securemodelines.vim
1 " vim: set sw=4 sts=4 et ft=vim :
2 " Script:           securemodelines.vim
3 " Version:          10d6c6b52fcdd12f3ba457126f66fee4ccceec04
4 " Author:           Ciaran McCreesh <ciaran.mccreesh at googlemail.com>
5 " Homepage:         http://github.com/ciaranm/securemodelines
6 " Requires:         Vim 7
7 " License:          Redistribute under the same terms as Vim itself
8 " Purpose:          A secure alternative to modelines
9
10 if &compatible || v:version < 700 || exists('g:loaded_securemodelines')
11     finish
12 endif
13 let g:loaded_securemodelines = 1
14
15 if (! exists("g:secure_modelines_allowed_items"))
16     let g:secure_modelines_allowed_items = [
17                 \ "textwidth",   "tw",
18                 \ "softtabstop", "sts",
19                 \ "tabstop",     "ts",
20                 \ "shiftwidth",  "sw",
21                 \ "expandtab",   "et",   "noexpandtab", "noet",
22                 \ "filetype",    "ft",
23                 \ "foldmethod",  "fdm",
24                 \ "readonly",    "ro",   "noreadonly", "noro",
25                 \ "rightleft",   "rl",   "norightleft", "norl",
26                 \ "cindent",     "cin",  "nocindent", "nocin",
27                 \ "smartindent", "si",   "nosmartindent", "nosi",
28                 \ "autoindent",  "ai",   "noautoindent", "noai",
29                 \ "spell",
30                 \ "spelllang"
31                 \ ]
32 endif
33
34 if (! exists("g:secure_modelines_verbose"))
35     let g:secure_modelines_verbose = 0
36 endif
37
38 if (! exists("g:secure_modelines_modelines"))
39     let g:secure_modelines_modelines=5
40 endif
41
42 if (! exists("g:secure_modelines_leave_modeline"))
43     if &modeline
44         set nomodeline
45         if g:secure_modelines_verbose
46             echohl WarningMsg
47             echo "Forcibly disabling internal modelines for securemodelines.vim"
48             echohl None
49         endif
50     endif
51 endif
52
53 fun! <SID>IsInList(list, i) abort
54     for l:item in a:list
55         if a:i == l:item
56             return 1
57         endif
58     endfor
59     return 0
60 endfun
61
62 fun! <SID>DoOne(item) abort
63     let l:matches = matchlist(a:item, '^\([a-z]\+\)\%([-+^]\?=[a-zA-Z0-9_\-.]\+\)\?$')
64     if len(l:matches) > 0
65         if <SID>IsInList(g:secure_modelines_allowed_items, l:matches[1])
66             exec "setlocal " . a:item
67         elseif g:secure_modelines_verbose
68             echohl WarningMsg
69             echo "Ignoring '" . a:item . "' in modeline"
70             echohl None
71         endif
72     endif
73 endfun
74
75 fun! <SID>DoNoSetModeline(line) abort
76     for l:item in split(a:line, '[ \t:]')
77         call <SID>DoOne(l:item)
78     endfor
79 endfun
80
81 fun! <SID>DoSetModeline(line) abort
82     for l:item in split(a:line)
83         call <SID>DoOne(l:item)
84     endfor
85 endfun
86
87 fun! <SID>CheckVersion(op, ver) abort
88     if a:op == "="
89         return v:version != a:ver
90     elseif a:op == "<"
91         return v:version < a:ver
92     elseif a:op == ">"
93         return v:version >= a:ver
94     else
95         return 0
96     endif
97 endfun
98
99 fun! <SID>DoModeline(line) abort
100     let l:matches = matchlist(a:line, '\%(\S\@<!\%(vi\|vim\([<>=]\?\)\([0-9]\+\)\?\)\|\sex\):\s*\%(set\s\+\)\?\([^:]\+\):\S\@!')
101     if len(l:matches) > 0
102         let l:operator = ">"
103         if len(l:matches[1]) > 0
104             let l:operator = l:matches[1]
105         endif
106         if len(l:matches[2]) > 0
107             if <SID>CheckVersion(l:operator, l:matches[2]) ? 0 : 1
108                 return
109             endif
110         endif
111         return <SID>DoSetModeline(l:matches[3])
112     endif
113
114     let l:matches = matchlist(a:line, '\%(\S\@<!\%(vi\|vim\([<>=]\?\)\([0-9]\+\)\?\)\|\sex\):\(.\+\)')
115     if len(l:matches) > 0
116         let l:operator = ">"
117         if len(l:matches[1]) > 0
118             let l:operator = l:matches[1]
119         endif
120         if len(l:matches[2]) > 0
121             if <SID>CheckVersion(l:operator, l:matches[2]) ? 0 : 1
122                 return
123             endif
124         endif
125         return <SID>DoNoSetModeline(l:matches[3])
126     endif
127 endfun
128
129 fun! <SID>DoModelines() abort
130     if line("$") > g:secure_modelines_modelines
131         let l:lines={ }
132         call map(filter(getline(1, g:secure_modelines_modelines) +
133                     \ getline(line("$") - g:secure_modelines_modelines, "$"),
134                     \ 'v:val =~ ":"'), 'extend(l:lines, { v:val : 0 } )')
135         for l:line in keys(l:lines)
136             call <SID>DoModeline(l:line)
137         endfor
138     else
139         for l:line in getline(1, "$")
140             call <SID>DoModeline(l:line)
141         endfor
142     endif
143 endfun
144
145 fun! SecureModelines_DoModelines() abort
146     call <SID>DoModelines()
147 endfun
148
149 aug SecureModeLines
150     au!
151     au BufRead,StdinReadPost * :call <SID>DoModelines()
152 aug END
153