vim: update release.sh to vim 7.3
[msysgit/mtrensch.git] / share / vim / vim72 / ftplugin / debchangelog.vim
blob00a025b47c3f2226a6a361c5d317991f61a5043d
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")
14   finish
15 endif
16 let b:did_ftplugin=1
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()
23 endif
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:* 
30 " Clean unloading
31 let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
32 " }}}1
34 if exists("g:did_changelog_ftplugin")
35   finish
36 endif
38 " Don't load another plugin (this is global)
39 let g:did_changelog_ftplugin = 1
41 " {{{1 GUI menu
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
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")
63         return g:debianemail
64     else
65         return "your@email.address"
66     endif
67 endfunction
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
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
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
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)', ''))
112     call append(1, "")
113     call append(2, "")
114     call append(3, " -- ")
115     call append(4, "")
116     call Urgency("low")
117     normal 1G0
118     call search(")")
119     normal h
120     normal \x01
121     call setline(1, substitute(getline(1), '-\$\$', '-', ''))
122     if exists("g:debchangelog_fold_enable")
123         foldopen
124     endif
125     call AddEntry()
126 endfunction
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
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
154 function Distribution(dist)
155     call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
156 endfunction
158 function Urgency(urg)
159     call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
160 endfunction
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
173 function Unfinalise()
174     call <SID>UnfinaliseMenu()
175     normal 1G
176     call search("^ -- ")
177     call setline(".", " -- ")
178 endfunction
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
191 function Finalise()
192     call <SID>FinaliseMenu()
193     normal 1G
194     call search("^ -- ")
195     call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . ">  " . <SID>Date())
196 endfunction
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>
222     if <SID>Finalised()
223         call <SID>FinaliseMenu()
224     else
225         call <SID>UnfinaliseMenu()
226     endif
227 endfunction
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
234 " }}}
235 " {{{1 folding
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
246   endwhile
247   return '[unknown]'
248 endfunction
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
266 function! DebChangelogFoldText()
267   if v:folddashes == '-'  " changelog entry fold
268     return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
269   endif
270   return foldtext()
271 endfunction
273 function! DebGetChangelogFold(lnum)
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
287 if exists("g:debchangelog_fold_enable")
288   silent! foldopen!   " unfold the entry the cursor is on (usually the first one)
289 endif
291 " }}}
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'
297 endif
299 fun! DebCompleteBugs(findstart, base)
300   if a:findstart
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'
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\'')
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')
352     endif
353     let completions = []
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
358         continue
359       endif
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
370 setlocal omnifunc=DebCompleteBugs
372 " }}}
374 " vim: set foldmethod=marker: