blob: 80ff8efe425d89274ca625da8fe67b846ad772a5 [file] [log] [blame]
Bram Moolenaar3577c6f2008-06-24 21:16:56 +00001" Vim filetype plugin file (GUI menu, folding and completion)
Bram Moolenaar00a927d2010-05-14 23:24:24 +02002" 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>
Bram Moolenaare06c1882010-07-21 22:05:20 +02006" Last Change: 2010-07-11
Bram Moolenaar00a927d2010-05-14 23:24:24 +02007" License: GNU GPL, version 2.0 or later
Bram Moolenaare06c1882010-07-21 22:05:20 +02008" URL: http://hg.debian.org/hg/pkg-vim/vim/file/unstable/runtime/ftplugin/debchangelog.vim
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +00009
Bram Moolenaarc236c162008-07-13 17:41:49 +000010" Bug completion requires apt-listbugs installed for Debian packages or
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011" python-launchpadlib installed for Ubuntu packages
Bram Moolenaarc236c162008-07-13 17:41:49 +000012
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +000013if exists("b:did_ftplugin")
14 finish
15endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000016let b:did_ftplugin=1
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +000017
18" {{{1 Local settings (do on every load)
Bram Moolenaar3577c6f2008-06-24 21:16:56 +000019if exists("g:debchangelog_fold_enable")
20 setlocal foldmethod=expr
21 setlocal foldexpr=DebGetChangelogFold(v:lnum)
22 setlocal foldtext=DebChangelogFoldText()
23endif
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +000024
25" Debian changelogs are not supposed to have any other text width,
26" so the user cannot override this setting
27setlocal tw=78
28setlocal comments=f:*
29
30" Clean unloading
31let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
32" }}}1
Bram Moolenaar071d4272004-06-13 20:20:40 +000033
34if exists("g:did_changelog_ftplugin")
35 finish
36endif
37
38" Don't load another plugin (this is global)
39let g:did_changelog_ftplugin = 1
40
Bram Moolenaarf193fff2006-04-27 00:02:13 +000041" {{{1 GUI menu
42
Bram Moolenaar071d4272004-06-13 20:20:40 +000043" 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?
46function <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
54endfunction
55
56" Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
57function <SID>Email()
58 if exists("$DEBEMAIL")
59 return $DEBEMAIL
60 elseif exists("$EMAIL")
61 return $EMAIL
62 elseif exists("g:debianemail")
Bram Moolenaarae5bce12005-08-15 21:41:48 +000063 return g:debianemail
Bram Moolenaar071d4272004-06-13 20:20:40 +000064 else
65 return "your@email.address"
66 endif
67endfunction
68
69" Returns date in RFC822 format.
70function <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
76endfunction
77
78function <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
86endfunction
87
88function <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
99endfunction
100
101" These functions implement the menus
102function 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
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +0000111 call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000112 call append(1, "")
113 call append(2, "")
114 call append(3, " -- ")
115 call append(4, "")
Bram Moolenaar071d4272004-06-13 20:20:40 +0000116 call Urgency("low")
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000117 normal 1G0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000118 call search(")")
119 normal h
120 normal 
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +0000121 call setline(1, substitute(getline(1), '-\$\$', '-', ''))
Bram Moolenaarc236c162008-07-13 17:41:49 +0000122 if exists("g:debchangelog_fold_enable")
123 foldopen
124 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000125 call AddEntry()
126endfunction
127
128function 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!
142endfunction
143
144function 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
152endfunction
153
154function Distribution(dist)
155 call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
156endfunction
157
158function Urgency(urg)
159 call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
160endfunction
161
162function <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
171endfunction
172
173function Unfinalise()
174 call <SID>UnfinaliseMenu()
175 normal 1G
176 call search("^ -- ")
177 call setline(".", " -- ")
178endfunction
179
180function <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
189endfunction
190
191function Finalise()
192 call <SID>FinaliseMenu()
193 normal 1G
194 call search("^ -- ")
195 call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . "> " . <SID>Date())
196endfunction
197
198
199function <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
227endfunction
228
229augroup changelogMenu
230au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
Bram Moolenaare06c1882010-07-21 22:05:20 +0200231au BufLeave * if &filetype == "debchangelog" | silent! aunmenu Changelog | endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000232augroup END
233
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000234" }}}
235" {{{1 folding
236
Bram Moolenaar9964e462007-05-05 17:54:07 +0000237" look for an author name in the [zonestart zoneend] lines searching backward
238function! 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
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000246 endwhile
Bram Moolenaar9964e462007-05-05 17:54:07 +0000247 return '[unknown]'
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000248endfunction
249
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000250" 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
252function! 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
264endfunction
265
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000266function! DebChangelogFoldText()
267 if v:folddashes == '-' " changelog entry fold
Bram Moolenaar9964e462007-05-05 17:54:07 +0000268 return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000269 endif
270 return foldtext()
271endfunction
272
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000273function! DebGetChangelogFold(lnum)
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000274 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 '='
285endfunction
286
Bram Moolenaarc236c162008-07-13 17:41:49 +0000287if exists("g:debchangelog_fold_enable")
288 silent! foldopen! " unfold the entry the cursor is on (usually the first one)
289endif
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000290
291" }}}
292
293" {{{1 omnicompletion for Closes: #
294
295if !exists('g:debchangelog_listbugs_severities')
296 let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist'
297endif
298
299fun! DebCompleteBugs(findstart, base)
300 if a:findstart
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000301 let line = getline('.')
Bram Moolenaarc236c162008-07-13 17:41:49 +0000302
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
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000320 return colidx
Bram Moolenaarc236c162008-07-13 17:41:49 +0000321 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
330import vim
331try:
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200332 from launchpadlib.launchpad import Launchpad
333 from lazr.restfulclient.errors import HTTPError
334 # login anonymously
335 lp = Launchpad.login_anonymously('debchangelog.vim', 'production')
336 ubuntu = lp.distributions['ubuntu']
337 try:
338 sp = ubuntu.getSourcePackage(name=vim.eval('pkgsrc'))
339 status = ('New', 'Incomplete', 'Confirmed', 'Triaged',
340 'In Progress', 'Fix Committed')
341 tasklist = sp.searchTasks(status=status, order_by='id')
342 liststr = '['
343 for task in tasklist:
344 bug = task.bug
345 liststr += "'#%d - %s'," % (bug.id, bug.title.replace('\'', '\'\''))
346 liststr += ']'
347 vim.command('silent let bug_lines = %s' % liststr.encode('utf-8'))
348 except HTTPError:
349 pass
Bram Moolenaarc236c162008-07-13 17:41:49 +0000350except ImportError:
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200351 vim.command('echoerr \'python-launchpadlib >= 1.5.4 needs to be installed to use Launchpad bug completion\'')
Bram Moolenaarc236c162008-07-13 17:41:49 +0000352EOF
353 else
354 if ! filereadable('/usr/sbin/apt-listbugs')
355 echoerr 'apt-listbugs not found, you should install it to use Closes bug completion'
356 return
357 endif
358 let pkgsrc = DebGetPkgSrcName(line('.'))
359 let listbugs_output = system('/usr/sbin/apt-listbugs -s ' . g:debchangelog_listbugs_severities . ' list ' . pkgsrc . ' | grep "^ #" 2> /dev/null')
360 let bug_lines = split(listbugs_output, '\n')
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000361 endif
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000362 let completions = []
363 for line in bug_lines
364 let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
Bram Moolenaarc236c162008-07-13 17:41:49 +0000365 " filter only those which match a:base:
366 if parts[1] !~ "^" . a:base
367 continue
368 endif
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000369 let completion = {}
370 let completion['word'] = parts[1]
371 let completion['menu'] = parts[2]
372 let completion['info'] = parts[0]
373 let completions += [completion]
374 endfor
375 return completions
376 endif
377endfun
378
379setlocal omnifunc=DebCompleteBugs
Bram Moolenaar9964e462007-05-05 17:54:07 +0000380
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000381" }}}
382
383" vim: set foldmethod=marker: