# HG changeset patch # User vimboss # Date 1139014796 0 # Node ID 441f938ea9e90e07a05e55fef17ab22d2607f5f3 # Parent 5acda076fb0c14489efc14cb9adde149cc1b4747 updated for version 7.0192 diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim --- a/runtime/autoload/ccomplete.vim +++ b/runtime/autoload/ccomplete.vim @@ -1,13 +1,13 @@ " Vim completion script " Language: C " Maintainer: Bram Moolenaar -" 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, 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, 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 + if s == 0 || base[s - 1] != ']' + call add(items, strpart(base, s, e - s)) 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 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, " 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, 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, " 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 there is a '*' before the name use "->". - if match(res[0]['tagline'], '\*\s*' . res[0]['match'] . '\>') > 0 - let res[0]['match'] .= '->' - else - let res[0]['match'] .= '.' + " 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 - endif + let brackets = items[last] . brackets + let last -= 1 + endwhile - return map(res, 'v:val["match"]') + 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(a:line, '\*[ \t(]*' . a:match . '\>') > 0 + return '->' + else + return '.' + endif + endif + return '' +endfunction + " 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, item 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 --- 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 locat :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 @@ 7 Add plugins for formatting. Should 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 @@ 7 Support WINDOW TABS. Works like sev 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 --- 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 --- 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 -" 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! 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 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