Mercurial > vim
comparison src/tag.c @ 15016:c338c91086b9 v8.1.0519
patch 8.1.0519: cannot save and restore the tag stack
commit https://github.com/vim/vim/commit/f49cc60aa802862c595ff619dccc11271633a94b
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Nov 11 15:21:05 2018 +0100
patch 8.1.0519: cannot save and restore the tag stack
Problem: Cannot save and restore the tag stack.
Solution: Add gettagstack() and settagstack(). (Yegappan Lakshmanan,
closes #3604)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 11 Nov 2018 15:30:07 +0100 |
parents | 27b9a84395b5 |
children | 7903dce131d4 |
comparison
equal
deleted
inserted
replaced
15015:abcfa9dcc93f | 15016:c338c91086b9 |
---|---|
4014 } | 4014 } |
4015 vim_free(matches); | 4015 vim_free(matches); |
4016 } | 4016 } |
4017 return ret; | 4017 return ret; |
4018 } | 4018 } |
4019 #endif | 4019 |
4020 /* | |
4021 * Return information about 'tag' in dict 'retdict'. | |
4022 */ | |
4023 static void | |
4024 get_tag_details(taggy_T *tag, dict_T *retdict) | |
4025 { | |
4026 list_T *pos; | |
4027 fmark_T *fmark; | |
4028 | |
4029 dict_add_string(retdict, "tagname", tag->tagname); | |
4030 dict_add_number(retdict, "matchnr", tag->cur_match + 1); | |
4031 dict_add_number(retdict, "bufnr", tag->cur_fnum); | |
4032 | |
4033 if ((pos = list_alloc_id(aid_tagstack_from)) == NULL) | |
4034 return; | |
4035 dict_add_list(retdict, "from", pos); | |
4036 | |
4037 fmark = &tag->fmark; | |
4038 list_append_number(pos, | |
4039 (varnumber_T)(fmark->fnum != -1 ? fmark->fnum : 0)); | |
4040 list_append_number(pos, (varnumber_T)fmark->mark.lnum); | |
4041 list_append_number(pos, (varnumber_T)(fmark->mark.col == MAXCOL ? | |
4042 MAXCOL : fmark->mark.col + 1)); | |
4043 list_append_number(pos, (varnumber_T)fmark->mark.coladd); | |
4044 } | |
4045 | |
4046 /* | |
4047 * Return the tag stack entries of the specified window 'wp' in dictionary | |
4048 * 'retdict'. | |
4049 */ | |
4050 void | |
4051 get_tagstack(win_T *wp, dict_T *retdict) | |
4052 { | |
4053 list_T *l; | |
4054 int i; | |
4055 dict_T *d; | |
4056 | |
4057 dict_add_number(retdict, "length", wp->w_tagstacklen); | |
4058 dict_add_number(retdict, "curidx", wp->w_tagstackidx + 1); | |
4059 l = list_alloc_id(aid_tagstack_items); | |
4060 if (l == NULL) | |
4061 return; | |
4062 dict_add_list(retdict, "items", l); | |
4063 | |
4064 for (i = 0; i < wp->w_tagstacklen; i++) | |
4065 { | |
4066 if ((d = dict_alloc_id(aid_tagstack_details)) == NULL) | |
4067 return; | |
4068 list_append_dict(l, d); | |
4069 | |
4070 get_tag_details(&wp->w_tagstack[i], d); | |
4071 } | |
4072 } | |
4073 | |
4074 /* | |
4075 * Free all the entries in the tag stack of the specified window | |
4076 */ | |
4077 static void | |
4078 tagstack_clear(win_T *wp) | |
4079 { | |
4080 int i; | |
4081 | |
4082 // Free the current tag stack | |
4083 for (i = 0; i < wp->w_tagstacklen; ++i) | |
4084 vim_free(wp->w_tagstack[i].tagname); | |
4085 wp->w_tagstacklen = 0; | |
4086 wp->w_tagstackidx = 0; | |
4087 } | |
4088 | |
4089 /* | |
4090 * Remove the oldest entry from the tag stack and shift the rest of | |
4091 * the entires to free up the top of the stack. | |
4092 */ | |
4093 static void | |
4094 tagstack_shift(win_T *wp) | |
4095 { | |
4096 taggy_T *tagstack = wp->w_tagstack; | |
4097 int i; | |
4098 | |
4099 vim_free(tagstack[0].tagname); | |
4100 for (i = 1; i < wp->w_tagstacklen; ++i) | |
4101 tagstack[i - 1] = tagstack[i]; | |
4102 wp->w_tagstacklen--; | |
4103 } | |
4104 | |
4105 /* | |
4106 * Push a new item to the tag stack | |
4107 */ | |
4108 static void | |
4109 tagstack_push_item( | |
4110 win_T *wp, | |
4111 char_u *tagname, | |
4112 int cur_fnum, | |
4113 int cur_match, | |
4114 pos_T mark, | |
4115 int fnum) | |
4116 { | |
4117 taggy_T *tagstack = wp->w_tagstack; | |
4118 int idx = wp->w_tagstacklen; // top of the stack | |
4119 | |
4120 // if the tagstack is full: remove the oldest entry | |
4121 if (idx >= TAGSTACKSIZE) | |
4122 { | |
4123 tagstack_shift(wp); | |
4124 idx = TAGSTACKSIZE - 1; | |
4125 } | |
4126 | |
4127 wp->w_tagstacklen++; | |
4128 tagstack[idx].tagname = tagname; | |
4129 tagstack[idx].cur_fnum = cur_fnum; | |
4130 tagstack[idx].cur_match = cur_match; | |
4131 if (tagstack[idx].cur_match < 0) | |
4132 tagstack[idx].cur_match = 0; | |
4133 tagstack[idx].fmark.mark = mark; | |
4134 tagstack[idx].fmark.fnum = fnum; | |
4135 } | |
4136 | |
4137 /* | |
4138 * Add a list of items to the tag stack in the specified window | |
4139 */ | |
4140 static void | |
4141 tagstack_push_items(win_T *wp, list_T *l) | |
4142 { | |
4143 listitem_T *li; | |
4144 dictitem_T *di; | |
4145 dict_T *itemdict; | |
4146 char_u *tagname; | |
4147 pos_T mark; | |
4148 int fnum; | |
4149 | |
4150 // Add one entry at a time to the tag stack | |
4151 for (li = l->lv_first; li != NULL; li = li->li_next) | |
4152 { | |
4153 if (li->li_tv.v_type != VAR_DICT || li->li_tv.vval.v_dict == NULL) | |
4154 continue; // Skip non-dict items | |
4155 itemdict = li->li_tv.vval.v_dict; | |
4156 | |
4157 // parse 'from' for the cursor position before the tag jump | |
4158 if ((di = dict_find(itemdict, (char_u *)"from", -1)) == NULL) | |
4159 continue; | |
4160 if (list2fpos(&di->di_tv, &mark, &fnum, NULL) != OK) | |
4161 continue; | |
4162 if ((tagname = | |
4163 get_dict_string(itemdict, (char_u *)"tagname", TRUE)) == NULL) | |
4164 continue; | |
4165 | |
4166 if (mark.col > 0) | |
4167 mark.col--; | |
4168 tagstack_push_item(wp, tagname, | |
4169 (int)get_dict_number(itemdict, (char_u *)"bufnr"), | |
4170 (int)get_dict_number(itemdict, (char_u *)"matchnr") - 1, | |
4171 mark, fnum); | |
4172 } | |
4173 } | |
4174 | |
4175 /* | |
4176 * Set the current index in the tag stack. Valid values are between 0 | |
4177 * and the stack length (inclusive). | |
4178 */ | |
4179 static void | |
4180 tagstack_set_curidx(win_T *wp, int curidx) | |
4181 { | |
4182 wp->w_tagstackidx = curidx; | |
4183 if (wp->w_tagstackidx < 0) // sanity check | |
4184 wp->w_tagstackidx = 0; | |
4185 if (wp->w_tagstackidx > wp->w_tagstacklen) | |
4186 wp->w_tagstackidx = wp->w_tagstacklen; | |
4187 } | |
4188 | |
4189 /* | |
4190 * Set the tag stack entries of the specified window. | |
4191 * 'action' is set to either 'a' for append or 'r' for replace. | |
4192 */ | |
4193 int | |
4194 set_tagstack(win_T *wp, dict_T *d, int action) | |
4195 { | |
4196 dictitem_T *di; | |
4197 list_T *l; | |
4198 | |
4199 if ((di = dict_find(d, (char_u *)"items", -1)) != NULL) | |
4200 { | |
4201 if (di->di_tv.v_type != VAR_LIST) | |
4202 { | |
4203 EMSG(_(e_listreq)); | |
4204 return FAIL; | |
4205 } | |
4206 l = di->di_tv.vval.v_list; | |
4207 | |
4208 if (action == 'r') | |
4209 tagstack_clear(wp); | |
4210 | |
4211 tagstack_push_items(wp, l); | |
4212 } | |
4213 | |
4214 if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL) | |
4215 tagstack_set_curidx(wp, (int)get_tv_number(&di->di_tv) - 1); | |
4216 | |
4217 return OK; | |
4218 } | |
4219 #endif |