]> granicus.if.org Git - vim/commitdiff
updated for version 7.0192 v7.0192
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Feb 2006 00:59:56 +0000 (00:59 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Feb 2006 00:59:56 +0000 (00:59 +0000)
runtime/autoload/ccomplete.vim
runtime/doc/todo.txt
runtime/doc/version7.txt
runtime/mswin.vim

index 8fde2d33ebb09e21bf5733ee1293637a47db7afe..5e0c2aea352055adcc5dd78442106e9bb4ed5631 100644 (file)
@@ -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
index 7bf40408be04c98dd6d760e802e63c20d8c0611d..41f57561c05284e653d37027dc5e5dc13ee1b089 100644 (file)
@@ -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.
index 053e7d18a8252eb8b26823a3a114419ec1b5d274..7c9d325b05eb7dc9137624c907bb3c59ff3ccdde 100644 (file)
@@ -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:
index 48458ed46b33d80915260e3cd04499e6a8e5d1d9..75c249fb8920949924065748c16b57b3e2dde95b 100644 (file)
@@ -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\e
+    normal! i\e
     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