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