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 / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / runtime / ftplugin / ada.vim < prev    next >
Encoding:
Text File  |  2003-05-11  |  6.4 KB  |  227 lines

  1. " Vim Ada plugin file
  2. " Language:    Ada
  3. " Maintainer:    Neil Bird <neil@fnxweb.com>
  4. " Last Change:    2003 May 11
  5. " Version:    $Id: ada.vim,v 1.7 2001/11/06 16:38:45 nabird Exp $
  6. " Look for the latest version at http://vim.sourceforge.net/
  7. "
  8. " Perform Ada specific completion & tagging.
  9. "
  10. "
  11. " Provides mapping overrides for tag jumping that figure out the current
  12. " Ada object and tag jump to that, not the 'simple' vim word.
  13. " Similarly allows <Ctrl-N> matching of full-length ada entities from tags.
  14. " Exports 'AdaWord()' function to return full name of Ada entity under the
  15. " cursor( or at given line/column), stripping whitespace/newlines as necessary.
  16.  
  17.  
  18. " Only do this when not done yet for this buffer
  19. if exists("b:did_ftplugin")
  20.   finish
  21. endif
  22.  
  23. " Don't load another plugin for this buffer
  24. let b:did_ftplugin = 1
  25.  
  26. " Temporarily set cpoptions to ensure the script loads OK
  27. let s:cpoptions = &cpoptions
  28. set cpo-=C
  29.  
  30.  
  31. " Ada comments
  32. setlocal comments+=O:--
  33.  
  34.  
  35. " Make local tag mappings for this buffer (if not already set)
  36. if mapcheck('<C-]>','n') == ''
  37.   nnoremap <unique> <buffer> <C-]>    :call JumpToTag_ada('')<cr>
  38. endif
  39. if mapcheck('g<C-]>','n') == ''
  40.   nnoremap <unique> <buffer> g<C-]>   :call JumpToTag_ada('','stj')<cr>
  41. endif
  42.  
  43. if mapcheck('<C-N>','i') == ''
  44.   inoremap <unique> <buffer> <C-N> <C-R>=<SID>AdaCompletion("\<lt>C-N>")<cr>
  45. endif
  46. if mapcheck('<C-P>','i') == ''
  47.   inoremap <unique> <buffer> <C-P> <C-R>=<SID>AdaCompletion("\<lt>C-P>")<cr>
  48. endif
  49. if mapcheck('<C-X><C-]>','i') == ''
  50.   inoremap <unique> <buffer> <C-X><C-]> <C-R>=<SID>AdaCompletion("\<lt>C-X>\<lt>C-]>")<cr>
  51. endif
  52. if mapcheck('<bs>','i') == ''
  53.   inoremap <silent> <unique> <buffer> <bs> <C-R>=<SID>AdaInsertBackspace()<cr>
  54. endif
  55.  
  56.  
  57. " Only do this when not done yet for this buffer & matchit is used
  58. if ! exists("b:match_words")  &&  exists("loaded_matchit")
  59.   " The following lines enable the macros/matchit.vim plugin for
  60.   " Ada-specific extended matching with the % key.
  61.   let s:notend = '\%(\<end\s\+\)\@<!'
  62.   let b:match_words=
  63.   \ s:notend . '\<if\>:\<elsif\>:\<else\>:\<end\>\s\+\<if\>,' .
  64.   \ s:notend . '\<case\>:\<when\>:\<end\>\s\+\<case\>,' .
  65.   \ '\%(\<while\>.*\|\<for\>.*\|'.s:notend.'\)\<loop\>:\<end\>\s\+\<loop\>,' .
  66.   \ '\%(\<do\>\|\<begin\>\):\<exception\>:\<end\>\s*\%($\|[;A-Z]\),' .
  67.   \ s:notend . '\<record\>:\<end\>\s\+\<record\>'
  68. endif
  69.  
  70.  
  71. " Prevent re-load of functions
  72. if exists('s:id')
  73.   finish
  74. endif
  75.  
  76. " Get this script's unique id
  77. map <script> <SID>?? <SID>??
  78. let s:id = substitute( maparg('<SID>??'), '^<SNR>\(.*\)_??$', '\1', '' )
  79. unmap <script> <SID>??
  80.  
  81.  
  82. " Extract current Ada word across multiple lines
  83. " AdaWord( [line, column] )\
  84. let s:AdaWordRegex = '\a\w*\(\_s*\.\_s*\a\w*\)*'
  85. let s:AdaComment   = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*"
  86.  
  87. function! AdaWord(...)
  88.   if a:0 > 1
  89.     let linenr = a:1
  90.     let colnr  = a:2 - 1
  91.   else
  92.     let linenr = line('.')
  93.     let colnr  = col('.') - 1
  94.   endif
  95.   let line = substitute( getline(linenr), s:AdaComment, '', '' )
  96.   " Cope with tag searching for items in comments; if we are, don't loop
  97.   " backards looking for previous lines
  98.   if colnr > strlen(line)
  99.     " We were in a comment
  100.     let line = getline(linenr)
  101.     let search_prev_lines = 0
  102.   else
  103.     let search_prev_lines = 1
  104.   endif
  105.  
  106.   " Go backwards until we find a match (Ada ID) that *doesn't* include our
  107.   " location - i.e., the previous ID. This is because the current 'correct'
  108.   " match will toggle matching/not matching as we traverse characters
  109.   " backwards. Thus, we have to find the previous unrelated match, exclude
  110.   " it, then use the next full match (ours).
  111.   " Remember to convert vim column 'colnr' [1..n] to string offset [0..(n-1)]
  112.   " ... but start, here, one after the required char.
  113.   let newcol = colnr + 1
  114.   while 1
  115.     let newcol = newcol - 1
  116.     if newcol < 0
  117.       " Have to include previous line from file
  118.       let linenr = linenr - 1
  119.       if linenr < 1  ||  !search_prev_lines
  120.     " Start of file or matching in a comment
  121.     let linenr = 1
  122.     let newcol = 0
  123.     let ourmatch = match( line, s:AdaWordRegex )
  124.     break
  125.       endif
  126.       " Get previous line, and prepend it to our search string
  127.       let newline = substitute( getline(linenr), s:AdaComment, '', '' )
  128.       let newcol  = strlen(newline) - 1
  129.       let colnr   = colnr + newcol
  130.       let line    = newline . line
  131.     endif
  132.     " Check to see if this is a match excluding 'us'
  133.     let mend = newcol + matchend( strpart(line,newcol), s:AdaWordRegex ) - 1
  134.     if mend >= newcol  &&  mend < colnr
  135.       " Yes
  136.       let ourmatch = mend+1 + match( strpart(line,mend+1), s:AdaWordRegex )
  137.       break
  138.     endif
  139.   endwhile
  140.  
  141.   " Got anything?
  142.   if ourmatch < 0
  143.     return ''
  144.   else
  145.     let line = strpart( line, ourmatch)
  146.   endif
  147.  
  148.   " Now simply add further lines until the match gets no bigger
  149.   let matchstr = matchstr( line, s:AdaWordRegex )
  150.   let lastline  = line('$')
  151.   let linenr    = line('.') + 1
  152.   while linenr <= lastline
  153.     let lastmatch = matchstr
  154.     let line = line . substitute( getline(linenr), s:AdaComment, '', '' )
  155.     let matchstr = matchstr( line, s:AdaWordRegex )
  156.     if matchstr == lastmatch
  157.       break
  158.     endif
  159.   endwhile
  160.  
  161.   " Strip whitespace & return
  162.   return substitute( matchstr, '\s\+', '', 'g' )
  163. endfunction
  164.  
  165.  
  166. " Word tag - include '.' and if Ada make uppercase
  167. " Name allows a common JumpToTag() to look for an ft specific JumpToTag_ft().
  168. function! JumpToTag_ada(word,...)
  169.   if a:word == ''
  170.     " Get current word
  171.     let word = AdaWord()
  172.     if word == ''
  173.       return
  174.     endif
  175.   else
  176.     let word = a:word
  177.   endif
  178.   if a:0 > 0
  179.     let mode = a:1
  180.   else
  181.     let mode = 'tj'
  182.   endif
  183.  
  184.   let v:errmsg = ''
  185.   execute 'silent!' mode word
  186.   if v:errmsg != ''
  187.     if v:errmsg =~ '^E426:'  " Tag not found
  188.       let ignorecase = &ignorecase
  189.       set ignorecase
  190.       execute mode word
  191.       let &ignorecase = ignorecase
  192.     else
  193.       " Repeat to give error
  194.       execute mode word
  195.     endif
  196.   endif
  197. endfunction
  198.  
  199.  
  200. " Word completion (^N/^R/^X^]) - force '.' inclusion
  201. function! s:AdaCompletion(cmd)
  202.   set iskeyword+=46
  203.   return a:cmd . "\<C-R>=<SNR>" . s:id . "_AdaCompletionEnd()\<CR>"
  204. endfunction
  205. function! s:AdaCompletionEnd()
  206.   set iskeyword-=46
  207.   return ''
  208. endfunction
  209.  
  210.  
  211. " Backspace at end of line after auto-inserted commentstring '-- ' wipes it
  212. function! s:AdaInsertBackspace()
  213.   let line = getline('.')
  214.   if col('.') > strlen(line) && match(line,'-- $') != -1 && match(&comments,'--') != -1
  215.     return "\<bs>\<bs>\<bs>"
  216.   else
  217.     return "\<bs>"
  218.   endif
  219. endfunction
  220.  
  221.  
  222. " Reset cpoptions
  223. let &cpoptions = s:cpoptions
  224. unlet s:cpoptions
  225.  
  226. " vim: sts=2 sw=2 :
  227.