updated for version 7.0144
This commit is contained in:
		| @ -1,8 +1,10 @@ | |||||||
| " Vim completion script | " Vim completion script | ||||||
| " Language:	C | " Language:	C | ||||||
| " Maintainer:	Bram Moolenaar <Bram@vim.org> | " Maintainer:	Bram Moolenaar <Bram@vim.org> | ||||||
| " Last Change:	2005 Sep 07 | " Last Change:	2005 Sep 09 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | " This function is used for the 'occultfunc' option. | ||||||
| function! ccomplete#Complete(findstart, base) | function! ccomplete#Complete(findstart, base) | ||||||
|   if a:findstart |   if a:findstart | ||||||
|     " Locate the start of the item, including "." and "->". |     " Locate the start of the item, including "." and "->". | ||||||
| @ -31,78 +33,140 @@ function! ccomplete#Complete(findstart, base) | |||||||
|     return map(taglist('^' . a:base), 'v:val["name"]') |     return map(taglist('^' . a:base), 'v:val["name"]') | ||||||
|   endif |   endif | ||||||
|  |  | ||||||
|   let basetext = matchstr(a:base, '.*\(\.\|->\)') |   " Find the variable items[0]. | ||||||
|  |   " 1. in current function (like with "gd") | ||||||
|   " Find variable locally in current function, current file or tags file. |   " 2. in tags file(s) (like with ":tag") | ||||||
|   if searchdecl(items[0]) == 0 || searchdecl(items[0], 1) == 0 |   " 3. in current file (like with "gD") | ||||||
|  |   let res = [] | ||||||
|  |   if searchdecl(items[0]) == 0 | ||||||
|     " Found, now figure out the type. |     " Found, now figure out the type. | ||||||
|     " TODO: join previous line if it makes sense |     " TODO: join previous line if it makes sense | ||||||
|     let line = getline('.') |     let line = getline('.') | ||||||
|     let col = col('.') |     let col = col('.') | ||||||
|     let res = ccomplete#Nextitem(strpart(line, 0, col), items[1:], basetext) |     let res = ccomplete#Nextitem(strpart(line, 0, col), items[1:]) | ||||||
|   else |   endif | ||||||
|     " Find the variable in the tags file |  | ||||||
|  |   if len(res) == 0 | ||||||
|  |     " Find the variable in the tags file(s) | ||||||
|     let diclist = taglist('^' . items[0] . '$') |     let diclist = taglist('^' . items[0] . '$') | ||||||
|  |  | ||||||
|     let res = [] |     let res = [] | ||||||
|     for i in range(len(diclist)) |     for i in range(len(diclist)) | ||||||
|       " For now we only recognize a variable. |       " New ctags has the "typename" field. | ||||||
|       " The command in the tags file must be a search pattern that shows the |       if has_key(diclist[i], 'typename') | ||||||
|       " declaration of the variable. | 	call extend(res, ccomplete#StructMembers(diclist[i]['typename'], items[1:])) | ||||||
|  |       endif | ||||||
|  |  | ||||||
|  |       " For a variable use the command, which must be a search pattern that | ||||||
|  |       " shows the declaration of the variable. | ||||||
|       if diclist[i]['kind'] == 'v' |       if diclist[i]['kind'] == 'v' | ||||||
| 	let line = diclist[i]['cmd'] | 	let line = diclist[i]['cmd'] | ||||||
| 	if line[0] == '/' && line[1] == '^' | 	if line[0] == '/' && line[1] == '^' | ||||||
| 	  let line = strpart(line, 2)		" Remove /^ from the cmd |  | ||||||
| 	  let col = match(line, items[0]) | 	  let col = match(line, items[0]) | ||||||
| 	  call extend(res, ccomplete#Nextitem(strpart(line, 0, col), items[1:], basetext) | 	  call extend(res, ccomplete#Nextitem(strpart(line, 2, col - 2), items[1:]) | ||||||
| 	endif | 	endif | ||||||
|       endif |       endif | ||||||
|     endfor |     endfor | ||||||
|   endif |   endif | ||||||
|  |  | ||||||
|   return res |   if len(res) == 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:]) | ||||||
|  |   endif | ||||||
|  |  | ||||||
|  |   " The basetext is up to the last "." or "->" and won't be changed.  The | ||||||
|  |   " matching members are concatenated to this. | ||||||
|  |   let basetext = matchstr(a:base, '.*\(\.\|->\)') | ||||||
|  |   return map(res, 'basetext . v:val') | ||||||
| endfunc | endfunc | ||||||
|  |  | ||||||
| function! ccomplete#Nextitem(lead, items, basetext) | " Find composing type in "lead" and match items[0] with it. | ||||||
|  | " Repeat this recursively for items[1], if it's there. | ||||||
|  | " Return the list of matches. | ||||||
|  | function! ccomplete#Nextitem(lead, items) | ||||||
|  |  | ||||||
|   " Use the text up to the variable name and split it in tokens. |   " Use the text up to the variable name and split it in tokens. | ||||||
|   let tokens = split(a:lead, '\s\+\|\<') |   let tokens = split(a:lead, '\s\+\|\<') | ||||||
|  |  | ||||||
|   " Try to recognize the type of the variable.  This is rough guessing... |   " Try to recognize the type of the variable.  This is rough guessing... | ||||||
|   let members = [] |   let res = [] | ||||||
|   let taglines = [] |  | ||||||
|   for tidx in range(len(tokens)) |   for tidx in range(len(tokens)) | ||||||
|  |  | ||||||
|     " Recognize 'struct foobar'. |     " Recognize "struct foobar" and "union foobar". | ||||||
|     if tokens[tidx] == 'struct' && tidx + 1 < len(tokens) |     if (tokens[tidx] == 'struct' || tokens[tidx] == 'union') && tidx + 1 < len(tokens) | ||||||
|       let [members, taglines] = ccomplete#StructMembers(tokens[tidx + 1], a:items[0]) |       let res = ccomplete#StructMembers(tokens[tidx] . ':' . tokens[tidx + 1], a:items) | ||||||
|       break |       break | ||||||
|     endif |     endif | ||||||
|  |  | ||||||
|     " Recognize a typedef: 'foobar_t'. |     " TODO: add more reserved words | ||||||
|  |     if index(['int', 'float', 'static', 'unsigned', 'extern'], tokens[tidx]) >= 0 | ||||||
|  |       continue | ||||||
|  |     endif | ||||||
|  |  | ||||||
|  |     " Use the tags file to find out if this is a typedef. | ||||||
|     let diclist = taglist('^' . tokens[tidx] . '$') |     let diclist = taglist('^' . tokens[tidx] . '$') | ||||||
|     for i in range(len(diclist)) |     for i in range(len(diclist)) | ||||||
|       " For now we only recognize "typedef struct foobar". |       " New ctags has the "typename" field. | ||||||
|       " The command in the tags file must be a search pattern that shows the |       if has_key(diclist[i], 'typename') | ||||||
|       " typedef. | 	call extend(res, ccomplete#StructMembers(diclist[i]['typename'], a:items)) | ||||||
|  | 	continue | ||||||
|  |       endif | ||||||
|  |  | ||||||
|  |       " For old ctags we only recognize "typedef struct foobar" in the tags | ||||||
|  |       " file command. | ||||||
|       let cmd = diclist[i]['cmd'] |       let cmd = diclist[i]['cmd'] | ||||||
|       let ci = matchend(cmd, 'typedef\s\+struct\s\+') |       let ci = matchend(cmd, 'typedef\s\+struct\s\+') | ||||||
|       if ci > 1 |       if ci > 1 | ||||||
| 	let name = matchstr(cmd, '\w*', ci) | 	let name = matchstr(cmd, '\w*', ci) | ||||||
| 	let [m, l] = ccomplete#StructMembers(name, a:items[0]) | 	call extend(res, ccomplete#StructMembers('struct:' . name, a:items)) | ||||||
| 	call extend(members, m) |  | ||||||
| 	call extend(taglines, l) |  | ||||||
|       endif |       endif | ||||||
|     endfor |     endfor | ||||||
|     if len(members) > 0 |     if len(res) > 0 | ||||||
|       break |       break | ||||||
|     endif |     endif | ||||||
|  |   endfor | ||||||
|  |  | ||||||
|  |   return res | ||||||
|  | endfunction | ||||||
|  |  | ||||||
|  |  | ||||||
|  | " Return a list with resulting matches | ||||||
|  | function! ccomplete#StructMembers(typename, items) | ||||||
|  |   " Todo: What about local structures? | ||||||
|  |   let fnames = join(map(tagfiles(), 'escape(v:val, " \\")')) | ||||||
|  |   if fnames == '' | ||||||
|  |     return [[], []] | ||||||
|  |   endif | ||||||
|  |  | ||||||
|  |   let typename = a:typename | ||||||
|  |   let qflist = [] | ||||||
|  |   while 1 | ||||||
|  |     exe 'silent! vimgrep /\t' . typename . '\>/j ' . fnames | ||||||
|  |     let qflist = getqflist() | ||||||
|  |     if len(qflist) > 0 || match(typename, "::") < 0 | ||||||
|  |       break | ||||||
|  |     endif | ||||||
|  |     " No match for "struct:context::name", remove "context::" and try again. | ||||||
|  |     let typename = substitute(typename, ':[^:]*::', ':', '') | ||||||
|  |   endwhile | ||||||
|  |  | ||||||
|  |   let members = [] | ||||||
|  |   let taglines = [] | ||||||
|  |   for l in qflist | ||||||
|  |     let memb = matchstr(l['text'], '[^\t]*') | ||||||
|  |     if memb =~ '^' . a:items[0] | ||||||
|  |       call add(members, memb) | ||||||
|  |       call add(taglines, l['text']) | ||||||
|  |     endif | ||||||
|   endfor |   endfor | ||||||
|  |  | ||||||
|   if len(members) > 0 |   if len(members) > 0 | ||||||
|  |     " No further items, return the result. | ||||||
|     if len(a:items) == 1 |     if len(a:items) == 1 | ||||||
|       return map(members, 'a:basetext . v:val') |       return members | ||||||
|     endif |     endif | ||||||
|  |  | ||||||
|     " More items following.  For each of the possible members find the |     " More items following.  For each of the possible members find the | ||||||
| @ -110,12 +174,18 @@ function! ccomplete#Nextitem(lead, items, basetext) | |||||||
|     let res = [] |     let res = [] | ||||||
|     for i in range(len(members)) |     for i in range(len(members)) | ||||||
|       let line = taglines[i] |       let line = taglines[i] | ||||||
|       let memb = members[i] |       let e = matchend(line, '\ttypename:') | ||||||
|       let s = match(line, '\t\zs/^') |       if e > 0 | ||||||
|       if s > 0 | 	" Use typename field | ||||||
| 	let e = match(line, members[i], s) | 	let name = matchstr(line, '[^\t]*', e) | ||||||
| 	if e > 0 | 	call extend(res, ccomplete#StructMembers(name, a:items[1:])) | ||||||
| 	  call extend(res, ccomplete#Nextitem(strpart(line, s, e - s), a:items[1:], a:basetext)) |       else | ||||||
|  | 	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:])) | ||||||
|  | 	  endif | ||||||
| 	endif | 	endif | ||||||
|       endif |       endif | ||||||
|     endfor |     endfor | ||||||
| @ -125,23 +195,3 @@ function! ccomplete#Nextitem(lead, items, basetext) | |||||||
|   " Failed to find anything. |   " Failed to find anything. | ||||||
|   return [] |   return [] | ||||||
| endfunction | 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 [members, taglines] |  | ||||||
| endfunction |  | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| *todo.txt*      For Vim version 7.0aa.  Last change: 2005 Sep 07 | *todo.txt*      For Vim version 7.0aa.  Last change: 2005 Sep 09 | ||||||
|  |  | ||||||
|  |  | ||||||
| 		  VIM REFERENCE MANUAL	  by Bram Moolenaar | 		  VIM REFERENCE MANUAL	  by Bram Moolenaar | ||||||
| @ -30,11 +30,10 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|. | |||||||
| 							*known-bugs* | 							*known-bugs* | ||||||
| -------------------- Known bugs and current work ----------------------- | -------------------- Known bugs and current work ----------------------- | ||||||
|  |  | ||||||
| When ":vimgrep" lists filenames while searching they should be shortened. |  | ||||||
| Silence messages for decompressing? |  | ||||||
|  |  | ||||||
| ccomplete: | ccomplete: | ||||||
| - need list of tags files used in 'tags'. | - Publish patch for ctags to add typedecl field. | ||||||
|  |     nameless struct/union doesn't work (TT_MODE in os_vms.c) | ||||||
|  | - When a typedef or struct is local to a file only use it in that file? | ||||||
|  |  | ||||||
| Mac unicode patch (Da Woon Jung): | Mac unicode patch (Da Woon Jung): | ||||||
| - selecting proportional font breaks display | - selecting proportional font breaks display | ||||||
|  | |||||||
| @ -1132,7 +1132,7 @@ do_search(oap, dirc, pat, count, options) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		msg_start(); | 		msg_start(); | ||||||
| 		trunc = msg_strtrunc(msgbuf); | 		trunc = msg_strtrunc(msgbuf, FALSE); | ||||||
|  |  | ||||||
| #ifdef FEAT_RIGHTLEFT | #ifdef FEAT_RIGHTLEFT | ||||||
| 		/* The search pattern could be shown on the right in rightleft | 		/* The search pattern could be shown on the right in rightleft | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user