summaryrefslogtreecommitdiff
path: root/src/list.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-08-15 22:14:53 +0200
committerBram Moolenaar <Bram@vim.org>2020-08-15 22:14:53 +0200
commited5918771fcf9877d8445e74c62ab1ce6b8e28c1 (patch)
tree6b2c25678e1d0b606ad7e6b82d2d6528b6b86be8 /src/list.c
parent11107bab7ead9124f46a7ddf6aa3bb66b43a8246 (diff)
downloadvim-git-ed5918771fcf9877d8445e74c62ab1ce6b8e28c1.tar.gz
patch 8.2.1463: Vim9: list slice not supported yetv8.2.1463
Problem: Vim9: list slice not supported yet. Solution: Add support for list slicing.
Diffstat (limited to 'src/list.c')
-rw-r--r--src/list.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/list.c b/src/list.c
index 24b49d83c..955272c37 100644
--- a/src/list.c
+++ b/src/list.c
@@ -888,6 +888,61 @@ list_slice(list_T *ol, long n1, long n2)
return l;
}
+ int
+list_slice_or_index(
+ list_T *list,
+ int range,
+ long n1_arg,
+ long n2_arg,
+ typval_T *rettv,
+ int verbose)
+{
+ long len = list_len(list);
+ long n1 = n1_arg;
+ long n2 = n2_arg;
+ typval_T var1;
+
+ if (n1 < 0)
+ n1 = len + n1;
+ if (n1 < 0 || n1 >= len)
+ {
+ // For a range we allow invalid values and return an empty
+ // list. A list index out of range is an error.
+ if (!range)
+ {
+ if (verbose)
+ semsg(_(e_listidx), n1);
+ return FAIL;
+ }
+ n1 = len;
+ }
+ if (range)
+ {
+ list_T *l;
+
+ if (n2 < 0)
+ n2 = len + n2;
+ else if (n2 >= len)
+ n2 = len - 1;
+ if (n2 < 0 || n2 + 1 < n1)
+ n2 = -1;
+ l = list_slice(list, n1, n2);
+ if (l == NULL)
+ return FAIL;
+ clear_tv(rettv);
+ rettv_list_set(rettv, l);
+ }
+ else
+ {
+ // copy the item to "var1" to avoid that freeing the list makes it
+ // invalid.
+ copy_tv(&list_find(list, n1)->li_tv, &var1);
+ clear_tv(rettv);
+ *rettv = var1;
+ }
+ return OK;
+}
+
/*
* Make a copy of list "orig". Shallow if "deep" is FALSE.
* The refcount of the new list is set to 1.