Update runtime files
[MacVim.git] / runtime / ftplugin / debchangelog.vim
blobcd5b07162ef4a0815a501dba22524f317db913e8
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 if exists("b:did_ftplugin")
11   finish
12 endif
13 let b:did_ftplugin=1
15 " {{{1 Local settings (do on every load)
16 if exists("g:debchangelog_fold_enable")
17   setlocal foldmethod=expr
18   setlocal foldexpr=DebGetChangelogFold(v:lnum)
19   setlocal foldtext=DebChangelogFoldText()
20 endif
22 " Debian changelogs are not supposed to have any other text width,
23 " so the user cannot override this setting
24 setlocal tw=78
25 setlocal comments=f:* 
27 " Clean unloading
28 let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
29 " }}}1
31 if exists("g:did_changelog_ftplugin")
32   finish
33 endif
35 " Don't load another plugin (this is global)
36 let g:did_changelog_ftplugin = 1
38 " {{{1 GUI menu
40 " Helper functions returning various data.
41 " Returns full name, either from $DEBFULLNAME or debianfullname.
42 " TODO Is there a way to determine name from anywhere else?
43 function <SID>FullName()
44     if exists("$DEBFULLNAME")
45         return $DEBFULLNAME
46     elseif exists("g:debianfullname")
47         return g:debianfullname
48     else
49         return "Your Name"
50     endif
51 endfunction
53 " Returns email address, from $DEBEMAIL, $EMAIL or debianemail.
54 function <SID>Email()
55     if exists("$DEBEMAIL")
56         return $DEBEMAIL
57     elseif exists("$EMAIL")
58         return $EMAIL
59     elseif exists("g:debianemail")
60         return g:debianemail
61     else
62         return "your@email.address"
63     endif
64 endfunction
66 " Returns date in RFC822 format.
67 function <SID>Date()
68     let savelang = v:lc_time
69     execute "language time C"
70     let dateandtime = strftime("%a, %d %b %Y %X %z")
71     execute "language time " . savelang
72     return dateandtime
73 endfunction
75 function <SID>WarnIfNotUnfinalised()
76     if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
77         echohl WarningMsg
78         echo "The entry has not been unfinalised before editing."
79         echohl None
80         return 1
81     endif
82     return 0
83 endfunction
85 function <SID>Finalised()
86     let savelinenum = line(".")
87     normal 1G
88     call search("^ -- ")
89     if match(getline("."), " -- [[:alpha:]][[:alnum:].]")!=-1
90         let returnvalue = 1
91     else
92         let returnvalue = 0
93     endif
94     execute savelinenum
95     return returnvalue
96 endfunction
98 " These functions implement the menus
99 function NewVersion()
100     " The new entry is unfinalised and shall be changed
101     amenu disable Changelog.New\ Version
102     amenu enable Changelog.Add\ Entry
103     amenu enable Changelog.Close\ Bug
104     amenu enable Changelog.Set\ Distribution
105     amenu enable Changelog.Set\ Urgency
106     amenu disable Changelog.Unfinalise
107     amenu enable Changelog.Finalise
108     call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', ''))
109     call append(1, "")
110     call append(2, "")
111     call append(3, " -- ")
112     call append(4, "")
113     call Urgency("low")
114     normal 1G0
115     call search(")")
116     normal h
117     normal \x01
118     call setline(1, substitute(getline(1), '-\$\$', '-', ''))
119     normal zo
120     call AddEntry()
121 endfunction
123 function AddEntry()
124     normal 1G
125     call search("^ -- ")
126     normal kk
127     call append(".", "  * ")
128     normal jjj
129     let warn=<SID>WarnIfNotUnfinalised()
130     normal kk
131     if warn
132         echohl MoreMsg
133         call input("Hit ENTER")
134         echohl None
135     endif
136     startinsert!
137 endfunction
139 function CloseBug()
140     normal 1G
141     call search("^ -- ")
142     let warn=<SID>WarnIfNotUnfinalised()
143     normal kk
144     call append(".", "  *  (closes: #" . input("Bug number to close: ") . ")")
145     normal j^ll
146     startinsert
147 endfunction
149 function Distribution(dist)
150     call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
151 endfunction
153 function Urgency(urg)
154     call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
155 endfunction
157 function <SID>UnfinaliseMenu()
158     " This means the entry shall be changed
159     amenu disable Changelog.New\ Version
160     amenu enable Changelog.Add\ Entry
161     amenu enable Changelog.Close\ Bug
162     amenu enable Changelog.Set\ Distribution
163     amenu enable Changelog.Set\ Urgency
164     amenu disable Changelog.Unfinalise
165     amenu enable Changelog.Finalise
166 endfunction
168 function Unfinalise()
169     call <SID>UnfinaliseMenu()
170     normal 1G
171     call search("^ -- ")
172     call setline(".", " -- ")
173 endfunction
175 function <SID>FinaliseMenu()
176     " This means the entry should not be changed anymore
177     amenu enable Changelog.New\ Version
178     amenu disable Changelog.Add\ Entry
179     amenu disable Changelog.Close\ Bug
180     amenu disable Changelog.Set\ Distribution
181     amenu disable Changelog.Set\ Urgency
182     amenu enable Changelog.Unfinalise
183     amenu disable Changelog.Finalise
184 endfunction
186 function Finalise()
187     call <SID>FinaliseMenu()
188     normal 1G
189     call search("^ -- ")
190     call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . ">  " . <SID>Date())
191 endfunction
194 function <SID>MakeMenu()
195     amenu &Changelog.&New\ Version                      :call NewVersion()<CR>
196     amenu Changelog.&Add\ Entry                         :call AddEntry()<CR>
197     amenu Changelog.&Close\ Bug                         :call CloseBug()<CR>
198     menu Changelog.-sep-                                <nul>
200     amenu Changelog.Set\ &Distribution.&unstable        :call Distribution("unstable")<CR>
201     amenu Changelog.Set\ Distribution.&frozen           :call Distribution("frozen")<CR>
202     amenu Changelog.Set\ Distribution.&stable           :call Distribution("stable")<CR>
203     menu Changelog.Set\ Distribution.-sep-              <nul>
204     amenu Changelog.Set\ Distribution.frozen\ unstable  :call Distribution("frozen unstable")<CR>
205     amenu Changelog.Set\ Distribution.stable\ unstable  :call Distribution("stable unstable")<CR>
206     amenu Changelog.Set\ Distribution.stable\ frozen    :call Distribution("stable frozen")<CR>
207     amenu Changelog.Set\ Distribution.stable\ frozen\ unstable  :call Distribution("stable frozen unstable")<CR>
209     amenu Changelog.Set\ &Urgency.&low                  :call Urgency("low")<CR>
210     amenu Changelog.Set\ Urgency.&medium                :call Urgency("medium")<CR>
211     amenu Changelog.Set\ Urgency.&high                  :call Urgency("high")<CR>
213     menu Changelog.-sep-                                <nul>
214     amenu Changelog.U&nfinalise                         :call Unfinalise()<CR>
215     amenu Changelog.&Finalise                           :call Finalise()<CR>
217     if <SID>Finalised()
218         call <SID>FinaliseMenu()
219     else
220         call <SID>UnfinaliseMenu()
221     endif
222 endfunction
224 augroup changelogMenu
225 au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
226 au BufLeave * if &filetype == "debchangelog" | aunmenu Changelog | endif
227 augroup END
229 " }}}
230 " {{{1 folding
232 " look for an author name in the [zonestart zoneend] lines searching backward
233 function! s:getAuthor(zonestart, zoneend)
234   let linepos = a:zoneend
235   while linepos >= a:zonestart
236     let line = getline(linepos)
237     if line =~ '^ --'
238       return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '')
239     endif
240     let linepos -= 1
241   endwhile
242   return '[unknown]'
243 endfunction
245 " Look for a package source name searching backward from the givenline and
246 " returns it. Return the empty string if the package name can't be found
247 function! DebGetPkgSrcName(lineno)
248   let lineidx = a:lineno
249   let pkgname = ''
250   while lineidx > 0
251     let curline = getline(lineidx)
252     if curline =~ '^\S'
253       let pkgname = matchlist(curline, '^\(\S\+\).*$')[1]
254       break
255     endif
256     let lineidx = lineidx - 1
257   endwhile
258   return pkgname
259 endfunction
261 function! DebChangelogFoldText()
262   if v:folddashes == '-'  " changelog entry fold
263     return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' '
264   endif
265   return foldtext()
266 endfunction
268 function! DebGetChangelogFold(lnum)
269   let line = getline(a:lnum)
270   if line =~ '^\w\+'
271     return '>1' " beginning of a changelog entry
272   endif
273   if line =~ '^\s\+\[.*\]'
274     return '>2' " beginning of an author-specific chunk
275   endif
276   if line =~ '^ --'
277     return '1'
278   endif
279   return '='
280 endfunction
282 silent! foldopen!   " unfold the entry the cursor is on (usually the first one)
284 " }}}
286 " {{{1 omnicompletion for Closes: #
288 if !exists('g:debchangelog_listbugs_severities')
289   let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist'
290 endif
292 fun! DebCompleteBugs(findstart, base)
293   if a:findstart
294     " it we are just after an '#', the completion should start at the '#',
295     " otherwise no completion is possible
296     let line = getline('.')
297     let colidx = col('.')
298     if colidx > 1 && line[colidx - 2] =~ '#'
299       let colidx = colidx - 2
300     else
301       let colidx = -1
302     endif
303     return colidx
304   else
305     if ! filereadable('/usr/sbin/apt-listbugs')
306       echoerr 'apt-listbugs not found, you should install it to use Closes bug completion'
307       return
308     endif
309     let pkgsrc = DebGetPkgSrcName(line('.'))
310     let listbugs_output = system('apt-listbugs -s ' . g:debchangelog_listbugs_severities . ' list ' . pkgsrc . ' | grep "^ #" 2> /dev/null')
311     let bug_lines = split(listbugs_output, '\n')
312     let completions = []
313     for line in bug_lines
314       let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
315       let completion = {}
316       let completion['word'] = parts[1]
317       let completion['menu'] = parts[2]
318       let completion['info'] = parts[0]
319       let completions += [completion]
320     endfor
321     return completions
322   endif
323 endfun
325 setlocal omnifunc=DebCompleteBugs
327 " }}}
329 " vim: set foldmethod=marker: