home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / runtime / dos / ftplugin / debchangelog.vim < prev    next >
Encoding:
Text File  |  2012-05-31  |  11.6 KB  |  384 lines

  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:  2012-01-31
  7. " License:      Vim License
  8. " URL:          http://hg.debian.org/hg/pkg-vim/vim/file/unstable/runtime/ftplugin/debchangelog.vim
  9.  
  10. " Bug completion requires apt-listbugs installed for Debian packages or
  11. " python-launchpadlib installed for Ubuntu packages
  12.  
  13. if exists("b:did_ftplugin")
  14.   finish
  15. endif
  16. let b:did_ftplugin=1
  17.  
  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
  24.  
  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:* 
  29.  
  30. " Clean unloading
  31. let b:undo_ftplugin = "setlocal tw< comments< foldmethod< foldexpr< foldtext<"
  32. " }}}1
  33.  
  34. if exists("g:did_changelog_ftplugin")
  35.   finish
  36. endif
  37.  
  38. " Don't load another plugin (this is global)
  39. let g:did_changelog_ftplugin = 1
  40.  
  41. " {{{1 GUI menu
  42.  
  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
  55.  
  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
  68.  
  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
  77.  
  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
  87.  
  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
  100.  
  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 
  121.     call setline(1, substitute(getline(1), '-\$\$', '-', ''))
  122.     if exists("g:debchangelog_fold_enable")
  123.         foldopen
  124.     endif
  125.     call AddEntry()
  126. endfunction
  127.  
  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
  143.  
  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
  153.  
  154. function Distribution(dist)
  155.     call setline(1, substitute(getline(1), ") [[:lower:] ]*;", ") " . a:dist . ";", ""))
  156. endfunction
  157.  
  158. function Urgency(urg)
  159.     call setline(1, substitute(getline(1), "urgency=.*$", "urgency=" . a:urg, ""))
  160. endfunction
  161.  
  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
  172.  
  173. function Unfinalise()
  174.     call <SID>UnfinaliseMenu()
  175.     normal 1G
  176.     call search("^ -- ")
  177.     call setline(".", " -- ")
  178. endfunction
  179.  
  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
  190.  
  191. function Finalise()
  192.     call <SID>FinaliseMenu()
  193.     normal 1G
  194.     call search("^ -- ")
  195.     call setline(".", " -- " . <SID>FullName() . " <" . <SID>Email() . ">  " . <SID>Date())
  196. endfunction
  197.  
  198.  
  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>
  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
  227. endfunction
  228.  
  229. augroup changelogMenu
  230. au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif
  231. au BufLeave * if &filetype == "debchangelog" | silent! aunmenu Changelog | endif
  232. augroup END
  233.  
  234. " }}}
  235. " {{{1 folding
  236.  
  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
  249.  
  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
  265.  
  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
  272.  
  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
  286.  
  287. if exists("g:debchangelog_fold_enable")
  288.   silent! foldopen!   " unfold the entry the cursor is on (usually the first one)
  289. endif
  290.  
  291. " }}}
  292.  
  293. " {{{1 omnicompletion for Closes: #
  294.  
  295. if !exists('g:debchangelog_listbugs_severities')
  296.   let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist'
  297. endif
  298.  
  299. fun! DebCompleteBugs(findstart, base)
  300.   if a:findstart
  301.     let line = getline('.')
  302.  
  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
  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 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
  350. except ImportError:
  351.     vim.command('echoerr \'python-launchpadlib >= 1.5.4 needs to be installed to use Launchpad bug completion\'')
  352. EOF
  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')
  361.     endif
  362.     let completions = []
  363.     for line in bug_lines
  364.       let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$')
  365.       " filter only those which match a:base:
  366.       if parts[1] !~ "^" . a:base
  367.         continue
  368.       endif
  369.       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
  377. endfun
  378.  
  379. setlocal omnifunc=DebCompleteBugs
  380.  
  381. " }}}
  382.  
  383. " vim: set foldmethod=marker:
  384.