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