mirror of
				https://github.com/vim/vim.git
				synced 2025-10-31 09:57:14 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			227 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			VimL
		
	
	
	
	
	
| " Vim Ada plugin file
 | |
| " Language:	Ada
 | |
| " Maintainer:	Neil Bird <neil@fnxweb.com>
 | |
| " Last Change:	2003 May 11
 | |
| " 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 :
 |