# HG changeset patch # User vimboss # Date 1125958486 0 # Node ID 7e6d264ec0a270beb9692df71fedb210c1896640 # Parent 35cde31bdcbd2bf6fe860e49101243905579ebba updated for version 7.0141 diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim --- a/runtime/autoload/ccomplete.vim +++ b/runtime/autoload/ccomplete.vim @@ -1,7 +1,7 @@ " Vim completion script " Language: C " Maintainer: Bram Moolenaar -" Last Change: 2005 Sep 01 +" Last Change: 2005 Sep 05 function! ccomplete#Complete(findstart, base) if a:findstart @@ -21,12 +21,81 @@ function! ccomplete#Complete(findstart, endif " return list of matches - let items = split(a:base, '\.\|->') - if len(items) == 1 + if a:base !~ '\.\|->' " Only one part, no "." or "->": complete from tags file. - let diclist = taglist(items[0]) + let diclist = taglist(a:base) return map(diclist, 'v:val["name"]') endif - return items + + " Find variable locally in function or file. + let items = split(a:base, '\.\|->') + + " At the moment we only do "aa.bb", not "aa.bb.cc" + if len(items) > 2 + return [] + endif + + let line = '' + 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('.') + else + " Find the variable in the tags file + let diclist = taglist(items[0]) + for i in range(len(diclist)) + " For now we only recognize a 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) + endif + let col = match(line, items[0]) + break + endif + endfor + endif + + if line == '' + return [] + endif + + " 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' + break + endif + endwhile + + " 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, '.*\.\|->') + + 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 /\/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) + endif + endfor + return res + endif + endfor + + return tokens endfunction 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: 2005 Sep 01 +*todo.txt* For Vim version 7.0aa. Last change: 2005 Sep 05 VIM REFERENCE MANUAL by Bram Moolenaar @@ -86,6 +86,7 @@ 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 How to get the members of that type? tags file has struct: and class: fields 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: 2005 Aug 31 +*version7.txt* For Vim version 7.0aa. Last change: 2005 Sep 05 VIM REFERENCE MANUAL by Bram Moolenaar @@ -123,6 +123,10 @@ When making a string upper-case with "vl s is replaced with "SS". This does not happen with "~" to avoid backwards compatibility problems and because "SS" can't be changed back to a sharp s. +"gd" previously found the very first occurrence of a variable in a function, +that could be the function argument without type. Now it finds the position +where the type is given. + ============================================================================== NEW FEATURES *new-7* @@ -569,6 +573,8 @@ When 'verbose' is set the output of the ":function" and ":autocmd" commands will show where it was last defined. (Yegappan Lakshmanan) +":function /pattern" lists functions matching the pattern. + ============================================================================== IMPROVEMENTS *improvements-7* diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -580,6 +580,7 @@ static void f_repeat __ARGS((typval_T *a static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_searchdecl __ARGS((typval_T *argvars, typval_T *rettv)); static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); @@ -6818,6 +6819,7 @@ static struct fst {"resolve", 1, 1, f_resolve}, {"reverse", 1, 1, f_reverse}, {"search", 1, 2, f_search}, + {"searchdecl", 1, 2, f_searchdecl}, {"searchpair", 3, 5, f_searchpair}, {"server2client", 2, 2, f_server2client}, {"serverlist", 0, 0, f_serverlist}, @@ -12976,6 +12978,28 @@ theend: } /* + * "searchdecl()" function + */ + static void +f_searchdecl(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + int locally = 1; + int error = FALSE; + char_u *name; + + rettv->vval.v_number = 1; /* default: FAIL */ + + name = get_tv_string_chk(&argvars[0]); + if (argvars[1].v_type != VAR_UNKNOWN) + locally = get_tv_number_chk(&argvars[1], &error) == 0; + if (!error && name != NULL) + rettv->vval.v_number = find_decl(name, (int)STRLEN(name), + locally, SEARCH_KEEP) == FAIL; +} + +/* * "searchpair()" function */ static void @@ -16801,6 +16825,44 @@ ex_function(eap) } /* + * ":function /pat": list functions matching pattern. + */ + if (*eap->arg == '/') + { + p = skip_regexp(eap->arg + 1, '/', TRUE, NULL); + if (!eap->skip) + { + regmatch_T regmatch; + + c = *p; + *p = NUL; + regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC); + *p = c; + if (regmatch.regprog != NULL) + { + regmatch.rm_ic = p_ic; + + todo = func_hashtab.ht_used; + for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) + { + if (!HASHITEM_EMPTY(hi)) + { + --todo; + fp = HI2UF(hi); + if (!isdigit(*fp->uf_name) + && vim_regexec(®match, fp->uf_name, 0)) + list_func_head(fp, FALSE); + } + } + } + } + if (*p == '/') + ++p; + eap->nextcmd = check_nextcmd(p); + return; + } + + /* * Get the function name. There are these situations: * func normal function name * "name" == func, "fudi.fd_dict" == NULL diff --git a/src/proto/search.pro b/src/proto/search.pro --- a/src/proto/search.pro +++ b/src/proto/search.pro @@ -17,7 +17,7 @@ pos_T *findmatch __ARGS((oparg_T *oap, i pos_T *findmatchlimit __ARGS((oparg_T *oap, int initc, int flags, int maxtravel)); void showmatch __ARGS((int c)); int findsent __ARGS((int dir, long count)); -int findpar __ARGS((oparg_T *oap, int dir, long count, int what, int both)); +int findpar __ARGS((int *pincl, int dir, long count, int what, int both)); int startPS __ARGS((linenr_T lnum, int para, int both)); int fwd_word __ARGS((long count, int bigword, int eol)); int bck_word __ARGS((long count, int bigword, int stop));