aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0dd261f53a..0ae96365b2 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5403,11 +5403,9 @@ static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int
int garbage_collect(void)
{
int copyID;
- win_T *wp;
funccall_T *fc, **pfc;
int did_free;
int did_free_funccal = FALSE;
- tabpage_T *tp;
/* Only do this once. */
want_garbage_collect = FALSE;
@@ -5442,14 +5440,16 @@ int garbage_collect(void)
}
/* window-local variables */
- FOR_ALL_TAB_WINDOWS(tp, wp)
- set_ref_in_item(&wp->w_winvar.di_tv, copyID);
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ set_ref_in_item(&wp->w_winvar.di_tv, copyID);
+ }
if (aucmd_win != NULL)
set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID);
/* tabpage-local variables */
- for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ FOR_ALL_TABS(tp) {
set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
+ }
/* global variables */
set_ref_in_ht(&globvarht, copyID);
@@ -9588,21 +9588,27 @@ find_win_by_nr (
tabpage_T *tp /* NULL for current tab page */
)
{
- win_T *wp;
- int nr;
-
- nr = get_tv_number_chk(vp, NULL);
+ int nr = get_tv_number_chk(vp, NULL);
- if (nr < 0)
+ if (nr < 0) {
return NULL;
- if (nr == 0)
+ }
+
+ if (nr == 0) {
return curwin;
+ }
- for (wp = (tp == NULL || tp == curtab) ? firstwin : tp->tp_firstwin;
- wp != NULL; wp = wp->w_next)
- if (--nr <= 0)
- break;
- return wp;
+ // This method accepts NULL as an alias for curtab.
+ if (tp == NULL) {
+ tp = curtab;
+ }
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, tp) {
+ if (--nr <= 0) {
+ return wp;
+ }
+ }
+ return NULL;
}
/*
@@ -13455,15 +13461,36 @@ static int item_compare(const void *s1, const void *s2)
{
sortItem_T *si1, *si2;
char_u *p1, *p2;
- char_u *tofree1, *tofree2;
+ char_u *tofree1 = NULL, *tofree2 = NULL;
int res;
char_u numbuf1[NUMBUFLEN];
char_u numbuf2[NUMBUFLEN];
si1 = (sortItem_T *)s1;
si2 = (sortItem_T *)s2;
- p1 = tv2string(&si1->item->li_tv, &tofree1, numbuf1, 0);
- p2 = tv2string(&si2->item->li_tv, &tofree2, numbuf2, 0);
+ typval_T *tv1 = &si1->item->li_tv;
+ typval_T *tv2 = &si2->item->li_tv;
+ // tv2string() puts quotes around a string and allocates memory. Don't do
+ // that for string variables. Use a single quote when comparing with a
+ // non-string to do what the docs promise.
+ if (tv1->v_type == VAR_STRING) {
+ if (tv2->v_type != VAR_STRING || item_compare_numeric) {
+ p1 = (char_u *)"'";
+ } else {
+ p1 = tv1->vval.v_string;
+ }
+ } else {
+ p1 = tv2string(tv1, &tofree1, numbuf1, 0);
+ }
+ if (tv2->v_type == VAR_STRING) {
+ if (tv1->v_type != VAR_STRING || item_compare_numeric) {
+ p2 = (char_u *)"'";
+ } else {
+ p2 = tv2->vval.v_string;
+ }
+ } else {
+ p2 = tv2string(tv2, &tofree2, numbuf2, 0);
+ }
if (p1 == NULL)
p1 = (char_u *)"";
if (p2 == NULL)
@@ -13481,8 +13508,8 @@ static int item_compare(const void *s1, const void *s2)
res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
}
- // When the result would be zero, compare the pointers themselves. Makes
- // the sort stable.
+ // When the result would be zero, compare the item indexes. Makes the
+ // sort stable.
if (res == 0 && !item_compare_keep_zero) {
res = si1->idx > si2->idx ? 1 : -1;
}