1 " Vim filetype plugin file (GUI menu, folding and completion)
2 " Language: Debian Changelog
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
7 " License: GNU GPL, version 2.0 or later
8 " URL: http://git.debian.org/?p=pkg-vim/vim.git;a=blob_plain;f=runtime/ftplugin/debchangelog.vim;hb=debian
10 " Bug completion requires apt-listbugs installed for Debian packages or
11 " python-launchpad-bugs installed for Ubuntu packages
13 if exists("b:did_ftplugin")
18 " {{{1 Local settings (do on every load)
19 if exists("g:debchangelog_fold_enable")
20 setlocal foldmethod=expr
21 setlocal foldexpr=DebGetChangelogFold(v:lnum)
22 setlocal foldtext=DebChangelogFoldText()
25 " Debian changelogs are not supposed to have any other text width,
26 " so the user cannot override this setting
31 let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
34 if exists("g:did_changelog_ftplugin")
38 " Don't load another plugin (this is global)
39 let g:did_changelog_ftplugin = 1
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")
49 elseif exists("g:debianfullname")
50 return g:debianfullname
56 " Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
58 if exists("$DEBEMAIL")
60 elseif exists("$EMAIL")
62 elseif exists("g:debianemail")
65 return "your@email.address"
69 " Returns date in RFC822 format.
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
78 function <SID>WarnIfNotUnfinalised()
79 if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
81 echo "The entry has not been unfinalised before editing."
88 function <SID>Finalised()
89 let savelinenum = line(".")
92 if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
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
111 call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
114 call append(3, " -- ")
121 call setline(1, substitute(getline(1), '-\$\$', '-', ''))
122 if exists("g:debchangelog_fold_enable")
132 call append(".", " * ")
134 let warn=<SID>WarnIfNotUnfinalised()
138 call input("Hit ENTER")
147 let warn=<SID>WarnIfNotUnfinalised()
149 call append(".", " * (closes: #" . input("Bug number to close: ") . ")")
154 function Distribution(dist)
155 call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
158 function Urgency(urg)
159 call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
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
173 function Unfinalise()
174 call <SID>UnfinaliseMenu()
177 call setline(".", " -- ")
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
192 call <SID>FinaliseMenu()
195 call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . "> " . <SID>Date())
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>
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>
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>
218 menu Changelog.-sep- <nul>
219 amenu Changelog.U&nfinalise :call Unfinalise()<CR>
220 amenu Changelog.&Finalise :call Finalise()<CR>
223 call <SID>FinaliseMenu()
225 call <SID>UnfinaliseMenu()
229 augroup changelogMenu
230 au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
231 au BufLeave * if &filetype == "debchangelog" | aunmenu Changelog | endif
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)
243 return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '')
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
256 let curline = getline(lineidx)
258 let pkgname = matchlist(curline, '^\(\S\+\).*$')[1]
261 let lineidx = lineidx - 1
266 function! DebChangelogFoldText()
267 if v:folddashes == '-' " changelog entry fold
268 return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
273 function! DebGetChangelogFold(lnum)
274 let line = getline(a:lnum)
276 return '>1' " beginning of a changelog entry
278 if line =~ '^\s\+\[.*\]'
279 return '>2' " beginning of an author-specific chunk
287 if exists("g:debchangelog_fold_enable")
288 silent! foldopen! " unfold the entry the cursor is on (usually the first one)
293 " {{{1 omnicompletion for Closes: #
295 if !exists('g:debchangelog_listbugs_severities')
296 let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist'
299 fun! DebCompleteBugs(findstart, base)
301 let line = getline('.')
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
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'
321 else " return matches:
323 if g:debchangelog_complete_mode == 'lp'
325 echoerr 'vim must be built with Python support to use LP bug completion'
328 let pkgsrc = DebGetPkgSrcName(line('.'))
332 from launchpadbugs import connector
333 buglist = connector.ConnectBugList()
334 bl = list(buglist('https://bugs.launchpad.net/ubuntu/+source/%s' % vim.eval('pkgsrc')))
338 liststr += "'#%d - %s'," % (int(bug), bug.summary.replace('\'', '\'\''))
340 vim.command('silent let bug_lines = %s' % liststr)
342 vim.command('echoerr \'python-launchpad-bugs needs to be installed to use Launchpad bug completion\'')
345 if ! filereadable('/usr/sbin/apt-listbugs')
346 echoerr 'apt-listbugs not found, you should install it to use Closes bug completion'
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')
354 for line in bug_lines
355 let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
356 " filter only those which match a:base:
357 if parts[1] !~ "^" . a:base
361 let completion['word'] = parts[1]
362 let completion['menu'] = parts[2]
363 let completion['info'] = parts[0]
364 let completions += [completion]
370 setlocal omnifunc=DebCompleteBugs
374 " vim: set foldmethod=marker: