1620
|
1 " Vim filetype plugin file (GUI menu, folding and completion)
|
7
|
2 " Language: Debian Changelog
|
1620
|
3 " Maintainer: Debian Vim Maintainers <pkg-vim-maintainers@lists.alioth.debian.org>
|
|
4 " Former Maintainers: Michael Piefel <piefel@informatik.hu-berlin.de>
|
|
5 " Stefano Zacchiroli <zack@debian.org>
|
|
6 " Last Change: 2008-03-08
|
848
|
7 " License: GNU GPL, version 2.0 or later
|
1620
|
8 " URL: http://git.debian.org/?p=pkg-vim/vim.git;a=blob_plain;f=runtime/ftplugin/debchangelog.vim;hb=debian
|
848
|
9
|
|
10 if exists("b:did_ftplugin")
|
|
11 finish
|
|
12 endif
|
1121
|
13 let b:did_ftplugin=1
|
848
|
14
|
|
15 " {{{1 Local settings (do on every load)
|
1620
|
16 if exists("g:debchangelog_fold_enable")
|
|
17 setlocal foldmethod=expr
|
|
18 setlocal foldexpr=DebGetChangelogFold(v:lnum)
|
|
19 setlocal foldtext=DebChangelogFoldText()
|
|
20 endif
|
848
|
21
|
|
22 " Debian changelogs are not supposed to have any other text width,
|
|
23 " so the user cannot override this setting
|
|
24 setlocal tw=78
|
|
25 setlocal comments=f:*
|
|
26
|
|
27 " Clean unloading
|
|
28 let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
|
|
29 " }}}1
|
7
|
30
|
|
31 if exists("g:did_changelog_ftplugin")
|
|
32 finish
|
|
33 endif
|
|
34
|
|
35 " Don't load another plugin (this is global)
|
|
36 let g:did_changelog_ftplugin = 1
|
|
37
|
844
|
38 " {{{1 GUI menu
|
|
39
|
7
|
40 " Helper functions returning various data.
|
|
41 " Returns full name, either from $DEBFULLNAME or debianfullname.
|
|
42 " TODO Is there a way to determine name from anywhere else?
|
|
43 function <SID>FullName()
|
|
44 if exists("$DEBFULLNAME")
|
|
45 return $DEBFULLNAME
|
|
46 elseif exists("g:debianfullname")
|
|
47 return g:debianfullname
|
|
48 else
|
|
49 return "Your Name"
|
|
50 endif
|
|
51 endfunction
|
|
52
|
|
53 " Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
|
|
54 function <SID>Email()
|
|
55 if exists("$DEBEMAIL")
|
|
56 return $DEBEMAIL
|
|
57 elseif exists("$EMAIL")
|
|
58 return $EMAIL
|
|
59 elseif exists("g:debianemail")
|
481
|
60 return g:debianemail
|
7
|
61 else
|
|
62 return "your@email.address"
|
|
63 endif
|
|
64 endfunction
|
|
65
|
|
66 " Returns date in RFC822 format.
|
|
67 function <SID>Date()
|
|
68 let savelang = v:lc_time
|
|
69 execute "language time C"
|
|
70 let dateandtime = strftime("%a, %d %b %Y %X %z")
|
|
71 execute "language time " . savelang
|
|
72 return dateandtime
|
|
73 endfunction
|
|
74
|
|
75 function <SID>WarnIfNotUnfinalised()
|
|
76 if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
|
|
77 echohl WarningMsg
|
|
78 echo "The entry has not been unfinalised before editing."
|
|
79 echohl None
|
|
80 return 1
|
|
81 endif
|
|
82 return 0
|
|
83 endfunction
|
|
84
|
|
85 function <SID>Finalised()
|
|
86 let savelinenum = line(".")
|
|
87 normal 1G
|
|
88 call search("^ -- ")
|
|
89 if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
|
|
90 let returnvalue = 1
|
|
91 else
|
|
92 let returnvalue = 0
|
|
93 endif
|
|
94 execute savelinenum
|
|
95 return returnvalue
|
|
96 endfunction
|
|
97
|
|
98 " These functions implement the menus
|
|
99 function NewVersion()
|
|
100 " The new entry is unfinalised and shall be changed
|
|
101 amenu disable Changelog.New\ Version
|
|
102 amenu enable Changelog.Add\ Entry
|
|
103 amenu enable Changelog.Close\ Bug
|
|
104 amenu enable Changelog.Set\ Distribution
|
|
105 amenu enable Changelog.Set\ Urgency
|
|
106 amenu disable Changelog.Unfinalise
|
|
107 amenu enable Changelog.Finalise
|
848
|
108 call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
|
7
|
109 call append(1, "")
|
|
110 call append(2, "")
|
|
111 call append(3, " -- ")
|
|
112 call append(4, "")
|
|
113 call Urgency("low")
|
1620
|
114 normal 1G0
|
7
|
115 call search(")")
|
|
116 normal h
|
|
117 normal
|
848
|
118 call setline(1, substitute(getline(1), '-\$\$', '-', ''))
|
|
119 normal zo
|
7
|
120 call AddEntry()
|
|
121 endfunction
|
|
122
|
|
123 function AddEntry()
|
|
124 normal 1G
|
|
125 call search("^ -- ")
|
|
126 normal kk
|
|
127 call append(".", " * ")
|
|
128 normal jjj
|
|
129 let warn=<SID>WarnIfNotUnfinalised()
|
|
130 normal kk
|
|
131 if warn
|
|
132 echohl MoreMsg
|
|
133 call input("Hit ENTER")
|
|
134 echohl None
|
|
135 endif
|
|
136 startinsert!
|
|
137 endfunction
|
|
138
|
|
139 function CloseBug()
|
|
140 normal 1G
|
|
141 call search("^ -- ")
|
|
142 let warn=<SID>WarnIfNotUnfinalised()
|
|
143 normal kk
|
|
144 call append(".", " * (closes: #" . input("Bug number to close: ") . ")")
|
|
145 normal j^ll
|
|
146 startinsert
|
|
147 endfunction
|
|
148
|
|
149 function Distribution(dist)
|
|
150 call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
|
|
151 endfunction
|
|
152
|
|
153 function Urgency(urg)
|
|
154 call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
|
|
155 endfunction
|
|
156
|
|
157 function <SID>UnfinaliseMenu()
|
|
158 " This means the entry shall be changed
|
|
159 amenu disable Changelog.New\ Version
|
|
160 amenu enable Changelog.Add\ Entry
|
|
161 amenu enable Changelog.Close\ Bug
|
|
162 amenu enable Changelog.Set\ Distribution
|
|
163 amenu enable Changelog.Set\ Urgency
|
|
164 amenu disable Changelog.Unfinalise
|
|
165 amenu enable Changelog.Finalise
|
|
166 endfunction
|
|
167
|
|
168 function Unfinalise()
|
|
169 call <SID>UnfinaliseMenu()
|
|
170 normal 1G
|
|
171 call search("^ -- ")
|
|
172 call setline(".", " -- ")
|
|
173 endfunction
|
|
174
|
|
175 function <SID>FinaliseMenu()
|
|
176 " This means the entry should not be changed anymore
|
|
177 amenu enable Changelog.New\ Version
|
|
178 amenu disable Changelog.Add\ Entry
|
|
179 amenu disable Changelog.Close\ Bug
|
|
180 amenu disable Changelog.Set\ Distribution
|
|
181 amenu disable Changelog.Set\ Urgency
|
|
182 amenu enable Changelog.Unfinalise
|
|
183 amenu disable Changelog.Finalise
|
|
184 endfunction
|
|
185
|
|
186 function Finalise()
|
|
187 call <SID>FinaliseMenu()
|
|
188 normal 1G
|
|
189 call search("^ -- ")
|
|
190 call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . "> " . <SID>Date())
|
|
191 endfunction
|
|
192
|
|
193
|
|
194 function <SID>MakeMenu()
|
|
195 amenu &Changelog.&New\ Version :call NewVersion()<CR>
|
|
196 amenu Changelog.&Add\ Entry :call AddEntry()<CR>
|
|
197 amenu Changelog.&Close\ Bug :call CloseBug()<CR>
|
|
198 menu Changelog.-sep- <nul>
|
|
199
|
|
200 amenu Changelog.Set\ &Distribution.&unstable :call Distribution("unstable")<CR>
|
|
201 amenu Changelog.Set\ Distribution.&frozen :call Distribution("frozen")<CR>
|
|
202 amenu Changelog.Set\ Distribution.&stable :call Distribution("stable")<CR>
|
|
203 menu Changelog.Set\ Distribution.-sep- <nul>
|
|
204 amenu Changelog.Set\ Distribution.frozen\ unstable :call Distribution("frozen unstable")<CR>
|
|
205 amenu Changelog.Set\ Distribution.stable\ unstable :call Distribution("stable unstable")<CR>
|
|
206 amenu Changelog.Set\ Distribution.stable\ frozen :call Distribution("stable frozen")<CR>
|
|
207 amenu Changelog.Set\ Distribution.stable\ frozen\ unstable :call Distribution("stable frozen unstable")<CR>
|
|
208
|
|
209 amenu Changelog.Set\ &Urgency.&low :call Urgency("low")<CR>
|
|
210 amenu Changelog.Set\ Urgency.&medium :call Urgency("medium")<CR>
|
|
211 amenu Changelog.Set\ Urgency.&high :call Urgency("high")<CR>
|
|
212
|
|
213 menu Changelog.-sep- <nul>
|
|
214 amenu Changelog.U&nfinalise :call Unfinalise()<CR>
|
|
215 amenu Changelog.&Finalise :call Finalise()<CR>
|
|
216
|
|
217 if <SID>Finalised()
|
|
218 call <SID>FinaliseMenu()
|
|
219 else
|
|
220 call <SID>UnfinaliseMenu()
|
|
221 endif
|
|
222 endfunction
|
|
223
|
|
224 augroup changelogMenu
|
|
225 au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
|
|
226 au BufLeave * if &filetype == "debchangelog" | aunmenu Changelog | endif
|
|
227 augroup END
|
|
228
|
844
|
229 " }}}
|
|
230 " {{{1 folding
|
|
231
|
1121
|
232 " look for an author name in the [zonestart zoneend] lines searching backward
|
|
233 function! s:getAuthor(zonestart, zoneend)
|
|
234 let linepos = a:zoneend
|
|
235 while linepos >= a:zonestart
|
|
236 let line = getline(linepos)
|
|
237 if line =~ '^ --'
|
|
238 return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '')
|
|
239 endif
|
|
240 let linepos -= 1
|
844
|
241 endwhile
|
1121
|
242 return '[unknown]'
|
844
|
243 endfunction
|
|
244
|
1620
|
245 " Look for a package source name searching backward from the givenline and
|
|
246 " returns it. Return the empty string if the package name can't be found
|
|
247 function! DebGetPkgSrcName(lineno)
|
|
248 let lineidx = a:lineno
|
|
249 let pkgname = ''
|
|
250 while lineidx > 0
|
|
251 let curline = getline(lineidx)
|
|
252 if curline =~ '^\S'
|
|
253 let pkgname = matchlist(curline, '^\(\S\+\).*$')[1]
|
|
254 break
|
|
255 endif
|
|
256 let lineidx = lineidx - 1
|
|
257 endwhile
|
|
258 return pkgname
|
|
259 endfunction
|
|
260
|
844
|
261 function! DebChangelogFoldText()
|
|
262 if v:folddashes == '-' " changelog entry fold
|
1121
|
263 return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
|
844
|
264 endif
|
|
265 return foldtext()
|
|
266 endfunction
|
|
267
|
1620
|
268 function! DebGetChangelogFold(lnum)
|
844
|
269 let line = getline(a:lnum)
|
|
270 if line =~ '^\w\+'
|
|
271 return '>1' " beginning of a changelog entry
|
|
272 endif
|
|
273 if line =~ '^\s\+\[.*\]'
|
|
274 return '>2' " beginning of an author-specific chunk
|
|
275 endif
|
|
276 if line =~ '^ --'
|
|
277 return '1'
|
|
278 endif
|
|
279 return '='
|
|
280 endfunction
|
|
281
|
1620
|
282 silent! foldopen! " unfold the entry the cursor is on (usually the first one)
|
|
283
|
|
284 " }}}
|
|
285
|
|
286 " {{{1 omnicompletion for Closes: #
|
|
287
|
|
288 if !exists('g:debchangelog_listbugs_severities')
|
|
289 let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist'
|
|
290 endif
|
|
291
|
|
292 fun! DebCompleteBugs(findstart, base)
|
|
293 if a:findstart
|
|
294 " it we are just after an '#', the completion should start at the '#',
|
|
295 " otherwise no completion is possible
|
|
296 let line = getline('.')
|
|
297 let colidx = col('.')
|
|
298 if colidx > 1 && line[colidx - 2] =~ '#'
|
|
299 let colidx = colidx - 2
|
|
300 else
|
|
301 let colidx = -1
|
|
302 endif
|
|
303 return colidx
|
|
304 else
|
|
305 if ! filereadable('/usr/sbin/apt-listbugs')
|
|
306 echoerr 'apt-listbugs not found, you should install it to use Closes bug completion'
|
|
307 return
|
|
308 endif
|
|
309 let pkgsrc = DebGetPkgSrcName(line('.'))
|
|
310 let listbugs_output = system('apt-listbugs -s ' . g:debchangelog_listbugs_severities . ' list ' . pkgsrc . ' | grep "^ #" 2> /dev/null')
|
|
311 let bug_lines = split(listbugs_output, '\n')
|
|
312 let completions = []
|
|
313 for line in bug_lines
|
|
314 let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
|
|
315 let completion = {}
|
|
316 let completion['word'] = parts[1]
|
|
317 let completion['menu'] = parts[2]
|
|
318 let completion['info'] = parts[0]
|
|
319 let completions += [completion]
|
|
320 endfor
|
|
321 return completions
|
|
322 endif
|
|
323 endfun
|
|
324
|
|
325 setlocal omnifunc=DebCompleteBugs
|
1121
|
326
|
844
|
327 " }}}
|
|
328
|
|
329 " vim: set foldmethod=marker:
|