diff options
51 files changed, 2669 insertions, 742 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bdc487894e..d4c102bb04 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,7 +108,7 @@ jobs: - if: "!cancelled()" name: lintcfull - run: ./ci/run_lint.sh lintcfull + run: make lintcfull - if: "!cancelled()" name: lintstylua @@ -125,19 +125,19 @@ jobs: - if: "!cancelled()" name: lintlua - run: ./ci/run_lint.sh lintlua + run: make lintlua - if: "!cancelled()" name: lintpy - run: ./ci/run_lint.sh lintpy + run: make lintpy - if: "!cancelled()" name: lintsh - run: ./ci/run_lint.sh lintsh + run: make lintsh - if: "!cancelled()" name: check-single-includes - run: ./ci/run_lint.sh check-single-includes + run: make check-single-includes - name: Cache dependencies run: ./ci/before_cache.sh diff --git a/.github/workflows/env.sh b/.github/workflows/env.sh index 03f4a10211..e7c9d19f3a 100755 --- a/.github/workflows/env.sh +++ b/.github/workflows/env.sh @@ -9,7 +9,6 @@ EOF cat <<EOF >> "$GITHUB_ENV" CACHE_ENABLE=true -CI_TARGET=tests CI_BUILD_DIR=$GITHUB_WORKSPACE BUILD_DIR=$GITHUB_WORKSPACE/build DEPS_BUILD_DIR=$HOME/nvim-deps @@ -58,7 +57,6 @@ EOF DEPS_CMAKE_FLAGS="$DEPS_CMAKE_FLAGS -DUSE_BUNDLED_LUV=ON" cat <<EOF >> "$GITHUB_ENV" USE_BUNDLED=OFF -CI_TARGET=lint EOF ;; functionaltest-lua) diff --git a/ci/run_lint.sh b/ci/run_lint.sh deleted file mode 100755 index ba1a61858e..0000000000 --- a/ci/run_lint.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -CI_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -source "${CI_DIR}/common/build.sh" -source "${CI_DIR}/common/suite.sh" - -rm -f "$END_MARKER" - -# Run all tests if no input argument is given -if (($# == 0)); then - tests=('lintcfull' 'lintlua' 'lintpy' 'lintsh' 'check-single-includes') -else - tests=("$@") -fi - -for i in "${tests[@]}"; do - make "$i" || fail "$i" -done - -end_tests diff --git a/ci/run_tests.sh b/ci/run_tests.sh index 23460b682e..da72d09506 100755 --- a/ci/run_tests.sh +++ b/ci/run_tests.sh @@ -33,3 +33,9 @@ for i in "${tests[@]}"; do done end_tests + +if [[ -s "${GCOV_ERROR_FILE}" ]]; then + echo '=== Unexpected gcov errors: ===' + cat "${GCOV_ERROR_FILE}" + exit 1 +fi diff --git a/ci/script.sh b/ci/script.sh deleted file mode 100755 index 74fc4eda6c..0000000000 --- a/ci/script.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -o pipefail - -ci/run_${CI_TARGET}.sh - -if [[ -s "${GCOV_ERROR_FILE}" ]]; then - echo '=== Unexpected gcov errors: ===' - cat "${GCOV_ERROR_FILE}" - exit 1 -fi diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 8c174fc129..4ed676e613 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -504,6 +504,7 @@ static int access_option_value(char *key, long *numval, char **stringval, int op static int access_option_value_for(char *key, long *numval, char **stringval, int opt_flags, int opt_type, void *from, bool get, Error *err) { + bool need_switch = false; switchwin_T switchwin; aco_save_T aco; int result = 0; @@ -511,24 +512,32 @@ static int access_option_value_for(char *key, long *numval, char **stringval, in try_start(); switch (opt_type) { case SREQ_WIN: - if (switch_win_noblock(&switchwin, (win_T *)from, win_find_tabpage((win_T *)from), true) - == FAIL) { - restore_win_noblock(&switchwin, true); - if (try_end(err)) { + need_switch = (win_T *)from != curwin; + if (need_switch) { + if (switch_win_noblock(&switchwin, (win_T *)from, win_find_tabpage((win_T *)from), true) + == FAIL) { + restore_win_noblock(&switchwin, true); + if (try_end(err)) { + return result; + } + api_set_error(err, kErrorTypeException, "Problem while switching windows"); return result; } - api_set_error(err, - kErrorTypeException, - "Problem while switching windows"); - return result; } result = access_option_value(key, numval, stringval, opt_flags, get, err); - restore_win_noblock(&switchwin, true); + if (need_switch) { + restore_win_noblock(&switchwin, true); + } break; case SREQ_BUF: - aucmd_prepbuf(&aco, (buf_T *)from); + need_switch = (buf_T *)from != curbuf; + if (need_switch) { + aucmd_prepbuf(&aco, (buf_T *)from); + } result = access_option_value(key, numval, stringval, opt_flags, get, err); - aucmd_restbuf(&aco); + if (need_switch) { + aucmd_restbuf(&aco); + } break; case SREQ_GLOBAL: result = access_option_value(key, numval, stringval, opt_flags, get, err); diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 2abe9068eb..0571e71cb5 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -136,7 +136,6 @@ static char *ctrl_x_mode_names[] = { }; static char e_hitend[] = N_("Hit end of paragraph"); -static char e_complwin[] = N_("E839: Completion function changed window"); static char e_compldel[] = N_("E840: Completion function deleted text"); /* @@ -3939,8 +3938,6 @@ static void expand_by_function(int type, char_u *base) dict_T *matchdict = NULL; char_u *funcname; pos_T pos; - win_T *curwin_save; - buf_T *curbuf_save; typval_T rettv; const int save_State = State; @@ -3959,9 +3956,9 @@ static void expand_by_function(int type, char_u *base) args[1].vval.v_string = base != NULL ? (char *)base : ""; pos = curwin->w_cursor; - curwin_save = curwin; - curbuf_save = curbuf; - // Lock the text to avoid weird things from happening. + // Lock the text to avoid weird things from happening. Also disallow + // switching to another window, it should not be needed and may end up in + // Insert mode in another buffer. textlock++; // Call a function, which returns a list or dict. @@ -3983,10 +3980,6 @@ static void expand_by_function(int type, char_u *base) } textlock--; - if (curwin_save != curwin || curbuf_save != curbuf) { - emsg(_(e_complwin)); - goto theend; - } curwin->w_cursor = pos; // restore the cursor position validate_cursor(); if (!equalpos(curwin->w_cursor, pos)) { @@ -5224,8 +5217,6 @@ static int ins_complete(int c, bool enable_pum) // set to 1 to obtain the length of text to use for completion. char_u *funcname; pos_T pos; - win_T *curwin_save; - buf_T *curbuf_save; const int save_State = State; // Call 'completefunc' or 'omnifunc' and get pattern length as a string @@ -5246,15 +5237,11 @@ static int ins_complete(int c, bool enable_pum) args[1].vval.v_string = ""; pos = curwin->w_cursor; - curwin_save = curwin; - curbuf_save = curbuf; + textlock++; colnr_T col = (colnr_T)call_func_retnr((char *)funcname, 2, args); + textlock--; State = save_State; - if (curwin_save != curwin || curbuf_save != curbuf) { - emsg(_(e_complwin)); - return FAIL; - } curwin->w_cursor = pos; // restore the cursor position validate_cursor(); if (!equalpos(curwin->w_cursor, pos)) { diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index f231146d7c..80586caf8e 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -1062,11 +1062,6 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr) return; } - const int save_textlock = textlock; - // "textlock" is set when evaluating 'completefunc' but we can change text - // here. - textlock = 0; - // Check for undo allowed here, because if something was already inserted // the line was already saved for undo and this check isn't done. if (!undo_allowed(curbuf)) { @@ -1081,7 +1076,6 @@ static void f_complete(typval_T *argvars, typval_T *rettv, FunPtr fptr) set_completion(startcol - 1, argvars[1].vval.v_list); } } - textlock = save_textlock; } /// "complete_add()" function diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 69ff37f23c..a5ba5e0b30 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -26,6 +26,7 @@ local SBOXOK = 0x40000 local CMDWIN = 0x80000 local MODIFY = 0x100000 local FLAGS = 0x200000 +local LOCK_OK = 0x1000000 local PREVIEW = 0x8000000 local FILES = bit.bor(XFILE, EXTRA) local WORD1 = bit.bor(EXTRA, NOSPC) @@ -41,19 +42,19 @@ module.flags = { module.cmds = { { command='append', - flags=bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(BANG, RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_append', }, { command='abbreviate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='abclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abclear', }, @@ -71,13 +72,13 @@ module.cmds = { }, { command='amenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='anoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -131,25 +132,25 @@ module.cmds = { }, { command='ascii', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='do_ascii', }, { command='autocmd', - flags=bit.bor(BANG, EXTRA, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(BANG, EXTRA, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_autocmd', }, { command='augroup', - flags=bit.bor(BANG, WORD1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_autocmd', }, { command='aunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, @@ -173,13 +174,13 @@ module.cmds = { }, { command='badd', - flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN), + flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_edit', }, { command='balt', - flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN), + flags=bit.bor(NEEDARG, FILE1, CMDARG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_edit', }, @@ -191,7 +192,7 @@ module.cmds = { }, { command='behave', - flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_behave', }, @@ -245,37 +246,37 @@ module.cmds = { }, { command='break', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_break', }, { command='breakadd', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_breakadd', }, { command='breakdel', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_breakdel', }, { command='breaklist', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_breaklist', }, { command='browse', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_wrongmodifier', }, { command='buffers', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='buflist_list', }, @@ -299,7 +300,7 @@ module.cmds = { }, { command='change', - flags=bit.bor(BANG, WHOLEFOLD, RANGE, COUNT, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(BANG, WHOLEFOLD, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_change', }, @@ -317,13 +318,13 @@ module.cmds = { }, { command='cabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='cabclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abclear', }, @@ -359,13 +360,13 @@ module.cmds = { }, { command='call', - flags=bit.bor(RANGE, NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_call', }, { command='catch', - flags=bit.bor(EXTRA, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_catch', }, @@ -407,7 +408,7 @@ module.cmds = { }, { command='cd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, @@ -419,7 +420,7 @@ module.cmds = { }, { command='center', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), + flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_align', }, @@ -469,13 +470,13 @@ module.cmds = { }, { command='chdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, { command='changes', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_changes', }, @@ -487,7 +488,7 @@ module.cmds = { }, { command='checkpath', - flags=bit.bor(TRLBAR, BANG, CMDWIN), + flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_checkpath', }, @@ -505,7 +506,7 @@ module.cmds = { }, { command='clist', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='qf_list', }, @@ -517,31 +518,31 @@ module.cmds = { }, { command='close', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_WINDOWS', func='ex_close', }, { command='clearjumps', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_clearjumps', }, { command='cmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='cmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='cmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -565,25 +566,25 @@ module.cmds = { }, { command='cnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='cnoreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='cnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='copy', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_copymove', }, @@ -595,43 +596,43 @@ module.cmds = { }, { command='colorscheme', - flags=bit.bor(WORD1, TRLBAR, CMDWIN), + flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_colorscheme', }, { command='command', - flags=bit.bor(EXTRA, BANG, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, BANG, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_command', }, { command='comclear', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_comclear', }, { command='compiler', - flags=bit.bor(BANG, TRLBAR, WORD1, CMDWIN), + flags=bit.bor(BANG, TRLBAR, WORD1, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_compiler', }, { command='continue', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_continue', }, { command='confirm', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_wrongmodifier', }, { command='const', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_const', }, @@ -679,19 +680,19 @@ module.cmds = { }, { command='cunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='cunabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='cunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, @@ -703,43 +704,43 @@ module.cmds = { }, { command='delete', - flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_operators', }, { command='delmarks', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_delmarks', }, { command='debug', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_debug', }, { command='debuggreedy', - flags=bit.bor(RANGE, ZEROR, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, ZEROR, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_debuggreedy', }, { command='delcommand', - flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_delcommand', }, { command='delfunction', - flags=bit.bor(BANG, NEEDARG, WORD1, CMDWIN), + flags=bit.bor(BANG, NEEDARG, WORD1, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_delfunction', }, { command='display', - flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_display', }, @@ -787,7 +788,7 @@ module.cmds = { }, { command='digraphs', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_digraphs', }, @@ -799,19 +800,19 @@ module.cmds = { }, { command='dlist', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), + flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_findpat', }, { command='doautocmd', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_doautocmd', }, { command='doautoall', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_doautoall', }, @@ -823,7 +824,7 @@ module.cmds = { }, { command='dsearch', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), + flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_findpat', }, @@ -841,85 +842,85 @@ module.cmds = { }, { command='earlier', - flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN), + flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_later', }, { command='echo', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_echo', }, { command='echoerr', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_execute', }, { command='echohl', - flags=bit.bor(EXTRA, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_echohl', }, { command='echomsg', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_execute', }, { command='echon', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_echo', }, { command='else', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_else', }, { command='elseif', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_else', }, { command='emenu', - flags=bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, RANGE, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, TRLBAR, NOTRLCOM, RANGE, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_emenu', }, { command='endif', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_endif', }, { command='endfunction', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_endfunction', }, { command='endfor', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_endwhile', }, { command='endtry', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_endtry', }, { command='endwhile', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_endwhile', }, @@ -931,7 +932,7 @@ module.cmds = { }, { command='eval', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_eval', }, @@ -943,13 +944,13 @@ module.cmds = { }, { command='execute', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_execute', }, { command='exit', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_exit', }, @@ -967,13 +968,13 @@ module.cmds = { }, { command='files', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='buflist_list', }, { command='filetype', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_filetype', }, @@ -991,13 +992,13 @@ module.cmds = { }, { command='finally', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_finally', }, { command='finish', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_finish', }, @@ -1009,13 +1010,13 @@ module.cmds = { }, { command='fold', - flags=bit.bor(RANGE, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_fold', }, { command='foldclose', - flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_foldopen', }, @@ -1033,31 +1034,31 @@ module.cmds = { }, { command='foldopen', - flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, BANG, WHOLEFOLD, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_foldopen', }, { command='for', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_while', }, { command='function', - flags=bit.bor(EXTRA, BANG, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, BANG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_function', }, { command='global', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, DFLALL, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_global', }, { command='goto', - flags=bit.bor(RANGE, COUNT, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, COUNT, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_goto', }, @@ -1075,13 +1076,13 @@ module.cmds = { }, { command='gui', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_nogui', }, { command='gvim', - flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILES, CMDARG, ARGOPT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_nogui', }, @@ -1105,7 +1106,7 @@ module.cmds = { }, { command='helptags', - flags=bit.bor(NEEDARG, FILES, TRLBAR, CMDWIN), + flags=bit.bor(NEEDARG, FILES, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_helptags', }, @@ -1117,7 +1118,7 @@ module.cmds = { }, { command='highlight', - flags=bit.bor(BANG, EXTRA, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_highlight', }, @@ -1129,31 +1130,31 @@ module.cmds = { }, { command='history', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_history', }, { command='insert', - flags=bit.bor(BANG, RANGE, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(BANG, RANGE, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_append', }, { command='iabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='iabclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abclear', }, { command='if', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_if', }, @@ -1165,55 +1166,55 @@ module.cmds = { }, { command='ilist', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), + flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_findpat', }, { command='imap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='imapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='imenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='inoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='inoreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='inoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='intro', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_intro', }, { command='isearch', - flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN), + flags=bit.bor(BANG, RANGE, DFLALL, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_findpat', }, @@ -1225,37 +1226,37 @@ module.cmds = { }, { command='iunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='iunabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='iunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='join', - flags=bit.bor(BANG, RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(BANG, RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_join', }, { command='jumps', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_jumps', }, { command='k', - flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_mark', }, @@ -1285,7 +1286,7 @@ module.cmds = { }, { command='list', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_print', }, @@ -1315,7 +1316,7 @@ module.cmds = { }, { command='language', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_language', }, @@ -1345,7 +1346,7 @@ module.cmds = { }, { command='later', - flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN), + flags=bit.bor(TRLBAR, EXTRA, NOSPC, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_later', }, @@ -1375,13 +1376,13 @@ module.cmds = { }, { command='lcd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, { command='lchdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, @@ -1405,7 +1406,7 @@ module.cmds = { }, { command='left', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), + flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_align', }, @@ -1417,7 +1418,7 @@ module.cmds = { }, { command='let', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_let', }, @@ -1503,19 +1504,19 @@ module.cmds = { }, { command='llist', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='qf_list', }, { command='lmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='lmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, @@ -1527,7 +1528,7 @@ module.cmds = { }, { command='lnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, @@ -1557,7 +1558,7 @@ module.cmds = { }, { command='loadkeymap', - flags=bit.bor(CMDWIN), + flags=bit.bor(CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_loadkeymap', }, @@ -1569,7 +1570,7 @@ module.cmds = { }, { command='lockvar', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), + flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_lockvar', }, @@ -1611,37 +1612,37 @@ module.cmds = { }, { command='lunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='lua', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_lua', }, { command='luado', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_luado', }, { command='luafile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_luafile', }, { command='lvimgrep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), addr_type='ADDR_OTHER', func='ex_vimgrep', }, { command='lvimgrepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), addr_type='ADDR_OTHER', func='ex_vimgrep', }, @@ -1653,19 +1654,19 @@ module.cmds = { }, { command='ls', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='buflist_list', }, { command='move', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_copymove', }, { command='mark', - flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, WORD1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_mark', }, @@ -1677,49 +1678,49 @@ module.cmds = { }, { command='map', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='mapclear', - flags=bit.bor(EXTRA, BANG, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='marks', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_marks', }, { command='match', - flags=bit.bor(RANGE, EXTRA, CMDWIN), + flags=bit.bor(RANGE, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_match', }, { command='menu', - flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='menutranslate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menutranslate', }, { command='messages', - flags=bit.bor(EXTRA, TRLBAR, RANGE, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, RANGE, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_messages', }, { command='mkexrc', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mkrc', }, @@ -1737,7 +1738,7 @@ module.cmds = { }, { command='mkvimrc', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mkrc', }, @@ -1749,19 +1750,19 @@ module.cmds = { }, { command='mode', - flags=bit.bor(WORD1, TRLBAR, CMDWIN), + flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mode', }, { command='mzscheme', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, SBOXOK), + flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK, SBOXOK), addr_type='ADDR_LINES', func='ex_script_ni', }, { command='mzfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_ni', }, @@ -1779,37 +1780,37 @@ module.cmds = { }, { command='nmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='nmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='nmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='nnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='nnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='noremap', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, @@ -1821,19 +1822,19 @@ module.cmds = { }, { command='nohlsearch', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_nohlsearch', }, { command='noreabbrev', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, { command='noremenu', - flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -1845,49 +1846,49 @@ module.cmds = { }, { command='normal', - flags=bit.bor(RANGE, BANG, EXTRA, NEEDARG, NOTRLCOM, CTRLV, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, BANG, EXTRA, NEEDARG, NOTRLCOM, CTRLV, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_normal', }, { command='number', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_print', }, { command='nunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='nunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='oldfiles', - flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_oldfiles', }, { command='omap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='omapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='omenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -1899,13 +1900,13 @@ module.cmds = { }, { command='onoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='onoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -1917,37 +1918,37 @@ module.cmds = { }, { command='ounmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='ounmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='ownsyntax', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_ownsyntax', }, { command='print', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, SBOXOK), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, SBOXOK), addr_type='ADDR_LINES', func='ex_print', }, { command='packadd', - flags=bit.bor(BANG, FILE1, NEEDARG, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, FILE1, NEEDARG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_packadd', }, { command='packloadall', - flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_packloadall', }, @@ -1959,19 +1960,19 @@ module.cmds = { }, { command='perl', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_perl', }, { command='perldo', - flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, DFLALL, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_perldo', }, { command='perlfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_perlfile', }, @@ -1989,7 +1990,7 @@ module.cmds = { }, { command='popup', - flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, BANG, TRLBAR, NOTRLCOM, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_popup', }, @@ -2013,13 +2014,13 @@ module.cmds = { }, { command='profile', - flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_profile', }, { command='profdel', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_breakdel', }, @@ -2085,85 +2086,85 @@ module.cmds = { }, { command='put', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, REGSTR, TRLBAR, ZEROR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, REGSTR, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_put', }, { command='pwd', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_pwd', }, { command='python', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_python3', }, { command='pydo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_pydo3', }, { command='pyfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_py3file', }, { command='py3', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_python3', }, { command='py3do', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_pydo3', }, { command='python3', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_python3', }, { command='py3file', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_py3file', }, { command='pyx', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_python3', }, { command='pyxdo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_pydo3', }, { command='pythonx', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_python3', }, { command='pyxfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_py3file', }, { command='quit', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_WINDOWS', func='ex_quit', }, @@ -2175,13 +2176,13 @@ module.cmds = { }, { command='qall', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_quit_all', }, { command='read', - flags=bit.bor(BANG, RANGE, WHOLEFOLD, FILE1, ARGOPT, TRLBAR, ZEROR, CMDWIN, MODIFY), + flags=bit.bor(BANG, RANGE, WHOLEFOLD, FILE1, ARGOPT, TRLBAR, ZEROR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_read', }, @@ -2193,55 +2194,55 @@ module.cmds = { }, { command='redo', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_redo', }, { command='redir', - flags=bit.bor(BANG, FILES, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILES, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_redir', }, { command='redraw', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_redraw', }, { command='redrawstatus', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_redrawstatus', }, { command='redrawtabline', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_redrawtabline', }, { command='registers', - flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_display', }, { command='resize', - flags=bit.bor(RANGE, TRLBAR, WORD1, CMDWIN), + flags=bit.bor(RANGE, TRLBAR, WORD1, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_resize', }, { command='retab', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, DFLALL, BANG, WORD1, CMDWIN, MODIFY), + flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, DFLALL, BANG, WORD1, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_retab', }, { command='return', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_return', }, @@ -2253,7 +2254,7 @@ module.cmds = { }, { command='right', - flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), + flags=bit.bor(TRLBAR, RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_align', }, @@ -2265,13 +2266,13 @@ module.cmds = { }, { command='rshada', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_shada', }, { command='runtime', - flags=bit.bor(BANG, NEEDARG, FILES, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, NEEDARG, FILES, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_runtime', }, @@ -2283,31 +2284,31 @@ module.cmds = { }, { command='ruby', - flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_ruby', }, { command='rubydo', - flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_rubydo', }, { command='rubyfile', - flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_rubyfile', }, { command='rviminfo', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_shada', }, { command='substitute', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, PREVIEW), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), addr_type='ADDR_LINES', func='ex_substitute', preview_func='ex_substitute_preview', @@ -2338,7 +2339,7 @@ module.cmds = { }, { command='saveas', - flags=bit.bor(BANG, FILE1, ARGOPT, CMDWIN, TRLBAR), + flags=bit.bor(BANG, FILE1, ARGOPT, CMDWIN, LOCK_OK, TRLBAR), addr_type='ADDR_NONE', func='ex_write', }, @@ -2398,13 +2399,13 @@ module.cmds = { }, { command='scriptnames', - flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, COUNT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_scriptnames', }, { command='scriptencoding', - flags=bit.bor(WORD1, TRLBAR, CMDWIN), + flags=bit.bor(WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_scriptencoding', }, @@ -2416,25 +2417,25 @@ module.cmds = { }, { command='set', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, SBOXOK), + flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), addr_type='ADDR_NONE', func='ex_set', }, { command='setfiletype', - flags=bit.bor(TRLBAR, EXTRA, NEEDARG, CMDWIN), + flags=bit.bor(TRLBAR, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_setfiletype', }, { command='setglobal', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, SBOXOK), + flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), addr_type='ADDR_NONE', func='ex_set', }, { command='setlocal', - flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, SBOXOK), + flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK), addr_type='ADDR_NONE', func='ex_set', }, @@ -2452,25 +2453,25 @@ module.cmds = { }, { command='simalt', - flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), + flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_ni', }, { command='sign', - flags=bit.bor(NEEDARG, RANGE, EXTRA, CMDWIN), + flags=bit.bor(NEEDARG, RANGE, EXTRA, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_sign', }, { command='silent', - flags=bit.bor(NEEDARG, EXTRA, BANG, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, BANG, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_wrongmodifier', }, { command='sleep', - flags=bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, COUNT, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_sleep', }, @@ -2482,26 +2483,26 @@ module.cmds = { }, { command='smagic', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, PREVIEW), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), addr_type='ADDR_LINES', func='ex_submagic', preview_func='ex_submagic_preview', }, { command='smap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='smapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='smenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -2513,26 +2514,26 @@ module.cmds = { }, { command='snomagic', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, PREVIEW), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, PREVIEW), addr_type='ADDR_LINES', func='ex_submagic', preview_func='ex_submagic_preview', }, { command='snoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='snoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='source', - flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(RANGE, DFLALL, WHOLEFOLD, BANG, FILE1, TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_source', }, @@ -2604,7 +2605,7 @@ module.cmds = { }, { command='stop', - flags=bit.bor(TRLBAR, BANG, CMDWIN), + flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_stop', }, @@ -2616,25 +2617,25 @@ module.cmds = { }, { command='startinsert', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_startinsert', }, { command='startgreplace', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_startinsert', }, { command='startreplace', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_startinsert', }, { command='stopinsert', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_stopinsert', }, @@ -2658,19 +2659,19 @@ module.cmds = { }, { command='sunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='sunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='suspend', - flags=bit.bor(TRLBAR, BANG, CMDWIN), + flags=bit.bor(TRLBAR, BANG, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_stop', }, @@ -2682,19 +2683,19 @@ module.cmds = { }, { command='swapname', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_swapname', }, { command='syntax', - flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_syntax', }, { command='syntime', - flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN), + flags=bit.bor(NEEDARG, WORD1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_syntime', }, @@ -2706,19 +2707,19 @@ module.cmds = { }, { command='t', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_copymove', }, { command='tcd', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, { command='tchdir', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_cd', }, @@ -2736,7 +2737,7 @@ module.cmds = { }, { command='tags', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='do_tags', }, @@ -2748,7 +2749,7 @@ module.cmds = { }, { command='tabclose', - flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_TABS', func='ex_tabclose', }, @@ -2802,7 +2803,7 @@ module.cmds = { }, { command='tabonly', - flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, ZEROR, EXTRA, NOSPC, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_TABS', func='ex_tabonly', }, @@ -2826,31 +2827,31 @@ module.cmds = { }, { command='tabs', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_tabs', }, { command='tcl', - flags=bit.bor(RANGE,EXTRA,NEEDARG,CMDWIN), + flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_script_ni', }, { command='tcldo', - flags=bit.bor(RANGE,DFLALL,EXTRA,NEEDARG,CMDWIN), + flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_ni', }, { command='tclfile', - flags=bit.bor(RANGE,FILE1,NEEDARG,CMDWIN), + flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_ni', }, { command='terminal', - flags=bit.bor(BANG, FILES, CMDWIN), + flags=bit.bor(BANG, FILES, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_terminal', }, @@ -2862,7 +2863,7 @@ module.cmds = { }, { command='throw', - flags=bit.bor(EXTRA, NEEDARG, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_throw', }, @@ -2880,37 +2881,37 @@ module.cmds = { }, { command='tlmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='tlnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='tlunmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='tmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='tmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='tmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, @@ -2922,7 +2923,7 @@ module.cmds = { }, { command='tnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, @@ -2946,7 +2947,7 @@ module.cmds = { }, { command='try', - flags=bit.bor(TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(TRLBAR, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_try', }, @@ -2958,37 +2959,37 @@ module.cmds = { }, { command='tunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='tunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='undo', - flags=bit.bor(BANG, RANGE, COUNT, ZEROR, TRLBAR, CMDWIN), + flags=bit.bor(BANG, RANGE, COUNT, ZEROR, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_undo', }, { command='undojoin', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_undojoin', }, { command='undolist', - flags=bit.bor(TRLBAR, CMDWIN), + flags=bit.bor(TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_undolist', }, { command='unabbreviate', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_abbreviate', }, @@ -3000,31 +3001,31 @@ module.cmds = { }, { command='unlet', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), + flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unlet', }, { command='unlockvar', - flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN), + flags=bit.bor(BANG, EXTRA, NEEDARG, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_lockvar', }, { command='unmap', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='unmenu', - flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(BANG, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='unsilent', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_wrongmodifier', }, @@ -3036,19 +3037,19 @@ module.cmds = { }, { command='vglobal', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, DFLALL, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, DFLALL, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_global', }, { command='version', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_version', }, { command='verbose', - flags=bit.bor(NEEDARG, RANGE, EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(NEEDARG, RANGE, EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_wrongmodifier', }, @@ -3072,13 +3073,13 @@ module.cmds = { }, { command='vimgrep', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), addr_type='ADDR_OTHER', func='ex_vimgrep', }, { command='vimgrepadd', - flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE), + flags=bit.bor(RANGE, BANG, NEEDARG, EXTRA, NOTRLCOM, TRLBAR, XFILE, LOCK_OK), addr_type='ADDR_OTHER', func='ex_vimgrep', }, @@ -3090,25 +3091,25 @@ module.cmds = { }, { command='vmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='vmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='vmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='vnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, @@ -3120,7 +3121,7 @@ module.cmds = { }, { command='vnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, @@ -3132,19 +3133,19 @@ module.cmds = { }, { command='vunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='vunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='write', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_write', }, @@ -3156,13 +3157,13 @@ module.cmds = { }, { command='wall', - flags=bit.bor(BANG, TRLBAR, CMDWIN), + flags=bit.bor(BANG, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='do_wqall', }, { command='while', - flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN), + flags=bit.bor(EXTRA, NOTRLCOM, SBOXOK, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_while', }, @@ -3174,7 +3175,7 @@ module.cmds = { }, { command='wincmd', - flags=bit.bor(NEEDARG, WORD1, RANGE, CMDWIN), + flags=bit.bor(NEEDARG, WORD1, RANGE, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_wincmd', }, @@ -3186,7 +3187,7 @@ module.cmds = { }, { command='winpos', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_ni', }, @@ -3216,7 +3217,7 @@ module.cmds = { }, { command='wshada', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_shada', }, @@ -3228,13 +3229,13 @@ module.cmds = { }, { command='wviminfo', - flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN), + flags=bit.bor(BANG, FILE1, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_shada', }, { command='xit', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILE1, ARGOPT, DFLALL, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_exit', }, @@ -3246,120 +3247,122 @@ module.cmds = { }, { command='xmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='xmapclear', - flags=bit.bor(EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_mapclear', }, { command='xmenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='xnoremap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_map', }, { command='xnoremenu', - flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(RANGE, ZEROR, EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_OTHER', func='ex_menu', }, { command='xunmap', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_unmap', }, { command='xunmenu', - flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN), + flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK), addr_type='ADDR_NONE', func='ex_menu', }, { command='yank', - flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, REGSTR, COUNT, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_operators', }, { command='z', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, FLAGS, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, EXTRA, FLAGS, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_z', }, + -- commands that don't start with a letter { command='!', enum='CMD_bang', - flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILES, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, BANG, FILES, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_bang', }, { command='#', enum='CMD_pound', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_print', }, { command='&', enum='CMD_and', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_substitute', }, { command='<', enum='CMD_lshift', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_operators', }, { command='=', enum='CMD_equal', - flags=bit.bor(RANGE, TRLBAR, DFLALL, FLAGS, CMDWIN), + flags=bit.bor(RANGE, TRLBAR, DFLALL, FLAGS, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_equal', }, { command='>', enum='CMD_rshift', - flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, COUNT, FLAGS, TRLBAR, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_operators', }, { command='@', enum='CMD_at', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, TRLBAR, CMDWIN, LOCK_OK), addr_type='ADDR_LINES', func='ex_at', }, { - command='Next', - flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), - addr_type='ADDR_OTHER', - func='ex_previous', - }, - { command='~', enum='CMD_tilde', - flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, MODIFY), + flags=bit.bor(RANGE, WHOLEFOLD, EXTRA, CMDWIN, LOCK_OK, MODIFY), addr_type='ADDR_LINES', func='ex_substitute', }, + -- commands that start with an uppercase letter + { + command='Next', + flags=bit.bor(EXTRA, RANGE, COUNT, BANG, CMDARG, ARGOPT, TRLBAR), + addr_type='ADDR_OTHER', + func='ex_previous', + }, } return module diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 6798f7693b..052926fa1f 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -57,11 +57,12 @@ #define EX_BUFUNL 0x10000 // accepts unlisted buffer too #define EX_ARGOPT 0x20000 // allow "++opt=val" argument #define EX_SBOXOK 0x40000 // allowed in the sandbox -#define EX_CMDWIN 0x80000 // allowed in cmdline window; when missing - // disallows editing another buffer when - // current buffer is locked +#define EX_CMDWIN 0x80000 // allowed in cmdline window #define EX_MODIFY 0x100000 // forbidden in non-'modifiable' buffer #define EX_FLAGS 0x200000 // allow flags after count in argument +#define EX_LOCK_OK 0x1000000 // command can be executed when textlock is + // set; when missing disallows editing another + // buffer when current buffer is locked #define EX_KEEPSCRIPT 0x4000000 // keep sctx of where command was invoked #define EX_PREVIEW 0x8000000 // allow incremental command preview #define EX_FILES (EX_XFILE | EX_EXTRA) // multiple extra files allowed diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 4e6846bf21..c4d2821e79 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1444,10 +1444,13 @@ bool parse_cmdline(char *cmdline, exarg_T *eap, CmdParseInfo *cmdinfo, char **er eap->getline = NULL; eap->cookie = NULL; + const bool save_ex_pressedreturn = ex_pressedreturn; // Parse command modifiers if (parse_command_modifiers(eap, errormsg, &cmdinfo->cmdmod, false) == FAIL) { + ex_pressedreturn = save_ex_pressedreturn; goto err; } + ex_pressedreturn = save_ex_pressedreturn; after_modifier = eap->cmd; // Save location after command modifiers @@ -1587,9 +1590,15 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) && !(curbuf->terminal && eap->cmdidx == CMD_put)) { ERROR(_(e_modifiable)); } - if (text_locked() && !(eap->argt & EX_CMDWIN) - && !IS_USER_CMDIDX(eap->cmdidx)) { - ERROR(_(get_text_locked_msg())); + if (!IS_USER_CMDIDX(eap->cmdidx)) { + if (cmdwin_type != 0 && !(eap->argt & EX_CMDWIN)) { + // Command not allowed in the command line window + ERROR(_(e_cmdwin)); + } + if (text_locked() && !(eap->argt & EX_LOCK_OK)) { + // Command not allowed when text is locked + ERROR(_(get_text_locked_msg())); + } } // Disallow editing another buffer when "curbuf->b_ro_locked" is set. // Do allow ":checktime" (it is postponed). @@ -1964,11 +1973,17 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter goto doend; } - if (text_locked() && !(ea.argt & EX_CMDWIN) - && !IS_USER_CMDIDX(ea.cmdidx)) { - // Command not allowed when editing the command line. - errormsg = _(get_text_locked_msg()); - goto doend; + if (!IS_USER_CMDIDX(ea.cmdidx)) { + if (cmdwin_type != 0 && !(ea.argt & EX_CMDWIN)) { + // Command not allowed in the command line window + errormsg = _(e_cmdwin); + goto doend; + } + if (text_locked() && !(ea.argt & EX_LOCK_OK)) { + // Command not allowed when text is locked + errormsg = _(get_text_locked_msg()); + goto doend; + } } // Disallow editing another buffer when "curbuf->b_ro_locked" is set. @@ -2407,7 +2422,8 @@ char *ex_errmsg(const char *const msg, const char *const arg) /// - Set ex_pressedreturn for an empty command line. /// /// @param skip_only if false, undo_cmdmod() must be called later to free -/// any cmod_filter_pat and cmod_filter_regmatch.regprog. +/// any cmod_filter_pat and cmod_filter_regmatch.regprog, +/// and ex_pressedreturn may be set. /// @param[out] errormsg potential error message. /// /// Call apply_cmdmod() to get the side effects of the modifiers: @@ -2421,7 +2437,7 @@ int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod, bool { char *p; - memset(cmod, 0, sizeof(*cmod)); + CLEAR_POINTER(cmod); // Repeat until no more command modifiers are found. for (;;) { @@ -3028,6 +3044,8 @@ char *find_ex_command(exarg_T *eap, int *full) if (ASCII_ISLOWER(c2)) { eap->cmdidx += cmdidxs2[CHAR_ORD_LOW(c1)][CHAR_ORD_LOW(c2)]; } + } else if (ASCII_ISUPPER(eap->cmd[0])) { + eap->cmdidx = CMD_Next; } else { eap->cmdidx = CMD_bang; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 92c9d83045..4c26cfe500 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -2696,14 +2696,12 @@ char_u *get_cmdprompt(void) return ccline.cmdprompt; } -/* - * Return TRUE when the text must not be changed and we can't switch to - * another window or buffer. Used when editing the command line etc. - */ -int text_locked(void) +/// Return true when the text must not be changed and we can't switch to +/// another window or buffer. True when editing the command line etc. +bool text_locked(void) { if (cmdwin_type != 0) { - return TRUE; + return true; } return textlock != 0; } diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 2ea108d3df..a4a521fa80 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -128,8 +128,10 @@ bool is_mouse_key(int c) /// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE int jump_to_mouse(int flags, bool *inclusive, int which_button) { - static int on_status_line = 0; // #lines below bottom of window - static int on_sep_line = 0; // on separator right of window + static int status_line_offset = 0; // #lines offset from status line + static int sep_line_offset = 0; // #cols offset from sep line + static bool on_status_line = false; + static bool on_sep_line = false; static bool on_winbar = false; static int prev_row = -1; static int prev_col = -1; @@ -144,6 +146,7 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) int col = mouse_col; int grid = mouse_grid; int fdc = 0; + bool keep_focus = flags & MOUSE_FOCUS; mouse_past_bottom = false; mouse_past_eol = false; @@ -164,10 +167,10 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) retnomove: // before moving the cursor for a left click which is NOT in a status // line, stop Visual mode - if (on_status_line) { + if (status_line_offset) { return IN_STATUS_LINE; } - if (on_sep_line) { + if (sep_line_offset) { return IN_SEP_LINE; } if (on_winbar) { @@ -189,49 +192,78 @@ retnomove: old_curwin = curwin; old_cursor = curwin->w_cursor; - if (!(flags & MOUSE_FOCUS)) { - if (row < 0 || col < 0) { // check if it makes sense - return IN_UNKNOWN; + if (row < 0 || col < 0) { // check if it makes sense + return IN_UNKNOWN; + } + + // find the window where the row is in + wp = mouse_find_win(&grid, &row, &col); + if (wp == NULL) { + return IN_UNKNOWN; + } + + on_status_line = (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) + ? row + wp->w_winbar_height - wp->w_height + 1 == 1 + : false; + + on_winbar = (row == -1) + ? wp->w_winbar_height != 0 + : false; + + on_sep_line = grid == DEFAULT_GRID_HANDLE && col >= wp->w_width + ? col - wp->w_width + 1 == 1 + : false; + + // The rightmost character of the status line might be a vertical + // separator character if there is no connecting window to the right. + if (on_status_line && on_sep_line) { + if (stl_connected(wp)) { + on_sep_line = false; + } else { + on_status_line = false; } + } - // find the window where the row is in - wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { - return IN_UNKNOWN; + if (keep_focus) { + // If we can't change focus, set the value of row, col and grid back to absolute values + // since the values relative to the window are only used when keep_focus is false + row = mouse_row; + col = mouse_col; + grid = mouse_grid; + } + + if (!keep_focus) { + if (on_winbar) { + return IN_OTHER_WIN | MOUSE_WINBAR; } + fdc = win_fdccol_count(wp); dragwin = NULL; - if (row == -1) { - on_winbar = wp->w_winbar_height != 0; - return IN_OTHER_WIN | (on_winbar ? MOUSE_WINBAR : 0); - } - on_winbar = false; - // winpos and height may change in win_enter()! if (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) { // In (or below) status line - on_status_line = row + wp->w_winbar_height - wp->w_height + 1; + status_line_offset = row + wp->w_winbar_height - wp->w_height + 1; dragwin = wp; } else { - on_status_line = 0; + status_line_offset = 0; } if (grid == DEFAULT_GRID_HANDLE && col >= wp->w_width) { // In separator line - on_sep_line = col - wp->w_width + 1; + sep_line_offset = col - wp->w_width + 1; dragwin = wp; } else { - on_sep_line = 0; + sep_line_offset = 0; } // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. - if (on_status_line && on_sep_line) { + if (status_line_offset && sep_line_offset) { if (stl_connected(wp)) { - on_sep_line = 0; + sep_line_offset = 0; } else { - on_status_line = 0; + status_line_offset = 0; } } @@ -239,8 +271,8 @@ retnomove: // click, stop Visual mode. if (VIsual_active && (wp->w_buffer != curwin->w_buffer - || (!on_status_line - && !on_sep_line + || (!status_line_offset + && !sep_line_offset && (wp->w_p_rl ? col < wp->w_width_inner - fdc : col >= fdc + (cmdwin_type == 0 && wp == curwin ? 0 : 1)) @@ -251,7 +283,7 @@ retnomove: if (cmdwin_type != 0 && wp != curwin) { // A click outside the command-line window: Use modeless // selection if possible. Allow dragging the status lines. - on_sep_line = 0; + sep_line_offset = 0; row = 0; col += wp->w_wincol; wp = curwin; @@ -266,7 +298,7 @@ retnomove: if (curwin != old_curwin) { set_mouse_topline(curwin); } - if (on_status_line) { // In (or below) status line + if (status_line_offset) { // In (or below) status line // Don't use start_arrow() if we're in the same window if (curwin == old_curwin) { return IN_STATUS_LINE; @@ -274,7 +306,7 @@ retnomove: return IN_STATUS_LINE | CURSOR_MOVED; } } - if (on_sep_line) { // In (or below) status line + if (sep_line_offset) { // In (or below) status line // Don't use start_arrow() if we're in the same window if (curwin == old_curwin) { return IN_SEP_LINE; @@ -284,25 +316,27 @@ retnomove: } curwin->w_cursor.lnum = curwin->w_topline; - } else if (on_status_line) { + } else if (status_line_offset) { if (which_button == MOUSE_LEFT && dragwin != NULL) { // Drag the status line count = row - dragwin->w_winrow - dragwin->w_height + 1 - - on_status_line; + - status_line_offset; win_drag_status_line(dragwin, count); did_drag |= count; } return IN_STATUS_LINE; // Cursor didn't move - } else if (on_sep_line && which_button == MOUSE_LEFT) { + } else if (sep_line_offset && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the separator column count = col - dragwin->w_wincol - dragwin->w_width + 1 - - on_sep_line; + - sep_line_offset; win_drag_vsep_line(dragwin, count); did_drag |= count; } return IN_SEP_LINE; // Cursor didn't move - } else if (on_winbar) { + } else if (on_status_line && which_button == MOUSE_RIGHT) { + return IN_STATUS_LINE; + } else if (on_winbar && which_button == MOUSE_RIGHT) { // After a click on the window bar don't start Visual mode. return IN_OTHER_WIN | MOUSE_WINBAR; } else { diff --git a/src/nvim/option.c b/src/nvim/option.c index a3bd960fa5..821c7208e3 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -4343,7 +4343,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va if (options[opt_idx].flags & P_UI_OPTION) { ui_call_option_set(cstr_as_string(options[opt_idx].fullname), - BOOLEAN_OBJ(value)); + BOOLEAN_OBJ(*varp)); } comp_col(); // in case 'ruler' or 'showcmd' changed @@ -4784,7 +4784,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf, if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) { ui_call_option_set(cstr_as_string(options[opt_idx].fullname), - INTEGER_OBJ(value)); + INTEGER_OBJ(*pp)); } comp_col(); // in case 'columns' or 'ls' changed diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c index 90c0b6f5c6..841277f8f3 100644 --- a/src/nvim/popupmnu.c +++ b/src/nvim/popupmnu.c @@ -976,7 +976,7 @@ static void pum_select_mouse_pos(void) if (mouse_grid == pum_grid.handle) { pum_selected = mouse_row; return; - } else if (mouse_grid > 1) { + } else if (mouse_grid != pum_anchor_grid) { pum_selected = -1; return; } diff --git a/src/nvim/testdir/check.vim b/src/nvim/testdir/check.vim index 8f97d959ce..4107df99d6 100644 --- a/src/nvim/testdir/check.vim +++ b/src/nvim/testdir/check.vim @@ -55,6 +55,14 @@ func CheckMSWindows() endif endfunc +" Command to check for NOT running on MS-Windows +command CheckNotMSWindows call CheckNotMSWindows() +func CheckNotMSWindows() + if has('win32') + throw 'Skipped: does not work on MS-Windows' + endif +endfunc + " Command to check for running on Unix command CheckUnix call CheckUnix() func CheckUnix() @@ -129,14 +137,6 @@ func CheckEnglish() endif endfunc -" Command to check for NOT running on MS-Windows -command CheckNotMSWindows call CheckNotMSWindows() -func CheckNotMSWindows() - if has('win32') - throw 'Skipped: does not work on MS-Windows' - endif -endfunc - " Command to check for not running under ASAN command CheckNotAsan call CheckNotAsan() func CheckNotAsan() diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim index 683bcabe34..d386d74f8d 100644 --- a/src/nvim/testdir/test_charsearch.vim +++ b/src/nvim/testdir/test_charsearch.vim @@ -29,6 +29,17 @@ func Test_charsearch() set cpo-=; normal! ;;p call assert_equal('ZabcdeZfghijkZZemnokqretkZvwxyz', getline(3)) + + " check that repeating a search before and after a line fails + normal 3Gfv + call assert_beeps('normal ;') + call assert_beeps('normal ,') + + " clear the character search + call setcharsearch({'char' : ''}) + call assert_equal('', getcharsearch().char) + + call assert_fails("call setcharsearch([])", 'E715:') enew! endfunc @@ -73,4 +84,18 @@ func Test_csearch_virtualedit() close! endfunc +" Test for character search failure in latin1 encoding +func Test_charsearch_latin1() + new + let save_enc = &encoding + " set encoding=latin1 + call setline(1, 'abcdefghijk') + call assert_beeps('normal fz') + call assert_beeps('normal tx') + call assert_beeps('normal $Fz') + call assert_beeps('normal $Tx') + let &encoding = save_enc + close! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim index 6c6a6290cb..3b8a5f27ad 100644 --- a/src/nvim/testdir/test_cursor_func.vim +++ b/src/nvim/testdir/test_cursor_func.vim @@ -99,6 +99,7 @@ func Test_screenpos() \ 'curscol': wincol + 9, \ 'endcol': wincol + 9}, screenpos(winid, 2, 22)) close + call assert_equal({}, screenpos(999, 1, 1)) bwipe! call assert_equal({'col': 1, 'row': 1, 'endcol': 1, 'curscol': 1}, screenpos(win_getid(), 1, 1)) diff --git a/src/nvim/testdir/test_edit.vim b/src/nvim/testdir/test_edit.vim index 65194f49dd..42c77518e4 100644 --- a/src/nvim/testdir/test_edit.vim +++ b/src/nvim/testdir/test_edit.vim @@ -349,8 +349,8 @@ func Test_edit_11_indentexpr() bw! endfunc +" Test changing indent in replace mode func Test_edit_12() - " Test changing indent in replace mode new call setline(1, ["\tabc", "\tdef"]) call cursor(2, 4) @@ -389,15 +389,15 @@ func Test_edit_12() call feedkeys("R\<c-t>\<c-t>", 'tnix') call assert_equal(["\tabc", "\t\t\tdef"], getline(1, '$')) call assert_equal([0, 2, 2, 0], getpos('.')) - set et - set sw& et& + set sw& + + " In replace mode, after hitting enter in a line with tab characters, + " pressing backspace should restore the tab characters. %d - call setline(1, ["\t/*"]) - set formatoptions=croql - call cursor(1, 3) - call feedkeys("A\<cr>\<cr>/", 'tnix') - call assert_equal(["\t/*", " *", " */"], getline(1, '$')) - set formatoptions& + setlocal autoindent backspace=2 + call setline(1, "\tone\t\ttwo") + exe "normal ggRred\<CR>six" .. repeat("\<BS>", 8) + call assert_equal(["\tone\t\ttwo"], getline(1, '$')) bw! endfunc @@ -420,16 +420,49 @@ func Test_edit_13() call assert_equal("", getline(2)) call assert_equal(" baz", getline(3)) set autoindent& + + " pressing <C-U> to erase line should keep the indent with 'autoindent' + set backspace=2 autoindent + %d + exe "normal i\tone\<CR>three\<C-U>two" + call assert_equal(["\tone", "\ttwo"], getline(1, '$')) + set backspace& autoindent& + bwipe! endfunc +" Test for autoindent removing indent when insert mode is stopped. Some parts +" of the code is exercised only when interactive mode is used. So use Vim in a +" terminal. +func Test_autoindent_remove_indent() + CheckRunVimInTerminal + let buf = RunVimInTerminal('-N Xfile', {'rows': 6, 'cols' : 20}) + call TermWait(buf) + call term_sendkeys(buf, ":set autoindent\n") + " leaving insert mode in a new line with indent added by autoindent, should + " remove the indent. + call term_sendkeys(buf, "i\<Tab>foo\<CR>\<Esc>") + " Need to delay for sometime, otherwise the code in getchar.c will not be + " exercised. + call TermWait(buf, 50) + " when a line is wrapped and the cursor is at the start of the second line, + " leaving insert mode, should move the cursor back to the first line. + call term_sendkeys(buf, "o" .. repeat('x', 20) .. "\<Esc>") + " Need to delay for sometime, otherwise the code in getchar.c will not be + " exercised. + call TermWait(buf, 50) + call term_sendkeys(buf, ":w\n") + call TermWait(buf) + call StopVimInTerminal(buf) + call assert_equal(["\tfoo", '', repeat('x', 20)], readfile('Xfile')) + call delete('Xfile') +endfunc + func Test_edit_CR() " Test for <CR> in insert mode " basically only in quickfix mode ist tested, the rest " has been taken care of by other tests - if !has("quickfix") - return - endif + CheckFeature quickfix botright new call writefile(range(1, 10), 'Xqflist.txt') call setqflist([{'filename': 'Xqflist.txt', 'lnum': 2}]) diff --git a/src/nvim/testdir/test_ex_mode.vim b/src/nvim/testdir/test_ex_mode.vim index b478332c79..122572f32a 100644 --- a/src/nvim/testdir/test_ex_mode.vim +++ b/src/nvim/testdir/test_ex_mode.vim @@ -191,6 +191,9 @@ func Test_ex_mode_errors() endfunc func Test_ex_mode_count_overflow() + " The multiplication causes an integer overflow + CheckNotAsan + " this used to cause a crash let lines =<< trim END call feedkeys("\<Esc>gQ\<CR>") diff --git a/src/nvim/testdir/test_excmd.vim b/src/nvim/testdir/test_excmd.vim index 6858efeaa9..7d581d5efd 100644 --- a/src/nvim/testdir/test_excmd.vim +++ b/src/nvim/testdir/test_excmd.vim @@ -509,6 +509,11 @@ func Test_run_excmd_with_text_locked() close call assert_fails("call feedkeys(\":\<C-R>=execute('bnext')\<CR>\", 'xt')", 'E565:') + + " :tabfirst + tabnew + call assert_fails("call feedkeys(\":\<C-R>=execute('tabfirst')\<CR>\", 'xt')", 'E565:') + tabclose endfunc " Test for the :verbose command diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 3feb4d5f7f..9b8d740efb 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -185,7 +185,9 @@ func Test_str2nr() call assert_fails('call str2nr([])', 'E730:') call assert_fails('call str2nr({->2})', 'E729:') - call assert_fails('call str2nr(1.2)', 'E806:') + if has('float') + call assert_fails('call str2nr(1.2)', 'E806:') + endif call assert_fails('call str2nr(10, [])', 'E474:') endfunc @@ -325,11 +327,18 @@ func Test_simplify() call assert_equal('./file', simplify('./dir/../file')) call assert_equal('../dir/file', simplify('dir/../../dir/file')) call assert_equal('./file', simplify('dir/.././file')) + call assert_equal('../dir', simplify('./../dir')) + call assert_equal('..', simplify('../testdir/..')) + call mkdir('Xdir') + call assert_equal('.', simplify('Xdir/../.')) + call delete('Xdir', 'd') call assert_fails('call simplify({->0})', 'E729:') call assert_fails('call simplify([])', 'E730:') call assert_fails('call simplify({})', 'E731:') - call assert_fails('call simplify(1.2)', 'E806:') + if has('float') + call assert_fails('call simplify(1.2)', 'E806:') + endif endfunc func Test_pathshorten() diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim index 403fc24391..1569177d66 100644 --- a/src/nvim/testdir/test_gf.vim +++ b/src/nvim/testdir/test_gf.vim @@ -35,6 +35,13 @@ func Test_gf_url() call search("URL") call assert_equal("URL://machine.name:1234?q=vim", expand("<cfile>")) + %d + call setline(1, "demo://remote_file") + wincmd f + call assert_equal('demo://remote_file', @%) + call assert_equal(2, winnr('$')) + close! + set isf&vim enew! endfunc @@ -63,11 +70,18 @@ func Test_gF() call assert_equal('Xfile', bufname('%')) call assert_equal(2, getcurpos()[1]) + " jumping to the file/line with CTRL-W_F + %bw! + edit Xfile1 + call setline(1, ['one', 'Xfile:4', 'three']) + exe "normal 2G\<C-W>F" + call assert_equal('Xfile', bufname('%')) + call assert_equal(4, getcurpos()[1]) + set isfname& call delete('Xfile') call delete('Xfile2') - bwipe Xfile - bwipe Xfile2 + %bw! endfunc " Test for invoking 'gf' on a ${VAR} variable @@ -163,4 +177,21 @@ func Test_gf_error() bwipe! endfunc +" If a file is not found by 'gf', then 'includeexpr' should be used to locate +" the file. +func Test_gf_includeexpr() + new + let g:Inc_fname = '' + func IncFunc() + let g:Inc_fname = v:fname + return v:fname + endfunc + setlocal includeexpr=IncFunc() + call setline(1, 'somefile.java') + call assert_fails('normal gf', 'E447:') + call assert_equal('somefile.java', g:Inc_fname) + close! + delfunc IncFunc +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index d09b25b0e7..c4a41a6742 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -154,8 +154,24 @@ func Test_gn_command() norm! gg0f2vf7gNd call assert_equal(['1678'], getline(1,'$')) sil! %d _ - set wrapscan&vim + + " Without 'wrapscan', in visual mode, running gn without a match should fail + " but the visual mode should be kept. + set nowrapscan + call setline('.', 'one two') + let @/ = 'one' + call assert_beeps('normal 0wvlgn') + exe "normal y" + call assert_equal('tw', @") + + " with exclusive selection, run gn and gN + set selection=exclusive + normal 0gny + call assert_equal('one', @") + normal 0wgNy + call assert_equal('one', @") + set selection& endfunc func Test_gN_repeat() diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim index 19513b315a..49095400ef 100644 --- a/src/nvim/testdir/test_goto.vim +++ b/src/nvim/testdir/test_goto.vim @@ -334,21 +334,24 @@ endfunc func Test_motion_if_elif_else_endif() new - a -/* Test pressing % on #if, #else #elsif and #endif, - * with nested #if - */ -#if FOO -/* ... */ -# if BAR -/* ... */ -# endif -#elif BAR -/* ... */ -#else -/* ... */ -#endif -. + let lines =<< trim END + /* Test pressing % on #if, #else #elsif and #endif, + * with nested #if + */ + #if FOO + /* ... */ + # if BAR + /* ... */ + # endif + #elif BAR + /* ... */ + #else + /* ... */ + #endif + + #define FOO 1 + END + call setline(1, lines) /#if FOO norm % call assert_equal([9, 1], getpos('.')[1:2]) @@ -364,6 +367,30 @@ func Test_motion_if_elif_else_endif() norm $% call assert_equal([6, 1], getpos('.')[1:2]) + " Test for [# and ]# command + call cursor(5, 1) + normal [# + call assert_equal([4, 1], getpos('.')[1:2]) + call cursor(5, 1) + normal ]# + call assert_equal([9, 1], getpos('.')[1:2]) + call cursor(10, 1) + normal [# + call assert_equal([9, 1], getpos('.')[1:2]) + call cursor(10, 1) + normal ]# + call assert_equal([11, 1], getpos('.')[1:2]) + + " Finding a match before the first line or after the last line should fail + normal gg + call assert_beeps('normal [#') + normal G + call assert_beeps('normal ]#') + + " Finding a match for a macro definition (#define) should fail + normal G + call assert_beeps('normal %') + bw! endfunc @@ -393,3 +420,5 @@ func Test_motion_c_comment() bw! endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index e963f308a2..93ab17955d 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -601,6 +601,107 @@ func Test_ins_compl_tag_sft() %bwipe! endfunc +" Test for 'completefunc' deleting text +func Test_completefunc_error() + new + " delete text when called for the first time + func CompleteFunc(findstart, base) + if a:findstart == 1 + normal dd + return col('.') - 1 + endif + return ['a', 'b'] + endfunc + set completefunc=CompleteFunc + call setline(1, ['', 'abcd', '']) + call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E565:') + + " delete text when called for the second time + func CompleteFunc2(findstart, base) + if a:findstart == 1 + return col('.') - 1 + endif + normal dd + return ['a', 'b'] + endfunc + set completefunc=CompleteFunc2 + call setline(1, ['', 'abcd', '']) + call assert_fails('exe "normal 2G$a\<C-X>\<C-U>"', 'E565:') + + " Jump to a different window from the complete function + func CompleteFunc3(findstart, base) + if a:findstart == 1 + return col('.') - 1 + endif + wincmd p + return ['a', 'b'] + endfunc + set completefunc=CompleteFunc3 + new + call assert_fails('exe "normal a\<C-X>\<C-U>"', 'E565:') + close! + + set completefunc& + delfunc CompleteFunc + delfunc CompleteFunc2 + delfunc CompleteFunc3 + close! +endfunc + +" Test for returning non-string values from 'completefunc' +func Test_completefunc_invalid_data() + new + func! CompleteFunc(findstart, base) + if a:findstart == 1 + return col('.') - 1 + endif + return [{}, '', 'moon'] + endfunc + set completefunc=CompleteFunc + exe "normal i\<C-X>\<C-U>" + call assert_equal('moon', getline(1)) + set completefunc& + close! +endfunc + +" Test for errors in using complete() function +func Test_complete_func_error() + call assert_fails('call complete(1, ["a"])', 'E785:') + func ListColors() + call complete(col('.'), "blue") + endfunc + call assert_fails('exe "normal i\<C-R>=ListColors()\<CR>"', 'E474:') + func ListMonths() + call complete(col('.'), test_null_list()) + endfunc + " Nvim allows a NULL list + " call assert_fails('exe "normal i\<C-R>=ListMonths()\<CR>"', 'E474:') + delfunc ListColors + delfunc ListMonths + call assert_fails('call complete_info({})', 'E714:') + call assert_equal([], complete_info(['items']).items) +endfunc + +" Test for completing words following a completed word in a line +func Test_complete_wrapscan() + " complete words from another buffer + new + call setline(1, ['one two', 'three four']) + new + setlocal complete=w + call feedkeys("itw\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt') + call assert_equal('two three four', getline(1)) + close! + " complete words from the current buffer + setlocal complete=. + %d + call setline(1, ['one two', '']) + call cursor(2, 1) + call feedkeys("ion\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>\<C-X>\<C-N>", 'xt') + call assert_equal('one two one two', getline(2)) + close! +endfunc + " Test for completing special characters func Test_complete_special_chars() new diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index a34a950526..e1d0b9a9ba 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -956,6 +956,16 @@ func Test_map_cmdkey_redo() ounmap i- endfunc +" Test for using <script> with a map to remap characters in rhs +func Test_script_local_remap() + new + inoremap <buffer> <SID>xyz mno + inoremap <buffer> <script> abc st<SID>xyzre + normal iabc + call assert_equal('stmnore', getline(1)) + bwipe! +endfunc + func Test_abbreviate_multi_byte() new iabbrev foo bar diff --git a/src/nvim/testdir/test_messages.vim b/src/nvim/testdir/test_messages.vim index 8be0c79499..5670368936 100644 --- a/src/nvim/testdir/test_messages.vim +++ b/src/nvim/testdir/test_messages.vim @@ -112,6 +112,136 @@ func Test_echospace() set ruler& showcmd& endfunc +" Test more-prompt (see :help more-prompt). +func Test_message_more() + CheckRunVimInTerminal + let buf = RunVimInTerminal('', {'rows': 6}) + call term_sendkeys(buf, ":call setline(1, range(1, 100))\n") + + call term_sendkeys(buf, ":%p#\n") + call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + + call term_sendkeys(buf, '?') + call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More -- SPACE/d/j: screen/page/line down, b/u/k: up, q: quit ', term_getline(buf, 6))}) + + " Down a line with j, <CR>, <NL> or <Down>. + call term_sendkeys(buf, "j") + call WaitForAssert({-> assert_equal(' 6 6', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + call term_sendkeys(buf, "\<NL>") + call WaitForAssert({-> assert_equal(' 7 7', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<CR>") + call WaitForAssert({-> assert_equal(' 8 8', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<Down>") + call WaitForAssert({-> assert_equal(' 9 9', term_getline(buf, 5))}) + + " Down a screen with <Space>, f, or <PageDown>. + call term_sendkeys(buf, 'f') + call WaitForAssert({-> assert_equal(' 14 14', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + call term_sendkeys(buf, ' ') + call WaitForAssert({-> assert_equal(' 19 19', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<PageDown>") + call WaitForAssert({-> assert_equal(' 24 24', term_getline(buf, 5))}) + + " Down a page (half a screen) with d. + call term_sendkeys(buf, 'd') + call WaitForAssert({-> assert_equal(' 27 27', term_getline(buf, 5))}) + + " Down all the way with 'G'. + call term_sendkeys(buf, 'G') + call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))}) + + " Up a line k, <BS> or <Up>. + call term_sendkeys(buf, 'k') + call WaitForAssert({-> assert_equal(' 99 99', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<BS>") + call WaitForAssert({-> assert_equal(' 98 98', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<Up>") + call WaitForAssert({-> assert_equal(' 97 97', term_getline(buf, 5))}) + + " Up a screen with b or <PageUp>. + call term_sendkeys(buf, 'b') + call WaitForAssert({-> assert_equal(' 92 92', term_getline(buf, 5))}) + call term_sendkeys(buf, "\<PageUp>") + call WaitForAssert({-> assert_equal(' 87 87', term_getline(buf, 5))}) + + " Up a page (half a screen) with u. + call term_sendkeys(buf, 'u') + call WaitForAssert({-> assert_equal(' 84 84', term_getline(buf, 5))}) + + " Up all the way with 'g'. + call term_sendkeys(buf, 'g') + call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + + " All the way down. Pressing f should do nothing but pressing + " space should end the more prompt. + call term_sendkeys(buf, 'G') + call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))}) + call term_sendkeys(buf, 'f') + call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 5))}) + call term_sendkeys(buf, ' ') + call WaitForAssert({-> assert_equal('100', term_getline(buf, 5))}) + + " Pressing g< shows the previous command output. + call term_sendkeys(buf, 'g<') + call WaitForAssert({-> assert_equal('100 100', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('Press ENTER or type command to continue', term_getline(buf, 6))}) + + call term_sendkeys(buf, ":%p#\n") + call WaitForAssert({-> assert_equal(' 5 5', term_getline(buf, 5))}) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + + " Stop command output with q, <Esc> or CTRL-C. + call term_sendkeys(buf, 'q') + call WaitForAssert({-> assert_equal('100', term_getline(buf, 5))}) + + " Execute a : command from the more prompt + call term_sendkeys(buf, ":%p#\n") + call term_wait(buf) + call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))}) + call term_sendkeys(buf, ":") + call term_wait(buf) + call WaitForAssert({-> assert_equal(':', term_getline(buf, 6))}) + call term_sendkeys(buf, "echo 'Hello'\n") + call term_wait(buf) + call WaitForAssert({-> assert_equal('Hello ', term_getline(buf, 5))}) + + call StopVimInTerminal(buf) +endfunc + +func Test_ask_yesno() + CheckRunVimInTerminal + let buf = RunVimInTerminal('', {'rows': 6}) + call term_sendkeys(buf, ":call setline(1, range(1, 2))\n") + + call term_sendkeys(buf, ":2,1s/^/n/\n") + call WaitForAssert({-> assert_equal('Backwards range given, OK to swap (y/n)?', term_getline(buf, 6))}) + call term_sendkeys(buf, "n") + call WaitForAssert({-> assert_match('^Backwards range given, OK to swap (y/n)?n *1,1 *All$', term_getline(buf, 6))}) + call WaitForAssert({-> assert_equal('1', term_getline(buf, 1))}) + + call term_sendkeys(buf, ":2,1s/^/Esc/\n") + call WaitForAssert({-> assert_equal('Backwards range given, OK to swap (y/n)?', term_getline(buf, 6))}) + call term_sendkeys(buf, "\<Esc>") + call WaitForAssert({-> assert_match('^Backwards range given, OK to swap (y/n)?n *1,1 *All$', term_getline(buf, 6))}) + call WaitForAssert({-> assert_equal('1', term_getline(buf, 1))}) + + call term_sendkeys(buf, ":2,1s/^/y/\n") + call WaitForAssert({-> assert_equal('Backwards range given, OK to swap (y/n)?', term_getline(buf, 6))}) + call term_sendkeys(buf, "y") + call WaitForAssert({-> assert_match('^Backwards range given, OK to swap (y/n)?y *2,1 *All$', term_getline(buf, 6))}) + call WaitForAssert({-> assert_equal('y1', term_getline(buf, 1))}) + call WaitForAssert({-> assert_equal('y2', term_getline(buf, 2))}) + + call StopVimInTerminal(buf) +endfunc + func Test_mapping_at_hit_return_prompt() nnoremap <C-B> :echo "hit ctrl-b"<CR> call feedkeys(":ls\<CR>", "xt") diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 2d5b66df26..9fbd1f774a 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -811,8 +811,9 @@ func Test_normal17_z_scroll_hor2() bw! endfunc -" Test for H, M and L commands with folds -func Test_scroll_cmds() +" Test for commands that scroll the window horizontally. Test with folds. +" H, M, L, CTRL-E, CTRL-Y, CTRL-U, CTRL-D, PageUp, PageDown commands +func Test_vert_scroll_cmds() 15new call setline(1, range(1, 100)) exe "normal! 30ggz\<CR>" @@ -821,6 +822,8 @@ func Test_scroll_cmds() 40,43fold 46,49fold let h = winheight(0) + + " Test for H, M and L commands " Top of the screen = 30 " Folded lines = 9 " Bottom of the screen = 30 + h + 9 - 1 @@ -828,15 +831,107 @@ func Test_scroll_cmds() call assert_equal(35 + h, line('.')) normal! 4H call assert_equal(33, line('.')) + + " Test for the CTRL-E and CTRL-Y commands with folds + %d + call setline(1, range(1, 10)) + 3,5fold + exe "normal 6G3\<C-E>" + call assert_equal(6, line('w0')) + exe "normal 2\<C-Y>" + call assert_equal(2, line('w0')) + + " Test for CTRL-Y on a folded line + %d + call setline(1, range(1, 100)) + exe (h + 2) .. "," .. (h + 4) .. "fold" + exe h + 5 + normal z- + exe "normal \<C-Y>\<C-Y>" + call assert_equal(h + 1, line('w$')) + + " Using <PageUp> and <PageDown> in an empty buffer should beep + %d + call assert_beeps('exe "normal \<PageUp>"') + call assert_beeps('exe "normal \<C-B>"') + call assert_beeps('exe "normal \<PageDown>"') + call assert_beeps('exe "normal \<C-F>"') + + " Test for <C-U> and <C-D> with fold + %d + call setline(1, range(1, 100)) + 10,35fold + set scroll=10 + exe "normal \<C-D>" + call assert_equal(36, line('.')) + exe "normal \<C-D>" + call assert_equal(46, line('.')) + exe "normal \<C-U>" + call assert_equal(36, line('.')) + exe "normal \<C-U>" + call assert_equal(10, line('.')) + exe "normal \<C-U>" + call assert_equal(1, line('.')) + set scroll& + + " Test for scrolling to the top of the file with <C-U> and a fold + 10 + normal ztL + exe "normal \<C-U>\<C-U>" + call assert_equal(1, line('w0')) + + " Test for CTRL-D on a folded line + %d + call setline(1, range(1, 100)) + 50,100fold + 75 + normal z- + exe "normal \<C-D>" + call assert_equal(50, line('.')) + call assert_equal(100, line('w$')) + normal z. + let lnum = winline() + exe "normal \<C-D>" + call assert_equal(lnum, winline()) + call assert_equal(50, line('.')) + normal zt + exe "normal \<C-D>" + call assert_equal(50, line('w0')) + set foldenable& close! endfunc +" Test for the 'sidescroll' option +func Test_sidescroll_opt() + new + 20vnew + + " scroll by 2 characters horizontally + set sidescroll=2 nowrap + call setline(1, repeat('a', 40)) + normal g$l + call assert_equal(19, screenpos(0, 1, 21).col) + normal l + call assert_equal(20, screenpos(0, 1, 22).col) + normal g0h + call assert_equal(2, screenpos(0, 1, 2).col) + call assert_equal(20, screenpos(0, 1, 20).col) + + " when 'sidescroll' is 0, cursor positioned at the center + set sidescroll=0 + normal g$l + call assert_equal(11, screenpos(0, 1, 21).col) + normal g0h + call assert_equal(10, screenpos(0, 1, 10).col) + + %bw! + set wrap& sidescroll& +endfunc + +" basic tests for foldopen/folddelete func Test_normal18_z_fold() - " basic tests for foldopen/folddelete - if !has("folding") - return - endif + CheckFeature folding call Setup_NewWindow() 50 setl foldenable fdm=marker foldlevel=5 @@ -1566,11 +1661,27 @@ func Test_normal28_parenthesis() norm! $d( call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$')) + " Move to the next sentence from a paragraph macro + %d + call setline(1, ['.LP', 'blue sky!. blue sky.', 'blue sky. blue sky.']) + call cursor(1, 1) + normal ) + call assert_equal([2, 1], [line('.'), col('.')]) + normal ) + call assert_equal([2, 12], [line('.'), col('.')]) + normal (( + call assert_equal([1, 1], [line('.'), col('.')]) + " It is an error if a next sentence is not found %d call setline(1, '.SH') call assert_beeps('normal )') + " If only dot is present, don't treat that as a sentence + call setline(1, '. This is a sentence.') + normal $(( + call assert_equal(3, col('.')) + " Jumping to a fold should open the fold call setline(1, ['', '', 'one', 'two', 'three']) set foldenable @@ -2484,92 +2595,6 @@ func Test_normal42_halfpage() bw! endfunc -" Tests for text object aw -func Test_normal43_textobject1() - new - call append(0, ['foobar,eins,foobar', 'foo,zwei,foo ']) - " diw - norm! 1gg0diw - call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$')) - " daw - norm! 2ggEdaw - call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$')) - %d - call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) - " diW - norm! 2ggwd2iW - call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$')) - " daW - norm! 1ggd2aW - call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$')) - - %d - call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) - " aw in visual line mode switches to characterwise mode - norm! 2gg$Vawd - call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$')) - norm! 1gg$Viwd - call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$')) - - " clean up - bw! -endfunc - -" Test for is and as text objects -func Test_normal44_textobjects2() - new - call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here']) - " Test for dis - does not remove trailing whitespace - norm! 1gg0dis - call assert_equal([' With some sentences!', '', 'Even with a question? And one more. And no sentence here', ''], getline(1,'$')) - " Test for das - removes leading whitespace - norm! 3ggf?ldas - call assert_equal([' With some sentences!', '', 'Even with a question? And no sentence here', ''], getline(1,'$')) - " when used in visual mode, is made characterwise - norm! 3gg$Visy - call assert_equal('v', visualmode()) - " reset visualmode() - norm! 3ggVy - norm! 3gg$Vasy - call assert_equal('v', visualmode()) - " basic testing for textobjects a< and at - %d - call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) - " a< - norm! 1gg0da< - call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) - norm! 1pj - call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) - " at - norm! d2at - call assert_equal([' '], getline(1,'$')) - %d - call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) - " i< - norm! 1gg0di< - call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) - norm! 1Pj - call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) - norm! d2it - call assert_equal(['<div></div>',' '], getline(1,'$')) - " basic testing for a[ and i[ text object - %d - call setline(1, [' ', '[', 'one [two]', 'thre', ']']) - norm! 3gg0di[ - call assert_equal([' ', '[', ']'], getline(1,'$')) - call setline(1, [' ', '[', 'one [two]', 'thre', ']']) - norm! 3gg0ftd2a[ - call assert_equal([' '], getline(1,'$')) - %d - " Test for i" when cursor is in front of a quoted object - call append(0, 'foo "bar"') - norm! 1gg0di" - call assert_equal(['foo ""', ''], getline(1,'$')) - - " clean up - bw! -endfunc - func Test_normal45_drop() if !has('dnd') " The ~ register does not exist @@ -3181,6 +3206,79 @@ func Test_normal_colon_op() close! endfunc +" Test for 'w' and 'b' commands +func Test_normal_word_move() + new + call setline(1, ['foo bar a', '', 'foo bar b']) + " copy a single character word at the end of a line + normal 1G$yw + call assert_equal('a', @") + " copy a single character word at the end of a file + normal G$yw + call assert_equal('b', @") + " check for a word movement handling an empty line properly + normal 1G$vwy + call assert_equal("a\n\n", @") + + " copy using 'b' command + %d + " non-empty blank line at the start of file + call setline(1, [' ', 'foo bar']) + normal 2Gyb + call assert_equal(" \n", @") + " try to copy backwards from the start of the file + call setline(1, ['one two', 'foo bar']) + call assert_beeps('normal ggyb') + " 'b' command should stop at an empty line + call setline(1, ['one two', '', 'foo bar']) + normal 3Gyb + call assert_equal("\n", @") + normal 3Gy2b + call assert_equal("two\n", @") + " 'b' command should not stop at a non-empty blank line + call setline(1, ['one two', ' ', 'foo bar']) + normal 3Gyb + call assert_equal("two\n ", @") + + close! +endfunc + +" Test for 'scrolloff' with a long line that doesn't fit in the screen +func Test_normal_scroloff() + 10new + 80vnew + call setline(1, repeat('a', 1000)) + set scrolloff=10 + normal gg10gj + call assert_equal(8, winline()) + normal 10gj + call assert_equal(10, winline()) + normal 10gk + call assert_equal(3, winline()) + set scrolloff& + close! +endfunc + +" Test for vertical scrolling with CTRL-F and CTRL-B with a long line +func Test_normal_vert_scroll_longline() + 10new + 80vnew + call setline(1, range(1, 10)) + call append(5, repeat('a', 1000)) + exe "normal gg\<C-F>" + call assert_equal(6, line('.')) + exe "normal \<C-F>\<C-F>" + call assert_equal(11, line('.')) + call assert_equal(1, winline()) + exe "normal \<C-B>" + call assert_equal(10, line('.')) + call assert_equal(3, winline()) + exe "normal \<C-B>\<C-B>" + call assert_equal(5, line('.')) + call assert_equal(5, winline()) + close! +endfunc + " Some commands like yy, cc, dd, >>, << and !! accept a count after " typing the first letter of the command. func Test_normal_count_after_operator() diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 2840378b97..1f003041e6 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -466,9 +466,11 @@ func Test_set_one_column() endfunc func Test_set_values() - " The file is only generated when running "make test" in the src directory. + " opt_test.vim is generated from ../optiondefs.h using gen_opt_test.vim if filereadable('opt_test.vim') source opt_test.vim + else + throw 'Skipped: opt_test.vim does not exist' endif endfunc @@ -813,6 +815,47 @@ func Test_opt_boolean() set number& endfunc +" Test for the 'window' option +func Test_window_opt() + " Needs only one open widow + %bw! + call setline(1, range(1, 8)) + set window=5 + exe "normal \<C-F>" + call assert_equal(4, line('w0')) + exe "normal \<C-F>" + call assert_equal(7, line('w0')) + exe "normal \<C-F>" + call assert_equal(8, line('w0')) + exe "normal \<C-B>" + call assert_equal(5, line('w0')) + exe "normal \<C-B>" + call assert_equal(2, line('w0')) + exe "normal \<C-B>" + call assert_equal(1, line('w0')) + set window=1 + exe "normal gg\<C-F>" + call assert_equal(2, line('w0')) + exe "normal \<C-F>" + call assert_equal(3, line('w0')) + exe "normal \<C-B>" + call assert_equal(2, line('w0')) + exe "normal \<C-B>" + call assert_equal(1, line('w0')) + enew! + set window& +endfunc + +" Test for the 'winminheight' option +func Test_opt_winminheight() + only! + let &winheight = &lines + 4 + call assert_fails('let &winminheight = &lines + 2', 'E36:') + call assert_true(&winminheight <= &lines) + set winminheight& + set winheight& +endfunc + func Test_opt_winminheight_term() " See test/functional/legacy/options_spec.lua CheckRunVimInTerminal @@ -856,6 +899,16 @@ func Test_opt_winminheight_term_tabs() call delete('Xwinminheight') endfunc +" Test for the 'winminwidth' option +func Test_opt_winminwidth() + only! + let &winwidth = &columns + 4 + call assert_fails('let &winminwidth = &columns + 2', 'E36:') + call assert_true(&winminwidth <= &columns) + set winminwidth& + set winwidth& +endfunc + " Test for setting option value containing spaces with isfname+=32 func Test_isfname_with_options() set isfname+=32 diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 7afa31a6d1..a5e4be49f4 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -382,11 +382,11 @@ func Test_completefunc_opens_new_window_two() setlocal completefunc=DummyCompleteTwo call setline(1, 'two') /^two - call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E764:') - call assert_notequal(winid, win_getid()) - q! + call assert_fails('call feedkeys("A\<C-X>\<C-U>\<C-N>\<Esc>", "x")', 'E565:') call assert_equal(winid, win_getid()) - call assert_equal('two', getline(1)) + " v8.2.1919 hasn't been ported yet + " call assert_equal('twodef', getline(1)) + call assert_equal('twoDEF', getline(1)) q! endfunc @@ -655,8 +655,8 @@ func Test_complete_func_mess() set completefunc=MessComplete new call setline(1, 'Ju') - call feedkeys("A\<c-x>\<c-u>/\<esc>", 'tx') - call assert_equal('Oct/Oct', getline(1)) + call assert_fails('call feedkeys("A\<c-x>\<c-u>/\<esc>", "tx")', 'E565:') + call assert_equal('Jan/', getline(1)) bwipe! set completefunc= endfunc diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 5649652fd2..ddd4229f17 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -301,6 +301,23 @@ func XwindowTests(cchar) call assert_equal(12, winwidth(0)) Xclose + " Horizontally or vertically splitting the quickfix window should create a + " normal window/buffer + Xopen + wincmd s + call assert_equal(0, getwininfo(win_getid())[0].quickfix) + call assert_equal(0, getwininfo(win_getid())[0].loclist) + call assert_notequal('quickfix', &buftype) + close + Xopen + wincmd v + call assert_equal(0, getwininfo(win_getid())[0].quickfix) + call assert_equal(0, getwininfo(win_getid())[0].loclist) + call assert_notequal('quickfix', &buftype) + close + Xopen + Xclose + if a:cchar == 'c' " Opening the quickfix window in multiple tab pages should reuse the " quickfix buffer @@ -503,10 +520,10 @@ func Xtest_browse(cchar) call assert_fails('Xprev', 'E553') call assert_fails('Xpfile', 'E553') Xnfile - call assert_equal('Xqftestfile2', bufname('%')) + call assert_equal('Xqftestfile2', @%) call assert_equal(10, line('.')) Xpfile - call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal('Xqftestfile1', @%) call assert_equal(6, line('.')) 5Xcc call assert_equal(5, g:Xgetlist({'idx':0}).idx) @@ -522,7 +539,7 @@ func Xtest_browse(cchar) call assert_equal(6, g:Xgetlist({'idx':0}).idx) Xlast Xprev - call assert_equal('Xqftestfile2', bufname('%')) + call assert_equal('Xqftestfile2', @%) call assert_equal(11, line('.')) call assert_fails('Xnext', 'E553') call assert_fails('Xnfile', 'E553') @@ -535,14 +552,14 @@ func Xtest_browse(cchar) endif call assert_equal(6, g:Xgetlist({'idx':0}).idx) Xrewind - call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal('Xqftestfile1', @%) call assert_equal(5, line('.')) 10Xnext - call assert_equal('Xqftestfile2', bufname('%')) + call assert_equal('Xqftestfile2', @%) call assert_equal(11, line('.')) 10Xprev - call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal('Xqftestfile1', @%) call assert_equal(5, line('.')) " Jumping to an error from the error window using cc command @@ -553,7 +570,7 @@ func Xtest_browse(cchar) Xopen 10Xcc call assert_equal(11, line('.')) - call assert_equal('Xqftestfile2', bufname('%')) + call assert_equal('Xqftestfile2', @%) Xopen call cursor(2, 1) if a:cchar == 'c' @@ -562,14 +579,14 @@ func Xtest_browse(cchar) .ll endif call assert_equal(6, line('.')) - call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal('Xqftestfile1', @%) " Jumping to an error from the error window (when only the error window is " present) Xopen | only Xlast 1 call assert_equal(5, line('.')) - call assert_equal('Xqftestfile1', bufname('%')) + call assert_equal('Xqftestfile1', @%) Xexpr "" call assert_fails('Xnext', 'E42:') @@ -1944,7 +1961,7 @@ func Test_switchbuf() copen | only cfirst call assert_equal(1, tabpagenr()) - call assert_equal('Xqftestfile1', bufname('')) + call assert_equal('Xqftestfile1', @%) " If opening a file changes 'switchbuf', then the new value should be " retained. @@ -2760,7 +2777,7 @@ func Test_cwindow_jump() wincmd b cfirst call assert_equal(2, winnr()) - call assert_equal('F1', bufname('')) + call assert_equal('F1', @%) enew | only exe 'sb' bnum exe 'botright sb' bnum @@ -2850,7 +2867,7 @@ func XvimgrepTests(cchar) edit +3 Xtestfile2 Xvimgrep +\cemacs+j Xtestfile1 let l = g:Xgetlist() - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal('Editor:Emacs EmAcS', l[0].text) " Test for unloading a buffer after vimgrep searched the buffer @@ -3107,20 +3124,80 @@ func Test_file_from_copen() endfunc func Test_resize_from_copen() + augroup QF_Test + au! + au FileType qf resize 5 + augroup END + try + " This should succeed without any exception. No other buffers are + " involved in the autocmd. + copen + finally augroup QF_Test - au! - au FileType qf resize 5 + au! augroup END - try - " This should succeed without any exception. No other buffers are - " involved in the autocmd. - copen - finally - augroup QF_Test - au! - augroup END - augroup! QF_Test - endtry + augroup! QF_Test + endtry +endfunc + +func Test_vimgrep_with_textlock() + new + + " Simple way to execute something with "textlock" set. + " Check that vimgrep without jumping can be executed. + au InsertCharPre * vimgrep /RunTheTest/j runtest.vim + normal ax + let qflist = getqflist() + call assert_true(len(qflist) > 0) + call assert_match('RunTheTest', qflist[0].text) + call setqflist([], 'r') + au! InsertCharPre + + " Check that vimgrepadd without jumping can be executed. + au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim + normal ax + let qflist = getqflist() + call assert_true(len(qflist) > 0) + call assert_match('RunTheTest', qflist[0].text) + call setqflist([], 'r') + au! InsertCharPre + + " Check that lvimgrep without jumping can be executed. + au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim + normal ax + let qflist = getloclist(0) + call assert_true(len(qflist) > 0) + call assert_match('RunTheTest', qflist[0].text) + call setloclist(0, [], 'r') + au! InsertCharPre + + " Check that lvimgrepadd without jumping can be executed. + au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim + normal ax + let qflist = getloclist(0) + call assert_true(len(qflist) > 0) + call assert_match('RunTheTest', qflist[0].text) + call setloclist(0, [], 'r') + au! InsertCharPre + + " trying to jump will give an error + au InsertCharPre * vimgrep /RunTheTest/ runtest.vim + call assert_fails('normal ax', 'E565:') + au! InsertCharPre + + au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim + call assert_fails('normal ax', 'E565:') + au! InsertCharPre + + au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim + call assert_fails('normal ax', 'E565:') + au! InsertCharPre + + au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim + call assert_fails('normal ax', 'E565:') + au! InsertCharPre + + bwipe! endfunc " Tests for the quickfix buffer b:changedtick variable @@ -3519,7 +3596,7 @@ func Xqfjump_tests(cchar) Xopen | only 2Xnext call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) - call assert_equal('F3', bufname('%')) + call assert_equal('F3', @%) Xnext call assert_equal(7, col('.')) Xnext @@ -4213,20 +4290,20 @@ func Xjumpto_first_error_test(cchar) " Test for cexpr/lexpr enew Xexpr l - call assert_equal('Xtestfile1', bufname('')) + call assert_equal('Xtestfile1', @%) call assert_equal(2, line('.')) " Test for cfile/lfile enew call writefile(l, 'Xerr') Xfile Xerr - call assert_equal('Xtestfile1', bufname('')) + call assert_equal('Xtestfile1', @%) call assert_equal(2, line('.')) " Test for cbuffer/lbuffer edit Xerr Xbuffer - call assert_equal('Xtestfile1', bufname('')) + call assert_equal('Xtestfile1', @%) call assert_equal(2, line('.')) call delete('Xerr') @@ -4251,7 +4328,7 @@ func Xautocmd_changelist(cchar) autocmd QuickFixCmdPost * Xolder call writefile(['Xtestfile2:4:Line4'], 'Xerr') Xfile Xerr - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal(4, line('.')) autocmd! QuickFixCmdPost @@ -4262,7 +4339,7 @@ func Xautocmd_changelist(cchar) call writefile(['Xtestfile2:4:Line4'], 'Xerr') edit Xerr Xbuffer - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal(4, line('.')) autocmd! QuickFixCmdPost @@ -4271,7 +4348,7 @@ func Xautocmd_changelist(cchar) Xexpr 'Xtestfile1:2:Line2' autocmd QuickFixCmdPost * Xolder Xexpr 'Xtestfile2:4:Line4' - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal(4, line('.')) autocmd! QuickFixCmdPost @@ -4282,7 +4359,7 @@ func Xautocmd_changelist(cchar) Xexpr 'Xtestfile1:2:Line2' autocmd QuickFixCmdPost * Xolder silent Xgrep Line5 Xtestfile2 - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal(5, line('.')) autocmd! QuickFixCmdPost endif @@ -4292,7 +4369,7 @@ func Xautocmd_changelist(cchar) Xexpr 'Xtestfile1:2:Line2' autocmd QuickFixCmdPost * Xolder silent Xvimgrep Line5 Xtestfile2 - call assert_equal('Xtestfile2', bufname('')) + call assert_equal('Xtestfile2', @%) call assert_equal(5, line('.')) autocmd! QuickFixCmdPost @@ -4607,7 +4684,7 @@ func Test_winonly_autocmd() " positioned correctly. ll 3 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id) - call assert_equal('Xtest1', bufname('')) + call assert_equal('Xtest1', @%) call assert_equal(15, line('.')) " Cleanup autocmd! WinEnter @@ -4668,51 +4745,51 @@ func Xtest_below(cchar) Xexpr ["X1:5:3:L5", "X2:5:2:L5", "X2:10:3:L10", "X2:15:4:L15", "X3:3:5:L3"] edit +7 X2 Xabove - call assert_equal(['X2', 5], [bufname(''), line('.')]) + call assert_equal(['X2', 5], [@%, line('.')]) call assert_fails('Xabove', 'E553:') normal 7G Xbefore - call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) call assert_fails('Xbefore', 'E553:') normal 2j Xbelow - call assert_equal(['X2', 10], [bufname(''), line('.')]) + call assert_equal(['X2', 10], [@%, line('.')]) normal 7G Xafter - call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) " Last error in this file Xbelow 99 - call assert_equal(['X2', 15], [bufname(''), line('.')]) + call assert_equal(['X2', 15], [@%, line('.')]) call assert_fails('Xbelow', 'E553:') normal gg Xafter 99 - call assert_equal(['X2', 15, 4], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')]) call assert_fails('Xafter', 'E553:') " First error in this file Xabove 99 - call assert_equal(['X2', 5], [bufname(''), line('.')]) + call assert_equal(['X2', 5], [@%, line('.')]) call assert_fails('Xabove', 'E553:') normal G Xbefore 99 - call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) call assert_fails('Xbefore', 'E553:') normal gg Xbelow 2 - call assert_equal(['X2', 10], [bufname(''), line('.')]) + call assert_equal(['X2', 10], [@%, line('.')]) normal gg Xafter 2 - call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) normal G Xabove 2 - call assert_equal(['X2', 10], [bufname(''), line('.')]) + call assert_equal(['X2', 10], [@%, line('.')]) normal G Xbefore 2 - call assert_equal(['X2', 10, 3], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')]) edit X4 call assert_fails('Xabove', 'E42:') @@ -4736,45 +4813,45 @@ func Xtest_below(cchar) \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"] edit +1 X2 Xbelow 2 - call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) normal 1G Xafter 2 - call assert_equal(['X2', 5, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')]) normal gg Xbelow 99 - call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) normal gg Xafter 99 - call assert_equal(['X2', 15, 3], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')]) normal G Xabove 2 - call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')]) normal G Xbefore 2 - call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) normal G Xabove 99 - call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) normal G Xbefore 99 - call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) normal 10G Xabove - call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')]) normal 10G$ 2Xbefore - call assert_equal(['X2', 10, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')]) normal 10G Xbelow - call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')]) normal 9G 5Xafter - call assert_equal(['X2', 15, 2], [bufname(''), line('.'), col('.')]) + call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')]) " Invalid range if a:cchar == 'c' diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim index abe28b77cd..52e745438d 100644 --- a/src/nvim/testdir/test_registers.vim +++ b/src/nvim/testdir/test_registers.vim @@ -684,6 +684,16 @@ func Test_insert_small_delete() bwipe! endfunc +" Record in insert mode using CTRL-O +func Test_record_in_insert_mode() + new + let @r = '' + call setline(1, ['foo']) + call feedkeys("i\<C-O>qrbaz\<C-O>q", 'xt') + call assert_equal('baz', @r) + bwipe! +endfunc + func Test_record_in_select_mode() new call setline(1, 'text') diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 747fb0e384..3d1bbfb726 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -1732,6 +1732,34 @@ func Test_invalid_regexp() call assert_fails("call search('\\%#=3ab')", 'E864:') endfunc +" Test for searching with 'smartcase' and 'ignorecase' +func Test_search_smartcase() + new + call setline(1, ['', 'Hello']) + set noignorecase nosmartcase + call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:') + + set ignorecase nosmartcase + exe "normal /\\a\\_.\\(.*\\)O\<CR>" + call assert_equal([2, 1], [line('.'), col('.')]) + + call cursor(1, 1) + set ignorecase smartcase + call assert_fails('exe "normal /\\a\\_.\\(.*\\)O\<CR>"', 'E486:') + + exe "normal /\\a\\_.\\(.*\\)o\<CR>" + call assert_equal([2, 1], [line('.'), col('.')]) + + " Test for using special atoms with 'smartcase' + call setline(1, ['', ' Hello\ ']) + call cursor(1, 1) + call feedkeys('/\_.\%(\uello\)\' .. "\<CR>", 'xt') + call assert_equal([2, 4], [line('.'), col('.')]) + + set ignorecase& smartcase& + close! +endfun + " Test 'smartcase' with utf-8. func Test_search_smartcase_utf8() new @@ -1751,6 +1779,102 @@ func Test_search_smartcase_utf8() close! endfunc +" Test searching past the end of a file +func Test_search_past_eof() + new + call setline(1, ['Line']) + exe "normal /\\n\\zs\<CR>" + call assert_equal([1, 4], [line('.'), col('.')]) + close! +endfunc + +" Test for various search offsets +func Test_search_offset() + " With /e, for a match in the first column of a line, the cursor should be + " placed at the end of the previous line. + new + call setline(1, ['one two', 'three four']) + call search('two\_.', 'e') + call assert_equal([1, 7], [line('.'), col('.')]) + + " with cursor at the beginning of the file, use /s+1 + call cursor(1, 1) + exe "normal /two/s+1\<CR>" + call assert_equal([1, 6], [line('.'), col('.')]) + + " with cursor at the end of the file, use /e-1 + call cursor(2, 10) + exe "normal ?three?e-1\<CR>" + call assert_equal([2, 4], [line('.'), col('.')]) + + " line offset - after the last line + call cursor(1, 1) + exe "normal /three/+1\<CR>" + call assert_equal([2, 1], [line('.'), col('.')]) + + " line offset - before the first line + call cursor(2, 1) + exe "normal ?one?-1\<CR>" + call assert_equal([1, 1], [line('.'), col('.')]) + + " character offset - before the first character in the file + call cursor(2, 1) + exe "normal ?one?s-1\<CR>" + call assert_equal([1, 1], [line('.'), col('.')]) + call cursor(2, 1) + exe "normal ?one?e-3\<CR>" + call assert_equal([1, 1], [line('.'), col('.')]) + + " character offset - after the last character in the file + call cursor(1, 1) + exe "normal /four/s+4\<CR>" + call assert_equal([2, 10], [line('.'), col('.')]) + call cursor(1, 1) + exe "normal /four/e+1\<CR>" + call assert_equal([2, 10], [line('.'), col('.')]) + + close! +endfunc + +" Test for searching for matching parenthesis using % +func Test_search_match_paren() + new + call setline(1, "abc(def')'ghi'('jk'\\t'lm)no") + " searching for a matching parenthesis should skip single quoted characters + call cursor(1, 4) + normal % + call assert_equal([1, 25], [line('.'), col('.')]) + normal % + call assert_equal([1, 4], [line('.'), col('.')]) + call cursor(1, 5) + normal ]) + call assert_equal([1, 25], [line('.'), col('.')]) + call cursor(1, 24) + normal [( + call assert_equal([1, 4], [line('.'), col('.')]) + + " matching parenthesis in 'virtualedit' mode with cursor after the eol + call setline(1, 'abc(defgh)') + set virtualedit=all + normal 20|% + call assert_equal(4, col('.')) + set virtualedit& + close! +endfunc + +" Test for searching a pattern and stopping before a specified line +func Test_search_stopline() + new + call setline(1, ['', '', '', 'vim']) + call assert_equal(0, search('vim', 'n', 3)) + call assert_equal(4, search('vim', 'n', 4)) + call setline(1, ['vim', '', '', '']) + call cursor(4, 1) + call assert_equal(0, search('vim', 'bn', 2)) + call assert_equal(1, search('vim', 'bn', 1)) + close! +endfunc + func Test_incsearch_highlighting_newline() CheckRunVimInTerminal CheckOption incsearch diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 9a115da8d3..d891684ecb 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -141,6 +141,8 @@ function Test_tabpage() call assert_fails("tabmove $3", 'E474:') call assert_fails("%tabonly", 'E16:') 1tabonly! + tabmove 1 + call assert_equal(1, tabpagenr()) tabnew call assert_fails("-2tabmove", 'E474:') tabonly! @@ -699,6 +701,69 @@ func Test_tabline_tabmenu() %bw! endfunc +" Test for changing the current tab page from an autocmd when closing a tab +" page. +func Test_tabpage_switchtab_on_close() + only + tabnew + tabnew + " Test for BufLeave + augroup T1 + au! + au BufLeave * tabfirst + augroup END + tabclose + call assert_equal(1, tabpagenr()) + augroup T1 + au! + augroup END + + " Test for WinLeave + $tabnew + augroup T1 + au! + au WinLeave * tabfirst + augroup END + tabclose + call assert_equal(1, tabpagenr()) + augroup T1 + au! + augroup END + + " Test for TabLeave + $tabnew + augroup T1 + au! + au TabLeave * tabfirst + augroup END + tabclose + call assert_equal(1, tabpagenr()) + augroup T1 + au! + augroup END + augroup! T1 + tabonly +endfunc + +" Test for closing the destination tabpage when jumping from one to another. +func Test_tabpage_close_on_switch() + tabnew + tabnew + edit Xfile + augroup T2 + au! + au BufLeave Xfile 1tabclose + augroup END + tabfirst + call assert_equal(2, tabpagenr()) + call assert_equal('Xfile', @%) + augroup T2 + au! + augroup END + augroup! T2 + %bw! +endfunc + " Test for jumping to last accessed tabpage func Test_lastused_tabpage() tabonly! diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index b1746641ee..1dd656ece5 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -5,12 +5,57 @@ source screendump.vim " SEGV occurs in older versions. (At least 7.4.1748 or older) func Test_ptag_with_notagstack() + CheckFeature quickfix + set notagstack call assert_fails('ptag does_not_exist_tag_name', 'E426') set tagstack&vim endfunc +func Test_ptjump() + CheckFeature quickfix + + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", + \ "one\tXfile\t1", + \ "three\tXfile\t3", + \ "two\tXfile\t2"], + \ 'Xtags') + call writefile(['one', 'two', 'three'], 'Xfile') + + %bw! + ptjump two + call assert_equal(2, winnr()) + wincmd p + call assert_equal(1, &previewwindow) + call assert_equal('Xfile', expand("%:p:t")) + call assert_equal(2, line('.')) + call assert_equal(2, winnr('$')) + call assert_equal(1, winnr()) + close + call setline(1, ['one', 'two', 'three']) + exe "normal 3G\<C-W>g}" + call assert_equal(2, winnr()) + wincmd p + call assert_equal(1, &previewwindow) + call assert_equal('Xfile', expand("%:p:t")) + call assert_equal(3, line('.')) + call assert_equal(2, winnr('$')) + call assert_equal(1, winnr()) + close + exe "normal 3G5\<C-W>\<C-G>}" + wincmd p + call assert_equal(5, winheight(0)) + close + + call delete('Xtags') + call delete('Xfile') + set tags& +endfunc + func Test_cancel_ptjump() + CheckFeature quickfix + set tags=Xtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", \ "word\tfile1\tcmd1", @@ -70,6 +115,8 @@ func Test_duplicate_tagjump() endfunc func Test_tagjump_switchbuf() + CheckFeature quickfix + set tags=Xtags call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", \ "second\tXfile1\t2", @@ -1274,6 +1321,10 @@ func Test_macro_search() close call assert_fails('3wincmd d', 'E387:') call assert_fails('6wincmd d', 'E388:') + new + call assert_fails("normal \<C-W>d", 'E349:') + call assert_fails("normal \<C-W>\<C-D>", 'E349:') + close " Test for :dsplit dsplit FOO diff --git a/src/nvim/testdir/test_termcodes.vim b/src/nvim/testdir/test_termcodes.vim index f3b10a922e..c0712aa892 100644 --- a/src/nvim/testdir/test_termcodes.vim +++ b/src/nvim/testdir/test_termcodes.vim @@ -1,4 +1,38 @@ +" Test for terminal keycodes that doesn't have termcap entries +func Test_special_term_keycodes() + new + " Test for <xHome>, <S-xHome> and <C-xHome> + " send <K_SPECIAL> <KS_EXTRA> keycode + call feedkeys("i\<C-K>\x80\xfd\x3f\n", 'xt') + " send <K_SPECIAL> <KS_MODIFIER> bitmap <K_SPECIAL> <KS_EXTRA> keycode + call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3f\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3f\n", 'xt') + " Test for <xEnd>, <S-xEnd> and <C-xEnd> + call feedkeys("i\<C-K>\x80\xfd\x3d\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3d\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3d\n", 'xt') + " Test for <zHome>, <S-zHome> and <C-zHome> + call feedkeys("i\<C-K>\x80\xfd\x40\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x40\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x40\n", 'xt') + " Test for <zEnd>, <S-zEnd> and <C-zEnd> + call feedkeys("i\<C-K>\x80\xfd\x3e\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x2\x80\xfd\x3e\n", 'xt') + call feedkeys("i\<C-K>\x80\xfc\x4\x80\xfd\x3e\n", 'xt') + " Test for <xUp>, <xDown>, <xLeft> and <xRight> + call feedkeys("i\<C-K>\x80\xfd\x41\n", 'xt') + call feedkeys("i\<C-K>\x80\xfd\x42\n", 'xt') + call feedkeys("i\<C-K>\x80\xfd\x43\n", 'xt') + call feedkeys("i\<C-K>\x80\xfd\x44\n", 'xt') + call assert_equal(['<Home>', '<S-Home>', '<C-Home>', + \ '<End>', '<S-End>', '<C-End>', + \ '<Home>', '<S-Home>', '<C-Home>', + \ '<End>', '<S-End>', '<C-End>', + \ '<Up>', '<Down>', '<Left>', '<Right>', ''], getline(1, '$')) + bw! +endfunc + func Test_simplify_ctrl_at() " feeding unsimplified CTRL-@ should still trigger i_CTRL-@ call feedkeys("ifoo\<Esc>A\<*C-@>x", 'xt') diff --git a/src/nvim/testdir/test_textformat.vim b/src/nvim/testdir/test_textformat.vim index f0a0f894c3..970f5ae0d0 100644 --- a/src/nvim/testdir/test_textformat.vim +++ b/src/nvim/testdir/test_textformat.vim @@ -1060,7 +1060,7 @@ func Test_tw_2_fo_tm_replace() endfunc " Test for 'matchpairs' with multibyte chars -func Test_mps() +func Test_mps_multibyte() new let t =<< trim END { @@ -1084,6 +1084,30 @@ func Test_mps() bwipe! endfunc +" Test for 'matchpairs' in latin1 encoding +func Test_mps_latin1() + new + let save_enc = &encoding + " set encoding=latin1 + call setline(1, 'abc(def)ghi') + normal % + call assert_equal(8, col('.')) + normal % + call assert_equal(4, col('.')) + call cursor(1, 6) + normal [( + call assert_equal(4, col('.')) + normal % + call assert_equal(8, col('.')) + call cursor(1, 6) + normal ]) + call assert_equal(8, col('.')) + normal % + call assert_equal(4, col('.')) + let &encoding = save_enc + close! +endfunc + func Test_empty_matchpairs() split set matchpairs= showmatch @@ -1137,6 +1161,30 @@ func Test_whichwrap_multi_byte() bwipe! endfunc +" Test for automatically adding comment leaders in insert mode +func Test_threepiece_comment() + new + setlocal expandtab + call setline(1, ["\t/*"]) + setlocal formatoptions=croql + call cursor(1, 3) + call feedkeys("A\<cr>\<cr>/", 'tnix') + call assert_equal(["\t/*", " *", " */"], getline(1, '$')) + + " If a comment ends in a single line, then don't add it in the next line + %d + call setline(1, '/* line1 */') + call feedkeys("A\<CR>next line", 'xt') + call assert_equal(['/* line1 */', 'next line'], getline(1, '$')) + + %d + " Copy the trailing indentation from the leader comment to a new line + setlocal autoindent noexpandtab + call feedkeys("a\t/*\tone\ntwo\n/", 'xt') + call assert_equal(["\t/*\tone", "\t *\ttwo", "\t */"], getline(1, '$')) + close! +endfunc + " Test for the 'f' flag in 'comments' (only the first line has the comment " string) func Test_firstline_comment() diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim index 210aba19a9..eeb2946a8b 100644 --- a/src/nvim/testdir/test_textobjects.vim +++ b/src/nvim/testdir/test_textobjects.vim @@ -233,6 +233,10 @@ func Test_empty_html_tag() normal 0f<vitsaaa call assert_equal('aaa', getline(1)) + " selecting a tag block in an non-empty blank line should fail + call setline(1, ' ') + call assert_beeps('normal $vaty') + bwipe! endfunc @@ -367,6 +371,168 @@ func Test_sentence_with_cursor_on_delimiter() %delete _ endfunc +" Test for the paragraph (ap) text object +func Test_paragraph() + new + call setline(1, ['First line.', 'Second line.', 'Third line.']) + call cursor(2, 1) + normal vapy + call assert_equal("First line.\nSecond line.\nThird line.\n", @") + + call cursor(2, 1) + call assert_beeps('normal vapapy') + + call setline(1, ['First line.', 'Second line.', ' ', '']) + call cursor(1, 1) + normal vapy + call assert_equal("First line.\nSecond line.\n \n\n", @") + + call setline(1, ['', '', '', 'First line.', 'Second line.']) + call cursor(2, 1) + normal yap + call assert_equal("\n\n\nFirst line.\nSecond line.\n", @") + call assert_beeps('normal 3yap') + exe "normal \<C-C>" + + %d + call setline(1, [' ', ' ', ' ']) + call cursor(2, 1) + normal Vipy + call assert_equal(" \n \n \n", @") + call cursor(2, 1) + call assert_beeps("normal Vipip") + exe "normal \<C-C>" + + close! +endfunc + +" Tests for text object aw +func Test_textobj_a_word() + new + call append(0, ['foobar,eins,foobar', 'foo,zwei,foo ']) + " diw + norm! 1gg0diw + call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$')) + " daw + norm! 2ggEdaw + call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$')) + " daw the last word in a line + call setline(1, ['foo bar', 'foo bar', '']) + call cursor(1, 5) + normal daw + call assert_equal('foo', getline(1)) + " aw in visual mode + call cursor(2, 5) + normal! vawx + call assert_equal('foo', getline(2)) + %d + call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) + " diW + norm! 2ggwd2iW + call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$')) + " daW + norm! 1ggd2aW + call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$')) + + %d + call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) + " aw in visual line mode switches to characterwise mode + norm! 2gg$Vawd + call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$')) + norm! 1gg$Viwd + call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$')) + + " visually selecting a tab before a word with 'selection' set to 'exclusive' + set selection=exclusive + normal gg3lvlawy + call assert_equal("\teins", @") + " visually selecting a tab before a word with 'selection' set to 'inclusive' + set selection=inclusive + normal gg3lvlawy + call assert_equal("\teins\t", @") + set selection& + + " selecting a word with no non-space characters in a buffer fails + %d + call setline(1, ' ') + call assert_beeps('normal 3lyaw') + + " visually selecting words backwards with no more words to select + call setline(1, 'one two') + call assert_beeps('normal 2lvh2aw') + exe "normal \<C-C>" + call assert_beeps('normal $vh3aw') + exe "normal \<C-C>" + call setline(1, ['', 'one two']) + call assert_beeps('normal 2G2lvh3aw') + exe "normal \<C-C>" + + " selecting words forward with no more words to select + %d + call setline(1, 'one a') + call assert_beeps('normal 0y3aw') + call setline(1, 'one two ') + call assert_beeps('normal 0y3aw') + call assert_beeps('normal 03ly2aw') + + " clean up + bw! +endfunc + +" Test for is and as text objects +func Test_textobj_sentence() + new + call append(0, ['This is a test. With some sentences!', '', + \ 'Even with a question? And one more. And no sentence here']) + " Test for dis - does not remove trailing whitespace + norm! 1gg0dis + call assert_equal([' With some sentences!', '', + \ 'Even with a question? And one more. And no sentence here', ''], + \ getline(1,'$')) + " Test for das - removes leading whitespace + norm! 3ggf?ldas + call assert_equal([' With some sentences!', '', + \ 'Even with a question? And no sentence here', ''], getline(1,'$')) + " when used in visual mode, is made characterwise + norm! 3gg$Visy + call assert_equal('v', visualmode()) + " reset visualmode() + norm! 3ggVy + norm! 3gg$Vasy + call assert_equal('v', visualmode()) + " basic testing for textobjects a< and at + %d + call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) + " a< + norm! 1gg0da< + call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! 1pj + call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + " at + norm! d2at + call assert_equal([' '], getline(1,'$')) + %d + call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) + " i< + norm! 1gg0di< + call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! 1Pj + call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! d2it + call assert_equal(['<div></div>',' '], getline(1,'$')) + " basic testing for a[ and i[ text object + %d + call setline(1, [' ', '[', 'one [two]', 'thre', ']']) + norm! 3gg0di[ + call assert_equal([' ', '[', ']'], getline(1,'$')) + call setline(1, [' ', '[', 'one [two]', 'thre', ']']) + norm! 3gg0ftd2a[ + call assert_equal([' '], getline(1,'$')) + + " clean up + bw! +endfunc + " Test for quote (', " and `) textobjects func Test_textobj_quote() new diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index da8bf12318..a9ec405aa4 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/testdir/test_undo.vim @@ -3,8 +3,6 @@ " undo-able pieces. Do that by setting 'undolevels'. " Also tests :earlier and :later. -source check.vim - func Test_undotree() new @@ -137,8 +135,7 @@ func BackOne(expected) endfunc func Test_undo_del_chars() - CheckFunction test_settime - + throw 'Skipped: Nvim does not support test_settime()' " Setup a buffer without creating undo entries new set ul=-1 @@ -334,8 +331,9 @@ func Test_insert_expr() endfunc func Test_undofile_earlier() - CheckFunction test_settime - + throw 'Skipped: Nvim does not support test_settime()' + " Issue #1254 + " create undofile with timestamps older than Vim startup time. let t0 = localtime() - 43200 call test_settime(t0) new Xfile @@ -368,7 +366,7 @@ func Test_wundo_errors() bwipe! endfunc -" Check that reading a truncted undo file doesn't hang. +" Check that reading a truncated undo file doesn't hang. func Test_undofile_truncated() new call setline(1, 'hello') @@ -431,6 +429,59 @@ func Test_cmd_in_reg_undo() let @a = '' endfunc +" This used to cause an illegal memory access +func Test_undo_append() + new + call feedkeys("axx\<Esc>v", 'xt') + undo + norm o + quit +endfunc + +func Test_undo_0() + new + set ul=100 + normal i1 + undo + normal i2 + undo + normal i3 + + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('3', getline(1)) + call assert_equal(3, d.seq_cur) + + undo 2 + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('2', getline(1)) + call assert_equal(2, d.seq_cur) + + undo 1 + undo 0 + let d = undotree() + call assert_equal('', getline(1)) + call assert_equal(0, d.seq_cur) + + redo + let d = undotree() + call assert_equal('1', getline(1)) + call assert_equal(1, d.seq_cur) + + bwipe! +endfunc + " undo or redo are noop if there is nothing to undo or redo func Test_undo_redo_noop() new @@ -456,15 +507,6 @@ func Test_redo_empty_line() bwipe! endfunc -" This used to cause an illegal memory access -func Test_undo_append() - new - call feedkeys("axx\<Esc>v", 'xt') - undo - norm o - quit -endfunc - funct Test_undofile() " Test undofile() without setting 'undodir'. if has('persistent_undo') @@ -506,50 +548,6 @@ funct Test_undofile() set undodir& endfunc -func Test_undo_0() - new - set ul=100 - normal i1 - undo - normal i2 - undo - normal i3 - - undo 0 - let d = undotree() - call assert_equal('', getline(1)) - call assert_equal(0, d.seq_cur) - - redo - let d = undotree() - call assert_equal('3', getline(1)) - call assert_equal(3, d.seq_cur) - - undo 2 - undo 0 - let d = undotree() - call assert_equal('', getline(1)) - call assert_equal(0, d.seq_cur) - - redo - let d = undotree() - call assert_equal('2', getline(1)) - call assert_equal(2, d.seq_cur) - - undo 1 - undo 0 - let d = undotree() - call assert_equal('', getline(1)) - call assert_equal(0, d.seq_cur) - - redo - let d = undotree() - call assert_equal('1', getline(1)) - call assert_equal(1, d.seq_cur) - - bwipe! -endfunc - " Tests for the undo file " Explicitly break changes up in undo-able pieces by setting 'undolevels'. func Test_undofile_2() @@ -735,6 +733,29 @@ func Test_undofile_cryptmethod_blowfish2() set undofile& undolevels& cryptmethod& endfunc +" Test for redoing with incrementing numbered registers +func Test_redo_repeat_numbered_register() + new + for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'], + \ [4, 'four'], [5, 'five'], [6, 'six'], + \ [7, 'seven'], [8, 'eight'], [9, 'nine']] + exe 'let @' .. i .. '="' .. v .. '\n"' + endfor + call feedkeys('"1p.........', 'xt') + call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six', + \ 'seven', 'eight', 'nine', 'nine'], getline(1, '$')) + bwipe! +endfunc + +" Test for redo in insert mode using CTRL-O with multibyte characters +func Test_redo_multibyte_in_insert_mode() + new + call feedkeys("a\<C-K>ft", 'xt') + call feedkeys("uiHe\<C-O>.llo", 'xt') + call assert_equal("He\ufb05llo", getline(1)) + bwipe! +endfunc + func Test_undo_mark() new " The undo is applied to the only line. diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index f77765d415..f9ac0e0884 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -1189,6 +1189,29 @@ func Test_AAA_start_visual_mode_with_count() close! endfunc +" Test for visually selecting an inner block (iB) +func Test_visual_inner_block() + new + call setline(1, ['one', '{', 'two', '{', 'three', '}', 'four', '}', 'five']) + call cursor(5, 1) + " visually select all the lines in the block and then execute iB + call feedkeys("ViB\<C-C>", 'xt') + call assert_equal([0, 5, 1, 0], getpos("'<")) + call assert_equal([0, 5, 6, 0], getpos("'>")) + " visually select two inner blocks + call feedkeys("ViBiB\<C-C>", 'xt') + call assert_equal([0, 3, 1, 0], getpos("'<")) + call assert_equal([0, 7, 5, 0], getpos("'>")) + " try to select non-existing inner block + call cursor(5, 1) + call assert_beeps('normal ViBiBiB') + " try to select a unclosed inner block + 8,9d + call cursor(5, 1) + call assert_beeps('normal ViBiB') + close! +endfunc + func Test_visual_put_in_block() new call setline(1, ['xxxx', 'y∞yy', 'zzzz']) diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index 41b0cd874c..7decac2c36 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -34,7 +34,16 @@ func Test_window_cmd_cmdwin_with_vsp() set ls&vim endfunc -function Test_window_cmd_wincmd_gf() +" Test for jumping to windows +func Test_window_jump() + new + " jumping to a window with a count greater than the max windows + exe "normal 4\<C-W>w" + call assert_equal(2, winnr()) + only +endfunc + +func Test_window_cmd_wincmd_gf() let fname = 'test_gf.txt' let swp_fname = '.' . fname . '.swp' call writefile([], fname) @@ -1119,6 +1128,181 @@ func Test_window_resize() %bwipe! endfunc +" Test for adjusting the window width when a window is closed with some +" windows using 'winfixwidth' +func Test_window_width_adjust() + only + " Three vertical windows. Windows 1 and 2 have 'winfixwidth' set and close + " window 2. + wincmd v + vert resize 10 + set winfixwidth + wincmd v + set winfixwidth + wincmd c + call assert_inrange(10, 12, winwidth(1)) + " Three vertical windows. Windows 2 and 3 have 'winfixwidth' set and close + " window 3. + only + set winfixwidth + wincmd v + vert resize 10 + set winfixwidth + wincmd v + set nowinfixwidth + wincmd b + wincmd c + call assert_inrange(10, 12, winwidth(2)) + + new | only +endfunc + +" Test for jumping to a vertical/horizontal neighbor window based on the +" current cursor position +func Test_window_goto_neightbor() + %bw! + + " Vertical window movement + + " create the following window layout: + " +--+--+ + " |w1|w3| + " +--+ | + " |w2| | + " +--+--+ + " |w4 | + " +-----+ + new + vsplit + split + " vertically jump from w4 + wincmd b + call setline(1, repeat(' ', &columns)) + call cursor(1, 1) + wincmd k + call assert_equal(2, winnr()) + wincmd b + call cursor(1, &columns) + redraw! + wincmd k + call assert_equal(3, winnr()) + %bw! + + " create the following window layout: + " +--+--+--+ + " |w1|w2|w3| + " +--+--+--+ + " |w4 | + " +--------+ + new + vsplit + vsplit + wincmd b + call setline(1, repeat(' ', &columns)) + call cursor(1, 1) + wincmd k + call assert_equal(1, winnr()) + wincmd b + call cursor(1, &columns / 2) + redraw! + wincmd k + call assert_equal(2, winnr()) + wincmd b + call cursor(1, &columns) + redraw! + wincmd k + call assert_equal(3, winnr()) + %bw! + + " Horizontal window movement + + " create the following window layout: + " +--+--+--+ + " |w1|w2|w4| + " +--+--+ | + " |w3 | | + " +-----+--+ + vsplit + split + vsplit + 4wincmd l + call setline(1, repeat([' '], &lines)) + call cursor(1, 1) + redraw! + wincmd h + call assert_equal(2, winnr()) + 4wincmd l + call cursor(&lines, 1) + redraw! + wincmd h + call assert_equal(3, winnr()) + %bw! + + " create the following window layout: + " +--+--+ + " |w1|w4| + " +--+ + + " |w2| | + " +--+ + + " |w3| | + " +--+--+ + vsplit + split + split + wincmd l + call setline(1, repeat([' '], &lines)) + call cursor(1, 1) + redraw! + wincmd h + call assert_equal(1, winnr()) + wincmd l + call cursor(&lines / 2, 1) + redraw! + wincmd h + call assert_equal(2, winnr()) + wincmd l + call cursor(&lines, 1) + redraw! + wincmd h + call assert_equal(3, winnr()) + %bw! +endfunc + +" Test for an autocmd closing the destination window when jumping from one +" window to another. +func Test_close_dest_window() + split + edit Xfile + + " Test for BufLeave + augroup T1 + au! + au BufLeave Xfile $wincmd c + augroup END + wincmd b + call assert_equal(1, winnr('$')) + call assert_equal('Xfile', @%) + augroup T1 + au! + augroup END + + " Test for WinLeave + new + wincmd p + augroup T1 + au! + au WinLeave * 1wincmd c + augroup END + wincmd t + call assert_equal(1, winnr('$')) + call assert_equal('Xfile', @%) + augroup T1 + au! + augroup END + augroup! T1 + %bw! +endfunc + func Test_win_move_separator() edit a leftabove vsplit b diff --git a/src/nvim/window.c b/src/nvim/window.c index cf10e635b6..06231150d5 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1982,7 +1982,7 @@ void win_move_after(win_T *win1, win_T *win2) return; } - // may need move the status line, window bar, horizontal or vertical separator of the last + // may need to move the status line, window bar, horizontal or vertical separator of the last // window if (win1 == lastwin) { height = win1->w_prev->w_status_height; diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 989ed27e16..3724dbf820 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1469,6 +1469,17 @@ describe('API', function() nvim('win_set_option', win, 'number', true) eq(true, nvim('get_option_value', 'number', {win = win})) end) + + it('getting current buffer option does not adjust cursor #19381', function() + nvim('command', 'new') + local buf = nvim('get_current_buf').id + local win = nvim('get_current_win').id + insert('some text') + feed('0v$') + eq({1, 9}, nvim('win_get_cursor', win)) + nvim('get_option_value', 'filetype', {buf = buf}) + eq({1, 9}, nvim('win_get_cursor', win)) + end) end) describe('nvim_{get,set}_current_buf, nvim_list_bufs', function() @@ -3613,6 +3624,38 @@ describe('API', function() eq('Error while parsing command line: E464: Ambiguous use of user-defined command', pcall_err(meths.parse_cmd, 'F', {})) end) + it('does not interfere with printing line in Ex mode #19400', function() + local screen = Screen.new(60, 7) + screen:set_default_attr_ids({ + [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [1] = {bold = true, reverse = true}, -- MsgSeparator + }) + screen:attach() + insert([[ + foo + bar]]) + feed('gQ1') + screen:expect([[ + foo | + bar | + {0:~ }| + {0:~ }| + {1: }| + Entering Ex mode. Type "visual" to go to Normal mode. | + :1^ | + ]]) + eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {})) + feed('<CR>') + screen:expect([[ + foo | + bar | + {1: }| + Entering Ex mode. Type "visual" to go to Normal mode. | + :1 | + foo | + :^ | + ]]) + end) end) describe('nvim_cmd', function() it('works', function () diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index a6763ba3c7..04fbb807be 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -73,9 +73,16 @@ describe('jobs', function() nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) end - expect_msg_seq({ - {'notification', 'stdout', {0, {'hello world abc', ''}}}, - }) + expect_msg_seq( + { + {'notification', 'stdout', {0, {'hello world abc'}}}, + {'notification', 'stdout', {0, {'', ''}}}, + }, + { + {'notification', 'stdout', {0, {'hello world abc', ''}}}, + {'notification', 'stdout', {0, {''}}} + } + ) end) it('append environment with pty #env', function() @@ -89,9 +96,16 @@ describe('jobs', function() else nvim('command', [[call jobstart('echo $TOTO $VAR', g:job_opts)]]) end - expect_msg_seq({ - {'notification', 'stdout', {0, {'hello world abc', ''}}}, - }) + expect_msg_seq( + { + {'notification', 'stdout', {0, {'hello world abc'}}}, + {'notification', 'stdout', {0, {'', ''}}}, + }, + { + {'notification', 'stdout', {0, {'hello world abc', ''}}}, + {'notification', 'stdout', {0, {''}}} + } + ) end) it('replace environment #env', function() diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua new file mode 100644 index 0000000000..7fc5f11a79 --- /dev/null +++ b/test/functional/legacy/edit_spec.lua @@ -0,0 +1,26 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local command = helpers.command +local expect = helpers.expect +local feed = helpers.feed +local sleep = helpers.sleep + +before_each(clear) + +-- oldtest: Test_autoindent_remove_indent() +it('autoindent removes indent when Insert mode is stopped', function() + command('set autoindent') + -- leaving insert mode in a new line with indent added by autoindent, should + -- remove the indent. + feed('i<Tab>foo<CR><Esc>') + -- Need to delay for sometime, otherwise the code in getchar.c will not be + -- exercised. + sleep(50) + -- when a line is wrapped and the cursor is at the start of the second line, + -- leaving insert mode, should move the cursor back to the first line. + feed('o' .. ('x'):rep(20) .. '<Esc>') + -- Need to delay for sometime, otherwise the code in getchar.c will not be + -- exercised. + sleep(50) + expect('\tfoo\n\n' .. ('x'):rep(20)) +end) diff --git a/test/functional/legacy/messages_spec.lua b/test/functional/legacy/messages_spec.lua index 34807a099c..b296ac909d 100644 --- a/test/functional/legacy/messages_spec.lua +++ b/test/functional/legacy/messages_spec.lua @@ -8,39 +8,389 @@ local feed = helpers.feed before_each(clear) describe('messages', function() - it('more prompt with control characters can be quit vim-patch:8.2.1844', function() - local screen = Screen.new(40, 6) + local screen + + describe('more prompt', function() + before_each(function() + screen = Screen.new(75, 6) + screen:set_default_attr_ids({ + [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [2] = {foreground = Screen.colors.Brown}, -- LineNr + [3] = {foreground = Screen.colors.Blue}, -- SpecialKey + }) + screen:attach() + command('set more') + end) + + -- oldtest: Test_message_more() + it('works', function() + command('call setline(1, range(1, 100))') + + feed(':%p#\n') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {1:-- More --}^ | + ]]) + + feed('?') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {1:-- More -- SPACE/d/j: screen/page/line down, b/u/k: up, q: quit }^ | + ]]) + + -- Down a line with j, <CR>, <NL> or <Down>. + feed('j') + screen:expect([[ + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {2: 6 }6 | + {1:-- More --}^ | + ]]) + feed('<NL>') + screen:expect([[ + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {2: 6 }6 | + {2: 7 }7 | + {1:-- More --}^ | + ]]) + feed('<CR>') + screen:expect([[ + {2: 4 }4 | + {2: 5 }5 | + {2: 6 }6 | + {2: 7 }7 | + {2: 8 }8 | + {1:-- More --}^ | + ]]) + feed('<Down>') + screen:expect([[ + {2: 5 }5 | + {2: 6 }6 | + {2: 7 }7 | + {2: 8 }8 | + {2: 9 }9 | + {1:-- More --}^ | + ]]) + + -- Down a screen with <Space>, f, or <PageDown>. + feed('f') + screen:expect([[ + {2: 10 }10 | + {2: 11 }11 | + {2: 12 }12 | + {2: 13 }13 | + {2: 14 }14 | + {1:-- More --}^ | + ]]) + feed('<Space>') + screen:expect([[ + {2: 15 }15 | + {2: 16 }16 | + {2: 17 }17 | + {2: 18 }18 | + {2: 19 }19 | + {1:-- More --}^ | + ]]) + feed('<PageDown>') + screen:expect([[ + {2: 20 }20 | + {2: 21 }21 | + {2: 22 }22 | + {2: 23 }23 | + {2: 24 }24 | + {1:-- More --}^ | + ]]) + + -- Down a page (half a screen) with d. + feed('d') + screen:expect([[ + {2: 23 }23 | + {2: 24 }24 | + {2: 25 }25 | + {2: 26 }26 | + {2: 27 }27 | + {1:-- More --}^ | + ]]) + + -- Down all the way with 'G'. + feed('G') + screen:expect([[ + {2: 96 }96 | + {2: 97 }97 | + {2: 98 }98 | + {2: 99 }99 | + {2:100 }100 | + {1:Press ENTER or type command to continue}^ | + ]]) + + -- Up a line k, <BS> or <Up>. + feed('k') + screen:expect([[ + {2: 95 }95 | + {2: 96 }96 | + {2: 97 }97 | + {2: 98 }98 | + {2: 99 }99 | + {1:-- More --}^ | + ]]) + feed('<BS>') + screen:expect([[ + {2: 94 }94 | + {2: 95 }95 | + {2: 96 }96 | + {2: 97 }97 | + {2: 98 }98 | + {1:-- More --}^ | + ]]) + feed('<Up>') + screen:expect([[ + {2: 93 }93 | + {2: 94 }94 | + {2: 95 }95 | + {2: 96 }96 | + {2: 97 }97 | + {1:-- More --}^ | + ]]) + + -- Up a screen with b or <PageUp>. + feed('b') + screen:expect([[ + {2: 88 }88 | + {2: 89 }89 | + {2: 90 }90 | + {2: 91 }91 | + {2: 92 }92 | + {1:-- More --}^ | + ]]) + feed('<PageUp>') + screen:expect([[ + {2: 83 }83 | + {2: 84 }84 | + {2: 85 }85 | + {2: 86 }86 | + {2: 87 }87 | + {1:-- More --}^ | + ]]) + + -- Up a page (half a screen) with u. + feed('u') + screen:expect([[ + {2: 80 }80 | + {2: 81 }81 | + {2: 82 }82 | + {2: 83 }83 | + {2: 84 }84 | + {1:-- More --}^ | + ]]) + + -- Up all the way with 'g'. + feed('g') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {1:-- More --}^ | + ]]) + + -- All the way down. Pressing f should do nothing but pressing + -- space should end the more prompt. + feed('G') + screen:expect([[ + {2: 96 }96 | + {2: 97 }97 | + {2: 98 }98 | + {2: 99 }99 | + {2:100 }100 | + {1:Press ENTER or type command to continue}^ | + ]]) + feed('f') + screen:expect_unchanged() + feed('<Space>') + screen:expect([[ + 96 | + 97 | + 98 | + 99 | + ^100 | + | + ]]) + + -- Pressing g< shows the previous command output. + feed('g<lt>') + screen:expect([[ + {2: 96 }96 | + {2: 97 }97 | + {2: 98 }98 | + {2: 99 }99 | + {2:100 }100 | + {1:Press ENTER or type command to continue}^ | + ]]) + + feed(':%p#\n') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {1:-- More --}^ | + ]]) + + -- Stop command output with q, <Esc> or CTRL-C. + feed('q') + screen:expect([[ + 96 | + 97 | + 98 | + 99 | + ^100 | + | + ]]) + + -- Execute a : command from the more prompt + feed(':%p#\n') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + {1:-- More --}^ | + ]]) + feed(':') + screen:expect([[ + {2: 1 }1 | + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + :^ | + ]]) + feed("echo 'Hello'\n") + screen:expect([[ + {2: 2 }2 | + {2: 3 }3 | + {2: 4 }4 | + {2: 5 }5 | + Hello | + {1:Press ENTER or type command to continue}^ | + ]]) + end) + + -- oldtest: Test_quit_long_message() + it('with control characters can be quit vim-patch:8.2.1844', function() + screen:try_resize(40, 6) + feed([[:echom range(9999)->join("\x01")<CR>]]) + screen:expect([[ + 0{3:^A}1{3:^A}2{3:^A}3{3:^A}4{3:^A}5{3:^A}6{3:^A}7{3:^A}8{3:^A}9{3:^A}10{3:^A}11{3:^A}12| + {3:^A}13{3:^A}14{3:^A}15{3:^A}16{3:^A}17{3:^A}18{3:^A}19{3:^A}20{3:^A}21{3:^A}22| + {3:^A}23{3:^A}24{3:^A}25{3:^A}26{3:^A}27{3:^A}28{3:^A}29{3:^A}30{3:^A}31{3:^A}32| + {3:^A}33{3:^A}34{3:^A}35{3:^A}36{3:^A}37{3:^A}38{3:^A}39{3:^A}40{3:^A}41{3:^A}42| + {3:^A}43{3:^A}44{3:^A}45{3:^A}46{3:^A}47{3:^A}48{3:^A}49{3:^A}50{3:^A}51{3:^A}52| + {1:-- More --}^ | + ]]) + feed('q') + screen:expect([[ + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + end) + + -- oldtest: Test_ask_yesno() + it('y/n prompt works', function() + screen = Screen.new(75, 6) screen:set_default_attr_ids({ - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg - [3] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [1] = {bold = true, foreground = Screen.colors.SeaGreen}, -- MoreMsg + [2] = {bold = true, reverse = true}, -- MsgSeparator }) screen:attach() - command('set more') - feed([[:echom range(9999)->join("\x01")<CR>]]) + command('set noincsearch nohlsearch inccommand=') + command('call setline(1, range(1, 2))') + + feed(':2,1s/^/n/\n') + screen:expect([[ + 1 | + 2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}^ | + ]]) + feed('n') + screen:expect([[ + ^1 | + 2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}n | + ]]) + + feed(':2,1s/^/Esc/\n') + screen:expect([[ + 1 | + 2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}^ | + ]]) + feed('<Esc>') + screen:expect([[ + ^1 | + 2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}n | + ]]) + + feed(':2,1s/^/y/\n') screen:expect([[ - 0{1:^A}1{1:^A}2{1:^A}3{1:^A}4{1:^A}5{1:^A}6{1:^A}7{1:^A}8{1:^A}9{1:^A}10{1:^A}11{1:^A}12| - {1:^A}13{1:^A}14{1:^A}15{1:^A}16{1:^A}17{1:^A}18{1:^A}19{1:^A}20{1:^A}21{1:^A}22| - {1:^A}23{1:^A}24{1:^A}25{1:^A}26{1:^A}27{1:^A}28{1:^A}29{1:^A}30{1:^A}31{1:^A}32| - {1:^A}33{1:^A}34{1:^A}35{1:^A}36{1:^A}37{1:^A}38{1:^A}39{1:^A}40{1:^A}41{1:^A}42| - {1:^A}43{1:^A}44{1:^A}45{1:^A}46{1:^A}47{1:^A}48{1:^A}49{1:^A}50{1:^A}51{1:^A}52| - {2:-- More --}^ | + 1 | + 2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}^ | ]]) - feed('q') + feed('y') screen:expect([[ - ^ | - {3:~ }| - {3:~ }| - {3:~ }| - {3:~ }| - | + y1 | + ^y2 | + {0:~ }| + {0:~ }| + {0:~ }| + {1:Backwards range given, OK to swap (y/n)?}y | ]]) end) + -- oldtest: Test_fileinfo_after_echo() it('fileinfo does not overwrite echo message vim-patch:8.2.4156', function() - local screen = Screen.new(40, 6) + screen = Screen.new(40, 6) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue}, -- NonText + [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText }) screen:attach() exec([[ @@ -60,10 +410,10 @@ describe('messages', function() feed('0$') screen:expect([[ ^hi | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| 'b' written | ]]) os.remove('b.txt') diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua index 82f856e4df..346a64c63b 100644 --- a/test/functional/ui/options_spec.lua +++ b/test/functional/ui/options_spec.lua @@ -87,6 +87,12 @@ describe('UI receives option updates', function() eq(expected, screen.options) end) + command("set pumblend=-1") + expected.pumblend = 0 + screen:expect(function() + eq(expected, screen.options) + end) + command("set guifont=Comic\\ Sans") expected.guifont = "Comic Sans" screen:expect(function() diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 39753cca5b..0cd991756c 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2427,6 +2427,34 @@ describe('builtin popupmenu', function() :let g:menustr = 'baz' | ]]) eq('baz', meths.get_var('menustr')) + meths.input_mouse('right', 'press', '', 0, 0, 4) + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + :let g:menustr = 'baz' | + ]]) + meths.input_mouse('right', 'drag', '', 0, 3, 6) + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{s: baz }{1: }| + {1:~ }| + :let g:menustr = 'baz' | + ]]) + meths.input_mouse('right', 'release', '', 0, 1, 6) + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :let g:menustr = 'foo' | + ]]) + eq('foo', meths.get_var('menustr')) end) end) @@ -2571,5 +2599,68 @@ describe('builtin popupmenu with ui/ext_multigrid', function() :let g:menustr = 'baz' | ]]}) eq('baz', meths.get_var('menustr')) + meths.input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + meths.input_mouse('right', 'drag', '', 2, 3, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 4 + {n: foo }| + {n: bar }| + {s: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + meths.input_mouse('right', 'release', '', 2, 1, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ]]}) + eq('foo', meths.get_var('menustr')) end) end) diff --git a/test/functional/ui/statusline_spec.lua b/test/functional/ui/statusline_spec.lua index 2733b9dd4a..82e669856f 100644 --- a/test/functional/ui/statusline_spec.lua +++ b/test/functional/ui/statusline_spec.lua @@ -20,7 +20,12 @@ describe('statusline clicks', function() command('set laststatus=2') exec([=[ function! MyClickFunc(minwid, clicks, button, mods) - let g:testvar = printf("%d %d %s", a:minwid, a:clicks, a:button) + let mods = trim(a:mods) + if mods ==# '' + let g:testvar = printf("%d %d %s", a:minwid, a:clicks, a:button) + else + let g:testvar = printf("%d %d %s %s", a:minwid, a:clicks, a:button, mods) + endif endfunction ]=]) end) @@ -37,7 +42,7 @@ describe('statusline clicks', function() meths.set_option('winbar', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T') meths.input_mouse('left', 'press', '', 0, 0, 17) eq('0 1 l', eval("g:testvar")) - meths.input_mouse('right', 'press', '', 0, 6, 17) + meths.input_mouse('right', 'press', '', 0, 0, 17) eq('0 1 r', eval("g:testvar")) end) @@ -84,6 +89,22 @@ describe('statusline clicks', function() meths.input_mouse('left', 'press', '', 0, 6, 0) eq(2, #meths.list_tabpages()) end) + + it("right click works when statusline isn't focused #18994", function() + meths.set_option('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T') + meths.input_mouse('right', 'press', '', 0, 6, 17) + eq('0 1 r', eval("g:testvar")) + meths.input_mouse('right', 'press', '', 0, 6, 17) + eq('0 2 r', eval("g:testvar")) + end) + + it("click works with modifiers #18994", function() + meths.set_option('statusline', 'Not clicky stuff %0@MyClickFunc@Clicky stuff%T') + meths.input_mouse('right', 'press', 's', 0, 6, 17) + eq('0 1 r s', eval("g:testvar")) + meths.input_mouse('left', 'press', 's', 0, 6, 17) + eq('0 1 l s', eval("g:testvar")) + end) end) describe('global statusline', function() diff --git a/test/functional/vimscript/let_spec.lua b/test/functional/vimscript/let_spec.lua index 85c9c690f9..ca1b5e8907 100644 --- a/test/functional/vimscript/let_spec.lua +++ b/test/functional/vimscript/let_spec.lua @@ -5,6 +5,7 @@ local clear = helpers.clear local command = helpers.command local eval = helpers.eval local meths = helpers.meths +local exec = helpers.exec local exec_capture = helpers.exec_capture local source = helpers.source local testprg = helpers.testprg @@ -91,3 +92,19 @@ describe(':let', function() eq(1, eval('1')) end) end) + +describe(':let and :const', function() + it('have the same output when called without arguments', function() + eq(exec_capture('let'), exec_capture('const')) + end) + + it('can be used in sandbox', function() + exec([[ + func Func() + let l:foo = 'foo' + const l:bar = 'bar' + endfunc + sandbox call Func() + ]]) + end) +end) |