Mirror of the Vim source from https://github.com/vim/vim
Revisión | 441f938ea9e90e07a05e55fef17ab22d2607f5f3 (tree) |
---|---|
Tiempo | 2006-02-04 09:59:56 |
Autor | vimboss |
Commiter | vimboss |
updated for version 7.0192
@@ -1,13 +1,13 @@ | ||
1 | 1 | " Vim completion script |
2 | 2 | " Language: C |
3 | 3 | " Maintainer: Bram Moolenaar <Bram@vim.org> |
4 | -" Last Change: 2006 Jan 30 | |
4 | +" Last Change: 2006 Feb 03 | |
5 | 5 | |
6 | 6 | |
7 | 7 | " This function is used for the 'omnifunc' option. |
8 | 8 | function! ccomplete#Complete(findstart, base) |
9 | 9 | if a:findstart |
10 | - " Locate the start of the item, including "." and "->". | |
10 | + " Locate the start of the item, including ".", "->" and "[...]". | |
11 | 11 | let line = getline('.') |
12 | 12 | let start = col('.') - 1 |
13 | 13 | let lastword = -1 |
@@ -24,6 +24,21 @@ | ||
24 | 24 | let lastword = start |
25 | 25 | endif |
26 | 26 | let start -= 2 |
27 | + elseif line[start - 1] == ']' | |
28 | + " Skip over [...]. | |
29 | + let n = 0 | |
30 | + let start -= 1 | |
31 | + while start > 0 | |
32 | + let start -= 1 | |
33 | + if line[start] == '[' | |
34 | + if n == 0 | |
35 | + break | |
36 | + endif | |
37 | + let n -= 1 | |
38 | + elseif line[start] == ']' " nested [] | |
39 | + let n += 1 | |
40 | + endif | |
41 | + endwhile | |
27 | 42 | else |
28 | 43 | break |
29 | 44 | endif |
@@ -43,20 +58,53 @@ | ||
43 | 58 | |
44 | 59 | let base = s:prepended . a:base |
45 | 60 | |
61 | + " Don't do anything for an empty base, would result in all the tags in the | |
62 | + " tags file. | |
63 | + if base == '' | |
64 | + return [] | |
65 | + endif | |
66 | + | |
46 | 67 | " Split item in words, keep empty word after "." or "->". |
47 | 68 | " "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc. |
48 | - let items = split(base, '\.\|->', 1) | |
49 | - if len(items) <= 1 | |
50 | - " Don't do anything for an empty base, would result in all the tags in the | |
51 | - " tags file. | |
52 | - if base == '' | |
53 | - return [] | |
69 | + " We can't use split, because we need to skip nested [...]. | |
70 | + let items = [] | |
71 | + let s = 0 | |
72 | + while 1 | |
73 | + let e = match(base, '\.\|->\|\[', s) | |
74 | + if e < 0 | |
75 | + if s == 0 || base[s - 1] != ']' | |
76 | + call add(items, strpart(base, s)) | |
77 | + endif | |
78 | + break | |
54 | 79 | endif |
55 | - | |
56 | - " Only one part, no "." or "->": complete from tags file. | |
57 | - " When local completion is wanted CTRL-N would have been used. | |
58 | - return map(taglist('^' . base), 's:Tag2item(v:val)') | |
59 | - endif | |
80 | + if s == 0 || base[s - 1] != ']' | |
81 | + call add(items, strpart(base, s, e - s)) | |
82 | + endif | |
83 | + if base[e] == '.' | |
84 | + let s = e + 1 " skip over '.' | |
85 | + elseif base[e] == '-' | |
86 | + let s = e + 2 " skip over '->' | |
87 | + else | |
88 | + " Skip over [...]. | |
89 | + let n = 0 | |
90 | + let s = e | |
91 | + let e += 1 | |
92 | + while e < len(base) | |
93 | + if base[e] == ']' | |
94 | + if n == 0 | |
95 | + break | |
96 | + endif | |
97 | + let n -= 1 | |
98 | + elseif base[e] == '[' " nested [...] | |
99 | + let n += 1 | |
100 | + endif | |
101 | + let e += 1 | |
102 | + endwhile | |
103 | + let e += 1 | |
104 | + call add(items, strpart(base, s, e - s)) | |
105 | + let s = e | |
106 | + endif | |
107 | + endwhile | |
60 | 108 | |
61 | 109 | " Find the variable items[0]. |
62 | 110 | " 1. in current function (like with "gd") |
@@ -68,7 +116,33 @@ | ||
68 | 116 | " TODO: join previous line if it makes sense |
69 | 117 | let line = getline('.') |
70 | 118 | let col = col('.') |
71 | - let res = s:Nextitem(strpart(line, 0, col), items[1:]) | |
119 | + if len(items) == 1 | |
120 | + " Completing one word and it's a local variable: May add '[', '.' or | |
121 | + " '->'. | |
122 | + let match = items[0] | |
123 | + if match(line, match . '\s*\[') > 0 | |
124 | + let match .= '[' | |
125 | + else | |
126 | + let res = s:Nextitem(strpart(line, 0, col), [''], 0) | |
127 | + if len(res) > 0 | |
128 | + " There are members, thus add "." or "->". | |
129 | + if match(line, '\*[ \t(]*' . match . '\>') > 0 | |
130 | + let match .= '->' | |
131 | + else | |
132 | + let match .= '.' | |
133 | + endif | |
134 | + endif | |
135 | + endif | |
136 | + let res = [{'match': match, 'tagline' : ''}] | |
137 | + else | |
138 | + " Completing "var.", "var.something", etc. | |
139 | + let res = s:Nextitem(strpart(line, 0, col), items[1:], 0) | |
140 | + endif | |
141 | + endif | |
142 | + | |
143 | + if len(items) == 1 | |
144 | + " Only one part, no "." or "->": complete from tags file. | |
145 | + call extend(res, map(taglist('^' . base), 's:Tag2item(v:val)')) | |
72 | 146 | endif |
73 | 147 | |
74 | 148 | if len(res) == 0 |
@@ -88,7 +162,7 @@ | ||
88 | 162 | let line = diclist[i]['cmd'] |
89 | 163 | if line[0] == '/' && line[1] == '^' |
90 | 164 | let col = match(line, '\<' . items[0] . '\>') |
91 | - call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:])) | |
165 | + call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:], 0)) | |
92 | 166 | endif |
93 | 167 | endif |
94 | 168 | endfor |
@@ -99,46 +173,70 @@ | ||
99 | 173 | " TODO: join previous line if it makes sense |
100 | 174 | let line = getline('.') |
101 | 175 | let col = col('.') |
102 | - let res = s:Nextitem(strpart(line, 0, col), items[1:]) | |
103 | - endif | |
104 | - | |
105 | - " If the one and only match was what's already there and it is a composite | |
106 | - " type, add a "." or "->". | |
107 | - if len(res) == 1 && res[0]['match'] == items[-1] && len(s:SearchMembers(res, [''])) > 0 | |
108 | - " If there is a '*' before the name use "->". | |
109 | - if match(res[0]['tagline'], '\*\s*' . res[0]['match'] . '\>') > 0 | |
110 | - let res[0]['match'] .= '->' | |
111 | - else | |
112 | - let res[0]['match'] .= '.' | |
113 | - endif | |
176 | + let res = s:Nextitem(strpart(line, 0, col), items[1:], 0) | |
114 | 177 | endif |
115 | 178 | |
116 | - return map(res, 'v:val["match"]') | |
179 | + " If the last item(s) are [...] they need to be added to the matches. | |
180 | + let last = len(items) - 1 | |
181 | + let brackets = '' | |
182 | + while last >= 0 | |
183 | + if items[last][0] != '[' | |
184 | + break | |
185 | + endif | |
186 | + let brackets = items[last] . brackets | |
187 | + let last -= 1 | |
188 | + endwhile | |
189 | + | |
190 | + return map(res, 's:Tagline2item(v:val, brackets)') | |
117 | 191 | endfunc |
118 | 192 | |
119 | -" | |
193 | +function! s:GetAddition(line, match, memarg, bracket) | |
194 | + " Guess if the item is an array. | |
195 | + if a:bracket && match(a:line, a:match . '\s*\[') > 0 | |
196 | + return '[' | |
197 | + endif | |
198 | + | |
199 | + " Check if the item has members. | |
200 | + if len(s:SearchMembers(a:memarg, [''])) > 0 | |
201 | + " If there is a '*' before the name use "->". | |
202 | + if match(a:line, '\*[ \t(]*' . a:match . '\>') > 0 | |
203 | + return '->' | |
204 | + else | |
205 | + return '.' | |
206 | + endif | |
207 | + endif | |
208 | + return '' | |
209 | +endfunction | |
210 | + | |
120 | 211 | " Turn the tag info "val" into an item for completion. |
121 | 212 | " "val" is is an item in the list returned by taglist(). |
213 | +" If it is a variable we may add "." or "->". Don't do it for other types, | |
214 | +" such as a typedef, by not including the info that s:GetAddition() uses. | |
122 | 215 | function! s:Tag2item(val) |
123 | - if has_key(a:val, "kind") && a:val["kind"] == 'v' | |
124 | - if len(s:SearchMembers([{'match': a:val["name"], 'dict': a:val}], [''])) > 0 | |
125 | - " If there is a '*' before the name use "->". This assumes the command | |
126 | - " is a search pattern! | |
127 | - if match(a:val['cmd'], '\*\s*' . a:val['name'] . '\>') > 0 | |
128 | - return a:val["name"] . '->' | |
129 | - else | |
130 | - return a:val["name"] . '.' | |
131 | - endif | |
216 | + if has_key(a:val, "kind") | |
217 | + if a:val["kind"] == 'v' | |
218 | + return {'match': a:val['name'], 'tagline': "\t" . a:val['cmd'], 'dict': a:val} | |
219 | + endif | |
220 | + if a:val["kind"] == 'f' | |
221 | + return {'match': a:val['name'] . '(', 'tagline': ""} | |
132 | 222 | endif |
133 | 223 | endif |
134 | - return a:val["name"] | |
224 | + return {'match': a:val['name'], 'tagline': ''} | |
225 | +endfunction | |
226 | + | |
227 | +" Turn a match item "val" into an item for completion. | |
228 | +" "val['match']" is the matching item. | |
229 | +" "val['tagline']" is the tagline in which the last part was found. | |
230 | +function! s:Tagline2item(val, brackets) | |
231 | + return a:val['match'] . a:brackets . s:GetAddition(a:val['tagline'], a:val['match'], [a:val], a:brackets == '') | |
135 | 232 | endfunction |
136 | 233 | |
137 | 234 | |
138 | 235 | " Find composing type in "lead" and match items[0] with it. |
139 | 236 | " Repeat this recursively for items[1], if it's there. |
237 | +" When resolving typedefs "depth" is used to avoid infinite recursion. | |
140 | 238 | " Return the list of matches. |
141 | -function! s:Nextitem(lead, items) | |
239 | +function! s:Nextitem(lead, items, depth) | |
142 | 240 | |
143 | 241 | " Use the text up to the variable name and split it in tokens. |
144 | 242 | let tokens = split(a:lead, '\s\+\|\<') |
@@ -154,7 +252,7 @@ | ||
154 | 252 | endif |
155 | 253 | |
156 | 254 | " TODO: add more reserved words |
157 | - if index(['int', 'float', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0 | |
255 | + if index(['int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0 | |
158 | 256 | continue |
159 | 257 | endif |
160 | 258 |
@@ -191,9 +289,9 @@ | ||
191 | 289 | if name != '' |
192 | 290 | call extend(res, s:StructMembers(cmdtokens[0] . ':' . name, a:items)) |
193 | 291 | endif |
194 | - else | |
292 | + elseif a:depth < 10 | |
195 | 293 | " Could be "typedef other_T some_T". |
196 | - call extend(res, s:Nextitem(cmdtokens[0], a:items)) | |
294 | + call extend(res, s:Nextitem(cmdtokens[0], a:items, a:depth + 1)) | |
197 | 295 | endif |
198 | 296 | endif |
199 | 297 | endif |
@@ -207,6 +305,7 @@ | ||
207 | 305 | endfunction |
208 | 306 | |
209 | 307 | |
308 | +" Search for members of structure "typename" in tags files. | |
210 | 309 | " Return a list with resulting matches. |
211 | 310 | " Each match is a dictionary with "match" and "tagline" entries. |
212 | 311 | function! s:StructMembers(typename, items) |
@@ -237,14 +336,21 @@ | ||
237 | 336 | endfor |
238 | 337 | |
239 | 338 | if len(matches) > 0 |
240 | - " No further items, return the result. | |
241 | - if len(a:items) == 1 | |
242 | - return matches | |
243 | - endif | |
339 | + " Skip over [...] items | |
340 | + let idx = 1 | |
341 | + while 1 | |
342 | + if idx >= len(a:items) | |
343 | + return matches " No further items, return the result. | |
344 | + endif | |
345 | + if a:items[idx][0] != '[' | |
346 | + break | |
347 | + endif | |
348 | + let idx += 1 | |
349 | + endwhile | |
244 | 350 | |
245 | 351 | " More items following. For each of the possible members find the |
246 | 352 | " matching following members. |
247 | - return s:SearchMembers(matches, a:items[1:]) | |
353 | + return s:SearchMembers(matches, a:items[idx :]) | |
248 | 354 | endif |
249 | 355 | |
250 | 356 | " Failed to find anything. |
@@ -257,9 +363,6 @@ | ||
257 | 363 | for i in range(len(a:matches)) |
258 | 364 | let typename = '' |
259 | 365 | if has_key(a:matches[i], 'dict') |
260 | - "if a:matches[i].dict['name'] == "gui" | |
261 | - "echomsg string(a:matches[i].dict) | |
262 | - "endif | |
263 | 366 | if has_key(a:matches[i].dict, 'typename') |
264 | 367 | let typename = a:matches[i].dict['typename'] |
265 | 368 | endif |
@@ -273,17 +376,14 @@ | ||
273 | 376 | endif |
274 | 377 | endif |
275 | 378 | if typename != '' |
276 | - call extend(res, s:StructMembers(name, a:items)) | |
379 | + call extend(res, s:StructMembers(typename, a:items)) | |
277 | 380 | else |
278 | 381 | " Use the search command (the declaration itself). |
279 | 382 | let s = match(line, '\t\zs/^') |
280 | 383 | if s > 0 |
281 | 384 | let e = match(line, '\<' . a:matches[i]['match'] . '\>', s) |
282 | 385 | if e > 0 |
283 | - "if a:matches[i].dict['name'] == "gui" | |
284 | - "echomsg strpart(line, s, e - s) | |
285 | - "endif | |
286 | - call extend(res, s:Nextitem(strpart(line, s, e - s), a:items)) | |
386 | + call extend(res, s:Nextitem(strpart(line, s, e - s), a:items, 0)) | |
287 | 387 | endif |
288 | 388 | endif |
289 | 389 | endif |
@@ -1,4 +1,4 @@ | ||
1 | -*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 01 | |
1 | +*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 03 | |
2 | 2 | |
3 | 3 | |
4 | 4 | VIM REFERENCE MANUAL by Bram Moolenaar |
@@ -37,7 +37,15 @@ | ||
37 | 37 | :lmake |
38 | 38 | |
39 | 39 | ccomplete / omnicomplete: |
40 | -- Also add . or -> when completing struct members. use s:Tag2item() | |
40 | +- Extra info for each entry to show in a tooltip kind of thing. | |
41 | + Should use a dictionary for each entry. Fields could be: | |
42 | + word the completed word | |
43 | + menu menu text (use word when missing) | |
44 | + info extra info, to be displayed in balloon (e.g., function args) | |
45 | + kind single letter indicating the type of word: | |
46 | + v = variable, f = function/method, c = composite (object, | |
47 | + struct pointer). | |
48 | + For C add tag "kind" field? | |
41 | 49 | - When an option is set: In completion mode and the user types (identifier) |
42 | 50 | characters, advance to the first match instead of removing the popup menu. |
43 | 51 | If there is no match remove the selection. (Yegappan Lakshmanan) |
@@ -49,17 +57,10 @@ | ||
49 | 57 | Need to postpone inserting anything until all matches have been found. |
50 | 58 | Then add a completion item with the longest common string (after what was |
51 | 59 | typed), if there is one. |
52 | -- When completing something that is a structure, add the "." or "->" right | |
53 | - away. How to figure out if it's a pointer or not? | |
60 | +- Finding out if an item has members (to add '.' or '->') requires a grep in | |
61 | + the tags files, that is very slow. Is there another solution? At least | |
62 | + stop at the first match. | |
54 | 63 | - When a typedef or struct is local to a file only use it in that file? |
55 | -- Extra info for each entry to show in a tooltip kind of thing. | |
56 | - Should use a dictionary for each entry. Fields could be: | |
57 | - word the completed word | |
58 | - menu menu text (use word when missing) | |
59 | - info extra info, to be displayed in balloon (e.g., function args) | |
60 | - kind single letter indicating the type of word: | |
61 | - v = variable, f = function/method, c = composite (object, | |
62 | - struct pointer). | |
63 | 64 | - Special mappings for when the popup menu is visible? Would allow for making |
64 | 65 | a specific selection (e.g, methods vs variables). |
65 | 66 |
@@ -113,6 +114,9 @@ | ||
113 | 114 | Edward L. Fox explains how it should be done for most Asian languages. (2005 |
114 | 115 | Nov 24) |
115 | 116 | |
117 | +An error in a function uses a line number that doesn't take line continuation | |
118 | +into account. (Mikolaj Machowski) Store line count in an extra array? | |
119 | + | |
116 | 120 | Mac unicode patch (Da Woon Jung): |
117 | 121 | - selecting proportional font breaks display |
118 | 122 | - UTF-8 text causes display problems. Font replacement causes this. |
@@ -166,7 +170,7 @@ | ||
166 | 170 | - mblen(NULL, 0) also in Vim 6.3? |
167 | 171 | |
168 | 172 | |
169 | -PLANNED FOR VERSION 7.0: | |
173 | +CONSIDERED FOR VERSION 7.0: | |
170 | 174 | |
171 | 175 | - Omni completion: Understands the programming language and finds matches |
172 | 176 | that make sense. Esp. members of classes/structs. |
@@ -278,7 +282,7 @@ | ||
278 | 282 | Then add GUI Tabs for some systems. |
279 | 283 | Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6. |
280 | 284 | Simple patch for GTK by Luis M (nov 7). |
281 | - Don't forget to provide an "X" to close a tab. | |
285 | + Don't forget to provide an "X" to close the current tab. | |
282 | 286 | Implementation: keep the list of windows as-is. When switching to another |
283 | 287 | tab make the buffers in the current windows hidden, save the window |
284 | 288 | layout, buildup the other window layout and fill with buffers. |
@@ -1,4 +1,4 @@ | ||
1 | -*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 01 | |
1 | +*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 02 | |
2 | 2 | |
3 | 3 | |
4 | 4 | VIM REFERENCE MANUAL by Bram Moolenaar |
@@ -1636,4 +1636,9 @@ | ||
1636 | 1636 | In a multi-byte file the foldmarker could be recognized in the trail byte. |
1637 | 1637 | (Taro Muraoka) |
1638 | 1638 | |
1639 | +Pasting with CTRL-V and menu didn't work properly when some commands are | |
1640 | +mapped. Use ":normal!" instead of ":normal". (Tony Apuzzo) | |
1641 | + | |
1642 | +Crashed when expanding a file name argument in backticks. | |
1643 | + | |
1639 | 1644 | vim:tw=78:ts=8:ft=help:norl: |
@@ -1,7 +1,7 @@ | ||
1 | 1 | " Set options and add mapping such that Vim behaves a lot like MS-Windows |
2 | 2 | " |
3 | 3 | " Maintainer: Bram Moolenaar <Bram@vim.org> |
4 | -" Last change: 2005 Dec 28 | |
4 | +" Last change: 2006 Feb 02 | |
5 | 5 | |
6 | 6 | " bail out if this isn't wanted (mrsvim.vim uses this). |
7 | 7 | if exists("g:skip_loading_mswin") && g:skip_loading_mswin |
@@ -47,18 +47,18 @@ | ||
47 | 47 | func! <SID>Paste() |
48 | 48 | let ove = &ve |
49 | 49 | set ve=all |
50 | - normal `^ | |
50 | + normal! `^ | |
51 | 51 | if @+ != '' |
52 | - normal "+gP | |
52 | + normal! "+gP | |
53 | 53 | endif |
54 | 54 | let c = col(".") |
55 | - normal i | |
55 | + normal! i | |
56 | 56 | if col(".") < c " compensate for i<ESC> moving the cursor left |
57 | 57 | " Avoid a beep when the text ends at the window edge. |
58 | 58 | let vb_save = &vb |
59 | 59 | let t_vb_save = &t_vb |
60 | 60 | set vb t_vb= |
61 | - normal l | |
61 | + normal! l | |
62 | 62 | let &vb = vb_save |
63 | 63 | let &t_vb = t_vb_save |
64 | 64 | endif |