aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/diff.c5
-rw-r--r--src/nvim/drawline.c2
-rw-r--r--src/nvim/eval.c102
-rw-r--r--src/nvim/eval/funcs.c9
-rw-r--r--src/nvim/eval/typval.c57
-rw-r--r--src/nvim/eval/typval.h6
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/getchar.c97
-rw-r--r--src/nvim/globals.h4
-rw-r--r--src/nvim/input.c16
-rw-r--r--src/nvim/mapping.c10
-rw-r--r--src/nvim/spellsuggest.c2
-rw-r--r--src/nvim/testdir/test_blob.vim783
-rw-r--r--src/nvim/testdir/test_filetype.vim1
-rw-r--r--src/nvim/testdir/test_tabpage.vim15
-rw-r--r--src/nvim/testdir/vim9.vim8
-rw-r--r--src/nvim/tui/tui.c2
-rw-r--r--src/nvim/window.c6
18 files changed, 738 insertions, 391 deletions
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index c5b28822d0..289939b2ca 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -31,6 +31,7 @@
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
+#include "nvim/extmark.h"
#include "nvim/extmark_defs.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
@@ -3102,6 +3103,9 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
if (buf_empty && (curbuf->b_ml.ml_line_count == 2)) {
// Added the first line into an empty buffer, need to
// delete the dummy empty line.
+ // This has a side effect of incrementing curbuf->deleted_bytes,
+ // which results in inaccurate reporting of the byte count of
+ // previous contents in buffer-update events.
buf_empty = false;
ml_delete((linenr_T)2, false);
}
@@ -3143,6 +3147,7 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
}
}
}
+ extmark_adjust(curbuf, lnum, lnum + count - 1, (long)MAXLNUM, added, kExtmarkUndo);
changed_lines(lnum, 0, lnum + count, added, true);
if (did_free) {
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index cd815da458..bf8649afe0 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -1199,7 +1199,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
statuscol.draw = true;
statuscol.sattrs = sattrs;
statuscol.foldinfo = foldinfo;
- statuscol.width = win_col_off(wp);
+ statuscol.width = win_col_off(wp) - (cmdwin_type != 0 && wp == curwin);
statuscol.use_cul = use_cursor_line_sign(wp, lnum);
statuscol.sign_cul_attr = statuscol.use_cul ? sign_cul_attr : 0;
statuscol.num_attr = sign_num_attr ? sign_num_attr
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 841588d4c3..698172442e 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -1498,21 +1498,14 @@ char *get_lval(char *const name, typval_T *const rettv, lval_T *const lp, const
tv_clear(&var1);
const int bloblen = tv_blob_len(lp->ll_tv->vval.v_blob);
- if (lp->ll_n1 < 0 || lp->ll_n1 > bloblen
- || (lp->ll_range && lp->ll_n1 == bloblen)) {
- if (!quiet) {
- semsg(_(e_blobidx), (int64_t)lp->ll_n1);
- }
+ if (tv_blob_check_index(bloblen, lp->ll_n1, quiet) == FAIL) {
tv_clear(&var2);
return NULL;
}
if (lp->ll_range && !lp->ll_empty2) {
lp->ll_n2 = (long)tv_get_number(&var2);
tv_clear(&var2);
- if (lp->ll_n2 < 0 || lp->ll_n2 >= bloblen || lp->ll_n2 < lp->ll_n1) {
- if (!quiet) {
- semsg(_(e_blobidx), (int64_t)lp->ll_n2);
- }
+ if (tv_blob_check_range(bloblen, lp->ll_n1, lp->ll_n2, quiet) == FAIL) {
return NULL;
}
}
@@ -1620,33 +1613,14 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool
lp->ll_n2 = tv_blob_len(lp->ll_blob) - 1;
}
- if (lp->ll_n2 - lp->ll_n1 + 1 != tv_blob_len(rettv->vval.v_blob)) {
- emsg(_("E972: Blob value does not have the right number of bytes"));
+ if (tv_blob_set_range(lp->ll_blob, lp->ll_n1, lp->ll_n2, rettv) == FAIL) {
return;
}
- if (lp->ll_empty2) {
- lp->ll_n2 = tv_blob_len(lp->ll_blob);
- }
-
- for (int il = (int)lp->ll_n1, ir = 0; il <= (int)lp->ll_n2; il++) {
- tv_blob_set(lp->ll_blob, il, tv_blob_get(rettv->vval.v_blob, ir++));
- }
} else {
bool error = false;
const char val = (char)tv_get_number_chk(rettv, &error);
if (!error) {
- garray_T *const gap = &lp->ll_blob->bv_ga;
-
- // Allow for appending a byte. Setting a byte beyond
- // the end is an error otherwise.
- if (lp->ll_n1 < gap->ga_len || lp->ll_n1 == gap->ga_len) {
- ga_grow(&lp->ll_blob->bv_ga, 1);
- tv_blob_set(lp->ll_blob, (int)lp->ll_n1, (uint8_t)val);
- if (lp->ll_n1 == gap->ga_len) {
- gap->ga_len++;
- }
- }
- // error for invalid range was already given in get_lval()
+ tv_blob_set_append(lp->ll_blob, (int)lp->ll_n1, (uint8_t)val);
}
}
} else if (op != NULL && *op != '=') {
@@ -2571,6 +2545,39 @@ static int eval4(char **arg, typval_T *rettv, int evaluate)
return OK;
}
+/// Make a copy of blob "tv1" and append blob "tv2".
+static void eval_addblob(typval_T *tv1, typval_T *tv2)
+{
+ const blob_T *const b1 = tv1->vval.v_blob;
+ const blob_T *const b2 = tv2->vval.v_blob;
+ blob_T *const b = tv_blob_alloc();
+
+ for (int i = 0; i < tv_blob_len(b1); i++) {
+ ga_append(&b->bv_ga, tv_blob_get(b1, i));
+ }
+ for (int i = 0; i < tv_blob_len(b2); i++) {
+ ga_append(&b->bv_ga, tv_blob_get(b2, i));
+ }
+
+ tv_clear(tv1);
+ tv_blob_set_ret(tv1, b);
+}
+
+/// Make a copy of list "tv1" and append list "tv2".
+static int eval_addlist(typval_T *tv1, typval_T *tv2)
+{
+ typval_T var3;
+ // Concatenate Lists.
+ if (tv_list_concat(tv1->vval.v_list, tv2->vval.v_list, &var3) == FAIL) {
+ tv_clear(tv1);
+ tv_clear(tv2);
+ return FAIL;
+ }
+ tv_clear(tv1);
+ *tv1 = var3;
+ return OK;
+}
+
/// Handle fourth level expression:
/// + number addition, concatenation of list or blob
/// - number subtraction
@@ -2584,7 +2591,6 @@ static int eval4(char **arg, typval_T *rettv, int evaluate)
static int eval5(char **arg, typval_T *rettv, int evaluate)
{
typval_T var2;
- typval_T var3;
varnumber_T n1, n2;
float_T f1 = 0, f2 = 0;
char *p;
@@ -2602,7 +2608,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate)
}
if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB))
- && (op == '.' || rettv->v_type != VAR_FLOAT)) {
+ && (op == '.' || rettv->v_type != VAR_FLOAT) && evaluate) {
// For "list + ...", an illegal use of the first operand as
// a number cannot be determined before evaluating the 2nd
// operand: if this is also a list, all is ok.
@@ -2610,7 +2616,7 @@ static int eval5(char **arg, typval_T *rettv, int evaluate)
// we know that the first operand needs to be a string or number
// without evaluating the 2nd operand. So check before to avoid
// side effects after an error.
- if (evaluate && !tv_check_str(rettv)) {
+ if ((op == '.' && !tv_check_str(rettv)) || (op != '.' && !tv_check_num(rettv))) {
tv_clear(rettv);
return FAIL;
}
@@ -2643,32 +2649,12 @@ static int eval5(char **arg, typval_T *rettv, int evaluate)
tv_clear(rettv);
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
- } else if (op == '+' && rettv->v_type == VAR_BLOB
- && var2.v_type == VAR_BLOB) {
- const blob_T *const b1 = rettv->vval.v_blob;
- const blob_T *const b2 = var2.vval.v_blob;
- blob_T *const b = tv_blob_alloc();
-
- for (int i = 0; i < tv_blob_len(b1); i++) {
- ga_append(&b->bv_ga, tv_blob_get(b1, i));
- }
- for (int i = 0; i < tv_blob_len(b2); i++) {
- ga_append(&b->bv_ga, tv_blob_get(b2, i));
- }
-
- tv_clear(rettv);
- tv_blob_set_ret(rettv, b);
- } else if (op == '+' && rettv->v_type == VAR_LIST
- && var2.v_type == VAR_LIST) {
- // Concatenate Lists.
- if (tv_list_concat(rettv->vval.v_list, var2.vval.v_list, &var3)
- == FAIL) {
- tv_clear(rettv);
- tv_clear(&var2);
+ } else if (op == '+' && rettv->v_type == VAR_BLOB && var2.v_type == VAR_BLOB) {
+ eval_addblob(rettv, &var2);
+ } else if (op == '+' && rettv->v_type == VAR_LIST && var2.v_type == VAR_LIST) {
+ if (eval_addlist(rettv, &var2) == FAIL) {
return FAIL;
}
- tv_clear(rettv);
- *rettv = var3;
} else {
bool error = false;
@@ -4864,7 +4850,7 @@ void filter_map(typval_T *argvars, typval_T *rettv, int map)
if (filter_map_one(&tv, expr, map, &rem) == FAIL || did_emsg) {
break;
}
- if (tv.v_type != VAR_NUMBER) {
+ if (tv.v_type != VAR_NUMBER && tv.v_type != VAR_BOOL) {
emsg(_(e_invalblob));
return;
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index d97f7b6d35..d3bac14754 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -3745,7 +3745,6 @@ static void f_inputsecret(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
/// "insert()" function
static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
- list_T *l;
bool error = false;
if (argvars[0].v_type == VAR_BLOB) {
@@ -3788,8 +3787,12 @@ static void f_insert(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
tv_copy(&argvars[0], rettv);
} else if (argvars[0].v_type != VAR_LIST) {
semsg(_(e_listblobarg), "insert()");
- } else if (!value_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
- N_("insert() argument"), TV_TRANSLATE)) {
+ } else {
+ list_T *l = argvars[0].vval.v_list;
+ if (value_check_lock(tv_list_locked(l), N_("insert() argument"), TV_TRANSLATE)) {
+ return;
+ }
+
int64_t before = 0;
if (argvars[2].v_type != VAR_UNKNOWN) {
before = tv_get_number_chk(&argvars[2], &error);
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 0a30cdb62e..d56efe30da 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -2710,6 +2710,63 @@ bool tv_blob_equal(const blob_T *const b1, const blob_T *const b2)
return true;
}
+/// Check if "n1" is a valid index for a blob with length "bloblen".
+int tv_blob_check_index(int bloblen, varnumber_T n1, bool quiet)
+{
+ if (n1 < 0 || n1 > bloblen) {
+ if (!quiet) {
+ semsg(_(e_blobidx), n1);
+ }
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Check if "n1"-"n2" is a valid range for a blob with length "bloblen".
+int tv_blob_check_range(int bloblen, varnumber_T n1, varnumber_T n2, bool quiet)
+{
+ if (n2 < 0 || n2 >= bloblen || n2 < n1) {
+ if (!quiet) {
+ semsg(_(e_blobidx), n2);
+ }
+ return FAIL;
+ }
+ return OK;
+}
+
+/// Set bytes "n1" to "n2" (inclusive) in "dest" to the value of "src".
+/// Caller must make sure "src" is a blob.
+/// Returns FAIL if the number of bytes does not match.
+int tv_blob_set_range(blob_T *dest, long n1, long n2, typval_T *src)
+{
+ if (n2 - n1 + 1 != tv_blob_len(src->vval.v_blob)) {
+ emsg(_("E972: Blob value does not have the right number of bytes"));
+ return FAIL;
+ }
+
+ for (int il = (int)n1, ir = 0; il <= (int)n2; il++) {
+ tv_blob_set(dest, il, tv_blob_get(src->vval.v_blob, ir++));
+ }
+ return OK;
+}
+
+/// Store one byte "byte" in blob "blob" at "idx".
+/// Append one byte if needed.
+void tv_blob_set_append(blob_T *blob, int idx, uint8_t byte)
+{
+ garray_T *gap = &blob->bv_ga;
+
+ // Allow for appending a byte. Setting a byte beyond
+ // the end is an error otherwise.
+ if (idx <= gap->ga_len) {
+ if (idx == gap->ga_len) {
+ ga_grow(gap, 1);
+ gap->ga_len++;
+ }
+ tv_blob_set(blob, idx, byte);
+ }
+}
+
/// "remove({blob})" function
void tv_blob_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg)
{
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 3f59cd3547..4a2654f03e 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -372,7 +372,7 @@ static inline uint8_t tv_blob_get(const blob_T *const b, int idx)
return ((uint8_t *)b->bv_ga.ga_data)[idx];
}
-static inline void tv_blob_set(blob_T *b, int idx, uint8_t c)
+static inline void tv_blob_set(blob_T *blob, int idx, uint8_t c)
REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL;
/// Store the byte `c` at index `idx` in the blob.
@@ -380,9 +380,9 @@ static inline void tv_blob_set(blob_T *b, int idx, uint8_t c)
/// @param[in] b Blob to index. Cannot be NULL.
/// @param[in] idx Index in a blob. Must be valid.
/// @param[in] c Value to store.
-static inline void tv_blob_set(blob_T *const b, int idx, uint8_t c)
+static inline void tv_blob_set(blob_T *const blob, int idx, uint8_t c)
{
- ((uint8_t *)b->bv_ga.ga_data)[idx] = c;
+ ((uint8_t *)blob->bv_ga.ga_data)[idx] = c;
}
/// Initialize VimL object
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index af26fe8a1c..a3e0e650fa 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -2456,7 +2456,7 @@ static bool cmdpreview_may_show(CommandLineState *s)
CpInfo cpinfo;
bool icm_split = *p_icm == 's'; // inccommand=split
buf_T *cmdpreview_buf;
- win_T *cmdpreview_win;
+ win_T *cmdpreview_win = NULL;
emsg_silent++; // Block error reporting as the command may be incomplete,
// but still update v:errmsg
@@ -2693,7 +2693,7 @@ char *getcmdline_prompt(const int firstc, const char *const prompt, const int at
/// Read the 'wildmode' option, fill wim_flags[].
int check_opt_wim(void)
{
- char_u new_wim_flags[4];
+ uint8_t new_wim_flags[4];
int i;
int idx = 0;
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c
index 37840f8875..183fd5e19f 100644
--- a/src/nvim/getchar.c
+++ b/src/nvim/getchar.c
@@ -125,8 +125,8 @@ static int KeyNoremap = 0; // remapping flags
// middle for typeahead and room for new characters (which needs to be 3 *
// MAXMAPLEN for the Amiga).
#define TYPELEN_INIT (5 * (MAXMAPLEN + 3))
-static char_u typebuf_init[TYPELEN_INIT]; // initial typebuf.tb_buf
-static char_u noremapbuf_init[TYPELEN_INIT]; // initial typebuf.tb_noremap
+static uint8_t typebuf_init[TYPELEN_INIT]; // initial typebuf.tb_buf
+static uint8_t noremapbuf_init[TYPELEN_INIT]; // initial typebuf.tb_noremap
static size_t last_recorded_len = 0; // number of last recorded chars
@@ -337,14 +337,12 @@ static int read_readbuffers(int advance)
static int read_readbuf(buffheader_T *buf, int advance)
{
- char_u c;
-
if (buf->bh_first.b_next == NULL) { // buffer is empty
return NUL;
}
buffblock_T *const curr = buf->bh_first.b_next;
- c = (char_u)curr->b_str[buf->bh_index];
+ uint8_t c = (uint8_t)curr->b_str[buf->bh_index];
if (advance) {
if (curr->b_str[++buf->bh_index] == NUL) {
@@ -657,17 +655,17 @@ void stuffescaped(const char *arg, bool literally)
static int read_redo(bool init, bool old_redo)
{
static buffblock_T *bp;
- static char_u *p;
+ static uint8_t *p;
int c;
int n;
- char_u buf[MB_MAXBYTES + 1];
+ uint8_t buf[MB_MAXBYTES + 1];
if (init) {
bp = old_redo ? old_redobuff.bh_first.b_next : redobuff.bh_first.b_next;
if (bp == NULL) {
return FAIL;
}
- p = (char_u *)bp->b_str;
+ p = (uint8_t *)bp->b_str;
return OK;
}
if ((c = *p) == NUL) {
@@ -688,9 +686,9 @@ static int read_redo(bool init, bool old_redo)
}
if (*++p == NUL && bp->b_next != NULL) {
bp = bp->b_next;
- p = (char_u *)bp->b_str;
+ p = (uint8_t *)bp->b_str;
}
- buf[i] = (char_u)c;
+ buf[i] = (uint8_t)c;
if (i == n - 1) { // last byte of a character
if (n != 1) {
c = utf_ptr2char((char *)buf);
@@ -854,7 +852,7 @@ bool noremap_keys(void)
// return FAIL for failure, OK otherwise
int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
{
- char_u *s1, *s2;
+ uint8_t *s1, *s2;
int addlen;
int val;
int nrm;
@@ -975,11 +973,11 @@ int ins_typebuf(char *str, int noremap, int offset, bool nottyped, bool silent)
/// @return the length of what was inserted
int ins_char_typebuf(int c, int modifiers)
{
- char_u buf[MB_MAXBYTES * 3 + 4];
- unsigned int len = special_to_buf(c, modifiers, true, (char *)buf);
+ char buf[MB_MAXBYTES * 3 + 4];
+ unsigned int len = special_to_buf(c, modifiers, true, buf);
assert(len < sizeof(buf));
buf[len] = NUL;
- (void)ins_typebuf((char *)buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
+ (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
return (int)len;
}
@@ -1081,11 +1079,11 @@ void del_typebuf(int len, int offset)
// Write typed characters to script file.
// If recording is on put the character in the recordbuffer.
-static void gotchars(const char_u *chars, size_t len)
+static void gotchars(const uint8_t *chars, size_t len)
FUNC_ATTR_NONNULL_ALL
{
- const char_u *s = chars;
- static char_u buf[4] = { 0 };
+ const uint8_t *s = chars;
+ static uint8_t buf[4] = { 0 };
static size_t buflen = 0;
size_t todo = len;
@@ -1404,7 +1402,7 @@ int merge_modifiers(int c_arg, int *modifiers)
int vgetc(void)
{
int c;
- char_u buf[MB_MAXBYTES + 1];
+ uint8_t buf[MB_MAXBYTES + 1];
// Do garbage collection when garbagecollect() was called previously and
// we are now at the toplevel.
@@ -1548,9 +1546,9 @@ int vgetc(void)
// Note: This will loop until enough bytes are received!
if ((n = MB_BYTE2LEN_CHECK(c)) > 1) {
no_mapping++;
- buf[0] = (char_u)c;
+ buf[0] = (uint8_t)c;
for (int i = 1; i < n; i++) {
- buf[i] = (char_u)vgetorpeek(true);
+ buf[i] = (uint8_t)vgetorpeek(true);
if (buf[i] == K_SPECIAL) {
// Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
// which represents a K_SPECIAL (0x80).
@@ -1815,7 +1813,7 @@ typedef enum {
/// Put "string[new_slen]" in typebuf.
/// Remove "slen" bytes.
/// @return FAIL for error, OK otherwise.
-static int put_string_in_typebuf(int offset, int slen, char_u *string, int new_slen)
+static int put_string_in_typebuf(int offset, int slen, uint8_t *string, int new_slen)
{
int extra = new_slen - slen;
string[new_slen] = NUL;
@@ -1838,7 +1836,7 @@ static int put_string_in_typebuf(int offset, int slen, char_u *string, int new_s
/// in Insert mode completion. This includes the form with a CTRL modifier.
static bool at_ins_compl_key(void)
{
- char_u *p = typebuf.tb_buf + typebuf.tb_off;
+ uint8_t *p = typebuf.tb_buf + typebuf.tb_off;
int c = *p;
if (typebuf.tb_len > 3 && c == K_SPECIAL && p[1] == KS_MODIFIER && (p[2] & MOD_MASK_CTRL)) {
@@ -1858,7 +1856,7 @@ static int check_simplify_modifier(int max_offset)
if (offset + 3 >= typebuf.tb_len) {
break;
}
- char_u *tp = typebuf.tb_buf + typebuf.tb_off + offset;
+ uint8_t *tp = typebuf.tb_buf + typebuf.tb_off + offset;
if (tp[0] == K_SPECIAL && tp[1] == KS_MODIFIER) {
// A modifier was not used for a mapping, apply it to ASCII
// keys. Shift would already have been applied.
@@ -1874,12 +1872,12 @@ static int check_simplify_modifier(int max_offset)
vgetc_char = c;
vgetc_mod_mask = tp[2];
}
- char_u new_string[MB_MAXBYTES];
+ uint8_t new_string[MB_MAXBYTES];
int len;
if (IS_SPECIAL(new_c)) {
new_string[0] = K_SPECIAL;
- new_string[1] = (char_u)K_SECOND(new_c);
- new_string[2] = (char_u)K_THIRD(new_c);
+ new_string[1] = (uint8_t)K_SECOND(new_c);
+ new_string[2] = (uint8_t)K_THIRD(new_c);
len = 3;
} else {
len = utf_char2bytes(new_c, (char *)new_string);
@@ -1889,7 +1887,7 @@ static int check_simplify_modifier(int max_offset)
return -1;
}
} else {
- tp[2] = (char_u)modifier;
+ tp[2] = (uint8_t)modifier;
if (put_string_in_typebuf(offset + 3, 1, new_string, len) == FAIL) {
return -1;
}
@@ -2010,10 +2008,10 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
// Don't allow mapping the first byte(s) of a multi-byte char.
// Happens when mapping <M-a> and then changing 'encoding'.
// Beware that 0x80 is escaped.
- char_u *p1 = (char_u *)mp->m_keys;
- char_u *p2 = (char_u *)mb_unescape((const char **)&p1);
+ char *p1 = mp->m_keys;
+ char *p2 = (char *)mb_unescape((const char **)&p1);
- if (p2 != NULL && MB_BYTE2LEN(tb_c1) > utfc_ptr2len((char *)p2)) {
+ if (p2 != NULL && MB_BYTE2LEN(tb_c1) > utfc_ptr2len(p2)) {
mlen = 0;
}
@@ -2077,7 +2075,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
// Check for match with 'pastetoggle'
if (*p_pt != NUL && mp == NULL && (State & (MODE_INSERT | MODE_NORMAL))) {
- bool match = typebuf_match_len((char_u *)p_pt, &mlen);
+ bool match = typebuf_match_len((uint8_t *)p_pt, &mlen);
if (match) {
// write chars to script file(s)
if (mlen > typebuf.tb_maplen) {
@@ -2267,7 +2265,7 @@ static int handle_mapping(int *keylenp, const bool *timedout, int *mapdepth)
// If this is a LANGMAP mapping, then we didn't record the keys
// at the start of the function and have to record them now.
if (keylen > typebuf.tb_maplen && (mp->m_mode & MODE_LANGMAP) != 0) {
- gotchars((char_u *)map_str, strlen(map_str));
+ gotchars((uint8_t *)map_str, strlen(map_str));
}
if (save_m_noremap != REMAP_YES) {
@@ -2442,7 +2440,7 @@ static int vgetorpeek(bool advance)
if (advance) {
// Also record this character, it might be needed to
// get out of Insert mode.
- *typebuf.tb_buf = (char_u)c;
+ *typebuf.tb_buf = (uint8_t)c;
gotchars(typebuf.tb_buf, 1);
}
cmd_silent = false;
@@ -2515,7 +2513,7 @@ static int vgetorpeek(bool advance)
// move cursor left, if possible
if (curwin->w_cursor.col != 0) {
colnr_T col = 0;
- char_u *ptr;
+ char *ptr;
if (curwin->w_wcol > 0) {
// After auto-indenting and no text is following,
// we are expecting to truncate the trailing
@@ -2524,11 +2522,10 @@ static int vgetorpeek(bool advance)
if (did_ai
&& *skipwhite(get_cursor_line_ptr() + curwin->w_cursor.col) == NUL) {
curwin->w_wcol = 0;
- ptr = (char_u *)get_cursor_line_ptr();
+ ptr = get_cursor_line_ptr();
chartabsize_T cts;
- init_chartabsize_arg(&cts, curwin,
- curwin->w_cursor.lnum, 0, (char *)ptr, (char *)ptr);
- while ((char_u *)cts.cts_ptr < ptr + curwin->w_cursor.col) {
+ init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, 0, ptr, ptr);
+ while (cts.cts_ptr < ptr + curwin->w_cursor.col) {
if (!ascii_iswhite(*cts.cts_ptr)) {
curwin->w_wcol = cts.cts_vcol;
}
@@ -2554,9 +2551,9 @@ static int vgetorpeek(bool advance)
if (col > 0 && curwin->w_wcol > 0) {
// Correct when the cursor is on the right halve
// of a double-wide character.
- ptr = (char_u *)get_cursor_line_ptr();
- col -= utf_head_off((char *)ptr, (char *)ptr + col);
- if (utf_ptr2cells((char *)ptr + col) > 1) {
+ ptr = get_cursor_line_ptr();
+ col -= utf_head_off(ptr, ptr + col);
+ if (utf_ptr2cells(ptr + col) > 1) {
curwin->w_wcol--;
}
}
@@ -2760,7 +2757,7 @@ static int vgetorpeek(bool advance)
}
if (timedout && c == ESC) {
- char_u nop_buf[3];
+ uint8_t nop_buf[3];
// When recording there will be no timeout. Add a <Nop> after the ESC
// to avoid that it forms a key code with following characters.
@@ -2798,7 +2795,7 @@ static int vgetorpeek(bool advance)
/// Return -1 when end of input script reached.
///
/// @param wait_time milliseconds
-int inchar(char_u *buf, int maxlen, long wait_time)
+int inchar(uint8_t *buf, int maxlen, long wait_time)
{
int len = 0; // Init for GCC.
int retesc = false; // Return ESC with gotint.
@@ -2837,7 +2834,7 @@ int inchar(char_u *buf, int maxlen, long wait_time)
return -1;
}
} else {
- buf[0] = (char_u)script_char;
+ buf[0] = (uint8_t)script_char;
len = 1;
}
}
@@ -2851,7 +2848,7 @@ int inchar(char_u *buf, int maxlen, long wait_time)
// and buf may be pointing inside typebuf.tb_buf[].
if (got_int) {
#define DUM_LEN (MAXMAPLEN * 3 + 3)
- char_u dum[DUM_LEN + 1];
+ uint8_t dum[DUM_LEN + 1];
for (;;) {
len = os_inchar(dum, DUM_LEN, 0L, 0, NULL);
@@ -2884,13 +2881,13 @@ int inchar(char_u *buf, int maxlen, long wait_time)
typebuf.tb_change_cnt = 1;
}
- return fix_input_buffer((char *)buf, len);
+ return fix_input_buffer(buf, len);
}
// Fix typed characters for use by vgetc() and check_termcode().
// "buf[]" must have room to triple the number of bytes!
// Returns the new length.
-int fix_input_buffer(char *buf, int len)
+int fix_input_buffer(uint8_t *buf, int len)
FUNC_ATTR_NONNULL_ALL
{
if (!using_script()) {
@@ -2901,7 +2898,7 @@ int fix_input_buffer(char *buf, int len)
}
// Reading from script, need to process special bytes
- char_u *p = (char_u *)buf;
+ uint8_t *p = buf;
// Two characters are special: NUL and K_SPECIAL.
// Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
@@ -2911,8 +2908,8 @@ int fix_input_buffer(char *buf, int len)
|| (p[0] == K_SPECIAL
&& (i < 2 || p[1] != KS_EXTRA))) {
memmove(p + 3, p + 1, (size_t)i);
- p[2] = (char_u)K_THIRD(p[0]);
- p[1] = (char_u)K_SECOND(p[0]);
+ p[2] = (uint8_t)K_THIRD(p[0]);
+ p[1] = (uint8_t)K_SECOND(p[0]);
p[0] = K_SPECIAL;
p += 2;
len += 2;
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 94448eb7d7..f3bfbdabf6 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -789,7 +789,7 @@ EXTERN int redir_reg INIT(= 0); // message redirection register
EXTERN int redir_vname INIT(= 0); // message redirection variable
EXTERN garray_T *capture_ga INIT(= NULL); // captured output for execute()
-EXTERN char_u langmap_mapchar[256]; // mapping for language keys
+EXTERN uint8_t langmap_mapchar[256]; // mapping for language keys
EXTERN int save_p_ls INIT(= -1); // Save 'laststatus' setting
EXTERN int save_p_wmh INIT(= -1); // Save 'winminheight' setting
@@ -832,7 +832,7 @@ EXTERN long sub_nsubs; // total number of substitutions
EXTERN linenr_T sub_nlines; // total number of lines changed
// table to store parsed 'wildmode'
-EXTERN char_u wim_flags[4];
+EXTERN uint8_t wim_flags[4];
// whether titlestring and iconstring contains statusline syntax
#define STL_IN_ICON 1
diff --git a/src/nvim/input.c b/src/nvim/input.c
index 5b9b866778..fa55c02a24 100644
--- a/src/nvim/input.c
+++ b/src/nvim/input.c
@@ -86,7 +86,7 @@ int ask_yesno(const char *const str, const bool direct)
/// Translates the interrupt character for unix to ESC.
int get_keystroke(MultiQueue *events)
{
- char *buf = NULL;
+ uint8_t *buf = NULL;
int buflen = 150;
int len = 0;
int n;
@@ -112,7 +112,7 @@ int get_keystroke(MultiQueue *events)
// First time: blocking wait. Second time: wait up to 100ms for a
// terminal code to complete.
- n = os_inchar((uint8_t *)buf + len, maxlen, len == 0 ? -1L : 100L, 0, events);
+ n = os_inchar(buf + len, maxlen, len == 0 ? -1L : 100L, 0, events);
if (n > 0) {
// Replace zero and K_SPECIAL by a special key code.
n = fix_input_buffer(buf + len, n);
@@ -127,14 +127,14 @@ int get_keystroke(MultiQueue *events)
}
// Handle modifier and/or special key code.
- n = (uint8_t)buf[0];
+ n = buf[0];
if (n == K_SPECIAL) {
- n = TO_SPECIAL((uint8_t)buf[1], (uint8_t)buf[2]);
- if ((uint8_t)buf[1] == KS_MODIFIER
+ n = TO_SPECIAL(buf[1], buf[2]);
+ if (buf[1] == KS_MODIFIER
|| n == K_IGNORE
|| (is_mouse_key(n) && n != K_LEFTMOUSE)) {
- if ((uint8_t)buf[1] == KS_MODIFIER) {
- mod_mask = (uint8_t)buf[2];
+ if (buf[1] == KS_MODIFIER) {
+ mod_mask = buf[2];
}
len -= 3;
if (len > 0) {
@@ -149,7 +149,7 @@ int get_keystroke(MultiQueue *events)
continue;
}
buf[len >= buflen ? buflen - 1 : len] = NUL;
- n = utf_ptr2char(buf);
+ n = utf_ptr2char((char *)buf);
break;
}
xfree(buf);
diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c
index 3840a00981..60524b9fb7 100644
--- a/src/nvim/mapping.c
+++ b/src/nvim/mapping.c
@@ -323,7 +323,7 @@ static void set_maparg_rhs(const char *const orig_rhs, const size_t orig_rhs_len
mapargs->orig_rhs_len = 0;
// stores <lua>ref_no<cr> in map_str
mapargs->rhs_len = (size_t)vim_snprintf(S_LEN(tmp_buf), "%c%c%c%d\r", K_SPECIAL,
- (char_u)KS_EXTRA, KE_LUA, rhs_lua);
+ KS_EXTRA, KE_LUA, rhs_lua);
mapargs->rhs = xstrdup(tmp_buf);
}
}
@@ -1879,7 +1879,7 @@ int makemap(FILE *fd, buf_T *buf)
// return FAIL for failure, OK otherwise
int put_escstr(FILE *fd, char *strstart, int what)
{
- char_u *str = (char_u *)strstart;
+ uint8_t *str = (uint8_t *)strstart;
int c;
// :map xx <Nop>
@@ -1956,7 +1956,7 @@ int put_escstr(FILE *fd, char *strstart, int what)
}
} else if (c < ' ' || c > '~' || c == '|'
|| (what == 0 && c == ' ')
- || (what == 1 && str == (char_u *)strstart && c == ' ')
+ || (what == 1 && str == (uint8_t *)strstart && c == ' ')
|| (what != 2 && c == '<')) {
if (putc(Ctrl_V, fd) < 0) {
return FAIL;
@@ -2383,7 +2383,7 @@ int langmap_adjust_mb(int c)
void langmap_init(void)
{
for (int i = 0; i < 256; i++) {
- langmap_mapchar[i] = (char_u)i; // we init with a one-to-one map
+ langmap_mapchar[i] = (uint8_t)i; // we init with a one-to-one map
}
ga_init(&langmap_mapga, sizeof(langmap_entry_T), 8);
}
@@ -2447,7 +2447,7 @@ void langmap_set(void)
langmap_set_entry(from, to);
} else {
assert(to <= UCHAR_MAX);
- langmap_mapchar[from & 255] = (char_u)to;
+ langmap_mapchar[from & 255] = (uint8_t)to;
}
// Advance to next pair
diff --git a/src/nvim/spellsuggest.c b/src/nvim/spellsuggest.c
index d176a65228..ea2d5e6ff7 100644
--- a/src/nvim/spellsuggest.c
+++ b/src/nvim/spellsuggest.c
@@ -1209,7 +1209,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char *fword, bool soun
// The loop may take an indefinite amount of time. Break out after some
// time.
- proftime_T time_limit;
+ proftime_T time_limit = 0;
if (spell_suggest_timeout > 0) {
time_limit = profile_setlimit(spell_suggest_timeout);
}
diff --git a/src/nvim/testdir/test_blob.vim b/src/nvim/testdir/test_blob.vim
index cf03d2011c..b1859f9dfe 100644
--- a/src/nvim/testdir/test_blob.vim
+++ b/src/nvim/testdir/test_blob.vim
@@ -1,5 +1,7 @@
" Tests for the Blob types
+source vim9.vim
+
func TearDown()
" Run garbage collection after every test
call test_garbagecollect_now()
@@ -9,186 +11,308 @@ endfunc
" Blob creation from constant
func Test_blob_create()
- let b = 0zDEADBEEF
- call assert_equal(v:t_blob, type(b))
- call assert_equal(4, len(b))
- call assert_equal(0xDE, b[0])
- call assert_equal(0xAD, b[1])
- call assert_equal(0xBE, b[2])
- call assert_equal(0xEF, b[3])
- call assert_fails('let x = b[4]')
-
- call assert_equal(0xDE, get(b, 0))
- call assert_equal(0xEF, get(b, 3))
-
- call assert_fails('let b = 0z1', 'E973:')
- call assert_fails('let b = 0z1x', 'E973:')
- call assert_fails('let b = 0z12345', 'E973:')
-
- call assert_equal(0z, v:_null_blob)
-
- let b = 0z001122.33445566.778899.aabbcc.dd
- call assert_equal(0z00112233445566778899aabbccdd, b)
- call assert_fails('let b = 0z1.1')
- call assert_fails('let b = 0z.')
- call assert_fails('let b = 0z001122.')
- call assert_fails('call get("", 1)', 'E896:')
- call assert_equal(0, len(v:_null_blob))
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call assert_equal(v:t_blob, type(b))
+ call assert_equal(4, len(b))
+ call assert_equal(0xDE, b[0])
+ call assert_equal(0xAD, b[1])
+ call assert_equal(0xBE, b[2])
+ call assert_equal(0xEF, b[3])
+ call assert_fails('VAR x = b[4]')
+
+ call assert_equal(0xDE, get(b, 0))
+ call assert_equal(0xEF, get(b, 3))
+
+ call assert_fails('VAR b = 0z1', 'E973:')
+ call assert_fails('VAR b = 0z1x', 'E973:')
+ call assert_fails('VAR b = 0z12345', 'E973:')
+
+ call assert_equal(0z, v:_null_blob)
+
+ LET b = 0z001122.33445566.778899.aabbcc.dd
+ call assert_equal(0z00112233445566778899aabbccdd, b)
+ call assert_fails('VAR b = 0z1.1')
+ call assert_fails('VAR b = 0z.')
+ call assert_fails('VAR b = 0z001122.')
+ call assert_fails('call get("", 1)', 'E896:')
+ call assert_equal(0, len(v:_null_blob))
+ END
+ call CheckLegacyAndVim9Success(lines)
endfunc
" assignment to a blob
func Test_blob_assign()
- let b = 0zDEADBEEF
- let b2 = b[1:2]
- call assert_equal(0zADBE, b2)
-
- let bcopy = b[:]
- call assert_equal(b, bcopy)
- call assert_false(b is bcopy)
-
- let b = 0zDEADBEEF
- let b2 = b
- call assert_true(b is b2)
- let b[:] = 0z11223344
- call assert_equal(0z11223344, b)
- call assert_equal(0z11223344, b2)
- call assert_true(b is b2)
-
- let b = 0zDEADBEEF
- let b[3:] = 0z66
- call assert_equal(0zDEADBE66, b)
- let b[:1] = 0z8899
- call assert_equal(0z8899BE66, b)
-
- call assert_fails('let b[2:3] = 0z112233', 'E972:')
- call assert_fails('let b[2:3] = 0z11', 'E972:')
- call assert_fails('let b[3:2] = 0z', 'E979:')
-
- let b = 0zDEADBEEF
- let b += 0z99
- call assert_equal(0zDEADBEEF99, b)
-
- call assert_fails('let b .= 0z33', 'E734:')
- call assert_fails('let b .= "xx"', 'E734:')
- call assert_fails('let b += "xx"', 'E734:')
- call assert_fails('let b[1:1] .= 0z55', 'E734:')
-
- let l = [0z12]
- let m = deepcopy(l)
- let m[0] = 0z34 " E742 or E741 should not occur.
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ VAR b2 = b[1 : 2]
+ call assert_equal(0zADBE, b2)
+
+ VAR bcopy = b[:]
+ call assert_equal(b, bcopy)
+ call assert_false(b is bcopy)
+
+ LET b = 0zDEADBEEF
+ LET b2 = b
+ call assert_true(b is b2)
+ LET b[:] = 0z11223344
+ call assert_equal(0z11223344, b)
+ call assert_equal(0z11223344, b2)
+ call assert_true(b is b2)
+
+ LET b = 0zDEADBEEF
+ LET b[3 :] = 0z66
+ call assert_equal(0zDEADBE66, b)
+ LET b[: 1] = 0z8899
+ call assert_equal(0z8899BE66, b)
+
+ LET b = 0zDEADBEEF
+ LET b += 0z99
+ call assert_equal(0zDEADBEEF99, b)
+
+ VAR l = [0z12]
+ VAR m = deepcopy(l)
+ LET m[0] = 0z34 #" E742 or E741 should not occur.
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[2 : 3] = 0z112233
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E972:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[2 : 3] = 0z11
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E972:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[3 : 2] = 0z
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b ..= 0z33
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b ..= "xx"
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b += "xx"
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1012:', 'E734:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[1 : 1] ..= 0z55
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E734:', 'E1183:', 'E734:'])
endfunc
func Test_blob_get_range()
+ let lines =<< trim END
+ VAR b = 0z0011223344
+ call assert_equal(0z2233, b[2 : 3])
+ call assert_equal(0z223344, b[2 : -1])
+ call assert_equal(0z00, b[0 : -5])
+ call assert_equal(0z, b[0 : -11])
+ call assert_equal(0z44, b[-1 :])
+ call assert_equal(0z0011223344, b[:])
+ call assert_equal(0z0011223344, b[: -1])
+ call assert_equal(0z, b[5 : 6])
+ call assert_equal(0z0011, b[-10 : 1])
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ " legacy script white space
let b = 0z0011223344
call assert_equal(0z2233, b[2:3])
- call assert_equal(0z223344, b[2:-1])
- call assert_equal(0z00, b[0:-5])
- call assert_equal(0z, b[0:-11])
- call assert_equal(0z44, b[-1:])
- call assert_equal(0z0011223344, b[:])
- call assert_equal(0z0011223344, b[:-1])
- call assert_equal(0z, b[5:6])
- call assert_equal(0z0011, b[-10:1])
endfunc
func Test_blob_get()
- let b = 0z0011223344
- call assert_equal(0x00, get(b, 0))
- call assert_equal(0x22, get(b, 2, 999))
- call assert_equal(0x44, get(b, 4))
- call assert_equal(0x44, get(b, -1))
- call assert_equal(-1, get(b, 5))
- call assert_equal(999, get(b, 5, 999))
- call assert_equal(-1, get(b, -8))
- call assert_equal(999, get(b, -8, 999))
- call assert_equal(10, get(v:_null_blob, 2, 10))
-
- call assert_equal(0x00, b[0])
- call assert_equal(0x22, b[2])
- call assert_equal(0x44, b[4])
- call assert_equal(0x44, b[-1])
- call assert_fails('echo b[5]', 'E979:')
- call assert_fails('echo b[-8]', 'E979:')
+ let lines =<< trim END
+ VAR b = 0z0011223344
+ call assert_equal(0x00, get(b, 0))
+ call assert_equal(0x22, get(b, 2, 999))
+ call assert_equal(0x44, get(b, 4))
+ call assert_equal(0x44, get(b, -1))
+ call assert_equal(-1, get(b, 5))
+ call assert_equal(999, get(b, 5, 999))
+ call assert_equal(-1, get(b, -8))
+ call assert_equal(999, get(b, -8, 999))
+ call assert_equal(10, get(v:_null_blob, 2, 10))
+
+ call assert_equal(0x00, b[0])
+ call assert_equal(0x22, b[2])
+ call assert_equal(0x44, b[4])
+ call assert_equal(0x44, b[-1])
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ VAR b = 0z0011223344
+ echo b[5]
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0z0011223344
+ echo b[-8]
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
endfunc
func Test_blob_to_string()
- let b = 0z00112233445566778899aabbccdd
- call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b))
- call assert_equal(b, eval(string(b)))
- call remove(b, 4, -1)
- call assert_equal('0z00112233', string(b))
- call remove(b, 0, 3)
- call assert_equal('0z', string(b))
+ let lines =<< trim END
+ VAR b = 0z00112233445566778899aabbccdd
+ call assert_equal('0z00112233.44556677.8899AABB.CCDD', string(b))
+ call assert_equal(b, eval(string(b)))
+ call remove(b, 4, -1)
+ call assert_equal('0z00112233', string(b))
+ call remove(b, 0, 3)
+ call assert_equal('0z', string(b))
+ call assert_equal('0z', string(v:_null_blob))
+ END
+ call CheckLegacyAndVim9Success(lines)
endfunc
func Test_blob_compare()
- let b1 = 0z0011
- let b2 = 0z1100
- let b3 = 0z001122
- call assert_true(b1 == b1)
- call assert_false(b1 == b2)
- call assert_false(b1 == b3)
- call assert_true(b1 != b2)
- call assert_true(b1 != b3)
- call assert_true(b1 == 0z0011)
- call assert_fails('echo b1 == 9', 'E977:')
- call assert_fails('echo b1 != 9', 'E977:')
-
- call assert_false(b1 is b2)
- let b2 = b1
- call assert_true(b1 == b2)
- call assert_true(b1 is b2)
- let b2 = copy(b1)
- call assert_true(b1 == b2)
- call assert_false(b1 is b2)
- let b2 = b1[:]
- call assert_true(b1 == b2)
- call assert_false(b1 is b2)
-
- call assert_fails('let x = b1 > b2')
- call assert_fails('let x = b1 < b2')
- call assert_fails('let x = b1 - b2')
- call assert_fails('let x = b1 / b2')
- call assert_fails('let x = b1 * b2')
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR b3 = 0z001122
+ call assert_true(b1 == b1)
+ call assert_false(b1 == b2)
+ call assert_false(b1 == b3)
+ call assert_true(b1 != b2)
+ call assert_true(b1 != b3)
+ call assert_true(b1 == 0z0011)
+
+ call assert_false(b1 is b2)
+ LET b2 = b1
+ call assert_true(b1 == b2)
+ call assert_true(b1 is b2)
+ LET b2 = copy(b1)
+ call assert_true(b1 == b2)
+ call assert_false(b1 is b2)
+ LET b2 = b1[:]
+ call assert_true(b1 == b2)
+ call assert_false(b1 is b2)
+ call assert_true(b1 isnot b2)
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ echo b1 == 9
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ echo b1 != 9
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E977:', 'E1072', 'E1072'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR x = b1 > b2
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR x = b1 < b2
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E978:', 'E1072:', 'E1072:'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR x = b1 - b2
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR x = b1 / b2
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])
+
+ let lines =<< trim END
+ VAR b1 = 0z0011
+ VAR b2 = 0z1100
+ VAR x = b1 * b2
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E974:', 'E1036:', 'E974:'])
endfunc
-" test for range assign
-func Test_blob_range_assign()
- let b = 0z00
- let b[1] = 0x11
- let b[2] = 0x22
- call assert_equal(0z001122, b)
- call assert_fails('let b[4] = 0x33', 'E979:')
+func Test_blob_index_assign()
+ let lines =<< trim END
+ VAR b = 0z00
+ LET b[1] = 0x11
+ LET b[2] = 0x22
+ call assert_equal(0z001122, b)
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ VAR b = 0z00
+ LET b[2] = 0x33
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0z00
+ LET b[-2] = 0x33
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
endfunc
func Test_blob_for_loop()
- let blob = 0z00010203
- let i = 0
- for byte in blob
- call assert_equal(i, byte)
- let i += 1
- endfor
- call assert_equal(4, i)
-
- let blob = 0z00
- call remove(blob, 0)
- call assert_equal(0, len(blob))
- for byte in blob
- call assert_error('loop over empty blob')
- endfor
-
- let blob = 0z0001020304
- let i = 0
- for byte in blob
- call assert_equal(i, byte)
- if i == 1
+ let lines =<< trim END
+ VAR blob = 0z00010203
+ VAR i = 0
+ for byte in blob
+ call assert_equal(i, byte)
+ LET i += 1
+ endfor
+ call assert_equal(4, i)
+
+ LET blob = 0z00
call remove(blob, 0)
- elseif i == 3
- call remove(blob, 3)
- endif
- let i += 1
- endfor
- call assert_equal(5, i)
+ call assert_equal(0, len(blob))
+ for byte in blob
+ call assert_report('loop over empty blob')
+ endfor
+
+ LET blob = 0z0001020304
+ LET i = 0
+ for byte in blob
+ call assert_equal(i, byte)
+ if i == 1
+ call remove(blob, 0)
+ elseif i == 3
+ call remove(blob, 3)
+ endif
+ LET i += 1
+ endfor
+ call assert_equal(5, i)
+ END
+ call CheckLegacyAndVim9Success(lines)
endfunc
func Test_blob_concatenate()
@@ -223,51 +347,101 @@ endfunc
" Test removing items in blob
func Test_blob_func_remove()
- " Test removing 1 element
- let b = 0zDEADBEEF
- call assert_equal(0xDE, remove(b, 0))
- call assert_equal(0zADBEEF, b)
-
- let b = 0zDEADBEEF
- call assert_equal(0xEF, remove(b, -1))
- call assert_equal(0zDEADBE, b)
-
- let b = 0zDEADBEEF
- call assert_equal(0xAD, remove(b, 1))
- call assert_equal(0zDEBEEF, b)
-
- " Test removing range of element(s)
- let b = 0zDEADBEEF
- call assert_equal(0zBE, remove(b, 2, 2))
- call assert_equal(0zDEADEF, b)
-
- let b = 0zDEADBEEF
- call assert_equal(0zADBE, remove(b, 1, 2))
- call assert_equal(0zDEEF, b)
+ let lines =<< trim END
+ #" Test removing 1 element
+ VAR b = 0zDEADBEEF
+ call assert_equal(0xDE, remove(b, 0))
+ call assert_equal(0zADBEEF, b)
+
+ LET b = 0zDEADBEEF
+ call assert_equal(0xEF, remove(b, -1))
+ call assert_equal(0zDEADBE, b)
+
+ LET b = 0zDEADBEEF
+ call assert_equal(0xAD, remove(b, 1))
+ call assert_equal(0zDEBEEF, b)
+
+ #" Test removing range of element(s)
+ LET b = 0zDEADBEEF
+ call assert_equal(0zBE, remove(b, 2, 2))
+ call assert_equal(0zDEADEF, b)
+
+ LET b = 0zDEADBEEF
+ call assert_equal(0zADBE, remove(b, 1, 2))
+ call assert_equal(0zDEEF, b)
+ END
+ call CheckLegacyAndVim9Success(lines)
" Test invalid cases
- let b = 0zDEADBEEF
- call assert_fails("call remove(b, 5)", 'E979:')
- call assert_fails("call remove(b, 1, 5)", 'E979:')
- call assert_fails("call remove(b, 3, 2)", 'E979:')
- call assert_fails("call remove(1, 0)", 'E896:')
- call assert_fails("call remove(b, b)", 'E974:')
- call assert_fails("call remove(b, 1, [])", 'E745:')
- call assert_fails("call remove(v:_null_blob, 1, 2)", 'E979:')
-
- " Translated from v8.2.3284
- let b = 0zDEADBEEF
- lockvar b
- call assert_fails('call remove(b, 0)', 'E741:')
- unlockvar b
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(b, 5)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(b, 1, 5)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(b, 3, 2)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(1, 0)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E896:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(b, b)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E974:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(b, 1, [])
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E745:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call remove(v:_null_blob, 1, 2)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E979:')
+
+ let lines =<< trim END
+ let b = 0zDEADBEEF
+ lockvar b
+ call remove(b, 0)
+ unlockvar b
+ END
+ call CheckScriptFailure(lines, 'E741:')
+
+ " can only check at script level, not in a :def function
+ let lines =<< trim END
+ vim9script
+ var b = 0zDEADBEEF
+ lockvar b
+ remove(b, 0)
+ END
+ call CheckScriptFailure(lines, 'E741:')
endfunc
func Test_blob_read_write()
- let b = 0zDEADBEEF
- call writefile(b, 'Xblob')
- let br = readfile('Xblob', 'B')
- call assert_equal(b, br)
- call delete('Xblob')
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call writefile(b, 'Xblob')
+ VAR br = readfile('Xblob', 'B')
+ call assert_equal(b, br)
+ call delete('Xblob')
+ END
+ call CheckLegacyAndVim9Success(lines)
" This was crashing when calling readfile() with a directory.
call assert_fails("call readfile('.', 'B')", 'E17: "." is a directory')
@@ -275,85 +449,190 @@ endfunc
" filter() item in blob
func Test_blob_filter()
- call assert_equal(v:_null_blob, filter(v:_null_blob, '0'))
- call assert_equal(0z, filter(0zDEADBEEF, '0'))
- call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE'))
- call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE'))
- call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF'))
- call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1'))
- call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02'))
- call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2'))
+ let lines =<< trim END
+ call assert_equal(v:_null_blob, filter(v:_null_blob, '0'))
+ call assert_equal(0z, filter(0zDEADBEEF, '0'))
+ call assert_equal(0zADBEEF, filter(0zDEADBEEF, 'v:val != 0xDE'))
+ call assert_equal(0zDEADEF, filter(0zDEADBEEF, 'v:val != 0xBE'))
+ call assert_equal(0zDEADBE, filter(0zDEADBEEF, 'v:val != 0xEF'))
+ call assert_equal(0zDEADBEEF, filter(0zDEADBEEF, '1'))
+ call assert_equal(0z01030103, filter(0z010203010203, 'v:val != 0x02'))
+ call assert_equal(0zADEF, filter(0zDEADBEEF, 'v:key % 2'))
+ END
+ call CheckLegacyAndVim9Success(lines)
endfunc
" map() item in blob
func Test_blob_map()
- call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1'))
- call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key'))
- call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val'))
-
- call assert_fails("call map(0z00, '[9]')", 'E978:')
+ let lines =<< trim END
+ call assert_equal(0zDFAEBFF0, map(0zDEADBEEF, 'v:val + 1'))
+ call assert_equal(0z00010203, map(0zDEADBEEF, 'v:key'))
+ call assert_equal(0zDEAEC0F2, map(0zDEADBEEF, 'v:key + v:val'))
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ call map(0z00, '[9]')
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E978:')
endfunc
func Test_blob_index()
- call assert_equal(2, index(0zDEADBEEF, 0xBE))
- call assert_equal(-1, index(0zDEADBEEF, 0))
- call assert_equal(2, index(0z11111111, 0x11, 2))
- call assert_equal(3, 0z11110111->index(0x11, 2))
- call assert_equal(2, index(0z11111111, 0x11, -2))
- call assert_equal(3, index(0z11110111, 0x11, -2))
- call assert_equal(0, index(0z11110111, 0x11, -10))
- call assert_fails("echo index(0z11110111, 0x11, [])", 'E745:')
- call assert_equal(-1, index(v:_null_blob, 1))
-
- call assert_fails('call index("asdf", 0)', 'E897:')
+ let lines =<< trim END
+ call assert_equal(2, index(0zDEADBEEF, 0xBE))
+ call assert_equal(-1, index(0zDEADBEEF, 0))
+ call assert_equal(2, index(0z11111111, 0x11, 2))
+ call assert_equal(3, 0z11110111->index(0x11, 2))
+ call assert_equal(2, index(0z11111111, 0x11, -2))
+ call assert_equal(3, index(0z11110111, 0x11, -2))
+ call assert_equal(0, index(0z11110111, 0x11, -10))
+ call assert_equal(-1, index(v:_null_blob, 1))
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ let lines =<< trim END
+ echo index(0z11110111, 0x11, [])
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E745:')
+
+ let lines =<< trim END
+ call index("asdf", 0)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E897:')
endfunc
func Test_blob_insert()
- let b = 0zDEADBEEF
- call insert(b, 0x33)
- call assert_equal(0z33DEADBEEF, b)
-
- let b = 0zDEADBEEF
- call insert(b, 0x33, 2)
- call assert_equal(0zDEAD33BEEF, b)
-
- call assert_fails('call insert(b, -1)', 'E475:')
- call assert_fails('call insert(b, 257)', 'E475:')
- call assert_fails('call insert(b, 0, [9])', 'E745:')
- call assert_fails('call insert(b, 0, -20)', 'E475:')
- call assert_fails('call insert(b, 0, 20)', 'E475:')
- call assert_fails('call insert(b, [])', 'E745:')
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, 0x33)
+ call assert_equal(0z33DEADBEEF, b)
+
+ LET b = 0zDEADBEEF
+ call insert(b, 0x33, 2)
+ call assert_equal(0zDEAD33BEEF, b)
+ END
+ call CheckLegacyAndVim9Success(lines)
+
+ " only works in legacy script
call assert_equal(0, insert(v:_null_blob, 0x33))
- " Translated from v8.2.3284
- let b = 0zDEADBEEF
- lockvar b
- call assert_fails('call insert(b, 3)', 'E741:')
- unlockvar b
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, -1)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E475:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, 257)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E475:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, 0, [9])
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E745:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, 0, -20)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E475:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, 0, 20)
+ END
+ call CheckLegacyAndVim9Failure(lines, 'E475:')
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ call insert(b, [])
+ END
+ call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E745:'])
+
+ let lines =<< trim END
+ insert(v:_null_blob, 0x33)
+ END
+ call CheckDefExecAndScriptFailure(lines, 'E1131:')
+
+ let lines =<< trim END
+ let b = 0zDEADBEEF
+ lockvar b
+ call insert(b, 3)
+ unlockvar b
+ END
+ call CheckScriptFailure(lines, 'E741:')
+
+ let lines =<< trim END
+ vim9script
+ var b = 0zDEADBEEF
+ lockvar b
+ insert(b, 3)
+ END
+ call CheckScriptFailure(lines, 'E741:')
endfunc
func Test_blob_reverse()
- call assert_equal(0zEFBEADDE, reverse(0zDEADBEEF))
- call assert_equal(0zBEADDE, reverse(0zDEADBE))
- call assert_equal(0zADDE, reverse(0zDEAD))
- call assert_equal(0zDE, reverse(0zDE))
- call assert_equal(0z, reverse(v:_null_blob))
+ let lines =<< trim END
+ call assert_equal(0zEFBEADDE, reverse(0zDEADBEEF))
+ call assert_equal(0zBEADDE, reverse(0zDEADBE))
+ call assert_equal(0zADDE, reverse(0zDEAD))
+ call assert_equal(0zDE, reverse(0zDE))
+ call assert_equal(0z, reverse(v:_null_blob))
+ END
+ call CheckLegacyAndVim9Success(lines)
+endfunc
+
+func Test_blob_json_encode()
+ let lines =<< trim END
+ #" call assert_equal('[222,173,190,239]', json_encode(0zDEADBEEF))
+ call assert_equal('[222, 173, 190, 239]', json_encode(0zDEADBEEF))
+ call assert_equal('[]', json_encode(0z))
+ END
+ call CheckLegacyAndVim9Success(lines)
endfunc
func Test_blob_lock()
- let b = 0z112233
- lockvar b
- call assert_fails('let b = 0z44', 'E741:')
- unlockvar b
- let b = 0z44
+ let lines =<< trim END
+ let b = 0z112233
+ lockvar b
+ unlockvar b
+ let b = 0z44
+ END
+ call CheckScriptSuccess(lines)
+
+ let lines =<< trim END
+ vim9script
+ var b = 0z112233
+ lockvar b
+ unlockvar b
+ b = 0z44
+ END
+ call CheckScriptSuccess(lines)
+
+ let lines =<< trim END
+ let b = 0z112233
+ lockvar b
+ let b = 0z44
+ END
+ call CheckScriptFailure(lines, 'E741:')
+
+ let lines =<< trim END
+ vim9script
+ var b = 0z112233
+ lockvar b
+ b = 0z44
+ END
+ call CheckScriptFailure(lines, 'E741:')
endfunc
func Test_blob_sort()
if has('float')
- call assert_fails('call sort([1.0, 0z11], "f")', 'E975:')
- else
- call assert_fails('call sort(["abc", 0z11], "f")', 'E702:')
+ call CheckLegacyAndVim9Failure(['call sort([1.0, 0z11], "f")'], 'E975:')
endif
+ call CheckLegacyAndVim9Failure(['call sort([11, 0z11], "N")'], 'E974:')
endfunc
" The following used to cause an out-of-bounds memory access
diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim
index 96ab5620ec..148f8b6d42 100644
--- a/src/nvim/testdir/test_filetype.vim
+++ b/src/nvim/testdir/test_filetype.vim
@@ -140,6 +140,7 @@ let s:filename_checks = {
\ 'csv': ['file.csv'],
\ 'cucumber': ['file.feature'],
\ 'cuda': ['file.cu', 'file.cuh'],
+ \ 'cue': ['file.cue'],
\ 'cupl': ['file.pld'],
\ 'cuplsim': ['file.si'],
\ 'cvs': ['cvs123'],
diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim
index b97aa409d8..c20c798c49 100644
--- a/src/nvim/testdir/test_tabpage.vim
+++ b/src/nvim/testdir/test_tabpage.vim
@@ -846,4 +846,19 @@ func Test_lastused_tabpage()
tabonly!
endfunc
+" this was giving ml_get errors
+func Test_tabpage_last_line()
+ enew
+ call setline(1, repeat(['a'], &lines + 5))
+ $
+ tabnew
+ call setline(1, repeat(['b'], &lines + 20))
+ $
+ tabNext
+ call assert_equal('a', getline('.'))
+
+ bwipe!
+ bwipe!
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/nvim/testdir/vim9.vim b/src/nvim/testdir/vim9.vim
index 3c0ff2b2dd..2cc3d88aa8 100644
--- a/src/nvim/testdir/vim9.vim
+++ b/src/nvim/testdir/vim9.vim
@@ -34,6 +34,10 @@ func CheckScriptSuccess(lines)
endtry
endfunc
+func CheckDefExecAndScriptFailure(lines, error, lnum = -3)
+ return
+endfunc
+
" Check that "lines" inside a legacy function has no error.
func CheckLegacySuccess(lines)
let cwd = getcwd()
@@ -98,9 +102,9 @@ endfunc
" Use ' #"' for a comment
func CheckLegacyAndVim9Failure(lines, error)
if type(a:error) == type('string')
- let legacyError = error
+ let legacyError = a:error
else
- let legacyError = error[0]
+ let legacyError = a:error[0]
endif
let legacylines = a:lines->deepcopy()->map({_, v ->
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index fee1d21672..48dc860ebd 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -1109,8 +1109,8 @@ void tui_set_mode(TUIData *tui, ModeShape mode)
// Hopefully the user's default cursor color is inverse.
unibi_out_ext(tui, tui->unibi_ext.reset_cursor_color);
} else {
+ char hexbuf[8];
if (tui->set_cursor_color_as_str) {
- char hexbuf[8];
snprintf(hexbuf, 7 + 1, "#%06x", aep.rgb_bg_color);
UNIBI_SET_STR_VAR(tui->params[0], hexbuf);
} else {
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 0a4d36acb2..38b7326363 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1899,8 +1899,8 @@ static void win_rotate(bool upwards, int count)
}
}
- win_T *wp1;
- win_T *wp2;
+ win_T *wp1 = NULL;
+ win_T *wp2 = NULL;
while (count--) {
if (upwards) { // first window becomes last window
@@ -4813,7 +4813,7 @@ static void win_enter_ext(win_T *const wp, const int flags)
// Might need to scroll the old window before switching, e.g., when the
// cursor was moved.
- if (*p_spk == 'c') {
+ if (*p_spk == 'c' && !curwin_invalid) {
update_topline(curwin);
}