Mercurial > vim
view runtime/ftplugin/ada.vim @ 861:169533a9699f v7.0g02
updated for version 7.0g02
author | vimboss |
---|---|
date | Wed, 03 May 2006 21:29:58 +0000 |
parents | 1f3b1021f002 |
children | e63691e7c504 |
line wrap: on
line source
" Vim Ada plugin file " Language: Ada " Maintainer: Neil Bird <neil@fnxweb.com> " Last Change: 2006 Apr 21 " Version: $Id$ " Look for the latest version at http://vim.sourceforge.net/ " " Perform Ada specific completion & tagging. " " " Provides mapping overrides for tag jumping that figure out the current " Ada object and tag jump to that, not the 'simple' vim word. " Similarly allows <Ctrl-N> matching of full-length ada entities from tags. " Exports 'AdaWord()' function to return full name of Ada entity under the " cursor( or at given line/column), stripping whitespace/newlines as necessary. " Only do this when not done yet for this buffer if exists("b:did_ftplugin") finish endif " Don't load another plugin for this buffer let b:did_ftplugin = 1 " Temporarily set cpoptions to ensure the script loads OK let s:cpoptions = &cpoptions set cpo-=C " Ada comments setlocal comments+=O:-- " Make local tag mappings for this buffer (if not already set) if mapcheck('<C-]>','n') == '' nnoremap <unique> <buffer> <C-]> :call JumpToTag_ada('')<cr> endif if mapcheck('g<C-]>','n') == '' nnoremap <unique> <buffer> g<C-]> :call JumpToTag_ada('','stj')<cr> endif if mapcheck('<C-N>','i') == '' inoremap <unique> <buffer> <C-N> <C-R>=<SID>AdaCompletion("\<lt>C-N>")<cr> endif if mapcheck('<C-P>','i') == '' inoremap <unique> <buffer> <C-P> <C-R>=<SID>AdaCompletion("\<lt>C-P>")<cr> endif if mapcheck('<C-X><C-]>','i') == '' inoremap <unique> <buffer> <C-X><C-]> <C-R>=<SID>AdaCompletion("\<lt>C-X>\<lt>C-]>")<cr> endif if mapcheck('<bs>','i') == '' inoremap <silent> <unique> <buffer> <bs> <C-R>=<SID>AdaInsertBackspace()<cr> endif " Only do this when not done yet for this buffer & matchit is used if ! exists("b:match_words") && exists("loaded_matchit") " The following lines enable the macros/matchit.vim plugin for " Ada-specific extended matching with the % key. let s:notend = '\%(\<end\s\+\)\@<!' let b:match_words= \ s:notend . '\<if\>:\<elsif\>:\<else\>:\<end\>\s\+\<if\>,' . \ s:notend . '\<case\>:\<when\>:\<end\>\s\+\<case\>,' . \ '\%(\<while\>.*\|\<for\>.*\|'.s:notend.'\)\<loop\>:\<end\>\s\+\<loop\>,' . \ '\%(\<do\>\|\<begin\>\):\<exception\>:\<end\>\s*\%($\|[;A-Z]\),' . \ s:notend . '\<record\>:\<end\>\s\+\<record\>' endif " Prevent re-load of functions if exists('s:id') finish endif " Get this script's unique id map <script> <SID>?? <SID>?? let s:id = substitute( maparg('<SID>??'), '^<SNR>\(.*\)_??$', '\1', '' ) unmap <script> <SID>?? " Extract current Ada word across multiple lines " AdaWord( [line, column] )\ let s:AdaWordRegex = '\a\w*\(\_s*\.\_s*\a\w*\)*' let s:AdaComment = "\\v^(\"[^\"]*\"|'.'|[^\"']){-}\\zs\\s*--.*" function! AdaWord(...) if a:0 > 1 let linenr = a:1 let colnr = a:2 - 1 else let linenr = line('.') let colnr = col('.') - 1 endif let line = substitute( getline(linenr), s:AdaComment, '', '' ) " Cope with tag searching for items in comments; if we are, don't loop " backards looking for previous lines if colnr > strlen(line) " We were in a comment let line = getline(linenr) let search_prev_lines = 0 else let search_prev_lines = 1 endif " Go backwards until we find a match (Ada ID) that *doesn't* include our " location - i.e., the previous ID. This is because the current 'correct' " match will toggle matching/not matching as we traverse characters " backwards. Thus, we have to find the previous unrelated match, exclude " it, then use the next full match (ours). " Remember to convert vim column 'colnr' [1..n] to string offset [0..(n-1)] " ... but start, here, one after the required char. let newcol = colnr + 1 while 1 let newcol = newcol - 1 if newcol < 0 " Have to include previous line from file let linenr = linenr - 1 if linenr < 1 || !search_prev_lines " Start of file or matching in a comment let linenr = 1 let newcol = 0 let ourmatch = match( line, s:AdaWordRegex ) break endif " Get previous line, and prepend it to our search string let newline = substitute( getline(linenr), s:AdaComment, '', '' ) let newcol = strlen(newline) - 1 let colnr = colnr + newcol let line = newline . line endif " Check to see if this is a match excluding 'us' let mend = newcol + matchend( strpart(line,newcol), s:AdaWordRegex ) - 1 if mend >= newcol && mend < colnr " Yes let ourmatch = mend+1 + match( strpart(line,mend+1), s:AdaWordRegex ) break endif endwhile " Got anything? if ourmatch < 0 return '' else let line = strpart( line, ourmatch) endif " Now simply add further lines until the match gets no bigger let matchstr = matchstr( line, s:AdaWordRegex ) let lastline = line('$') let linenr = line('.') + 1 while linenr <= lastline let lastmatch = matchstr let line = line . substitute( getline(linenr), s:AdaComment, '', '' ) let matchstr = matchstr( line, s:AdaWordRegex ) if matchstr == lastmatch break endif endwhile " Strip whitespace & return return substitute( matchstr, '\s\+', '', 'g' ) endfunction " Word tag - include '.' and if Ada make uppercase " Name allows a common JumpToTag() to look for an ft specific JumpToTag_ft(). function! JumpToTag_ada(word,...) if a:word == '' " Get current word let word = AdaWord() if word == '' return endif else let word = a:word endif if a:0 > 0 let mode = a:1 else let mode = 'tj' endif let v:errmsg = '' execute 'silent!' mode word if v:errmsg != '' if v:errmsg =~ '^E426:' " Tag not found let ignorecase = &ignorecase set ignorecase execute mode word let &ignorecase = ignorecase else " Repeat to give error execute mode word endif endif endfunction " Word completion (^N/^R/^X^]) - force '.' inclusion function! s:AdaCompletion(cmd) set iskeyword+=46 return a:cmd . "\<C-R>=<SNR>" . s:id . "_AdaCompletionEnd()\<CR>" endfunction function! s:AdaCompletionEnd() set iskeyword-=46 return '' endfunction " Backspace at end of line after auto-inserted commentstring '-- ' wipes it function! s:AdaInsertBackspace() let line = getline('.') if col('.') > strlen(line) && match(line,'-- $') != -1 && match(&comments,'--') != -1 return "\<bs>\<bs>\<bs>" else return "\<bs>" endif endfunction " Reset cpoptions let &cpoptions = s:cpoptions unlet s:cpoptions " vim: sts=2 sw=2 :