This commit is contained in:
rolag
2019-04-28 19:58:13 +01:00
parent 924dd6f14a
commit fb6ff2a593
2 changed files with 155 additions and 175 deletions

View File

@@ -10404,21 +10404,18 @@ static void f_gettabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
getwinvar(argvars, rettv, 1); getwinvar(argvars, rettv, 1);
} }
/* // "gettagstack()" function
* "gettagstack()" function static void f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void
f_gettagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{ {
win_T *wp = curwin; // default is current window win_T *wp = curwin; // default is current window
tv_dict_alloc_ret(rettv); tv_dict_alloc_ret(rettv);
if (argvars[0].v_type != VAR_UNKNOWN) if (argvars[0].v_type != VAR_UNKNOWN) {
{ wp = find_win_by_nr_or_id(&argvars[0]);
wp = find_win_by_nr_or_id(&argvars[0]); if (wp == NULL) {
if (wp == NULL) return;
return; }
} }
get_tagstack(wp, rettv->vval.v_dict); get_tagstack(wp, rettv->vval.v_dict);
@@ -15216,62 +15213,58 @@ static void f_settabwinvar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
setwinvar(argvars, rettv, 1); setwinvar(argvars, rettv, 1);
} }
/* // "settagstack()" function
* "settagstack()" function static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
*/
static void
f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{ {
static char *e_invact2 = N_("E962: Invalid action: '%s'"); static char *e_invact2 = N_("E962: Invalid action: '%s'");
win_T *wp; win_T *wp;
dict_T *d; dict_T *d;
int action = 'r'; int action = 'r';
rettv->vval.v_number = -1; rettv->vval.v_number = -1;
// first argument: window number or id // first argument: window number or id
wp = find_win_by_nr_or_id(&argvars[0]); wp = find_win_by_nr_or_id(&argvars[0]);
if (wp == NULL) if (wp == NULL) {
return; return;
}
// second argument: dict with items to set in the tag stack // second argument: dict with items to set in the tag stack
if (argvars[1].v_type != VAR_DICT) if (argvars[1].v_type != VAR_DICT) {
{ EMSG(_(e_dictreq));
EMSG(_(e_dictreq)); return;
return;
} }
d = argvars[1].vval.v_dict; d = argvars[1].vval.v_dict;
if (d == NULL) if (d == NULL) {
return; return;
}
// third argument: action - 'a' for append and 'r' for replace. // third argument: action - 'a' for append and 'r' for replace.
// default is to replace the stack. // default is to replace the stack.
if (argvars[2].v_type == VAR_UNKNOWN) if (argvars[2].v_type == VAR_UNKNOWN) {
action = 'r'; action = 'r';
else if (argvars[2].v_type == VAR_STRING) } else if (argvars[2].v_type == VAR_STRING) {
{ const char *actstr;
const char *actstr; actstr = tv_get_string_chk(&argvars[2]);
actstr = tv_get_string_chk(&argvars[2]); if (actstr == NULL) {
if (actstr == NULL) return;
return; }
if ((*actstr == 'r' || *actstr == 'a') && actstr[1] == NUL) if ((*actstr == 'r' || *actstr == 'a') && actstr[1] == NUL) {
action = *actstr; action = *actstr;
else } else {
{ EMSG2(_(e_invact2), actstr);
EMSG2(_(e_invact2), actstr); return;
return; }
} } else {
} EMSG(_(e_stringreq));
else return;
{
EMSG(_(e_stringreq));
return;
} }
if (set_tagstack(wp, d, action) == OK) if (set_tagstack(wp, d, action) == OK) {
rettv->vval.v_number = 0; rettv->vval.v_number = 0;
else } else {
EMSG(_(e_listreq)); EMSG(_(e_listreq));
}
} }
/* /*

View File

@@ -2864,201 +2864,188 @@ int get_tags(list_T *list, char_u *pat, char_u *buf_fname)
return ret; return ret;
} }
/* // Return information about 'tag' in dict 'retdict'.
* Return information about 'tag' in dict 'retdict'. static void get_tag_details(taggy_T *tag, dict_T *retdict)
*/
static void
get_tag_details(taggy_T *tag, dict_T *retdict)
{ {
list_T *pos; list_T *pos;
fmark_T *fmark; fmark_T *fmark;
tv_dict_add_str(retdict, S_LEN("tagname"), (const char *)tag->tagname); tv_dict_add_str(retdict, S_LEN("tagname"), (const char *)tag->tagname);
tv_dict_add_nr(retdict, S_LEN("matchnr"), tag->cur_match + 1); tv_dict_add_nr(retdict, S_LEN("matchnr"), tag->cur_match + 1);
tv_dict_add_nr(retdict, S_LEN("bufnr"), tag->cur_fnum); tv_dict_add_nr(retdict, S_LEN("bufnr"), tag->cur_fnum);
if ((pos = tv_list_alloc(4)) == NULL) if ((pos = tv_list_alloc(4)) == NULL) {
return; return;
}
tv_dict_add_list(retdict, S_LEN("from"), pos); tv_dict_add_list(retdict, S_LEN("from"), pos);
fmark = &tag->fmark; fmark = &tag->fmark;
tv_list_append_number(pos, tv_list_append_number(pos,
(varnumber_T)(fmark->fnum != -1 ? fmark->fnum : 0)); (varnumber_T)(fmark->fnum != -1 ? fmark->fnum : 0));
tv_list_append_number(pos, (varnumber_T)fmark->mark.lnum); tv_list_append_number(pos, (varnumber_T)fmark->mark.lnum);
tv_list_append_number(pos, (varnumber_T)(fmark->mark.col == MAXCOL ? tv_list_append_number(pos, (varnumber_T)(fmark->mark.col == MAXCOL ?
MAXCOL : fmark->mark.col + 1)); MAXCOL : fmark->mark.col + 1));
tv_list_append_number(pos, (varnumber_T)fmark->mark.coladd); tv_list_append_number(pos, (varnumber_T)fmark->mark.coladd);
} }
/* // Return the tag stack entries of the specified window 'wp' in dictionary
* Return the tag stack entries of the specified window 'wp' in dictionary // 'retdict'.
* 'retdict'. void get_tagstack(win_T *wp, dict_T *retdict)
*/
void
get_tagstack(win_T *wp, dict_T *retdict)
{ {
list_T *l; list_T *l;
int i; int i;
dict_T *d; dict_T *d;
tv_dict_add_nr(retdict, S_LEN("length"), wp->w_tagstacklen); tv_dict_add_nr(retdict, S_LEN("length"), wp->w_tagstacklen);
tv_dict_add_nr(retdict, S_LEN("curidx"), wp->w_tagstackidx + 1); tv_dict_add_nr(retdict, S_LEN("curidx"), wp->w_tagstackidx + 1);
l = tv_list_alloc(2); l = tv_list_alloc(2);
if (l == NULL) if (l == NULL) {
return; return;
}
tv_dict_add_list(retdict, S_LEN("items"), l); tv_dict_add_list(retdict, S_LEN("items"), l);
for (i = 0; i < wp->w_tagstacklen; i++) for (i = 0; i < wp->w_tagstacklen; i++) {
{ if ((d = tv_dict_alloc()) == NULL) {
if ((d = tv_dict_alloc()) == NULL) return;
return; }
tv_list_append_dict(l, d); tv_list_append_dict(l, d);
get_tag_details(&wp->w_tagstack[i], d); get_tag_details(&wp->w_tagstack[i], d);
} }
} }
/* // Free all the entries in the tag stack of the specified window
* Free all the entries in the tag stack of the specified window static void tagstack_clear(win_T *wp)
*/
static void
tagstack_clear(win_T *wp)
{ {
int i; int i;
// Free the current tag stack // Free the current tag stack
for (i = 0; i < wp->w_tagstacklen; ++i) for (i = 0; i < wp->w_tagstacklen; i++) {
xfree(wp->w_tagstack[i].tagname); xfree(wp->w_tagstack[i].tagname);
}
wp->w_tagstacklen = 0; wp->w_tagstacklen = 0;
wp->w_tagstackidx = 0; wp->w_tagstackidx = 0;
} }
/* // Remove the oldest entry from the tag stack and shift the rest of
* Remove the oldest entry from the tag stack and shift the rest of // the entires to free up the top of the stack.
* the entires to free up the top of the stack. static void tagstack_shift(win_T *wp)
*/
static void
tagstack_shift(win_T *wp)
{ {
taggy_T *tagstack = wp->w_tagstack; taggy_T *tagstack = wp->w_tagstack;
int i; int i;
xfree(tagstack[0].tagname); xfree(tagstack[0].tagname);
for (i = 1; i < wp->w_tagstacklen; ++i) for (i = 1; i < wp->w_tagstacklen; i++) {
tagstack[i - 1] = tagstack[i]; tagstack[i - 1] = tagstack[i];
}
wp->w_tagstacklen--; wp->w_tagstacklen--;
} }
/* // Push a new item to the tag stack
* Push a new item to the tag stack static void tagstack_push_item(
*/ win_T *wp,
static void char_u *tagname,
tagstack_push_item( int cur_fnum,
win_T *wp, int cur_match,
char_u *tagname, pos_T mark,
int cur_fnum, int fnum)
int cur_match,
pos_T mark,
int fnum)
{ {
taggy_T *tagstack = wp->w_tagstack; taggy_T *tagstack = wp->w_tagstack;
int idx = wp->w_tagstacklen; // top of the stack int idx = wp->w_tagstacklen; // top of the stack
// if the tagstack is full: remove the oldest entry // if the tagstack is full: remove the oldest entry
if (idx >= TAGSTACKSIZE) if (idx >= TAGSTACKSIZE) {
{ tagstack_shift(wp);
tagstack_shift(wp); idx = TAGSTACKSIZE - 1;
idx = TAGSTACKSIZE - 1;
} }
wp->w_tagstacklen++; wp->w_tagstacklen++;
tagstack[idx].tagname = tagname; tagstack[idx].tagname = tagname;
tagstack[idx].cur_fnum = cur_fnum; tagstack[idx].cur_fnum = cur_fnum;
tagstack[idx].cur_match = cur_match; tagstack[idx].cur_match = cur_match;
if (tagstack[idx].cur_match < 0) if (tagstack[idx].cur_match < 0) {
tagstack[idx].cur_match = 0; tagstack[idx].cur_match = 0;
}
tagstack[idx].fmark.mark = mark; tagstack[idx].fmark.mark = mark;
tagstack[idx].fmark.fnum = fnum; tagstack[idx].fmark.fnum = fnum;
} }
/* // Add a list of items to the tag stack in the specified window
* Add a list of items to the tag stack in the specified window static void tagstack_push_items(win_T *wp, list_T *l)
*/
static void
tagstack_push_items(win_T *wp, list_T *l)
{ {
listitem_T *li; listitem_T *li;
dictitem_T *di; dictitem_T *di;
dict_T *itemdict; dict_T *itemdict;
char_u *tagname; char_u *tagname;
pos_T mark; pos_T mark;
int fnum; int fnum;
// Add one entry at a time to the tag stack // Add one entry at a time to the tag stack
for (li = l->lv_first; li != NULL; li = li->li_next) for (li = tv_list_first(l); li != NULL; li = TV_LIST_ITEM_NEXT(l, li)) {
{ if (TV_LIST_ITEM_TV(li)->v_type != VAR_DICT
if (li->li_tv.v_type != VAR_DICT || li->li_tv.vval.v_dict == NULL) || TV_LIST_ITEM_TV(li)->vval.v_dict == NULL) {
continue; // Skip non-dict items continue; // Skip non-dict items
itemdict = li->li_tv.vval.v_dict; }
itemdict = TV_LIST_ITEM_TV(li)->vval.v_dict;
// parse 'from' for the cursor position before the tag jump // parse 'from' for the cursor position before the tag jump
if ((di = tv_dict_find(itemdict, "from", -1)) == NULL) if ((di = tv_dict_find(itemdict, "from", -1)) == NULL) {
continue; continue;
if (list2fpos(&di->di_tv, &mark, &fnum, NULL) != OK) }
continue; if (list2fpos(&di->di_tv, &mark, &fnum, NULL) != OK) {
if ((tagname = (char_u *) continue;
tv_dict_get_string(itemdict, "tagname", TRUE)) == NULL) }
continue; if ((tagname = (char_u *)
tv_dict_get_string(itemdict, "tagname", true)) == NULL) {
continue;
}
if (mark.col > 0) if (mark.col > 0) {
mark.col--; mark.col--;
tagstack_push_item(wp, tagname, }
(int)tv_dict_get_number(itemdict, "bufnr"), tagstack_push_item(wp, tagname,
(int)tv_dict_get_number(itemdict, "matchnr") - 1, (int)tv_dict_get_number(itemdict, "bufnr"),
mark, fnum); (int)tv_dict_get_number(itemdict, "matchnr") - 1,
mark, fnum);
} }
} }
/* // Set the current index in the tag stack. Valid values are between 0
* Set the current index in the tag stack. Valid values are between 0 // and the stack length (inclusive).
* and the stack length (inclusive). static void tagstack_set_curidx(win_T *wp, int curidx)
*/
static void
tagstack_set_curidx(win_T *wp, int curidx)
{ {
wp->w_tagstackidx = curidx; wp->w_tagstackidx = curidx;
if (wp->w_tagstackidx < 0) // sanity check if (wp->w_tagstackidx < 0) { // sanity check
wp->w_tagstackidx = 0; wp->w_tagstackidx = 0;
if (wp->w_tagstackidx > wp->w_tagstacklen) }
wp->w_tagstackidx = wp->w_tagstacklen; if (wp->w_tagstackidx > wp->w_tagstacklen) {
wp->w_tagstackidx = wp->w_tagstacklen;
}
} }
/* // Set the tag stack entries of the specified window.
* Set the tag stack entries of the specified window. // 'action' is set to either 'a' for append or 'r' for replace.
* 'action' is set to either 'a' for append or 'r' for replace. int set_tagstack(win_T *wp, dict_T *d, int action)
*/
int
set_tagstack(win_T *wp, dict_T *d, int action)
{ {
dictitem_T *di; dictitem_T *di;
list_T *l; list_T *l;
if ((di = tv_dict_find(d, "items", -1)) != NULL) if ((di = tv_dict_find(d, "items", -1)) != NULL) {
{ if (di->di_tv.v_type != VAR_LIST) {
if (di->di_tv.v_type != VAR_LIST) return FAIL;
{ }
return FAIL; l = di->di_tv.vval.v_list;
}
l = di->di_tv.vval.v_list;
if (action == 'r') if (action == 'r') {
tagstack_clear(wp); tagstack_clear(wp);
}
tagstack_push_items(wp, l); tagstack_push_items(wp, l);
} }
if ((di = tv_dict_find(d, "curidx", -1)) != NULL) if ((di = tv_dict_find(d, "curidx", -1)) != NULL) {
tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1); tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1);
}
return OK; return OK;
} }