diff options
author | Bram Moolenaar <Bram@vim.org> | 2006-02-04 00:59:56 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2006-02-04 00:59:56 +0000 |
commit | 0e5bd96f84660bd87e5814feb24af3db80bb434c (patch) | |
tree | dd12a869d72e6e30e1afc4c37b7d5ed5d82ebcab | |
parent | 986920760e65384efdbe7158231849ab422ddae3 (diff) |
updated for version 7.0192v7.0192
-rw-r--r-- | runtime/autoload/ccomplete.vim | 206 | ||||
-rw-r--r-- | runtime/doc/todo.txt | 32 | ||||
-rw-r--r-- | runtime/doc/version7.txt | 7 | ||||
-rw-r--r-- | runtime/mswin.vim | 10 |
4 files changed, 182 insertions, 73 deletions
diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim index 8fde2d33eb..5e0c2aea35 100644 --- a/runtime/autoload/ccomplete.vim +++ b/runtime/autoload/ccomplete.vim @@ -1,13 +1,13 @@ " Vim completion script " Language: C " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last Change: 2006 Jan 30 +" Last Change: 2006 Feb 03 " This function is used for the 'omnifunc' option. function! ccomplete#Complete(findstart, base) if a:findstart - " Locate the start of the item, including "." and "->". + " Locate the start of the item, including ".", "->" and "[...]". let line = getline('.') let start = col('.') - 1 let lastword = -1 @@ -24,6 +24,21 @@ function! ccomplete#Complete(findstart, base) let lastword = start endif let start -= 2 + elseif line[start - 1] == ']' + " Skip over [...]. + let n = 0 + let start -= 1 + while start > 0 + let start -= 1 + if line[start] == '[' + if n == 0 + break + endif + let n -= 1 + elseif line[start] == ']' " nested [] + let n += 1 + endif + endwhile else break endif @@ -43,20 +58,53 @@ function! ccomplete#Complete(findstart, base) let base = s:prepended . a:base + " Don't do anything for an empty base, would result in all the tags in the + " tags file. + if base == '' + return [] + endif + " Split item in words, keep empty word after "." or "->". " "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc. - let items = split(base, '\.\|->', 1) - if len(items) <= 1 - " Don't do anything for an empty base, would result in all the tags in the - " tags file. - if base == '' - return [] + " We can't use split, because we need to skip nested [...]. + let items = [] + let s = 0 + while 1 + let e = match(base, '\.\|->\|\[', s) + if e < 0 + if s == 0 || base[s - 1] != ']' + call add(items, strpart(base, s)) + endif + break endif - - " Only one part, no "." or "->": complete from tags file. - " When local completion is wanted CTRL-N would have been used. - return map(taglist('^' . base), 's:Tag2item(v:val)') - endif + if s == 0 || base[s - 1] != ']' + call add(items, strpart(base, s, e - s)) + endif + if base[e] == '.' + let s = e + 1 " skip over '.' + elseif base[e] == '-' + let s = e + 2 " skip over '->' + else + " Skip over [...]. + let n = 0 + let s = e + let e += 1 + while e < len(base) + if base[e] == ']' + if n == 0 + break + endif + let n -= 1 + elseif base[e] == '[' " nested [...] + let n += 1 + endif + let e += 1 + endwhile + let e += 1 + call add(items, strpart(base, s, e - s)) + let s = e + endif + endwhile " Find the variable items[0]. " 1. in current function (like with "gd") @@ -68,7 +116,33 @@ function! ccomplete#Complete(findstart, base) " TODO: join previous line if it makes sense let line = getline('.') let col = col('.') - let res = s:Nextitem(strpart(line, 0, col), items[1:]) + if len(items) == 1 + " Completing one word and it's a local variable: May add '[', '.' or + " '->'. + let match = items[0] + if match(line, match . '\s*\[') > 0 + let match .= '[' + else + let res = s:Nextitem(strpart(line, 0, col), [''], 0) + if len(res) > 0 + " There are members, thus add "." or "->". + if match(line, '\*[ \t(]*' . match . '\>') > 0 + let match .= '->' + else + let match .= '.' + endif + endif + endif + let res = [{'match': match, 'tagline' : ''}] + else + " Completing "var.", "var.something", etc. + let res = s:Nextitem(strpart(line, 0, col), items[1:], 0) + endif + endif + + if len(items) == 1 + " Only one part, no "." or "->": complete from tags file. + call extend(res, map(taglist('^' . base), 's:Tag2item(v:val)')) endif if len(res) == 0 @@ -88,7 +162,7 @@ function! ccomplete#Complete(findstart, base) let line = diclist[i]['cmd'] if line[0] == '/' && line[1] == '^' let col = match(line, '\<' . items[0] . '\>') - call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:])) + call extend(res, s:Nextitem(strpart(line, 2, col - 2), items[1:], 0)) endif endif endfor @@ -99,46 +173,70 @@ function! ccomplete#Complete(findstart, base) " TODO: join previous line if it makes sense let line = getline('.') let col = col('.') - let res = s:Nextitem(strpart(line, 0, col), items[1:]) + let res = s:Nextitem(strpart(line, 0, col), items[1:], 0) endif - " If the one and only match was what's already there and it is a composite - " type, add a "." or "->". - if len(res) == 1 && res[0]['match'] == items[-1] && len(s:SearchMembers(res, [''])) > 0 + " If the last item(s) are [...] they need to be added to the matches. + let last = len(items) - 1 + let brackets = '' + while last >= 0 + if items[last][0] != '[' + break + endif + let brackets = items[last] . brackets + let last -= 1 + endwhile + + return map(res, 's:Tagline2item(v:val, brackets)') +endfunc + +function! s:GetAddition(line, match, memarg, bracket) + " Guess if the item is an array. + if a:bracket && match(a:line, a:match . '\s*\[') > 0 + return '[' + endif + + " Check if the item has members. + if len(s:SearchMembers(a:memarg, [''])) > 0 " If there is a '*' before the name use "->". - if match(res[0]['tagline'], '\*\s*' . res[0]['match'] . '\>') > 0 - let res[0]['match'] .= '->' + if match(a:line, '\*[ \t(]*' . a:match . '\>') > 0 + return '->' else - let res[0]['match'] .= '.' + return '.' endif endif + return '' +endfunction - return map(res, 'v:val["match"]') -endfunc - -" " Turn the tag info "val" into an item for completion. " "val" is is an item in the list returned by taglist(). +" If it is a variable we may add "." or "->". Don't do it for other types, +" such as a typedef, by not including the info that s:GetAddition() uses. function! s:Tag2item(val) - if has_key(a:val, "kind") && a:val["kind"] == 'v' - if len(s:SearchMembers([{'match': a:val["name"], 'dict': a:val}], [''])) > 0 - " If there is a '*' before the name use "->". This assumes the command - " is a search pattern! - if match(a:val['cmd'], '\*\s*' . a:val['name'] . '\>') > 0 - return a:val["name"] . '->' - else - return a:val["name"] . '.' - endif + if has_key(a:val, "kind") + if a:val["kind"] == 'v' + return {'match': a:val['name'], 'tagline': "\t" . a:val['cmd'], 'dict': a:val} + endif + if a:val["kind"] == 'f' + return {'match': a:val['name'] . '(', 'tagline': ""} endif endif - return a:val["name"] + return {'match': a:val['name'], 'tagline': ''} +endfunction + +" Turn a match item "val" into an item for completion. +" "val['match']" is the matching item. +" "val['tagline']" is the tagline in which the last part was found. +function! s:Tagline2item(val, brackets) + return a:val['match'] . a:brackets . s:GetAddition(a:val['tagline'], a:val['match'], [a:val], a:brackets == '') endfunction " Find composing type in "lead" and match items[0] with it. " Repeat this recursively for items[1], if it's there. +" When resolving typedefs "depth" is used to avoid infinite recursion. " Return the list of matches. -function! s:Nextitem(lead, items) +function! s:Nextitem(lead, items, depth) " Use the text up to the variable name and split it in tokens. let tokens = split(a:lead, '\s\+\|\<') @@ -154,7 +252,7 @@ function! s:Nextitem(lead, items) endif " TODO: add more reserved words - if index(['int', 'float', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0 + if index(['int', 'short', 'char', 'float', 'double', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0 continue endif @@ -191,9 +289,9 @@ function! s:Nextitem(lead, items) if name != '' call extend(res, s:StructMembers(cmdtokens[0] . ':' . name, a:items)) endif - else + elseif a:depth < 10 " Could be "typedef other_T some_T". - call extend(res, s:Nextitem(cmdtokens[0], a:items)) + call extend(res, s:Nextitem(cmdtokens[0], a:items, a:depth + 1)) endif endif endif @@ -207,6 +305,7 @@ function! s:Nextitem(lead, items) endfunction +" Search for members of structure "typename" in tags files. " Return a list with resulting matches. " Each match is a dictionary with "match" and "tagline" entries. function! s:StructMembers(typename, items) @@ -237,14 +336,21 @@ function! s:StructMembers(typename, items) endfor if len(matches) > 0 - " No further items, return the result. - if len(a:items) == 1 - return matches - endif + " Skip over [...] items + let idx = 1 + while 1 + if idx >= len(a:items) + return matches " No further items, return the result. + endif + if a:items[idx][0] != '[' + break + endif + let idx += 1 + endwhile " More items following. For each of the possible members find the " matching following members. - return s:SearchMembers(matches, a:items[1:]) + return s:SearchMembers(matches, a:items[idx :]) endif " Failed to find anything. @@ -257,9 +363,6 @@ function! s:SearchMembers(matches, items) for i in range(len(a:matches)) let typename = '' if has_key(a:matches[i], 'dict') - "if a:matches[i].dict['name'] == "gui" - "echomsg string(a:matches[i].dict) - "endif if has_key(a:matches[i].dict, 'typename') let typename = a:matches[i].dict['typename'] endif @@ -273,17 +376,14 @@ function! s:SearchMembers(matches, items) endif endif if typename != '' - call extend(res, s:StructMembers(name, a:items)) + call extend(res, s:StructMembers(typename, a:items)) else " Use the search command (the declaration itself). let s = match(line, '\t\zs/^') if s > 0 let e = match(line, '\<' . a:matches[i]['match'] . '\>', s) if e > 0 - "if a:matches[i].dict['name'] == "gui" - "echomsg strpart(line, s, e - s) - "endif - call extend(res, s:Nextitem(strpart(line, s, e - s), a:items)) + call extend(res, s:Nextitem(strpart(line, s, e - s), a:items, 0)) endif endif endif diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 7bf40408be..41f57561c0 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 01 +*todo.txt* For Vim version 7.0aa. Last change: 2006 Feb 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -37,7 +37,15 @@ Variant of ":helpgrep" that uses a location list? How about: :lmake ccomplete / omnicomplete: -- Also add . or -> when completing struct members. use s:Tag2item() +- Extra info for each entry to show in a tooltip kind of thing. + Should use a dictionary for each entry. Fields could be: + word the completed word + menu menu text (use word when missing) + info extra info, to be displayed in balloon (e.g., function args) + kind single letter indicating the type of word: + v = variable, f = function/method, c = composite (object, + struct pointer). + For C add tag "kind" field? - When an option is set: In completion mode and the user types (identifier) characters, advance to the first match instead of removing the popup menu. If there is no match remove the selection. (Yegappan Lakshmanan) @@ -49,17 +57,10 @@ ccomplete / omnicomplete: Need to postpone inserting anything until all matches have been found. Then add a completion item with the longest common string (after what was typed), if there is one. -- When completing something that is a structure, add the "." or "->" right - away. How to figure out if it's a pointer or not? +- Finding out if an item has members (to add '.' or '->') requires a grep in + the tags files, that is very slow. Is there another solution? At least + stop at the first match. - When a typedef or struct is local to a file only use it in that file? -- Extra info for each entry to show in a tooltip kind of thing. - Should use a dictionary for each entry. Fields could be: - word the completed word - menu menu text (use word when missing) - info extra info, to be displayed in balloon (e.g., function args) - kind single letter indicating the type of word: - v = variable, f = function/method, c = composite (object, - struct pointer). - Special mappings for when the popup menu is visible? Would allow for making a specific selection (e.g, methods vs variables). @@ -113,6 +114,9 @@ spelling: Edward L. Fox explains how it should be done for most Asian languages. (2005 Nov 24) +An error in a function uses a line number that doesn't take line continuation +into account. (Mikolaj Machowski) Store line count in an extra array? + Mac unicode patch (Da Woon Jung): - selecting proportional font breaks display - UTF-8 text causes display problems. Font replacement causes this. @@ -166,7 +170,7 @@ Awaiting response: - mblen(NULL, 0) also in Vim 6.3? -PLANNED FOR VERSION 7.0: +CONSIDERED FOR VERSION 7.0: - Omni completion: Understands the programming language and finds matches that make sense. Esp. members of classes/structs. @@ -278,7 +282,7 @@ PLANNED FOR VERSION 7.0: Then add GUI Tabs for some systems. Patch for GTK 1.2 passed on by Christian Michon, 2004 Jan 6. Simple patch for GTK by Luis M (nov 7). - Don't forget to provide an "X" to close a tab. + Don't forget to provide an "X" to close the current tab. Implementation: keep the list of windows as-is. When switching to another tab make the buffers in the current windows hidden, save the window layout, buildup the other window layout and fill with buffers. diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt index 053e7d18a8..7c9d325b05 100644 --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 01 +*version7.txt* For Vim version 7.0aa. Last change: 2006 Feb 02 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1636,4 +1636,9 @@ characters in v:this_session. In a multi-byte file the foldmarker could be recognized in the trail byte. (Taro Muraoka) +Pasting with CTRL-V and menu didn't work properly when some commands are +mapped. Use ":normal!" instead of ":normal". (Tony Apuzzo) + +Crashed when expanding a file name argument in backticks. + vim:tw=78:ts=8:ft=help:norl: diff --git a/runtime/mswin.vim b/runtime/mswin.vim index 48458ed46b..75c249fb89 100644 --- a/runtime/mswin.vim +++ b/runtime/mswin.vim @@ -1,7 +1,7 @@ " Set options and add mapping such that Vim behaves a lot like MS-Windows " " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last change: 2005 Dec 28 +" Last change: 2006 Feb 02 " bail out if this isn't wanted (mrsvim.vim uses this). if exists("g:skip_loading_mswin") && g:skip_loading_mswin @@ -47,18 +47,18 @@ if has("virtualedit") func! <SID>Paste() let ove = &ve set ve=all - normal `^ + normal! `^ if @+ != '' - normal "+gP + normal! "+gP endif let c = col(".") - normal i + normal! i if col(".") < c " compensate for i<ESC> moving the cursor left " Avoid a beep when the text ends at the window edge. let vb_save = &vb let t_vb_save = &t_vb set vb t_vb= - normal l + normal! l let &vb = vb_save let &t_vb = t_vb_save endif |