Mercurial > vim
comparison runtime/ftplugin/ada.vim @ 7:3fc0f57ecb91 v7.0001
updated for version 7.0001
author | vimboss |
---|---|
date | Sun, 13 Jun 2004 20:20:40 +0000 |
parents | |
children | 1f3b1021f002 |
comparison
equal
deleted
inserted
replaced
6:c2daee826b8f | 7:3fc0f57ecb91 |
---|---|
1 " Vim Ada plugin file | |
2 " Language: Ada | |
3 " Maintainer: Neil Bird <neil@fnxweb.com> | |
4 " Last Change: 2003 May 11 | |
5 " Version: $Id$ | |
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 : |