diff options
28 files changed, 353 insertions, 157 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 81d7f4b83a..3e75914743 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -4975,7 +4975,7 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* If {list} is a list of dictionaries, then the optional {dict} argument supports the following additional items: - key key of the item which is fuzzy matched against + key Key of the item which is fuzzy matched against {str}. The value of this item should be a string. text_cb |Funcref| that will be called for every item @@ -4983,6 +4983,8 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* This should accept a dictionary item as the argument and return the text for that item to use for fuzzy matching. + limit Maximum number of matches in {list} to be + returned. Zero means no limit. {str} is treated as a literal string and regular expression matching is NOT supported. The maximum supported {str} length @@ -4995,6 +4997,9 @@ matchfuzzy({list}, {str} [, {dict}]) *matchfuzzy()* empty list is returned. If length of {str} is greater than 256, then returns an empty list. + When {limit} is given, matchfuzzy() will find up to this + number of matches in {list} and return them in sorted order. + Refer to |fuzzy-matching| for more information about fuzzy matching strings. diff --git a/runtime/doc/term.txt b/runtime/doc/term.txt index bdf0094721..9969fc0a79 100644 --- a/runtime/doc/term.txt +++ b/runtime/doc/term.txt @@ -117,6 +117,43 @@ go to the window below: > tmux send-keys 'Escape' [ 2 7 u 'C-W' j Where `'Escape' [ 2 7 u` is an unambiguous `CSI u` sequence for the <Esc> key. + *tui-modifyOtherKeys* *tui-csiu* +Historically, terminal emulators could not distinguish between certain control +key modifiers and other keys. For example, <C-I> and <Tab> are represented the +same way, as are <Esc> and <C-[>, <CR> and <C-M>, and <NL> and <C-J>. This +meant that Nvim also could not map these keys separately. + +Modern terminal emulators are able to distinguish between these pairs of keys +by encoding control modifiers differently. There are two common but distinct +ways of doing this, known as "modifyOtherKeys" and "CSI u". Nvim supports both +encoding methods and at startup will tell the terminal emulator that it +understands these key encodings. If your terminal emulator supports it then +this will allow you to map the key pairs listed above separately. + +At startup Nvim will query your terminal to see if it supports the CSI u +encoding by writing the sequence > + + CSI ? u CSI c + +If your terminal emulator responds with > + + CSI ? <flags> u + +this means your terminal supports the CSI u encoding and Nvim will tell your +terminal to enable it by writing the sequence > + + CSI > 1 u + +If your terminal does not support CSI u then Nvim will instead enable the +"modifyOtherKeys" encoding by writing the sequence > + + CSI > 4 ; 2 m + +When Nvim exits cleanly it will send the corresponding sequence to disable the +special key encoding. If Nvim does not exit cleanly then your terminal +emulator could be in a bad state. If this happens, simply run "reset". + + *tui-colors* Nvim uses 256 colours by default, ignoring |terminfo| for most terminal types, including "linux" (whose virtual terminals have had 256-colour support since diff --git a/runtime/filetype.vim b/runtime/filetype.vim index e72d6fc0c0..5fee083977 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -817,6 +817,7 @@ au BufNewFile,BufRead *.t.html setf tilde " HTML (.shtml and .stm for server side) au BufNewFile,BufRead *.html,*.htm,*.shtml,*.stm call dist#ft#FThtml() +au BufNewFile,BufRead *.cshtml setf html " HTML with Ruby - eRuby au BufNewFile,BufRead *.erb,*.rhtml setf eruby diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 420d343a8a..1297ef6241 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -142,6 +142,7 @@ local extension = { cs = "cs", csc = "csc", csdl = "csdl", + cshtml = "html", fdr = "csp", csp = "csp", css = "css", diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index 614d83f565..6a8d6dcad7 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -185,7 +185,12 @@ end function M.on_publish_diagnostics(_, result, ctx, config) local client_id = ctx.client_id local uri = result.uri - local bufnr = vim.uri_to_bufnr(uri) + local fname = vim.uri_to_fname(uri) + local diagnostics = result.diagnostics + if #diagnostics == 0 and vim.fn.bufexists(fname) == 0 then + return + end + local bufnr = vim.fn.bufadd(fname) if not bufnr then return @@ -193,7 +198,6 @@ function M.on_publish_diagnostics(_, result, ctx, config) client_id = get_client_id(client_id) local namespace = M.get_namespace(client_id) - local diagnostics = result.diagnostics if config then for _, opt in pairs(config) do diff --git a/src/nvim/search.c b/src/nvim/search.c index 4fc5ac93aa..48df289831 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -5093,26 +5093,30 @@ static int fuzzy_match_item_compare(const void *const s1, const void *const s2) /// for each item or use 'item_cb' Funcref function to get the string. /// If 'retmatchpos' is true, then return a list of positions where 'str' /// matches for each item. -static void fuzzy_match_in_list(list_T *const items, char_u *const str, const bool matchseq, +static void fuzzy_match_in_list(list_T *const l, char_u *const str, const bool matchseq, const char_u *const key, Callback *const item_cb, - const bool retmatchpos, list_T *const fmatchlist) + const bool retmatchpos, list_T *const fmatchlist, + const long max_matches) FUNC_ATTR_NONNULL_ARG(2, 5, 7) { - const long len = tv_list_len(items); + long len = tv_list_len(l); if (len == 0) { return; } + if (max_matches > 0 && len > max_matches) { + len = max_matches; + } - fuzzyItem_T *const ptrs = xcalloc(len, sizeof(fuzzyItem_T)); - long i = 0; - bool found_match = false; + fuzzyItem_T *const items = xcalloc(len, sizeof(fuzzyItem_T)); + long match_count = 0; uint32_t matches[MAX_FUZZY_MATCHES]; // For all the string items in items, get the fuzzy matching score - TV_LIST_ITER(items, li, { - ptrs[i].idx = i; - ptrs[i].item = li; - ptrs[i].score = SCORE_NONE; + TV_LIST_ITER(l, li, { + if (max_matches > 0 && match_count >= max_matches) { + break; + } + char_u *itemstr = NULL; typval_T rettv; rettv.v_type = VAR_UNKNOWN; @@ -5143,31 +5147,33 @@ static void fuzzy_match_in_list(list_T *const items, char_u *const str, const bo int score; if (itemstr != NULL && fuzzy_match(itemstr, str, matchseq, &score, matches, - sizeof(matches) / sizeof(matches[0]))) { + MAX_FUZZY_MATCHES)) { + items[match_count].idx = match_count; + items[match_count].item = li; + items[match_count].score = score; + // Copy the list of matching positions in itemstr to a list, if // 'retmatchpos' is set. if (retmatchpos) { - ptrs[i].lmatchpos = tv_list_alloc(kListLenMayKnow); + items[match_count].lmatchpos = tv_list_alloc(kListLenMayKnow); int j = 0; const char_u *p = str; while (*p != NUL) { if (!ascii_iswhite(utf_ptr2char(p))) { - tv_list_append_number(ptrs[i].lmatchpos, matches[j]); + tv_list_append_number(items[match_count].lmatchpos, matches[j]); j++; } MB_PTR_ADV(p); } } - ptrs[i].score = score; - found_match = true; + match_count++; } - i++; tv_clear(&rettv); }); - if (found_match) { + if (match_count > 0) { // Sort the list by the descending order of the match score - qsort(ptrs, len, sizeof(fuzzyItem_T), fuzzy_match_item_compare); + qsort(items, match_count, sizeof(fuzzyItem_T), fuzzy_match_item_compare); // For matchfuzzy(), return a list of matched strings. // ['str1', 'str2', 'str3'] @@ -5176,48 +5182,49 @@ static void fuzzy_match_in_list(list_T *const items, char_u *const str, const bo // is a list of lists where each list item is a list of matched // character positions. The third item is a list of matching scores. // [['str1', 'str2', 'str3'], [[1, 3], [1, 3], [1, 3]]] - list_T *l; + list_T *retlist; if (retmatchpos) { const listitem_T *const li = tv_list_find(fmatchlist, 0); assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL); - l = TV_LIST_ITEM_TV(li)->vval.v_list; + retlist = TV_LIST_ITEM_TV(li)->vval.v_list; } else { - l = fmatchlist; + retlist = fmatchlist; } // Copy the matching strings with a valid score to the return list - for (i = 0; i < len; i++) { - if (ptrs[i].score == SCORE_NONE) { + for (long i = 0; i < match_count; i++) { + if (items[i].score == SCORE_NONE) { break; } - tv_list_append_tv(l, TV_LIST_ITEM_TV(ptrs[i].item)); + tv_list_append_tv(retlist, TV_LIST_ITEM_TV(items[i].item)); } // next copy the list of matching positions if (retmatchpos) { const listitem_T *li = tv_list_find(fmatchlist, -2); assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL); - l = TV_LIST_ITEM_TV(li)->vval.v_list; - for (i = 0; i < len; i++) { - if (ptrs[i].score == SCORE_NONE) { + retlist = TV_LIST_ITEM_TV(li)->vval.v_list; + + for (long i = 0; i < match_count; i++) { + if (items[i].score == SCORE_NONE) { break; } - tv_list_append_list(l, ptrs[i].lmatchpos); + tv_list_append_list(retlist, items[i].lmatchpos); } // copy the matching scores li = tv_list_find(fmatchlist, -1); assert(li != NULL && TV_LIST_ITEM_TV(li)->vval.v_list != NULL); - l = TV_LIST_ITEM_TV(li)->vval.v_list; - for (i = 0; i < len; i++) { - if (ptrs[i].score == SCORE_NONE) { + retlist = TV_LIST_ITEM_TV(li)->vval.v_list; + for (long i = 0; i < match_count; i++) { + if (items[i].score == SCORE_NONE) { break; } - tv_list_append_number(l, ptrs[i].score); + tv_list_append_number(retlist, items[i].score); } } } - xfree(ptrs); + xfree(items); } /// Do fuzzy matching. Returns the list of matched strings in 'rettv'. @@ -5239,6 +5246,7 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, Callback cb = CALLBACK_NONE; const char_u *key = NULL; bool matchseq = false; + long max_matches = 0; if (argvars[2].v_type != VAR_UNKNOWN) { if (argvars[2].v_type != VAR_DICT || argvars[2].vval.v_dict == NULL) { emsg(_(e_dictreq)); @@ -5248,8 +5256,8 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, // To search a dict, either a callback function or a key can be // specified. dict_T *const d = argvars[2].vval.v_dict; - const dictitem_T *const di = tv_dict_find(d, "key", -1); - if (di != NULL) { + const dictitem_T *di; + if ((di = tv_dict_find(d, "key", -1)) != NULL) { if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL || *di->di_tv.vval.v_string == NUL) { semsg(_(e_invarg2), tv_get_string(&di->di_tv)); @@ -5259,7 +5267,14 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, } else if (!tv_dict_get_callback(d, "text_cb", -1, &cb)) { semsg(_(e_invargval), "text_cb"); return; + } else if ((di = tv_dict_find(d, "limit", -1)) != NULL) { + if (di->di_tv.v_type != VAR_NUMBER) { + semsg(_(e_invarg2), tv_get_string(&di->di_tv)); + return; + } + max_matches = (long)tv_get_number_chk(&di->di_tv, NULL); } + if (tv_dict_find(d, "matchseq", -1) != NULL) { matchseq = true; } @@ -5278,7 +5293,7 @@ static void do_fuzzymatch(const typval_T *const argvars, typval_T *const rettv, } fuzzy_match_in_list(argvars[0].vval.v_list, (char_u *)tv_get_string(&argvars[1]), matchseq, key, - &cb, retmatchpos, rettv->vval.v_list); + &cb, retmatchpos, rettv->vval.v_list, max_matches); callback_free(&cb); } diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 7a52d0a044..6872eb3bb7 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -258,6 +258,7 @@ let s:filename_checks = { \ 'rnoweb': ['file.rnw', 'file.snw'], \ 'rrst': ['file.rrst', 'file.srst'], \ 'template': ['file.tmpl'], + \ 'html': ['file.html', 'file.htm', 'file.cshtml'], \ 'htmlm4': ['file.html.m4'], \ 'httest': ['file.htt', 'file.htb'], \ 'ibasic': ['file.iba', 'file.ibi'], diff --git a/src/nvim/testdir/test_matchfuzzy.vim b/src/nvim/testdir/test_matchfuzzy.vim index abcc9b40c1..d53f8b0f4d 100644 --- a/src/nvim/testdir/test_matchfuzzy.vim +++ b/src/nvim/testdir/test_matchfuzzy.vim @@ -245,4 +245,16 @@ func Test_matchfuzzypos_mbyte() call assert_equal([['xффйд'], [[2, 3, 4]], [168]], matchfuzzypos(['xффйд'], 'фйд')) endfunc +" Test for matchfuzzy() with limit +func Test_matchfuzzy_limit() + let x = ['1', '2', '3', '2'] + call assert_equal(['2', '2'], x->matchfuzzy('2')) + call assert_equal(['2', '2'], x->matchfuzzy('2', #{})) + call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 0})) + call assert_equal(['2'], x->matchfuzzy('2', #{limit: 1})) + call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 2})) + call assert_equal(['2', '2'], x->matchfuzzy('2', #{limit: 3})) + call assert_fails("call matchfuzzy(x, '2', #{limit: '2'})", 'E475:') +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/tui/input.c b/src/nvim/tui/input.c index 691b2ea9da..399ad325d1 100644 --- a/src/nvim/tui/input.c +++ b/src/nvim/tui/input.c @@ -13,6 +13,7 @@ #include "nvim/option.h" #include "nvim/os/input.h" #include "nvim/os/os.h" +#include "nvim/tui/tui.h" #include "nvim/tui/input.h" #include "nvim/vim.h" #ifdef WIN32 @@ -41,6 +42,7 @@ void tinput_init(TermInput *input, Loop *loop) input->paste = 0; input->in_fd = STDIN_FILENO; input->waiting_for_bg_response = 0; + input->extkeys_type = kExtkeysNone; // The main thread is waiting for the UI thread to call CONTINUE, so it can // safely access global variables. input->ttimeout = (bool)p_ttimeout; @@ -344,6 +346,39 @@ static void tk_getkeys(TermInput *input, bool force) forward_modified_utf8(input, &key); } else if (key.type == TERMKEY_TYPE_MOUSE) { forward_mouse_event(input, &key); + } else if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { + // There is no specified limit on the number of parameters a CSI sequence can contain, so just + // allocate enough space for a large upper bound + long args[16]; + size_t nargs = 16; + unsigned long cmd; + if (termkey_interpret_csi(input->tk, &key, args, &nargs, &cmd) == TERMKEY_RES_KEY) { + uint8_t intermediate = (cmd >> 16) & 0xFF; + uint8_t initial = (cmd >> 8) & 0xFF; + uint8_t command = cmd & 0xFF; + + // Currently unused + (void)intermediate; + + if (input->waiting_for_csiu_response > 0) { + if (initial == '?' && command == 'u') { + // The first (and only) argument contains the current progressive + // enhancement flags. Only enable CSI u mode if the first bit + // (disambiguate escape codes) is not already set + if (nargs > 0 && (args[0] & 0x1) == 0) { + input->extkeys_type = kExtkeysCSIu; + } else { + input->extkeys_type = kExtkeysNone; + } + } else if (initial == '?' && command == 'c') { + // Received Primary Device Attributes response + input->waiting_for_csiu_response = 0; + tui_enable_extkeys(input->tui_data); + } else { + input->waiting_for_csiu_response--; + } + } + } } } diff --git a/src/nvim/tui/input.h b/src/nvim/tui/input.h index 2a8ea32a88..84daf40744 100644 --- a/src/nvim/tui/input.h +++ b/src/nvim/tui/input.h @@ -6,6 +6,13 @@ #include "nvim/event/stream.h" #include "nvim/event/time.h" +#include "nvim/tui/tui.h" + +typedef enum { + kExtkeysNone, + kExtkeysCSIu, + kExtkeysXterm, +} ExtkeysType; typedef struct term_input { int in_fd; @@ -14,6 +21,8 @@ typedef struct term_input { bool waiting; bool ttimeout; int8_t waiting_for_bg_response; + int8_t waiting_for_csiu_response; + ExtkeysType extkeys_type; long ttimeoutlen; TermKey *tk; #if TERMKEY_VERSION_MAJOR > 0 || TERMKEY_VERSION_MINOR > 18 @@ -25,6 +34,7 @@ typedef struct term_input { RBuffer *key_buffer; uv_mutex_t key_buffer_mutex; uv_cond_t key_buffer_cond; + TUIData *tui_data; } TermInput; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 4b5ad4cff8..61c6dc5ca3 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -71,7 +71,7 @@ typedef struct { int top, bot, left, right; } Rect; -typedef struct { +struct TUIData { UIBridgeData *bridge; Loop *loop; unibi_var_t params[9]; @@ -132,9 +132,10 @@ typedef struct { int set_underline_style; int set_underline_color; int enable_extended_keys, disable_extended_keys; + int get_extkeys; } unibi_ext; char *space_buf; -} TUIData; +}; static bool volatile got_winch = false; static bool did_user_set_dimensions = false; @@ -179,6 +180,32 @@ UI *tui_start(void) return ui_bridge_attach(ui, tui_main, tui_scheduler); } +void tui_enable_extkeys(TUIData *data) +{ + TermInput input = data->input; + unibi_term *ut = data->ut; + UI *ui = data->bridge->ui; + + switch (input.extkeys_type) { + case kExtkeysCSIu: + data->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys", + "\x1b[>1u"); + data->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys", + "\x1b[<1u"); + break; + case kExtkeysXterm: + data->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys", + "\x1b[>4;2m"); + data->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys", + "\x1b[>4;0m"); + break; + default: + break; + } + + unibi_out_ext(ui, data->unibi_ext.enable_extended_keys); +} + static size_t unibi_pre_fmt_str(TUIData *data, unsigned int unibi_index, char *buf, size_t len) { const char *str = unibi_get_str(data->ut, unibi_index); @@ -228,8 +255,10 @@ static void terminfo_start(UI *ui) data->unibi_ext.set_underline_color = -1; data->unibi_ext.enable_extended_keys = -1; data->unibi_ext.disable_extended_keys = -1; + data->unibi_ext.get_extkeys = -1; data->out_fd = STDOUT_FILENO; data->out_isatty = os_isatty(data->out_fd); + data->input.tui_data = data; const char *term = os_getenv("TERM"); #ifdef WIN32 @@ -311,8 +340,9 @@ static void terminfo_start(UI *ui) // Enable bracketed paste unibi_out_ext(ui, data->unibi_ext.enable_bracketed_paste); - // Enable extended keys (also known as 'modifyOtherKeys' or CSI u) - unibi_out_ext(ui, data->unibi_ext.enable_extended_keys); + // Query the terminal to see if it supports CSI u + data->input.waiting_for_csiu_response = 5; + unibi_out_ext(ui, data->unibi_ext.get_extkeys); int ret; uv_loop_init(&data->write_loop); @@ -1810,6 +1840,12 @@ static void patch_terminfo_bugs(TUIData *data, const char *term, const char *col data->unibi_ext.get_bg = (int)unibi_add_ext_str(ut, "ext.get_bg", "\x1b]11;?\x07"); + // Query the terminal to see if it supports CSI u key encoding by writing CSI + // ? u followed by a request for the primary device attributes (CSI c) + // See https://sw.kovidgoyal.net/kitty/keyboard-protocol/#detection-of-support-for-this-protocol + data->unibi_ext.get_extkeys = (int)unibi_add_ext_str(ut, "ext.get_extkeys", + "\x1b[?u\x1b[c"); + // Terminals with 256-colour SGR support despite what terminfo says. if (unibi_get_num(ut, unibi_max_colors) < 256) { // See http://fedoraproject.org/wiki/Features/256_Color_Terminals @@ -2074,15 +2110,9 @@ static void augment_terminfo(TUIData *data, const char *term, long vte_version, "\x1b[58:2::%p1%d:%p2%d:%p3%dm"); } - data->unibi_ext.enable_extended_keys = unibi_find_ext_str(ut, "Eneks"); - data->unibi_ext.disable_extended_keys = unibi_find_ext_str(ut, "Dseks"); - if (data->unibi_ext.enable_extended_keys == -1) { - if (!kitty && (vte_version == 0 || vte_version >= 5400)) { - data->unibi_ext.enable_extended_keys = (int)unibi_add_ext_str(ut, "ext.enable_extended_keys", - "\x1b[>4;2m"); - data->unibi_ext.disable_extended_keys = (int)unibi_add_ext_str(ut, "ext.disable_extended_keys", - "\x1b[>4m"); - } + if (!kitty && (vte_version == 0 || vte_version >= 5400)) { + // Fallback to Xterm's modifyOtherKeys if terminal does not support CSI u + data->input.extkeys_type = kExtkeysXterm; } } diff --git a/src/nvim/tui/tui.h b/src/nvim/tui/tui.h index 996496ee60..88ea73e99c 100644 --- a/src/nvim/tui/tui.h +++ b/src/nvim/tui/tui.h @@ -4,6 +4,8 @@ #include "nvim/cursor_shape.h" #include "nvim/ui.h" +typedef struct TUIData TUIData; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "tui/tui.h.generated.h" #endif diff --git a/test/functional/api/autocmd_spec.lua b/test/functional/api/autocmd_spec.lua index 377b4fecf0..a30af63ba1 100644 --- a/test/functional/api/autocmd_spec.lua +++ b/test/functional/api/autocmd_spec.lua @@ -727,7 +727,7 @@ describe('autocmd api', function() set_ft("txt") set_ft("python") - eq(get_executed_count(), 2) + eq(2, get_executed_count()) end) it('works getting called multiple times', function() @@ -736,7 +736,7 @@ describe('autocmd api', function() set_ft() set_ft() - eq(get_executed_count(), 3) + eq(3, get_executed_count()) end) it('handles ++once', function() @@ -746,7 +746,7 @@ describe('autocmd api', function() set_ft('txt') set_ft('help') - eq(get_executed_count(), 1) + eq(1, get_executed_count()) end) it('errors on unexpected keys', function() @@ -874,7 +874,7 @@ describe('autocmd api', function() set_ft("txt") set_ft("python") - eq(get_executed_count(), 1) + eq(1, get_executed_count()) end) it('autocmds can be registered multiple times.', function() @@ -888,7 +888,7 @@ describe('autocmd api', function() set_ft("txt") set_ft("python") - eq(get_executed_count(), 3 * 2) + eq(3 * 2, get_executed_count()) end) it('can be deleted', function() diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua index d828bdf948..0fbf58a8e7 100644 --- a/test/functional/api/proc_spec.lua +++ b/test/functional/api/proc_spec.lua @@ -63,9 +63,9 @@ describe('API', function() local pid = funcs.getpid() local pinfo = request('nvim_get_proc', pid) eq((iswin() and 'nvim.exe' or 'nvim'), pinfo.name) - eq(pinfo.pid, pid) - eq(type(pinfo.ppid), 'number') - neq(pinfo.ppid, pid) + eq(pid, pinfo.pid) + eq('number', type(pinfo.ppid)) + neq(pid, pinfo.ppid) end) it('validates input', function() diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 04b79a7157..f4b1a7fd59 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -122,9 +122,9 @@ describe('API', function() -- Functions nvim('exec', 'function Foo()\ncall setline(1,["xxx"])\nendfunction', false) - eq(nvim('get_current_line'), '') + eq('', nvim('get_current_line')) nvim('exec', 'call Foo()', false) - eq(nvim('get_current_line'), 'xxx') + eq('xxx', nvim('get_current_line')) -- Autocmds nvim('exec','autocmd BufAdd * :let x1 = "Hello"', false) @@ -1841,10 +1841,10 @@ describe('API', function() -- spin the loop a bit helpers.run(nil, nil, on_setup) - eq(nvim('get_var', 'x1'), '…') + eq('…', nvim('get_var', 'x1')) -- Because of the double escaping this is neq - neq(nvim('get_var', 'x2'), '…') - eq(nvim('get_var', 'x3'), '…') + neq('…', nvim('get_var', 'x2')) + eq('…', nvim('get_var', 'x3')) end) end) diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua index 37a9f0b836..f6fb859ccc 100644 --- a/test/functional/core/main_spec.lua +++ b/test/functional/core/main_spec.lua @@ -52,11 +52,15 @@ describe('Command-line option', function() if helpers.pending_win32(pending) then return end local screen = Screen.new(40, 8) screen:attach() - funcs.termopen({ + local args = { nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', - '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', - '-s', '-' - }) + '--cmd', 'set noswapfile shortmess+=IFW fileformats=unix', + '-s', '-' + } + + -- Need to explicitly pipe to stdin so that the embedded Nvim instance doesn't try to read + -- data from the terminal #18181 + funcs.termopen(string.format([[echo "" | %s]], table.concat(args, " "))) screen:expect([[ ^ | {1:~ }| diff --git a/test/functional/editor/langmap_spec.lua b/test/functional/editor/langmap_spec.lua index e4349a22e7..af19f97a68 100644 --- a/test/functional/editor/langmap_spec.lua +++ b/test/functional/editor/langmap_spec.lua @@ -30,7 +30,7 @@ describe("'langmap'", function() command('nmapclear') end) it("'langnoremap' is by default ON", function() - eq(eval('&langnoremap'), 1) + eq(1, eval('&langnoremap')) end) it("Results of maps are not converted when 'langnoremap' ON.", function() @@ -71,19 +71,19 @@ describe("'langmap'", function() feed('<C-w>s') local origwin = curwin() feed('<C-w>i') - neq(curwin(), origwin) + neq(origwin, curwin()) -- Works when setting a mark feed('yy3p3gg0mwgg0mi') - eq(call('getpos', "'i"), {0, 3, 1, 0}) - eq(call('getpos', "'w"), {0, 1, 1, 0}) + eq({0, 3, 1, 0}, call('getpos', "'i")) + eq({0, 1, 1, 0}, call('getpos', "'w")) feed('3dd') -- Works when moving to a mark feed("'i") - eq(call('getpos', '.'), {0, 1, 1, 0}) + eq({0, 1, 1, 0}, call('getpos', '.')) -- Works when selecting a register feed('qillqqwhhq') - eq(eval('@i'), 'hh') - eq(eval('@w'), 'll') + eq('hh', eval('@i')) + eq('ll', eval('@w')) feed('a<C-r>i<esc>') expect('illii www') feed('"ip') @@ -107,7 +107,7 @@ describe("'langmap'", function() expect('wwi www') feed('u@a') expect('wwi www') - eq(eval('@a'), ':s/i/w/gc\ryyn') + eq(':s/i/w/gc\ryyn', eval('@a')) end) it('insert-mode CTRL-G', function() command('set langmap=jk,kj') @@ -127,7 +127,7 @@ describe("'langmap'", function() helhellolo helxlo hello]]) - eq(eval('@a'), 'gg3|ahellojx') + eq('gg3|ahellojx', eval('@a')) end) it('command-line CTRL-\\', function() command('set langmap=en,ne') @@ -145,8 +145,8 @@ describe("'langmap'", function() set langmap=ij,ji ]]) feed(':let <C-R>i=1<CR>') - eq(eval('i_value'), 1) - eq(eval('j_value'), 0) + eq(1, eval('i_value')) + eq(0, eval('j_value')) end) -- it('-- More -- prompt', function() -- -- The 'b' 'j' 'd' 'f' commands at the -- More -- prompt @@ -186,17 +186,17 @@ describe("'langmap'", function() nnoremap x :call Map()<CR> ]]) feed('x1<CR>') - eq(eval('gotten_one'), 1) + eq(1, eval('gotten_one')) command('let g:gotten_one = 0') feed_command('call Map()') feed('1<CR>') - eq(eval('gotten_one'), 1) + eq(1, eval('gotten_one')) end) end) it('conversions are not applied during setreg()', function() call('setreg', 'i', 'ww') - eq(eval('@i'), 'ww') + eq('ww', eval('@i')) end) it('conversions not applied in insert mode', function() feed('aiiiwww') diff --git a/test/functional/editor/macro_spec.lua b/test/functional/editor/macro_spec.lua index d4cf6b28fd..53be7dcc62 100644 --- a/test/functional/editor/macro_spec.lua +++ b/test/functional/editor/macro_spec.lua @@ -17,20 +17,20 @@ describe('macros', function() it('can be recorded and replayed', function() feed('qiahello<esc>q') expect('hello') - eq(eval('@i'), 'ahello') + eq('ahello', eval('@i')) feed('@i') expect('hellohello') - eq(eval('@i'), 'ahello') + eq('ahello', eval('@i')) end) it('applies maps', function() command('imap x l') command('nmap l a') feed('qilxxx<esc>q') expect('lll') - eq(eval('@i'), 'lxxx') + eq('lxxx', eval('@i')) feed('@i') expect('llllll') - eq(eval('@i'), 'lxxx') + eq('lxxx', eval('@i')) end) it('can be replayed with Q', function() diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua index 6a2e86ccb4..fbb67f9c03 100644 --- a/test/functional/legacy/arglist_spec.lua +++ b/test/functional/legacy/arglist_spec.lua @@ -17,7 +17,7 @@ describe('argument list commands', function() end local function assert_fails(cmd, err) - neq(exc_exec(cmd):find(err), nil) + neq(nil, exc_exec(cmd):find(err)) end it('test that argidx() works', function() diff --git a/test/functional/legacy/function_sort_spec.lua b/test/functional/legacy/function_sort_spec.lua index 12875460e0..414953aacc 100644 --- a/test/functional/legacy/function_sort_spec.lua +++ b/test/functional/legacy/function_sort_spec.lua @@ -52,6 +52,6 @@ describe('sort', function() eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval([[sort([3.3, 1, "2", "A", "a", "AA"], '')]])) eq({'2', 'A', 'AA', 'a', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 0)')) eq({'2', 'A', 'a', 'AA', 1, 3.3}, eval('sort([3.3, 1, "2", "A", "a", "AA"], 1)')) - neq(exc_exec('call sort([3.3, 1, "2"], 3)'):find('E474:'), nil) + neq(nil, exc_exec('call sort([3.3, 1, "2"], 3)'):find('E474:')) end) end) diff --git a/test/functional/legacy/wordcount_spec.lua b/test/functional/legacy/wordcount_spec.lua index 826743b0ca..21f96628c0 100644 --- a/test/functional/legacy/wordcount_spec.lua +++ b/test/functional/legacy/wordcount_spec.lua @@ -50,44 +50,44 @@ describe('wordcount', function() ]=]) -- Test 1: empty window - eq(eval('DoRecordWin()'), - eval([=[ + eq(eval([=[ [[''], {'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0, 'bytes': 0, 'cursor_bytes': 0}] - ]=]) + ]=]), + eval('DoRecordWin()') ) -- Test 2: some words, cursor at start command([[call PutInWindow('one two three')]]) - eq(eval('DoRecordWin([1, 1, 0])'), - eval([=[ + eq(eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0, 'bytes': 15, 'cursor_bytes': 1}] - ]=]) + ]=]), + eval('DoRecordWin([1, 1, 0])') ) -- Test 3: some words, cursor at end command([[call PutInWindow('one two three')]]) - eq(eval('DoRecordWin([2, 99, 0])'), - eval([=[ + eq(eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 14}] - ]=]) + ]=]), + eval('DoRecordWin([2, 99, 0])') ) -- Test 4: some words, cursor at end, ve=all command('set ve=all') command([[call PutInWindow('one two three')]]) - eq(eval('DoRecordWin([2,99,0])'), - eval([=[ + eq(eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 15}] - ]=]) + ]=]), + eval('DoRecordWin([2,99,0])') ) command('set ve=') -- Test 5: several lines with words command([=[call PutInWindow(['one two three', 'one two three', 'one two three'])]=]) - eq(eval('DoRecordWin([4,99,0])'), - eval([=[ + eq(eval([=[ [['', 'one two three', 'one two three', 'one two three'], {'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9, 'bytes': 43, 'cursor_bytes': 42}] - ]=]) + ]=]), + eval('DoRecordWin([4,99,0])') ) -- Test 6: one line with BOM set @@ -95,10 +95,10 @@ describe('wordcount', function() command('wincmd k') command('set bomb') command('wincmd j') - eq(eval('DoRecordWin([2,99,0])'), - eval([=[ + eq(eval([=[ [['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 18, 'cursor_bytes': 14}] - ]=]) + ]=]), + eval('DoRecordWin([2,99,0])') ) command('wincmd k') command('set nobomb') @@ -106,18 +106,18 @@ describe('wordcount', function() -- Test 7: one line with multibyte words command([=[call PutInWindow(['Äne M¤ne Müh'])]=]) - eq(eval('DoRecordWin([2,99,0])'), - eval([=[ + eq(eval([=[ [['', 'Äne M¤ne Müh'], {'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3, 'bytes': 17, 'cursor_bytes': 16}] - ]=]) + ]=]), + eval('DoRecordWin([2,99,0])') ) -- Test 8: several lines with multibyte words command([=[call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])]=]) - eq(eval('DoRecordWin([3,99,0])'), - eval([=[ + eq(eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7, 'bytes': 36, 'cursor_bytes': 35}] - ]=]) + ]=]), + eval('DoRecordWin([3,99,0])') ) -- Test 9: visual mode, complete buffer @@ -131,10 +131,10 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval('log'), - eval([=[ + eq(eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32, 'visual_words': 7, 'visual_bytes': 36}] - ]=]) + ]=]), + eval('log') ) -- Test 10: visual mode (empty) @@ -148,10 +148,10 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval('log'), - eval([=[ + eq(eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1, 'visual_words': 0, 'visual_bytes': 1}] - ]=]) + ]=]), + eval('log') ) -- Test 11: visual mode, single line @@ -165,10 +165,10 @@ describe('wordcount', function() command('set stl= ls=1') command('let log=DoRecordWin([3,99,0])') command('let log[1]=g:visual_stat') - eq(eval('log'), - eval([=[ + eq(eval([=[ [['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13, 'visual_words': 3, 'visual_bytes': 16}] - ]=]) + ]=]), + eval('log') ) end) end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index ae6a1d5765..d9a8dfd2e8 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -645,17 +645,17 @@ describe('lua stdlib', function() return vim.tbl_islist(c) and count == 0 ]])) - eq(exec_lua([[ + eq({a = {b = 1}}, exec_lua([[ local a = { a = { b = 1 } } local b = { a = {} } return vim.tbl_deep_extend("force", a, b) - ]]), {a = {b = 1}}) + ]])) - eq(exec_lua([[ + eq({a = {b = 1}}, exec_lua([[ local a = { a = 123 } local b = { a = { b = 1} } return vim.tbl_deep_extend("force", a, b) - ]]), {a = {b = 1}}) + ]])) ok(exec_lua([[ local a = { a = {[2] = 3} } @@ -664,11 +664,11 @@ describe('lua stdlib', function() return vim.deep_equal(c, {a = {[3] = 3}}) ]])) - eq(exec_lua([[ + eq({a = 123}, exec_lua([[ local a = { a = { b = 1} } local b = { a = 123 } return vim.tbl_deep_extend("force", a, b) - ]]), {a = 123 }) + ]])) matches('invalid "behavior": nil', pcall_err(exec_lua, [[ diff --git a/test/functional/options/keymap_spec.lua b/test/functional/options/keymap_spec.lua index 52a714f7a8..a814c35a39 100644 --- a/test/functional/options/keymap_spec.lua +++ b/test/functional/options/keymap_spec.lua @@ -120,9 +120,9 @@ describe("'keymap' / :lmap", function() it("Can be toggled with <C-^> in insert mode", function() feed('i<C-^>l<C-^>l<esc>') expect('lalllaaa') - eq(eval('&iminsert'), 1) + eq(1, eval('&iminsert')) feed('i<C-^><esc>') - eq(eval('&iminsert'), 0) + eq(0, eval('&iminsert')) end) end) describe("'imsearch' option", function() @@ -136,36 +136,36 @@ describe("'keymap' / :lmap", function() expect('aaa') end) it("Can be toggled with C-^", function() - eq(eval('&imsearch'), 1) + eq(1, eval('&imsearch')) feed('/<C-^>lll<cr>3x') expect('aaa') - eq(eval('&imsearch'), 0) + eq(0, eval('&imsearch')) feed('u0/<C-^>lll<cr>3x') expect('lll') - eq(eval('&imsearch'), 1) + eq(1, eval('&imsearch')) end) it("can follow 'iminsert'", function() command('set imsearch=-1') feed('/lll<cr>3x') expect('lll') - eq(eval('&imsearch'), -1) - eq(eval('&iminsert'), 1) + eq(-1, eval('&imsearch')) + eq(1, eval('&iminsert')) feed('u/<C-^>lll<cr>3x') expect('aaa') - eq(eval('&imsearch'), -1) - eq(eval('&iminsert'), 0) + eq(-1, eval('&imsearch')) + eq(0, eval('&iminsert')) end) end) it(":lmap not applied to macros", function() command("call setreg('a', 'il')") feed('@a') expect('llllaaa') - eq(call('getreg', 'a'), 'il') + eq('il', call('getreg', 'a')) end) it(":lmap applied to macro recording", function() feed('qail<esc>q@a') expect('aalllaaa') - eq(call('getreg', 'a'), 'ia') + eq('ia', call('getreg', 'a')) end) it(":lmap not applied to mappings", function() command('imap t l') diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index 83d794b620..19b01edb29 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -3,6 +3,7 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local exec_lua = helpers.exec_lua local eq = helpers.eq +local neq = require('test.helpers').neq describe('vim.lsp.diagnostic', function() local fake_uri @@ -227,5 +228,43 @@ describe('vim.lsp.diagnostic', function() eq(exec_lua([[return vim.str_byteindex(..., 7, true)]], line), result[1].col) eq(exec_lua([[return vim.str_byteindex(..., 8, true)]], line), result[1].end_col) end) + + it('does not create buffer on empty diagnostics', function() + local bufnr + + -- No buffer is created without diagnostics + bufnr = exec_lua [[ + vim.lsp.diagnostic.on_publish_diagnostics(nil, { + uri = "file:///fake/uri2", + diagnostics = {}, + }, {client_id=client_id}) + return vim.fn.bufnr(vim.uri_to_fname("file:///fake/uri2")) + ]] + eq(bufnr, -1) + + -- Create buffer on diagnostics + bufnr = exec_lua [[ + vim.lsp.diagnostic.on_publish_diagnostics(nil, { + uri = "file:///fake/uri2", + diagnostics = { + make_error('Diagnostic', 0, 0, 0, 0), + }, + }, {client_id=client_id}) + return vim.fn.bufnr(vim.uri_to_fname("file:///fake/uri2")) + ]] + neq(bufnr, -1) + eq(exec_lua([[return #vim.diagnostic.get(...)]], bufnr), 1) + + -- Clear diagnostics after buffer was created + bufnr = exec_lua [[ + vim.lsp.diagnostic.on_publish_diagnostics(nil, { + uri = "file:///fake/uri2", + diagnostics = {}, + }, {client_id=client_id}) + return vim.fn.bufnr(vim.uri_to_fname("file:///fake/uri2")) + ]] + neq(bufnr, -1) + eq(exec_lua([[return #vim.diagnostic.get(...)]], bufnr), 0) + end) end) end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 359d1f206a..96e7b1b6bc 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -85,8 +85,8 @@ describe('float window', function() local buf = meths.create_buf(false, false) meths.buf_set_lines(buf, 0, -1, true, {'the floatwin'}) local win = meths.open_win(buf, true, {relative='win', width=16, height=1, row=0, col=10}) - eq(pcall_err(funcs.win_execute, win, 'close'), 'Vim(close):E37: No write since last change (add ! to override)') - eq(pcall_err(funcs.win_execute, win, 'bdelete'), 'Vim(bdelete):E89: No write since last change for buffer 2 (add ! to override)') + eq('Vim(close):E37: No write since last change (add ! to override)', pcall_err(funcs.win_execute, win, 'close')) + eq('Vim(bdelete):E89: No write since last change for buffer 2 (add ! to override)', pcall_err(funcs.win_execute, win, 'bdelete')) funcs.win_execute(win, 'bwipe!') end) @@ -367,7 +367,7 @@ describe('float window', function() return vim.api.nvim_open_win(bufnr, false, opts) ]]) command('windo echo') - neq(eval('win_getid()'), winid) + neq(winid, eval('win_getid()')) end) it('is active after windo when focusable', function() @@ -384,7 +384,7 @@ describe('float window', function() return vim.api.nvim_open_win(bufnr, false, opts) ]]) command('windo echo') - eq(eval('win_getid()'), winid) + eq(winid, eval('win_getid()')) end) it('supports windo with focusable and non-focusable floats', function() diff --git a/test/functional/vimscript/reltime_spec.lua b/test/functional/vimscript/reltime_spec.lua index d87943e485..6d661402a6 100644 --- a/test/functional/vimscript/reltime_spec.lua +++ b/test/functional/vimscript/reltime_spec.lua @@ -12,7 +12,7 @@ describe('reltimestr(), reltimefloat()', function() local later = reltime() local elapsed = reltime(now) - neq(reltimestr(elapsed), '0.0') + neq('0.0', reltimestr(elapsed)) ok(reltimefloat(elapsed) > 0.0) -- original vim test for < 0.1, but easily fails on travis ok(nil ~= string.match(reltimestr(elapsed), "0%.")) @@ -26,7 +26,7 @@ describe('reltimestr(), reltimefloat()', function() eq(0.0, reltimefloat(same)) local differs = reltime(now, later) - neq(reltimestr(differs), '0.0') + neq('0.0', reltimestr(differs)) ok(reltimefloat(differs) > 0.0) -- original vim test for < 0.1, but easily fails on travis ok(nil ~= string.match(reltimestr(differs), "0%.")) diff --git a/test/functional/vimscript/setpos_spec.lua b/test/functional/vimscript/setpos_spec.lua index 935f387bcc..02e550dcc0 100644 --- a/test/functional/vimscript/setpos_spec.lua +++ b/test/functional/vimscript/setpos_spec.lua @@ -24,41 +24,41 @@ describe('setpos() function', function() end) it('can set the current cursor position', function() setpos(".", {0, 2, 1, 0}) - eq(getpos("."), {0, 2, 1, 0}) + eq({0, 2, 1, 0}, getpos(".")) setpos(".", {2, 1, 1, 0}) - eq(getpos("."), {0, 1, 1, 0}) + eq({0, 1, 1, 0}, getpos(".")) local ret = exc_exec('call setpos(".", [1, 1, 1, 0])') eq(0, ret) end) it('can set lowercase marks in the current buffer', function() setpos("'d", {0, 2, 1, 0}) - eq(getpos("'d"), {0, 2, 1, 0}) + eq({0, 2, 1, 0}, getpos("'d")) command('undo') command('call setpos("\'d", [2, 3, 1, 0])') - eq(getpos("'d"), {0, 3, 1, 0}) + eq({0, 3, 1, 0}, getpos("'d")) end) it('can set lowercase marks in other buffers', function() local retval = setpos("'d", {1, 2, 1, 0}) eq(0, retval) setpos("'d", {1, 2, 1, 0}) - eq(getpos("'d"), {0, 0, 0, 0}) + eq({0, 0, 0, 0}, getpos("'d")) command('wincmd w') - eq(eval('bufnr("%")'), 1) - eq(getpos("'d"), {0, 2, 1, 0}) + eq(1, eval('bufnr("%")')) + eq({0, 2, 1, 0}, getpos("'d")) end) it("fails when setting a mark in a buffer that doesn't exist", function() local retval = setpos("'d", {3, 2, 1, 0}) eq(-1, retval) - eq(getpos("'d"), {0, 0, 0, 0}) + eq({0, 0, 0, 0}, getpos("'d")) retval = setpos("'D", {3, 2, 1, 0}) eq(-1, retval) - eq(getpos("'D"), {0, 0, 0, 0}) + eq({0, 0, 0, 0}, getpos("'D")) end) it('can set uppercase marks', function() setpos("'D", {2, 2, 3, 0}) - eq(getpos("'D"), {2, 2, 3, 0}) + eq({2, 2, 3, 0}, getpos("'D")) -- Can set a mark in another buffer setpos("'D", {1, 2, 2, 0}) - eq(getpos("'D"), {1, 2, 2, 0}) + eq({1, 2, 2, 0}, getpos("'D")) end) end) diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua index a0e02b6624..c039b95d16 100644 --- a/test/unit/os/env_spec.lua +++ b/test/unit/os/env_spec.lua @@ -154,7 +154,7 @@ describe('env.c', function() local value = 'TESTVALUE' os_setenv(name, value, 1) eq(OK, os_unsetenv(name)) - neq(os_getenv(name), value) + neq(value, os_getenv(name)) -- Depending on the platform the var might be unset or set as '' assert.True(os_getenv(name) == nil or os_getenv(name) == '') if os_getenv(name) == nil then |