changeset 511:32cf0d2e14b4

updated for version 7.0143
author vimboss
date Wed, 07 Sep 2005 21:21:14 +0000
parents b47114409935
children f607f15ab091
files runtime/autoload/ccomplete.vim runtime/doc/todo.txt runtime/doc/version7.txt
diffstat 3 files changed, 112 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/autoload/ccomplete.vim
+++ b/runtime/autoload/ccomplete.vim
@@ -1,11 +1,11 @@
 " Vim completion script
 " Language:	C
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2005 Sep 05
+" Last Change:	2005 Sep 07
 
 function! ccomplete#Complete(findstart, base)
   if a:findstart
-    " locate the start of the word
+    " Locate the start of the item, including "." and "->".
     let line = getline('.')
     let start = col('.') - 1
     while start > 0
@@ -20,82 +20,128 @@ function! ccomplete#Complete(findstart, 
     return start
   endif
 
-  " return list of matches
-  if a:base !~ '\.\|->'
+  " Return list of matches.
+
+  " Split item in words, keep empty word after "." or "->".
+  " "aa" -> ['aa'], "aa." -> ['aa', ''], "aa.bb" -> ['aa', 'bb'], etc.
+  let items = split(a:base, '\.\|->', 1)
+  if len(items) <= 1
     " Only one part, no "." or "->": complete from tags file.
-    let diclist = taglist(a:base)
-    return map(diclist, 'v:val["name"]')
+    " When local completion is wanted CTRL-N would have been used.
+    return map(taglist('^' . a:base), 'v:val["name"]')
   endif
 
-  " Find variable locally in function or file.
-  let items = split(a:base, '\.\|->')
+  let basetext = matchstr(a:base, '.*\(\.\|->\)')
 
-  " At the moment we only do "aa.bb", not "aa.bb.cc"
-  if len(items) > 2
-    return []
-  endif
-
-  let line = ''
+  " Find variable locally in current function, current file or tags file.
   if searchdecl(items[0]) == 0 || searchdecl(items[0], 1) == 0
     " Found, now figure out the type.
     " TODO: join previous line if it makes sense
     let line = getline('.')
     let col = col('.')
+    let res = ccomplete#Nextitem(strpart(line, 0, col), items[1:], basetext)
   else
     " Find the variable in the tags file
-    let diclist = taglist(items[0])
+    let diclist = taglist('^' . items[0] . '$')
+
+    let res = []
     for i in range(len(diclist))
       " For now we only recognize a variable.
+      " The command in the tags file must be a search pattern that shows the
+      " declaration of the variable.
       if diclist[i]['kind'] == 'v'
 	let line = diclist[i]['cmd']
 	if line[0] == '/' && line[1] == '^'
