blob: 00a025b47c3f2226a6a361c5d317991f61a5043d [file] [log] [blame]
Bram Moolenaar3577c6f2008-06-24 21:16:56 +00001" Vim filetype plugin file (GUI menu, folding and completion)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002" Language: Debian Changelog
Bram Moolenaar3577c6f2008-06-24 21:16:56 +00003" 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
Bram Moolenaarbd2ac7e2006-04-28 22:34:45 +00007" License: GNU GPL, version 2.0 or later
Bram Moolenaar3577c6f2008-06-24 21:16:56 +00008" URL: http://git.debian.org/?p=pkg-vim/vim.git;a=blob_plain;f=runtime/ftplugin/debchangelog.vim;hb=debian
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
11" python-launchpad-bugs installed for Ubuntu packages
12
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
231au BufLeave * if &filetype == "debchangelog" | aunmenu Changelog | endif
232augroup 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:
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)
341except ImportError:
342 vim.command('echoerr \'python-launchpad-bugs needs to be installed to use Launchpad bug completion\'')
343EOF
344 else
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')
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000352 endif
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000353 let completions = []
354 for line in bug_lines
355 let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
Bram Moolenaarc236c162008-07-13 17:41:49 +0000356 " filter only those which match a:base:
357 if parts[1] !~ "^" . a:base
358 continue
359 endif
Bram Moolenaar3577c6f2008-06-24 21:16:56 +0000360 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
368endfun
369
370setlocal omnifunc=DebCompleteBugs
Bram Moolenaar9964e462007-05-05 17:54:07 +0000371
Bram Moolenaarf193fff2006-04-27 00:02:13 +0000372" }}}
373
374" vim: set foldmethod=marker: