]> git.sev.monster Git - dotfiles.git/blob - base/.vim/plugin/modeliner.vim
rename git aliases, simplify push-all
[dotfiles.git] / base / .vim / plugin / modeliner.vim
1 " Modeliner
2 "
3 " Version: 0.3.0
4 " Description:
5 "
6 "   Generates a modeline from current settings. 
7 "
8 " Last Change: 27-Jun-2008.
9 " Maintainer: Shuhei Kubota <chimachima@gmail.com>
10 "
11 " Usage:
12 "   execute ':Modeliner'.
13 "   Then a modeline is generated.
14 "
15 "   The modeline will either be appended next to the current line or replace
16 "   the existing one.
17 "
18 "   If you want to customize option, modify g:Modeliner_format.
19
20 if !exists('g:Modeliner_format')
21     let g:Modeliner_format = 'et ff= fenc= sts= sw= ts='
22     " /[ ,:]/ delimited.
23     "
24     " if the type of a option is NOT 'boolean' (see :help 'option-name'),
25     " append '=' to the end of each option.
26 endif
27
28
29 "[text] vi: tw=80 noai
30 "[text] vim:tw=80 noai
31 " ex:tw=80 : noai:
32 "
33 "[text] vim: set tw=80 noai:[text]
34 "[text] vim: se tw=80 noai:[text]
35 "[text] vim:set tw=80 noai:[text]
36 " vim: set tw=80 noai: [text]
37 " vim:se tw=80 noai:
38
39
40 command! Modeliner  call <SID>Modeliner_execute()
41
42
43 " to retrieve the position
44 let s:Modeline_SEARCH_PATTERN = '\svi:\|vim:\|ex:'
45 " to extract options from existing modeline
46 let s:Modeline_EXTRACT_PATTERN = '\v(.*)\s+(vi|vim|ex):\s*(set?\s+)?(.+)' " very magic
47 " first form
48 "let s:Modeline_EXTRACT_OPTPATTERN1 = '\v(.+)' " very magic
49 " second form
50 let s:Modeline_EXTRACT_OPTPATTERN2 = '\v(.+):(.*)' " very magic
51
52
53 function! s:Modeliner_execute()
54     let options = []
55
56     " find existing modeline, and determine the insert position
57     let info = s:SearchExistingModeline()
58
59     " parse g:Modeliner_format and join options with them
60     let extractedOptStr = g:Modeliner_format . ' ' . info.optStr
61     let extractedOptStr = substitute(extractedOptStr, '[ ,:]\+', ' ', 'g')
62     let extractedOptStr = substitute(extractedOptStr, '=\S*', '=', 'g')
63     let extractedOptStr = substitute(extractedOptStr, 'no\(.\+\)', '\1', 'g')
64     let opts = sort(split(extractedOptStr))
65     "echom 'opt(list): ' . join(opts, ', ')
66
67     let optStr = ''
68     let prevO = ''
69     for o in opts
70         if o == prevO | continue | endif
71         let prevO = o
72
73         if stridx(o, '=') != -1
74             " let optExpr = 'ts=' . &ts
75             execute 'let optExpr = "' . o . '" . &' . strpart(o, 0, strlen(o) - 1)
76         else
77             " let optExpr = (&et ? '' : 'no') . 'et'
78             execute 'let optExpr = (&' . o . '? "" : "no") . "' . o . '"'
79         endif
80
81         let optStr = optStr . ' ' . optExpr
82     endfor
83
84     if info.lineNum == 0
85         let modeline = s:Commentify(optStr)
86     else
87         let modeline = info.firstText . ' vim: set' . optStr . ' :' . info.lastText
88     endif
89
90
91     " insert new modeline 
92     if info.lineNum != 0
93         "modeline FOUND -> replace the modeline
94
95         "show the existing modeline
96         let orgLine = line('.')
97         let orgCol  = col('.')
98         call cursor(info.lineNum, 1)
99         normal V
100         redraw
101
102         "confirm
103         "if confirm('Are you sure to overwrite this existing modeline?', "&Yes\n&No", 1) == 1
104         echo 'Are you sure to overwrite this existing modeline? [y/N]'
105         if char2nr(tolower(nr2char(getchar()))) == char2nr('y')
106             call setline(info.lineNum, modeline)
107
108             "show the modeline being changed
109             if (info.lineNum != line('.')) && (info.lineNum != line('.') + 1)
110                 redraw
111                 sleep 1
112             endif
113         endif
114
115         "back to the previous position
116         echo
117         execute "normal \<ESC>"
118         call cursor(orgLine, orgCol)
119     else
120         "modeline NOT found -> append new modeline
121         call append('.', modeline)
122     endif
123
124 endfunction
125
126
127 function! s:Commentify(s)
128     if exists('g:NERDMapleader') " NERDCommenter
129         let result = b:left . ' vim: set' . a:s . ' : ' . b:right
130     else
131         let result = substitute(&commentstring, '%s', ' vim: set' . a:s . ' : ', '')
132     endif
133
134     return result
135 endfunction
136
137
138 function! s:SearchExistingModeline()
139     let info = {'lineNum':0, 'text':'', 'firstText':'', 'lastText':'', 'optStr':''}
140
141     let candidates = []
142
143     " cursor position?
144     call add(candidates, line('.'))
145     " user may position the cursor to previous line...
146     call add(candidates, line('.') + 1)
147     let cnt = 0
148     while cnt < &modelines
149     " header?
150         call add(candidates, cnt + 1)
151     " footer?
152         call add(candidates, line('$') - cnt)
153         let cnt = cnt + 1
154     endwhile
155
156     " search
157     for i in candidates
158         let lineNum = i
159         let text = getline(lineNum)
160
161         if match(text, s:Modeline_SEARCH_PATTERN) != -1
162             let info.lineNum = lineNum
163             let info.text = text
164             break
165         endif
166     endfor
167
168     " extract texts
169     if info.lineNum != 0
170         "echom 'modeline: ' info.lineNum . ' ' . info.text
171
172         let info.firstText = substitute(info.text, s:Modeline_EXTRACT_PATTERN, '\1', '')
173
174         let isSecondForm = (strlen(substitute(info.text, s:Modeline_EXTRACT_PATTERN, '\3', '')) != 0)
175         "echom 'form : ' . string(isSecondForm + 1)
176         if isSecondForm == 0
177             let info.lastText = ''
178             let info.optStr = substitute(info.text, s:Modeline_EXTRACT_PATTERN, '\4', '')
179         else
180             let info.lastText = substitute(
181                             \ substitute(info.text, s:Modeline_EXTRACT_PATTERN, '\4', ''),
182                             \ s:Modeline_EXTRACT_OPTPATTERN2,
183                             \ '\2',
184                             \ '')
185             let info.optStr = substitute(
186                                 \ substitute(info.text, s:Modeline_EXTRACT_PATTERN, '\4', ''),
187                                 \ s:Modeline_EXTRACT_OPTPATTERN2,
188                                 \ '\1',
189                                 \ '')
190         endif
191     endif
192
193     "echom 'firstText: ' . info.firstText
194     "echom 'lastText: ' . info.lastText
195     "echom 'optStr: ' . info.optStr
196
197     return info
198 endfunction
199
200
201 function! s:ExtractOptionStringFromModeline(text)
202     let info = {}
203
204     let info.firstText = substitute(a:text, s:Modeline_EXTRACT_PATTERN, '\1', '')
205
206     let isSecondForm = (strlen(substitute(a:text, s:Modeline_EXTRACT_PATTERN, '\3', '') != 0)
207     if isSecondForm == 0
208         let info.lastText = ''
209         let info.optStr = substitute(a:text, s:Modeline_EXTRACT_PATTERN, '\2', '')
210     else
211         let info.lastText = substitute(
212                         \ substitute(a:text, s:Modeline_EXTRACT_PATTERN, '\4', ''),
213                         \ s:Modeline_EXTRACT_OPTPATTERN2,
214                         \ '\2',
215                         \ '')
216         let info.optStr = substitute(
217                             \ substitute(a:text, s:Modeline_EXTRACT_PATTERN, '\4', ''),
218                             \ s:Modeline_EXTRACT_OPTPATTERN2,
219                             \ '\1',
220                             \ '')
221     endif
222
223     return info
224 endfunction
225
226 " vim: set et fenc=utf-8 ff=unix sts=4 sw=4 ts=4 : 
This page took 0.05224 seconds and 4 git commands to generate.