-	  " the command is a search pattern, remove the leading /^
-	  let line = strpart(line, 2)
+	  let line = strpart(line, 2)		" Remove /^ from the cmd
+	  let col = match(line, items[0])
+	  call extend(res, ccomplete#Nextitem(strpart(line, 0, col), items[1:], basetext)
 	endif
-	let col = match(line, items[0])
-	break
       endif
     endfor
   endif
 
-  if line == ''
-    return []
-  endif
+  return res
+endfunc
+
+function! ccomplete#Nextitem(lead, items, basetext)
+
+  " Use the text up to the variable name and split it in tokens.
+  let tokens = split(a:lead, '\s\+\|\<')
+
+  " Try to recognize the type of the variable.  This is rough guessing...
+  let members = []
+  let taglines = []
+  for tidx in range(len(tokens))
 
-  " Is there a * before the variable name?
-  let col -= 1
-  let star = 0
-  while col > 0
-    let col -= 1
-    if line[col] == '*'
-      let star = 1
-    elseif line[col] !~ '\s'
+    " Recognize 'struct foobar'.
+    if tokens[tidx] == 'struct' && tidx + 1 < len(tokens)
+      let [members, taglines] = ccomplete#StructMembers(tokens[tidx + 1], a:items[0])
+      break
+    endif
+
+    " Recognize a typedef: 'foobar_t'.
+    let diclist = taglist('^' . tokens[tidx] . '$')
+    for i in range(len(diclist))
+      " For now we only recognize "typedef struct foobar".
+      " The command in the tags file must be a search pattern that shows the
+      " typedef.
+      let cmd = diclist[i]['cmd']
+      let ci = matchend(cmd, 'typedef\s\+struct\s\+')
+      if ci > 1
+	let name = matchstr(cmd, '\w*', ci)
+	let [m, l] = ccomplete#StructMembers(name, a:items[0])
+	call extend(members, m)
+	call extend(taglines, l)
+      endif
+    endfor
+    if len(members) > 0
       break
     endif
-  endwhile
+
+  endfor
 
-  " Use the line up to the variable name and split it in tokens.
-  let lead = strpart(line, 0, col + 1)
-  let tokens = split(lead, '\s\+\|\<')
-
-  let basetext = matchstr(a:base, '.*\.\|->')
+  if len(members) > 0
+    if len(a:items) == 1
+      return map(members, 'a:basetext . v:val')
+    endif
 
-  for i in range(len(tokens) - 1)
-    if tokens[i] == 'struct'
-      let name = tokens[i + 1]
-      " Todo: Use all tags files; What about local structures?
-      exe 'vimgrep /\<struct:' . name . '\>/j tags'
-      let res = []
-      for l in getqflist()
-	let memb = matchstr(l['text'], '[^\t]*')
-	if len(items) == 1 || memb =~ '^' . items[1]
-	  call add(res, basetext . memb)
+    " More items following.  For each of the possible members find the
+    " matching following members.
+    let res = []
+    for i in range(len(members))
+      let line = taglines[i]
+      let memb = members[i]
+      let s = match(line, '\t\zs/^')
+      if s > 0
+	let e = match(line, members[i], s)
+	if e > 0
+	  call extend(res, ccomplete#Nextitem(strpart(line, s, e - s), a:items[1:], a:basetext))
 	endif
-      endfor
-      return res
+      endif
+    endfor
+    return res
+  endif
+
+  " Failed to find anything.
+  return []
+endfunction
+
+
+" Return a list with two lists:
+" - a list of members of structure "name" starting with string "item".
+" - a list of the tag lines where the member is defined.
+function! ccomplete#StructMembers(name, item)
+  " Todo: Use all tags files; What about local structures?
+  exe 'vimgrep /\<struct:' . a:name . '\>/j tags'
+
+  let members = []
+  let taglines = []
+  for l in getqflist()
+    let memb = matchstr(l['text'], '[^\t]*')
+    if memb =~ '^' . a:item
+      call add(members, memb)
+      call add(taglines, l['text'])
     endif
   endfor
-
-  return tokens
+  return [members, taglines]
 endfunction
-
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Sep 06
+*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Sep 07
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,12 +30,11 @@ be worked on, but only if you sponsor Vi
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-When ":vimgrep" lists filenames they should be shortened.  Silence messages
-for decompressing.
+When ":vimgrep" lists filenames while searching they should be shortened.
+Silence messages for decompressing?
 
-When 'rl' is set "q/" causes hit-enter prompt.
-
-Try out using the free MS compiler and debugger, using Make_mvc.mak.
+ccomplete:
+- need list of tags files used in 'tags'.
 
 Mac unicode patch (Da Woon Jung):
 - selecting proportional font breaks display
@@ -43,6 +42,7 @@ Mac unicode patch (Da Woon Jung):
 
 Win32: Use the free downloadable compiler 7.1.  Figure out how to do debugging
 (with Agide?) and describe it. (George Reilly)
+Try out using the free MS compiler and debugger, using Make_mvc.mak.
 
 Autoload:
 - Add a Vim script in $VIMRUNTIME/tools that takes a file with a list of
@@ -91,7 +91,8 @@ PLANNED FOR VERSION 7.0:
 	    How to get the type of "var"?
 		tags file doesn't give type of typedef!  E.g., oparg_T is
 		listed with "^} oparg_T;$"
-		mlcscope may do it, but I can't find the sources
+		mlcscope may do it, but it's not very portable.
+		    http://www.exptools.com/cscope
 	    How to get the members of that type?
 		tags file has struct: and class: fields
 
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Sep 06
+*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Sep 07
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1326,4 +1326,10 @@ Could be noticed with a Thai font.
 Output of ":function" could leave some of the typed text behind. (Yegappan
 Lakshmanan)
 
+When the command line history has only a few lines the command line window
+would be opened with these lines above the first window line.
+
+When using a command line window for search strings ":qa" would result in
+searching for "qa" instead of quitting all windows.
+
  vim:tw=78:ts=8:ft=help:norl: