From 2eae5db069dc171f74cd863487655f6a88e5384d Mon Sep 17 00:00:00 2001 From: Mehmet Samet Duman Date: Fri, 3 Apr 2026 22:21:25 +0300 Subject: NOISSUE rebrand vim to MNV's not Vim Signed-off-by: Mehmet Samet Duman --- uvim/src/testdir/Make_all.mak | 80 +- uvim/src/testdir/Make_amiga.mak | 10 +- uvim/src/testdir/Make_ming.mak | 62 +- uvim/src/testdir/Make_mvc.mak | 72 +- uvim/src/testdir/Make_vms.mms | 18 +- uvim/src/testdir/Makefile | 102 +- uvim/src/testdir/README.txt | 38 +- uvim/src/testdir/commondumps.mnv | 229 + uvim/src/testdir/commondumps.vim | 229 - uvim/src/testdir/crash/crash_scrollbar | 4 +- uvim/src/testdir/crash/mnv_msg_trunc_poc | 1 + uvim/src/testdir/crash/mnv_regsub_both | 10 + uvim/src/testdir/crash/mnv_regsub_both_poc | Bin 0 -> 244 bytes uvim/src/testdir/crash/poc_tagfunc.mnv | 6 + uvim/src/testdir/crash/poc_tagfunc.vim | 6 - uvim/src/testdir/crash/vim_msg_trunc_poc | 1 - uvim/src/testdir/crash/vim_regsub_both | 10 - uvim/src/testdir/crash/vim_regsub_both_poc | Bin 244 -> 0 bytes .../testdir/dumps/Test_incsearch_mnvgrep_01.dump | 9 + .../testdir/dumps/Test_incsearch_mnvgrep_02.dump | 9 + .../testdir/dumps/Test_incsearch_mnvgrep_03.dump | 9 + .../testdir/dumps/Test_incsearch_mnvgrep_04.dump | 9 + .../testdir/dumps/Test_incsearch_mnvgrep_05.dump | 9 + .../testdir/dumps/Test_incsearch_vimgrep_01.dump | 9 - .../testdir/dumps/Test_incsearch_vimgrep_02.dump | 9 - .../testdir/dumps/Test_incsearch_vimgrep_03.dump | 9 - .../testdir/dumps/Test_incsearch_vimgrep_04.dump | 9 - .../testdir/dumps/Test_incsearch_vimgrep_05.dump | 9 - .../src/testdir/dumps/Test_mnv9_closure_fails.dump | 6 + uvim/src/testdir/dumps/Test_mnv9_no_redraw.dump | 6 + .../dumps/Test_mnv9_reject_declaration_1.dump | 6 + .../dumps/Test_mnv9_reject_declaration_2.dump | 6 + uvim/src/testdir/dumps/Test_mnv9_silent_echo.dump | 6 + uvim/src/testdir/dumps/Test_popup_setbuf_04.mnv | 4 + uvim/src/testdir/dumps/Test_popup_setbuf_04.vim | 4 - uvim/src/testdir/dumps/Test_popup_setbuf_05.mnv | 4 + uvim/src/testdir/dumps/Test_popup_setbuf_05.vim | 4 - uvim/src/testdir/dumps/Test_popup_setbuf_06.mnv | 4 + uvim/src/testdir/dumps/Test_popup_setbuf_06.vim | 4 - .../dumps/Test_termdebug_evaluate_in_popup_01.mnv | 9 + .../dumps/Test_termdebug_evaluate_in_popup_01.vim | 9 - .../dumps/Test_termdebug_evaluate_in_popup_02.mnv | 6 + .../dumps/Test_termdebug_evaluate_in_popup_02.vim | 6 - uvim/src/testdir/dumps/Test_undo_after_write_1.mnv | 2 + uvim/src/testdir/dumps/Test_undo_after_write_1.vim | 2 - uvim/src/testdir/dumps/Test_undo_after_write_2.mnv | 2 + uvim/src/testdir/dumps/Test_undo_after_write_2.vim | 2 - uvim/src/testdir/dumps/Test_verbose_system_1.mnv | 5 + uvim/src/testdir/dumps/Test_verbose_system_1.vim | 5 - uvim/src/testdir/dumps/Test_verbose_system_2.mnv | 5 + uvim/src/testdir/dumps/Test_verbose_system_2.vim | 5 - .../src/testdir/dumps/Test_vim9_closure_fails.dump | 6 - uvim/src/testdir/dumps/Test_vim9_no_redraw.dump | 6 - .../dumps/Test_vim9_reject_declaration_1.dump | 6 - .../dumps/Test_vim9_reject_declaration_2.dump | 6 - uvim/src/testdir/dumps/Test_vim9_silent_echo.dump | 6 - uvim/src/testdir/dumps/Test_xxd_color_0.mnv | 2 + uvim/src/testdir/dumps/Test_xxd_color_0.vim | 2 - uvim/src/testdir/dumps/Test_xxd_color_1.mnv | 2 + uvim/src/testdir/dumps/Test_xxd_color_1.vim | 2 - uvim/src/testdir/keycode_check.mnv | 471 + uvim/src/testdir/keycode_check.vim | 471 - uvim/src/testdir/runtest.mnv | 691 ++ uvim/src/testdir/runtest.vim | 691 -- uvim/src/testdir/samples/Test_tohtml_basic.c.html | 10 +- .../samples/Test_tohtml_basic_no_css.c.html | 8 +- uvim/src/testdir/samples/matchparen.mnv | 234 + uvim/src/testdir/samples/matchparen.vim | 234 - uvim/src/testdir/samples/re.freeze.txt | 2 +- uvim/src/testdir/sautest/autoload/Test104.mnv | 1 + uvim/src/testdir/sautest/autoload/Test104.vim | 1 - uvim/src/testdir/sautest/autoload/auto9.mnv | 9 + uvim/src/testdir/sautest/autoload/auto9.vim | 9 - uvim/src/testdir/sautest/autoload/foo.mnv | 15 + uvim/src/testdir/sautest/autoload/foo.vim | 15 - uvim/src/testdir/sautest/autoload/footest.mnv | 5 + uvim/src/testdir/sautest/autoload/footest.vim | 5 - uvim/src/testdir/sautest/autoload/globone.mnv | 1 + uvim/src/testdir/sautest/autoload/globone.vim | 1 - uvim/src/testdir/sautest/autoload/globtwo.mnv | 1 + uvim/src/testdir/sautest/autoload/globtwo.vim | 1 - uvim/src/testdir/sautest/autoload/sourced.mnv | 4 + uvim/src/testdir/sautest/autoload/sourced.vim | 4 - uvim/src/testdir/test10.in | 8 +- uvim/src/testdir/test29.in | 2 +- uvim/src/testdir/test_alot.mnv | 31 + uvim/src/testdir/test_alot.vim | 31 - uvim/src/testdir/test_alot_latin.mnv | 7 + uvim/src/testdir/test_alot_latin.vim | 7 - uvim/src/testdir/test_alot_utf8.mnv | 14 + uvim/src/testdir/test_alot_utf8.vim | 14 - uvim/src/testdir/test_arabic.mnv | 592 + uvim/src/testdir/test_arabic.vim | 592 - uvim/src/testdir/test_arglist.mnv | 821 ++ uvim/src/testdir/test_arglist.vim | 821 -- uvim/src/testdir/test_assert.mnv | 527 + uvim/src/testdir/test_assert.vim | 527 - uvim/src/testdir/test_autochdir.mnv | 120 + uvim/src/testdir/test_autochdir.vim | 120 - uvim/src/testdir/test_autocmd.mnv | 5970 ++++++++++ uvim/src/testdir/test_autocmd.vim | 5970 ---------- uvim/src/testdir/test_autoload.mnv | 29 + uvim/src/testdir/test_autoload.vim | 29 - uvim/src/testdir/test_backspace_opt.mnv | 169 + uvim/src/testdir/test_backspace_opt.vim | 169 - uvim/src/testdir/test_backup.mnv | 86 + uvim/src/testdir/test_backup.vim | 86 - uvim/src/testdir/test_balloon.mnv | 97 + uvim/src/testdir/test_balloon.vim | 97 - uvim/src/testdir/test_balloon_gui.mnv | 20 + uvim/src/testdir/test_balloon_gui.vim | 20 - uvim/src/testdir/test_behave.mnv | 31 + uvim/src/testdir/test_behave.vim | 31 - uvim/src/testdir/test_bench_regexp.mnv | 23 + uvim/src/testdir/test_bench_regexp.vim | 23 - uvim/src/testdir/test_blob.mnv | 941 ++ uvim/src/testdir/test_blob.vim | 941 -- uvim/src/testdir/test_blockedit.mnv | 134 + uvim/src/testdir/test_blockedit.vim | 134 - uvim/src/testdir/test_breakindent.mnv | 1232 ++ uvim/src/testdir/test_breakindent.vim | 1232 -- uvim/src/testdir/test_buffer.mnv | 916 ++ uvim/src/testdir/test_buffer.vim | 916 -- uvim/src/testdir/test_bufline.mnv | 339 + uvim/src/testdir/test_bufline.vim | 339 - uvim/src/testdir/test_bufwintabinfo.mnv | 230 + uvim/src/testdir/test_bufwintabinfo.vim | 230 - uvim/src/testdir/test_cd.mnv | 423 + uvim/src/testdir/test_cd.vim | 423 - uvim/src/testdir/test_cdo.mnv | 215 + uvim/src/testdir/test_cdo.vim | 215 - uvim/src/testdir/test_changedtick.mnv | 97 + uvim/src/testdir/test_changedtick.vim | 97 - uvim/src/testdir/test_changelist.mnv | 105 + uvim/src/testdir/test_changelist.vim | 105 - uvim/src/testdir/test_channel.mnv | 2946 +++++ uvim/src/testdir/test_channel.py | 10 +- uvim/src/testdir/test_channel.vim | 2946 ----- uvim/src/testdir/test_channel_6.py | 4 +- uvim/src/testdir/test_channel_dap.py | 2 +- uvim/src/testdir/test_channel_lsp.py | 6 +- uvim/src/testdir/test_channel_unix.py | 4 +- uvim/src/testdir/test_charsearch.mnv | 100 + uvim/src/testdir/test_charsearch.vim | 100 - uvim/src/testdir/test_charsearch_utf8.mnv | 26 + uvim/src/testdir/test_charsearch_utf8.vim | 26 - uvim/src/testdir/test_checkpath.mnv | 116 + uvim/src/testdir/test_checkpath.vim | 116 - uvim/src/testdir/test_cindent.mnv | 5530 +++++++++ uvim/src/testdir/test_cindent.vim | 5530 --------- uvim/src/testdir/test_cjk_linebreak.mnv | 101 + uvim/src/testdir/test_cjk_linebreak.vim | 101 - uvim/src/testdir/test_clientserver.mnv | 366 + uvim/src/testdir/test_clientserver.vim | 366 - uvim/src/testdir/test_clipmethod.mnv | 228 + uvim/src/testdir/test_clipmethod.vim | 228 - uvim/src/testdir/test_close_count.mnv | 176 + uvim/src/testdir/test_close_count.vim | 176 - uvim/src/testdir/test_cmd_lists.mnv | 70 + uvim/src/testdir/test_cmd_lists.vim | 70 - uvim/src/testdir/test_cmdline.mnv | 5393 +++++++++ uvim/src/testdir/test_cmdline.vim | 5393 --------- uvim/src/testdir/test_cmdmods.mnv | 95 + uvim/src/testdir/test_cmdmods.vim | 95 - uvim/src/testdir/test_cmdwin.mnv | 614 + uvim/src/testdir/test_cmdwin.vim | 614 - uvim/src/testdir/test_codestyle.mnv | 198 + uvim/src/testdir/test_codestyle.vim | 198 - uvim/src/testdir/test_command_count.mnv | 198 + uvim/src/testdir/test_command_count.vim | 198 - uvim/src/testdir/test_comments.mnv | 283 + uvim/src/testdir/test_comments.vim | 283 - uvim/src/testdir/test_comparators.mnv | 13 + uvim/src/testdir/test_comparators.vim | 13 - uvim/src/testdir/test_compiler.mnv | 768 ++ uvim/src/testdir/test_compiler.vim | 768 -- uvim/src/testdir/test_conceal.mnv | 683 ++ uvim/src/testdir/test_conceal.vim | 683 -- uvim/src/testdir/test_const.mnv | 335 + uvim/src/testdir/test_const.vim | 335 - uvim/src/testdir/test_cpoptions.mnv | 956 ++ uvim/src/testdir/test_cpoptions.vim | 956 -- uvim/src/testdir/test_crash.mnv | 282 + uvim/src/testdir/test_crash.vim | 282 - uvim/src/testdir/test_crypt.mnv | 494 + uvim/src/testdir/test_crypt.vim | 494 - uvim/src/testdir/test_cscope.mnv | 336 + uvim/src/testdir/test_cscope.vim | 336 - uvim/src/testdir/test_cursor_func.mnv | 628 + uvim/src/testdir/test_cursor_func.vim | 628 - uvim/src/testdir/test_cursorline.mnv | 368 + uvim/src/testdir/test_cursorline.vim | 368 - uvim/src/testdir/test_curswant.mnv | 68 + uvim/src/testdir/test_curswant.vim | 68 - uvim/src/testdir/test_debugger.mnv | 1569 +++ uvim/src/testdir/test_debugger.vim | 1569 --- uvim/src/testdir/test_delete.mnv | 132 + uvim/src/testdir/test_delete.vim | 132 - uvim/src/testdir/test_diffmode.mnv | 3634 ++++++ uvim/src/testdir/test_diffmode.vim | 3631 ------ uvim/src/testdir/test_digraph.mnv | 627 + uvim/src/testdir/test_digraph.vim | 627 - uvim/src/testdir/test_display.mnv | 695 ++ uvim/src/testdir/test_display.vim | 695 -- uvim/src/testdir/test_edit.mnv | 2460 ++++ uvim/src/testdir/test_edit.vim | 2460 ---- uvim/src/testdir/test_environ.mnv | 87 + uvim/src/testdir/test_environ.vim | 87 - uvim/src/testdir/test_erasebackword.mnv | 22 + uvim/src/testdir/test_erasebackword.vim | 22 - uvim/src/testdir/test_escaped_glob.mnv | 33 + uvim/src/testdir/test_escaped_glob.vim | 33 - uvim/src/testdir/test_eval_stuff.mnv | 1306 ++ uvim/src/testdir/test_eval_stuff.vim | 1306 -- uvim/src/testdir/test_ex_equal.mnv | 34 + uvim/src/testdir/test_ex_equal.vim | 34 - uvim/src/testdir/test_ex_mode.mnv | 408 + uvim/src/testdir/test_ex_mode.vim | 403 - uvim/src/testdir/test_ex_undo.mnv | 21 + uvim/src/testdir/test_ex_undo.vim | 21 - uvim/src/testdir/test_ex_z.mnv | 117 + uvim/src/testdir/test_ex_z.vim | 117 - uvim/src/testdir/test_excmd.mnv | 763 ++ uvim/src/testdir/test_excmd.vim | 763 -- uvim/src/testdir/test_exec_while_if.mnv | 43 + uvim/src/testdir/test_exec_while_if.vim | 43 - uvim/src/testdir/test_execute_func.mnv | 228 + uvim/src/testdir/test_execute_func.vim | 228 - uvim/src/testdir/test_exists.mnv | 393 + uvim/src/testdir/test_exists.vim | 393 - uvim/src/testdir/test_exists_autocmd.mnv | 28 + uvim/src/testdir/test_exists_autocmd.vim | 28 - uvim/src/testdir/test_exit.mnv | 153 + uvim/src/testdir/test_exit.vim | 153 - uvim/src/testdir/test_expand.mnv | 234 + uvim/src/testdir/test_expand.vim | 234 - uvim/src/testdir/test_expand_dllpath.mnv | 36 + uvim/src/testdir/test_expand_dllpath.vim | 36 - uvim/src/testdir/test_expand_func.mnv | 149 + uvim/src/testdir/test_expand_func.vim | 149 - uvim/src/testdir/test_expr.mnv | 1119 ++ uvim/src/testdir/test_expr.vim | 1119 -- uvim/src/testdir/test_expr_utf8.mnv | 44 + uvim/src/testdir/test_expr_utf8.vim | 44 - uvim/src/testdir/test_file_perm.mnv | 29 + uvim/src/testdir/test_file_perm.vim | 29 - uvim/src/testdir/test_file_size.mnv | 59 + uvim/src/testdir/test_file_size.vim | 59 - uvim/src/testdir/test_filechanged.mnv | 305 + uvim/src/testdir/test_filechanged.vim | 305 - uvim/src/testdir/test_filecopy.mnv | 69 + uvim/src/testdir/test_filecopy.vim | 69 - uvim/src/testdir/test_fileformat.mnv | 325 + uvim/src/testdir/test_fileformat.vim | 325 - uvim/src/testdir/test_filetype.mnv | 3416 ++++++ uvim/src/testdir/test_filetype.vim | 3416 ------ uvim/src/testdir/test_filter_cmd.mnv | 197 + uvim/src/testdir/test_filter_cmd.vim | 197 - uvim/src/testdir/test_filter_map.mnv | 410 + uvim/src/testdir/test_filter_map.vim | 410 - uvim/src/testdir/test_find_complete.mnv | 164 + uvim/src/testdir/test_find_complete.vim | 164 - uvim/src/testdir/test_findfile.mnv | 869 ++ uvim/src/testdir/test_findfile.vim | 869 -- uvim/src/testdir/test_fixeol.mnv | 118 + uvim/src/testdir/test_fixeol.vim | 118 - uvim/src/testdir/test_flatten.mnv | 109 + uvim/src/testdir/test_flatten.vim | 109 - uvim/src/testdir/test_float_func.mnv | 388 + uvim/src/testdir/test_float_func.vim | 388 - uvim/src/testdir/test_fnameescape.mnv | 27 + uvim/src/testdir/test_fnameescape.vim | 27 - uvim/src/testdir/test_fnamemodify.mnv | 108 + uvim/src/testdir/test_fnamemodify.vim | 108 - uvim/src/testdir/test_fold.mnv | 2109 ++++ uvim/src/testdir/test_fold.vim | 2108 ---- uvim/src/testdir/test_format.mnv | 404 + uvim/src/testdir/test_format.vim | 404 - uvim/src/testdir/test_function_lists.mnv | 107 + uvim/src/testdir/test_function_lists.vim | 107 - uvim/src/testdir/test_functions.mnv | 4629 ++++++++ uvim/src/testdir/test_functions.vim | 4629 -------- uvim/src/testdir/test_ga.mnv | 44 + uvim/src/testdir/test_ga.vim | 44 - uvim/src/testdir/test_getcwd.mnv | 268 + uvim/src/testdir/test_getcwd.vim | 268 - uvim/src/testdir/test_gettext.mnv | 20 + uvim/src/testdir/test_gettext.vim | 20 - uvim/src/testdir/test_gettext_cp1251.mnv | 34 + uvim/src/testdir/test_gettext_cp1251.vim | 34 - uvim/src/testdir/test_gettext_make.mnv | 72 + uvim/src/testdir/test_gettext_make.vim | 72 - uvim/src/testdir/test_gettext_makefile_in1.mnv | 7 + uvim/src/testdir/test_gettext_makefile_in1.vim | 7 - uvim/src/testdir/test_gettext_makefile_in2.mnv | 6 + uvim/src/testdir/test_gettext_makefile_in2.vim | 6 - uvim/src/testdir/test_gettext_makefile_in3.mnv | 4 + uvim/src/testdir/test_gettext_makefile_in3.vim | 4 - uvim/src/testdir/test_gettext_makefile_in4.mnv | 6 + uvim/src/testdir/test_gettext_makefile_in4.vim | 6 - uvim/src/testdir/test_gettext_utf8.mnv | 48 + uvim/src/testdir/test_gettext_utf8.vim | 48 - uvim/src/testdir/test_getvar.mnv | 182 + uvim/src/testdir/test_getvar.vim | 182 - uvim/src/testdir/test_gf.mnv | 388 + uvim/src/testdir/test_gf.vim | 388 - uvim/src/testdir/test_glob2regpat.mnv | 35 + uvim/src/testdir/test_glob2regpat.vim | 35 - uvim/src/testdir/test_global.mnv | 156 + uvim/src/testdir/test_global.vim | 156 - uvim/src/testdir/test_gn.mnv | 221 + uvim/src/testdir/test_gn.vim | 221 - uvim/src/testdir/test_goto.mnv | 449 + uvim/src/testdir/test_goto.vim | 449 - uvim/src/testdir/test_gui.mnv | 1892 +++ uvim/src/testdir/test_gui.vim | 1892 --- uvim/src/testdir/test_gui_init.mnv | 44 + uvim/src/testdir/test_gui_init.vim | 44 - uvim/src/testdir/test_hardcopy.mnv | 237 + uvim/src/testdir/test_hardcopy.vim | 237 - uvim/src/testdir/test_help.mnv | 292 + uvim/src/testdir/test_help.vim | 292 - uvim/src/testdir/test_help_tagjump.mnv | 318 + uvim/src/testdir/test_help_tagjump.vim | 318 - uvim/src/testdir/test_hide.mnv | 97 + uvim/src/testdir/test_hide.vim | 97 - uvim/src/testdir/test_highlight.mnv | 1683 +++ uvim/src/testdir/test_highlight.vim | 1683 --- uvim/src/testdir/test_history.mnv | 318 + uvim/src/testdir/test_history.vim | 318 - uvim/src/testdir/test_hlsearch.mnv | 114 + uvim/src/testdir/test_hlsearch.vim | 114 - uvim/src/testdir/test_iminsert.mnv | 324 + uvim/src/testdir/test_iminsert.vim | 324 - uvim/src/testdir/test_increment.mnv | 950 ++ uvim/src/testdir/test_increment.vim | 950 -- uvim/src/testdir/test_increment_dbcs.mnv | 28 + uvim/src/testdir/test_increment_dbcs.vim | 28 - uvim/src/testdir/test_indent.mnv | 387 + uvim/src/testdir/test_indent.vim | 387 - uvim/src/testdir/test_input.mnv | 111 + uvim/src/testdir/test_input.vim | 111 - uvim/src/testdir/test_ins_complete.mnv | 6292 ++++++++++ uvim/src/testdir/test_ins_complete.vim | 6292 ---------- uvim/src/testdir/test_ins_complete_no_halt.mnv | 51 + uvim/src/testdir/test_ins_complete_no_halt.vim | 51 - uvim/src/testdir/test_interrupt.mnv | 32 + uvim/src/testdir/test_interrupt.vim | 32 - uvim/src/testdir/test_job_fails.mnv | 15 + uvim/src/testdir/test_job_fails.vim | 15 - uvim/src/testdir/test_join.mnv | 448 + uvim/src/testdir/test_join.vim | 448 - uvim/src/testdir/test_json.mnv | 391 + uvim/src/testdir/test_json.vim | 391 - uvim/src/testdir/test_jumplist.mnv | 199 + uvim/src/testdir/test_jumplist.vim | 199 - uvim/src/testdir/test_lambda.mnv | 383 + uvim/src/testdir/test_lambda.vim | 383 - uvim/src/testdir/test_langmap.mnv | 88 + uvim/src/testdir/test_langmap.vim | 88 - uvim/src/testdir/test_largefile.mnv | 31 + uvim/src/testdir/test_largefile.vim | 31 - uvim/src/testdir/test_let.mnv | 868 ++ uvim/src/testdir/test_let.vim | 868 -- uvim/src/testdir/test_lineending.mnv | 22 + uvim/src/testdir/test_lineending.vim | 22 - uvim/src/testdir/test_lispindent.mnv | 129 + uvim/src/testdir/test_lispindent.vim | 129 - uvim/src/testdir/test_listchars.mnv | 859 ++ uvim/src/testdir/test_listchars.vim | 859 -- uvim/src/testdir/test_listdict.mnv | 2131 ++++ uvim/src/testdir/test_listdict.vim | 2131 ---- uvim/src/testdir/test_listener.mnv | 804 ++ uvim/src/testdir/test_listener.vim | 804 -- uvim/src/testdir/test_listlbr.mnv | 388 + uvim/src/testdir/test_listlbr.vim | 388 - uvim/src/testdir/test_listlbr_utf8.mnv | 388 + uvim/src/testdir/test_listlbr_utf8.vim | 388 - uvim/src/testdir/test_lua.mnv | 1281 ++ uvim/src/testdir/test_lua.vim | 1281 -- uvim/src/testdir/test_makeencoding.mnv | 117 + uvim/src/testdir/test_makeencoding.vim | 117 - uvim/src/testdir/test_map_functions.mnv | 651 + uvim/src/testdir/test_map_functions.vim | 651 - uvim/src/testdir/test_mapping.mnv | 1953 +++ uvim/src/testdir/test_mapping.vim | 1953 --- uvim/src/testdir/test_marks.mnv | 326 + uvim/src/testdir/test_marks.vim | 326 - uvim/src/testdir/test_match.mnv | 441 + uvim/src/testdir/test_match.vim | 441 - uvim/src/testdir/test_matchadd_conceal.mnv | 444 + uvim/src/testdir/test_matchadd_conceal.vim | 444 - uvim/src/testdir/test_matchadd_conceal_utf8.mnv | 44 + uvim/src/testdir/test_matchadd_conceal_utf8.vim | 44 - uvim/src/testdir/test_matchfuzzy.mnv | 325 + uvim/src/testdir/test_matchfuzzy.vim | 325 - uvim/src/testdir/test_memory_usage.mnv | 162 + uvim/src/testdir/test_memory_usage.vim | 162 - uvim/src/testdir/test_menu.mnv | 659 + uvim/src/testdir/test_menu.vim | 659 - uvim/src/testdir/test_messages.mnv | 838 ++ uvim/src/testdir/test_messages.vim | 838 -- uvim/src/testdir/test_method.mnv | 180 + uvim/src/testdir/test_method.vim | 180 - uvim/src/testdir/test_mksession.mnv | 1334 +++ uvim/src/testdir/test_mksession.vim | 1334 --- uvim/src/testdir/test_mksession_utf8.mnv | 142 + uvim/src/testdir/test_mksession_utf8.vim | 142 - uvim/src/testdir/test_mnv9_assign.mnv | 3935 ++++++ uvim/src/testdir/test_mnv9_builtin.mnv | 5420 +++++++++ uvim/src/testdir/test_mnv9_class.mnv | 11872 +++++++++++++++++++ uvim/src/testdir/test_mnv9_cmd.mnv | 2131 ++++ uvim/src/testdir/test_mnv9_disassemble.mnv | 4097 +++++++ uvim/src/testdir/test_mnv9_enum.mnv | 1682 +++ uvim/src/testdir/test_mnv9_expr.mnv | 4490 +++++++ uvim/src/testdir/test_mnv9_fails.mnv | 60 + uvim/src/testdir/test_mnv9_func.mnv | 4867 ++++++++ uvim/src/testdir/test_mnv9_generics.mnv | 3577 ++++++ uvim/src/testdir/test_mnv9_import.mnv | 3722 ++++++ uvim/src/testdir/test_mnv9_interface.mnv | 1459 +++ uvim/src/testdir/test_mnv9_python3.mnv | 16 + uvim/src/testdir/test_mnv9_script.mnv | 5828 +++++++++ uvim/src/testdir/test_mnv9_typealias.mnv | 927 ++ uvim/src/testdir/test_mnvinfo.mnv | 1394 +++ uvim/src/testdir/test_mnvscript.mnv | 7708 ++++++++++++ uvim/src/testdir/test_modeless.mnv | 418 + uvim/src/testdir/test_modeless.vim | 418 - uvim/src/testdir/test_modeline.mnv | 496 + uvim/src/testdir/test_modeline.vim | 496 - uvim/src/testdir/test_move.mnv | 70 + uvim/src/testdir/test_move.vim | 70 - uvim/src/testdir/test_mswin_event.mnv | 1021 ++ uvim/src/testdir/test_mswin_event.vim | 1021 -- uvim/src/testdir/test_mzscheme.mnv | 61 + uvim/src/testdir/test_mzscheme.vim | 61 - uvim/src/testdir/test_nested_function.mnv | 68 + uvim/src/testdir/test_nested_function.vim | 68 - uvim/src/testdir/test_netbeans.mnv | 1027 ++ uvim/src/testdir/test_netbeans.py | 6 +- uvim/src/testdir/test_netbeans.vim | 1027 -- uvim/src/testdir/test_normal.mnv | 4461 +++++++ uvim/src/testdir/test_normal.vim | 4461 ------- uvim/src/testdir/test_number.mnv | 405 + uvim/src/testdir/test_number.vim | 405 - uvim/src/testdir/test_options.mnv | 3095 +++++ uvim/src/testdir/test_options.vim | 3095 ----- uvim/src/testdir/test_options_all.mnv | 13 + uvim/src/testdir/test_options_all.vim | 13 - uvim/src/testdir/test_packadd.mnv | 518 + uvim/src/testdir/test_packadd.vim | 518 - uvim/src/testdir/test_partial.mnv | 443 + uvim/src/testdir/test_partial.vim | 443 - uvim/src/testdir/test_paste.mnv | 334 + uvim/src/testdir/test_paste.vim | 334 - uvim/src/testdir/test_perl.mnv | 381 + uvim/src/testdir/test_perl.vim | 381 - uvim/src/testdir/test_plugin_comment.mnv | 635 + uvim/src/testdir/test_plugin_comment.vim | 635 - uvim/src/testdir/test_plugin_glvs.mnv | 378 + uvim/src/testdir/test_plugin_glvs.vim | 378 - uvim/src/testdir/test_plugin_helpcurwin.mnv | 13 + uvim/src/testdir/test_plugin_helpcurwin.vim | 13 - uvim/src/testdir/test_plugin_helptoc.mnv | 40 + uvim/src/testdir/test_plugin_helptoc.vim | 40 - uvim/src/testdir/test_plugin_man.mnv | 149 + uvim/src/testdir/test_plugin_man.vim | 149 - uvim/src/testdir/test_plugin_matchparen.mnv | 202 + uvim/src/testdir/test_plugin_matchparen.vim | 202 - uvim/src/testdir/test_plugin_netrw.mnv | 606 + uvim/src/testdir/test_plugin_netrw.vim | 606 - uvim/src/testdir/test_plugin_osc52.mnv | 96 + uvim/src/testdir/test_plugin_osc52.vim | 96 - uvim/src/testdir/test_plugin_tar.mnv | 149 + uvim/src/testdir/test_plugin_tar.vim | 149 - uvim/src/testdir/test_plugin_termdebug.mnv | 864 ++ uvim/src/testdir/test_plugin_termdebug.vim | 864 -- uvim/src/testdir/test_plugin_tohtml.mnv | 70 + uvim/src/testdir/test_plugin_tohtml.vim | 70 - uvim/src/testdir/test_plugin_tutor.mnv | 54 + uvim/src/testdir/test_plugin_tutor.vim | 54 - uvim/src/testdir/test_plugin_zip.mnv | 298 + uvim/src/testdir/test_plugin_zip.vim | 298 - uvim/src/testdir/test_plus_arg_edit.mnv | 45 + uvim/src/testdir/test_plus_arg_edit.vim | 45 - uvim/src/testdir/test_popup.mnv | 2423 ++++ uvim/src/testdir/test_popup.vim | 2423 ---- uvim/src/testdir/test_popupwin.mnv | 5105 ++++++++ uvim/src/testdir/test_popupwin.vim | 5105 -------- uvim/src/testdir/test_popupwin_textprop.mnv | 174 + uvim/src/testdir/test_popupwin_textprop.vim | 174 - uvim/src/testdir/test_preview.mnv | 106 + uvim/src/testdir/test_preview.vim | 106 - uvim/src/testdir/test_profile.mnv | 778 ++ uvim/src/testdir/test_profile.vim | 778 -- uvim/src/testdir/test_prompt_buffer.mnv | 365 + uvim/src/testdir/test_prompt_buffer.vim | 365 - uvim/src/testdir/test_put.mnv | 447 + uvim/src/testdir/test_put.vim | 445 - uvim/src/testdir/test_python2.mnv | 4055 +++++++ uvim/src/testdir/test_python2.vim | 4055 ------- uvim/src/testdir/test_python3.mnv | 4413 +++++++ uvim/src/testdir/test_python3.vim | 4413 ------- uvim/src/testdir/test_pyx2.mnv | 148 + uvim/src/testdir/test_pyx2.vim | 148 - uvim/src/testdir/test_pyx3.mnv | 147 + uvim/src/testdir/test_pyx3.vim | 147 - uvim/src/testdir/test_quickfix.mnv | 7009 +++++++++++ uvim/src/testdir/test_quickfix.vim | 7009 ----------- uvim/src/testdir/test_quotestar.mnv | 155 + uvim/src/testdir/test_quotestar.vim | 155 - uvim/src/testdir/test_random.mnv | 53 + uvim/src/testdir/test_random.vim | 53 - uvim/src/testdir/test_recover.mnv | 518 + uvim/src/testdir/test_recover.vim | 518 - uvim/src/testdir/test_regex_char_classes.mnv | 295 + uvim/src/testdir/test_regex_char_classes.vim | 295 - uvim/src/testdir/test_regexp_latin.mnv | 1175 ++ uvim/src/testdir/test_regexp_latin.vim | 1175 -- uvim/src/testdir/test_regexp_utf8.mnv | 654 + uvim/src/testdir/test_regexp_utf8.vim | 654 - uvim/src/testdir/test_registers.mnv | 1302 ++ uvim/src/testdir/test_registers.vim | 1302 -- uvim/src/testdir/test_reltime.mnv | 30 + uvim/src/testdir/test_reltime.vim | 30 - uvim/src/testdir/test_remote.mnv | 149 + uvim/src/testdir/test_remote.vim | 149 - uvim/src/testdir/test_rename.mnv | 111 + uvim/src/testdir/test_rename.vim | 111 - uvim/src/testdir/test_restricted.mnv | 223 + uvim/src/testdir/test_restricted.vim | 223 - uvim/src/testdir/test_retab.mnv | 185 + uvim/src/testdir/test_retab.vim | 185 - uvim/src/testdir/test_ruby.mnv | 458 + uvim/src/testdir/test_ruby.vim | 458 - uvim/src/testdir/test_scriptnames.mnv | 106 + uvim/src/testdir/test_scriptnames.vim | 106 - uvim/src/testdir/test_scroll_opt.mnv | 1442 +++ uvim/src/testdir/test_scroll_opt.vim | 1442 --- uvim/src/testdir/test_scrollbind.mnv | 275 + uvim/src/testdir/test_scrollbind.vim | 275 - uvim/src/testdir/test_search.mnv | 2424 ++++ uvim/src/testdir/test_search.vim | 2424 ---- uvim/src/testdir/test_search_stat.mnv | 649 + uvim/src/testdir/test_search_stat.vim | 649 - uvim/src/testdir/test_searchpos.mnv | 30 + uvim/src/testdir/test_searchpos.vim | 30 - uvim/src/testdir/test_selectmode.mnv | 339 + uvim/src/testdir/test_selectmode.vim | 339 - uvim/src/testdir/test_set.mnv | 76 + uvim/src/testdir/test_set.vim | 76 - uvim/src/testdir/test_sha256.mnv | 34 + uvim/src/testdir/test_sha256.vim | 34 - uvim/src/testdir/test_shell.mnv | 313 + uvim/src/testdir/test_shell.vim | 313 - uvim/src/testdir/test_shift.mnv | 914 ++ uvim/src/testdir/test_shift.vim | 914 -- uvim/src/testdir/test_shortpathname.mnv | 104 + uvim/src/testdir/test_shortpathname.vim | 104 - uvim/src/testdir/test_signals.mnv | 200 + uvim/src/testdir/test_signals.vim | 200 - uvim/src/testdir/test_signs.mnv | 2166 ++++ uvim/src/testdir/test_signs.vim | 2166 ---- uvim/src/testdir/test_sleep.mnv | 23 + uvim/src/testdir/test_sleep.vim | 23 - uvim/src/testdir/test_smartindent.mnv | 159 + uvim/src/testdir/test_smartindent.vim | 159 - uvim/src/testdir/test_sort.mnv | 1588 +++ uvim/src/testdir/test_sort.vim | 1588 --- uvim/src/testdir/test_sound.mnv | 104 + uvim/src/testdir/test_sound.vim | 104 - uvim/src/testdir/test_source.mnv | 674 ++ uvim/src/testdir/test_source.vim | 674 -- uvim/src/testdir/test_source_utf8.mnv | 61 + uvim/src/testdir/test_source_utf8.vim | 61 - uvim/src/testdir/test_spell.mnv | 1584 +++ uvim/src/testdir/test_spell.vim | 1584 --- uvim/src/testdir/test_spell_utf8.mnv | 831 ++ uvim/src/testdir/test_spell_utf8.vim | 831 -- uvim/src/testdir/test_spellfile.mnv | 1169 ++ uvim/src/testdir/test_spellfile.vim | 1169 -- uvim/src/testdir/test_spellrare.mnv | 60 + uvim/src/testdir/test_spellrare.vim | 60 - uvim/src/testdir/test_stacktrace.mnv | 142 + uvim/src/testdir/test_stacktrace.vim | 142 - uvim/src/testdir/test_startup.mnv | 1511 +++ uvim/src/testdir/test_startup.vim | 1511 --- uvim/src/testdir/test_startup_utf8.mnv | 108 + uvim/src/testdir/test_startup_utf8.vim | 108 - uvim/src/testdir/test_stat.mnv | 222 + uvim/src/testdir/test_stat.vim | 222 - uvim/src/testdir/test_statusline.mnv | 724 ++ uvim/src/testdir/test_statusline.vim | 724 -- uvim/src/testdir/test_statuslineopt.mnv | 415 + uvim/src/testdir/test_statuslineopt.vim | 415 - uvim/src/testdir/test_substitute.mnv | 1529 +++ uvim/src/testdir/test_substitute.vim | 1529 --- uvim/src/testdir/test_suspend.mnv | 117 + uvim/src/testdir/test_suspend.vim | 117 - uvim/src/testdir/test_swap.mnv | 572 + uvim/src/testdir/test_swap.vim | 572 - uvim/src/testdir/test_syn_attr.mnv | 834 ++ uvim/src/testdir/test_syn_attr.vim | 834 -- uvim/src/testdir/test_syntax.mnv | 992 ++ uvim/src/testdir/test_syntax.vim | 992 -- uvim/src/testdir/test_system.mnv | 256 + uvim/src/testdir/test_system.vim | 256 - uvim/src/testdir/test_tab.mnv | 92 + uvim/src/testdir/test_tab.vim | 92 - uvim/src/testdir/test_tabline.mnv | 253 + uvim/src/testdir/test_tabline.vim | 253 - uvim/src/testdir/test_tabpage.mnv | 1077 ++ uvim/src/testdir/test_tabpage.vim | 1077 -- uvim/src/testdir/test_tabpanel.mnv | 895 ++ uvim/src/testdir/test_tabpanel.vim | 895 -- uvim/src/testdir/test_tagcase.mnv | 75 + uvim/src/testdir/test_tagcase.vim | 75 - uvim/src/testdir/test_tagfunc.mnv | 459 + uvim/src/testdir/test_tagfunc.vim | 459 - uvim/src/testdir/test_tagjump.mnv | 1696 +++ uvim/src/testdir/test_tagjump.vim | 1696 --- uvim/src/testdir/test_taglist.mnv | 335 + uvim/src/testdir/test_taglist.vim | 335 - uvim/src/testdir/test_tcl.mnv | 766 ++ uvim/src/testdir/test_tcl.vim | 766 -- uvim/src/testdir/test_termcodes.mnv | 3122 +++++ uvim/src/testdir/test_termcodes.vim | 3122 ----- uvim/src/testdir/test_termencoding.mnv | 38 + uvim/src/testdir/test_termencoding.vim | 38 - uvim/src/testdir/test_terminal.mnv | 2454 ++++ uvim/src/testdir/test_terminal.vim | 2454 ---- uvim/src/testdir/test_terminal2.mnv | 743 ++ uvim/src/testdir/test_terminal2.vim | 743 -- uvim/src/testdir/test_terminal3.mnv | 1243 ++ uvim/src/testdir/test_terminal3.vim | 1243 -- uvim/src/testdir/test_terminal_fail.mnv | 19 + uvim/src/testdir/test_terminal_fail.vim | 19 - uvim/src/testdir/test_textformat.mnv | 1363 +++ uvim/src/testdir/test_textformat.vim | 1363 --- uvim/src/testdir/test_textobjects.mnv | 780 ++ uvim/src/testdir/test_textobjects.vim | 780 -- uvim/src/testdir/test_textprop.mnv | 4910 ++++++++ uvim/src/testdir/test_textprop.vim | 4910 -------- uvim/src/testdir/test_timers.mnv | 543 + uvim/src/testdir/test_timers.vim | 543 - uvim/src/testdir/test_true_false.mnv | 152 + uvim/src/testdir/test_true_false.vim | 152 - uvim/src/testdir/test_trycatch.mnv | 2405 ++++ uvim/src/testdir/test_trycatch.vim | 2405 ---- uvim/src/testdir/test_tuple.mnv | 2466 ++++ uvim/src/testdir/test_tuple.vim | 2466 ---- uvim/src/testdir/test_undo.mnv | 928 ++ uvim/src/testdir/test_undo.vim | 928 -- uvim/src/testdir/test_uniq.mnv | 610 + uvim/src/testdir/test_uniq.vim | 610 - uvim/src/testdir/test_unlet.mnv | 79 + uvim/src/testdir/test_unlet.vim | 79 - uvim/src/testdir/test_user_func.mnv | 1090 ++ uvim/src/testdir/test_user_func.vim | 1090 -- uvim/src/testdir/test_usercommands.mnv | 1014 ++ uvim/src/testdir/test_usercommands.vim | 1014 -- uvim/src/testdir/test_utf8.mnv | 375 + uvim/src/testdir/test_utf8.vim | 375 - uvim/src/testdir/test_utf8_comparisons.mnv | 131 + uvim/src/testdir/test_utf8_comparisons.vim | 131 - uvim/src/testdir/test_vartabs.mnv | 514 + uvim/src/testdir/test_vartabs.vim | 514 - uvim/src/testdir/test_version.mnv | 23 + uvim/src/testdir/test_version.vim | 23 - uvim/src/testdir/test_vim9_assign.vim | 3935 ------ uvim/src/testdir/test_vim9_builtin.vim | 5420 --------- uvim/src/testdir/test_vim9_class.vim | 11872 ------------------- uvim/src/testdir/test_vim9_cmd.vim | 2131 ---- uvim/src/testdir/test_vim9_disassemble.vim | 4097 ------- uvim/src/testdir/test_vim9_enum.vim | 1682 --- uvim/src/testdir/test_vim9_expr.vim | 4490 ------- uvim/src/testdir/test_vim9_fails.vim | 60 - uvim/src/testdir/test_vim9_func.vim | 4867 -------- uvim/src/testdir/test_vim9_generics.vim | 3577 ------ uvim/src/testdir/test_vim9_import.vim | 3722 ------ uvim/src/testdir/test_vim9_interface.vim | 1459 --- uvim/src/testdir/test_vim9_python3.vim | 16 - uvim/src/testdir/test_vim9_script.vim | 5828 --------- uvim/src/testdir/test_vim9_typealias.vim | 927 -- uvim/src/testdir/test_viminfo.vim | 1394 --- uvim/src/testdir/test_vimscript.vim | 7708 ------------ uvim/src/testdir/test_virtualedit.mnv | 756 ++ uvim/src/testdir/test_virtualedit.vim | 756 -- uvim/src/testdir/test_visual.mnv | 3045 +++++ uvim/src/testdir/test_visual.vim | 3045 ----- uvim/src/testdir/test_wayland.mnv | 630 + uvim/src/testdir/test_wayland.vim | 630 - uvim/src/testdir/test_winbar.mnv | 188 + uvim/src/testdir/test_winbar.vim | 188 - uvim/src/testdir/test_winbuf_close.mnv | 228 + uvim/src/testdir/test_winbuf_close.vim | 228 - uvim/src/testdir/test_window_cmd.mnv | 2524 ++++ uvim/src/testdir/test_window_cmd.vim | 2524 ---- uvim/src/testdir/test_window_id.mnv | 140 + uvim/src/testdir/test_window_id.vim | 140 - uvim/src/testdir/test_windows_home.mnv | 121 + uvim/src/testdir/test_windows_home.vim | 121 - uvim/src/testdir/test_winfixbuf.mnv | 3367 ++++++ uvim/src/testdir/test_winfixbuf.vim | 3367 ------ uvim/src/testdir/test_wnext.mnv | 103 + uvim/src/testdir/test_wnext.vim | 103 - uvim/src/testdir/test_wordcount.mnv | 106 + uvim/src/testdir/test_wordcount.vim | 106 - uvim/src/testdir/test_writefile.mnv | 1000 ++ uvim/src/testdir/test_writefile.vim | 1000 -- uvim/src/testdir/test_xdg.mnv | 335 + uvim/src/testdir/test_xdg.vim | 335 - uvim/src/testdir/test_xxd.mnv | 825 ++ uvim/src/testdir/test_xxd.vim | 825 -- uvim/src/testdir/util/amiga.mnv | 6 + uvim/src/testdir/util/amiga.vim | 6 - uvim/src/testdir/util/check.mnv | 364 + uvim/src/testdir/util/check.vim | 364 - uvim/src/testdir/util/color_ramp.mnv | 85 + uvim/src/testdir/util/color_ramp.vim | 85 - uvim/src/testdir/util/dos.mnv | 9 + uvim/src/testdir/util/dos.vim | 9 - uvim/src/testdir/util/gen_opt_test.mnv | 554 + uvim/src/testdir/util/gen_opt_test.vim | 554 - uvim/src/testdir/util/gui_init.mnv | 6 + uvim/src/testdir/util/gui_init.vim | 6 - uvim/src/testdir/util/gui_preinit.mnv | 7 + uvim/src/testdir/util/gui_preinit.vim | 7 - uvim/src/testdir/util/mnv9.mnv | 549 + uvim/src/testdir/util/mouse.mnv | 372 + uvim/src/testdir/util/mouse.vim | 372 - uvim/src/testdir/util/popupbounce.mnv | 80 + uvim/src/testdir/util/popupbounce.vim | 80 - uvim/src/testdir/util/screendump.mnv | 231 + uvim/src/testdir/util/screendump.vim | 231 - uvim/src/testdir/util/script_util.mnv | 69 + uvim/src/testdir/util/script_util.vim | 69 - uvim/src/testdir/util/setup.mnv | 47 + uvim/src/testdir/util/setup.vim | 47 - uvim/src/testdir/util/setup_gui.mnv | 31 + uvim/src/testdir/util/setup_gui.vim | 31 - uvim/src/testdir/util/shared.mnv | 476 + uvim/src/testdir/util/shared.vim | 476 - uvim/src/testdir/util/socketserver.mnv | 17 + uvim/src/testdir/util/socketserver.vim | 17 - uvim/src/testdir/util/summarize.mnv | 62 + uvim/src/testdir/util/summarize.vim | 62 - uvim/src/testdir/util/term_util.mnv | 211 + uvim/src/testdir/util/term_util.vim | 211 - uvim/src/testdir/util/unix.mnv | 13 + uvim/src/testdir/util/unix.vim | 13 - uvim/src/testdir/util/view_util.mnv | 129 + uvim/src/testdir/util/view_util.vim | 129 - uvim/src/testdir/util/vim9.vim | 549 - uvim/src/testdir/util/vms.mnv | 6 + uvim/src/testdir/util/vms.vim | 6 - uvim/src/testdir/util/window_manager.mnv | 107 + uvim/src/testdir/util/window_manager.vim | 107 - uvim/src/testdir/viewdumps.mnv | 11 + uvim/src/testdir/viewdumps.vim | 11 - 759 files changed, 276170 insertions(+), 276159 deletions(-) create mode 100644 uvim/src/testdir/commondumps.mnv delete mode 100644 uvim/src/testdir/commondumps.vim create mode 100644 uvim/src/testdir/crash/mnv_msg_trunc_poc create mode 100644 uvim/src/testdir/crash/mnv_regsub_both create mode 100644 uvim/src/testdir/crash/mnv_regsub_both_poc create mode 100644 uvim/src/testdir/crash/poc_tagfunc.mnv delete mode 100644 uvim/src/testdir/crash/poc_tagfunc.vim delete mode 100644 uvim/src/testdir/crash/vim_msg_trunc_poc delete mode 100644 uvim/src/testdir/crash/vim_regsub_both delete mode 100644 uvim/src/testdir/crash/vim_regsub_both_poc create mode 100644 uvim/src/testdir/dumps/Test_incsearch_mnvgrep_01.dump create mode 100644 uvim/src/testdir/dumps/Test_incsearch_mnvgrep_02.dump create mode 100644 uvim/src/testdir/dumps/Test_incsearch_mnvgrep_03.dump create mode 100644 uvim/src/testdir/dumps/Test_incsearch_mnvgrep_04.dump create mode 100644 uvim/src/testdir/dumps/Test_incsearch_mnvgrep_05.dump delete mode 100644 uvim/src/testdir/dumps/Test_incsearch_vimgrep_01.dump delete mode 100644 uvim/src/testdir/dumps/Test_incsearch_vimgrep_02.dump delete mode 100644 uvim/src/testdir/dumps/Test_incsearch_vimgrep_03.dump delete mode 100644 uvim/src/testdir/dumps/Test_incsearch_vimgrep_04.dump delete mode 100644 uvim/src/testdir/dumps/Test_incsearch_vimgrep_05.dump create mode 100644 uvim/src/testdir/dumps/Test_mnv9_closure_fails.dump create mode 100644 uvim/src/testdir/dumps/Test_mnv9_no_redraw.dump create mode 100644 uvim/src/testdir/dumps/Test_mnv9_reject_declaration_1.dump create mode 100644 uvim/src/testdir/dumps/Test_mnv9_reject_declaration_2.dump create mode 100644 uvim/src/testdir/dumps/Test_mnv9_silent_echo.dump create mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_04.mnv delete mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_04.vim create mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_05.mnv delete mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_05.vim create mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_06.mnv delete mode 100644 uvim/src/testdir/dumps/Test_popup_setbuf_06.vim create mode 100644 uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.mnv delete mode 100644 uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.vim create mode 100644 uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.mnv delete mode 100644 uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.vim create mode 100644 uvim/src/testdir/dumps/Test_undo_after_write_1.mnv delete mode 100644 uvim/src/testdir/dumps/Test_undo_after_write_1.vim create mode 100644 uvim/src/testdir/dumps/Test_undo_after_write_2.mnv delete mode 100644 uvim/src/testdir/dumps/Test_undo_after_write_2.vim create mode 100644 uvim/src/testdir/dumps/Test_verbose_system_1.mnv delete mode 100644 uvim/src/testdir/dumps/Test_verbose_system_1.vim create mode 100644 uvim/src/testdir/dumps/Test_verbose_system_2.mnv delete mode 100644 uvim/src/testdir/dumps/Test_verbose_system_2.vim delete mode 100644 uvim/src/testdir/dumps/Test_vim9_closure_fails.dump delete mode 100644 uvim/src/testdir/dumps/Test_vim9_no_redraw.dump delete mode 100644 uvim/src/testdir/dumps/Test_vim9_reject_declaration_1.dump delete mode 100644 uvim/src/testdir/dumps/Test_vim9_reject_declaration_2.dump delete mode 100644 uvim/src/testdir/dumps/Test_vim9_silent_echo.dump create mode 100644 uvim/src/testdir/dumps/Test_xxd_color_0.mnv delete mode 100644 uvim/src/testdir/dumps/Test_xxd_color_0.vim create mode 100644 uvim/src/testdir/dumps/Test_xxd_color_1.mnv delete mode 100644 uvim/src/testdir/dumps/Test_xxd_color_1.vim create mode 100644 uvim/src/testdir/keycode_check.mnv delete mode 100644 uvim/src/testdir/keycode_check.vim create mode 100644 uvim/src/testdir/runtest.mnv delete mode 100644 uvim/src/testdir/runtest.vim create mode 100644 uvim/src/testdir/samples/matchparen.mnv delete mode 100644 uvim/src/testdir/samples/matchparen.vim create mode 100644 uvim/src/testdir/sautest/autoload/Test104.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/Test104.vim create mode 100644 uvim/src/testdir/sautest/autoload/auto9.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/auto9.vim create mode 100644 uvim/src/testdir/sautest/autoload/foo.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/foo.vim create mode 100644 uvim/src/testdir/sautest/autoload/footest.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/footest.vim create mode 100644 uvim/src/testdir/sautest/autoload/globone.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/globone.vim create mode 100644 uvim/src/testdir/sautest/autoload/globtwo.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/globtwo.vim create mode 100644 uvim/src/testdir/sautest/autoload/sourced.mnv delete mode 100644 uvim/src/testdir/sautest/autoload/sourced.vim create mode 100644 uvim/src/testdir/test_alot.mnv delete mode 100644 uvim/src/testdir/test_alot.vim create mode 100644 uvim/src/testdir/test_alot_latin.mnv delete mode 100644 uvim/src/testdir/test_alot_latin.vim create mode 100644 uvim/src/testdir/test_alot_utf8.mnv delete mode 100644 uvim/src/testdir/test_alot_utf8.vim create mode 100644 uvim/src/testdir/test_arabic.mnv delete mode 100644 uvim/src/testdir/test_arabic.vim create mode 100644 uvim/src/testdir/test_arglist.mnv delete mode 100644 uvim/src/testdir/test_arglist.vim create mode 100644 uvim/src/testdir/test_assert.mnv delete mode 100644 uvim/src/testdir/test_assert.vim create mode 100644 uvim/src/testdir/test_autochdir.mnv delete mode 100644 uvim/src/testdir/test_autochdir.vim create mode 100644 uvim/src/testdir/test_autocmd.mnv delete mode 100644 uvim/src/testdir/test_autocmd.vim create mode 100644 uvim/src/testdir/test_autoload.mnv delete mode 100644 uvim/src/testdir/test_autoload.vim create mode 100644 uvim/src/testdir/test_backspace_opt.mnv delete mode 100644 uvim/src/testdir/test_backspace_opt.vim create mode 100644 uvim/src/testdir/test_backup.mnv delete mode 100644 uvim/src/testdir/test_backup.vim create mode 100644 uvim/src/testdir/test_balloon.mnv delete mode 100644 uvim/src/testdir/test_balloon.vim create mode 100644 uvim/src/testdir/test_balloon_gui.mnv delete mode 100644 uvim/src/testdir/test_balloon_gui.vim create mode 100644 uvim/src/testdir/test_behave.mnv delete mode 100644 uvim/src/testdir/test_behave.vim create mode 100644 uvim/src/testdir/test_bench_regexp.mnv delete mode 100644 uvim/src/testdir/test_bench_regexp.vim create mode 100644 uvim/src/testdir/test_blob.mnv delete mode 100644 uvim/src/testdir/test_blob.vim create mode 100644 uvim/src/testdir/test_blockedit.mnv delete mode 100644 uvim/src/testdir/test_blockedit.vim create mode 100644 uvim/src/testdir/test_breakindent.mnv delete mode 100644 uvim/src/testdir/test_breakindent.vim create mode 100644 uvim/src/testdir/test_buffer.mnv delete mode 100644 uvim/src/testdir/test_buffer.vim create mode 100644 uvim/src/testdir/test_bufline.mnv delete mode 100644 uvim/src/testdir/test_bufline.vim create mode 100644 uvim/src/testdir/test_bufwintabinfo.mnv delete mode 100644 uvim/src/testdir/test_bufwintabinfo.vim create mode 100644 uvim/src/testdir/test_cd.mnv delete mode 100644 uvim/src/testdir/test_cd.vim create mode 100644 uvim/src/testdir/test_cdo.mnv delete mode 100644 uvim/src/testdir/test_cdo.vim create mode 100644 uvim/src/testdir/test_changedtick.mnv delete mode 100644 uvim/src/testdir/test_changedtick.vim create mode 100644 uvim/src/testdir/test_changelist.mnv delete mode 100644 uvim/src/testdir/test_changelist.vim create mode 100644 uvim/src/testdir/test_channel.mnv delete mode 100644 uvim/src/testdir/test_channel.vim create mode 100644 uvim/src/testdir/test_charsearch.mnv delete mode 100644 uvim/src/testdir/test_charsearch.vim create mode 100644 uvim/src/testdir/test_charsearch_utf8.mnv delete mode 100644 uvim/src/testdir/test_charsearch_utf8.vim create mode 100644 uvim/src/testdir/test_checkpath.mnv delete mode 100644 uvim/src/testdir/test_checkpath.vim create mode 100644 uvim/src/testdir/test_cindent.mnv delete mode 100644 uvim/src/testdir/test_cindent.vim create mode 100644 uvim/src/testdir/test_cjk_linebreak.mnv delete mode 100644 uvim/src/testdir/test_cjk_linebreak.vim create mode 100644 uvim/src/testdir/test_clientserver.mnv delete mode 100644 uvim/src/testdir/test_clientserver.vim create mode 100644 uvim/src/testdir/test_clipmethod.mnv delete mode 100644 uvim/src/testdir/test_clipmethod.vim create mode 100644 uvim/src/testdir/test_close_count.mnv delete mode 100644 uvim/src/testdir/test_close_count.vim create mode 100644 uvim/src/testdir/test_cmd_lists.mnv delete mode 100644 uvim/src/testdir/test_cmd_lists.vim create mode 100644 uvim/src/testdir/test_cmdline.mnv delete mode 100644 uvim/src/testdir/test_cmdline.vim create mode 100644 uvim/src/testdir/test_cmdmods.mnv delete mode 100644 uvim/src/testdir/test_cmdmods.vim create mode 100644 uvim/src/testdir/test_cmdwin.mnv delete mode 100644 uvim/src/testdir/test_cmdwin.vim create mode 100644 uvim/src/testdir/test_codestyle.mnv delete mode 100644 uvim/src/testdir/test_codestyle.vim create mode 100644 uvim/src/testdir/test_command_count.mnv delete mode 100644 uvim/src/testdir/test_command_count.vim create mode 100644 uvim/src/testdir/test_comments.mnv delete mode 100644 uvim/src/testdir/test_comments.vim create mode 100644 uvim/src/testdir/test_comparators.mnv delete mode 100644 uvim/src/testdir/test_comparators.vim create mode 100644 uvim/src/testdir/test_compiler.mnv delete mode 100644 uvim/src/testdir/test_compiler.vim create mode 100644 uvim/src/testdir/test_conceal.mnv delete mode 100644 uvim/src/testdir/test_conceal.vim create mode 100644 uvim/src/testdir/test_const.mnv delete mode 100644 uvim/src/testdir/test_const.vim create mode 100644 uvim/src/testdir/test_cpoptions.mnv delete mode 100644 uvim/src/testdir/test_cpoptions.vim create mode 100644 uvim/src/testdir/test_crash.mnv delete mode 100644 uvim/src/testdir/test_crash.vim create mode 100644 uvim/src/testdir/test_crypt.mnv delete mode 100644 uvim/src/testdir/test_crypt.vim create mode 100644 uvim/src/testdir/test_cscope.mnv delete mode 100644 uvim/src/testdir/test_cscope.vim create mode 100644 uvim/src/testdir/test_cursor_func.mnv delete mode 100644 uvim/src/testdir/test_cursor_func.vim create mode 100644 uvim/src/testdir/test_cursorline.mnv delete mode 100644 uvim/src/testdir/test_cursorline.vim create mode 100644 uvim/src/testdir/test_curswant.mnv delete mode 100644 uvim/src/testdir/test_curswant.vim create mode 100644 uvim/src/testdir/test_debugger.mnv delete mode 100644 uvim/src/testdir/test_debugger.vim create mode 100644 uvim/src/testdir/test_delete.mnv delete mode 100644 uvim/src/testdir/test_delete.vim create mode 100644 uvim/src/testdir/test_diffmode.mnv delete mode 100644 uvim/src/testdir/test_diffmode.vim create mode 100644 uvim/src/testdir/test_digraph.mnv delete mode 100644 uvim/src/testdir/test_digraph.vim create mode 100644 uvim/src/testdir/test_display.mnv delete mode 100644 uvim/src/testdir/test_display.vim create mode 100644 uvim/src/testdir/test_edit.mnv delete mode 100644 uvim/src/testdir/test_edit.vim create mode 100644 uvim/src/testdir/test_environ.mnv delete mode 100644 uvim/src/testdir/test_environ.vim create mode 100644 uvim/src/testdir/test_erasebackword.mnv delete mode 100644 uvim/src/testdir/test_erasebackword.vim create mode 100644 uvim/src/testdir/test_escaped_glob.mnv delete mode 100644 uvim/src/testdir/test_escaped_glob.vim create mode 100644 uvim/src/testdir/test_eval_stuff.mnv delete mode 100644 uvim/src/testdir/test_eval_stuff.vim create mode 100644 uvim/src/testdir/test_ex_equal.mnv delete mode 100644 uvim/src/testdir/test_ex_equal.vim create mode 100644 uvim/src/testdir/test_ex_mode.mnv delete mode 100644 uvim/src/testdir/test_ex_mode.vim create mode 100644 uvim/src/testdir/test_ex_undo.mnv delete mode 100644 uvim/src/testdir/test_ex_undo.vim create mode 100644 uvim/src/testdir/test_ex_z.mnv delete mode 100644 uvim/src/testdir/test_ex_z.vim create mode 100644 uvim/src/testdir/test_excmd.mnv delete mode 100644 uvim/src/testdir/test_excmd.vim create mode 100644 uvim/src/testdir/test_exec_while_if.mnv delete mode 100644 uvim/src/testdir/test_exec_while_if.vim create mode 100644 uvim/src/testdir/test_execute_func.mnv delete mode 100644 uvim/src/testdir/test_execute_func.vim create mode 100644 uvim/src/testdir/test_exists.mnv delete mode 100644 uvim/src/testdir/test_exists.vim create mode 100644 uvim/src/testdir/test_exists_autocmd.mnv delete mode 100644 uvim/src/testdir/test_exists_autocmd.vim create mode 100644 uvim/src/testdir/test_exit.mnv delete mode 100644 uvim/src/testdir/test_exit.vim create mode 100644 uvim/src/testdir/test_expand.mnv delete mode 100644 uvim/src/testdir/test_expand.vim create mode 100644 uvim/src/testdir/test_expand_dllpath.mnv delete mode 100644 uvim/src/testdir/test_expand_dllpath.vim create mode 100644 uvim/src/testdir/test_expand_func.mnv delete mode 100644 uvim/src/testdir/test_expand_func.vim create mode 100644 uvim/src/testdir/test_expr.mnv delete mode 100644 uvim/src/testdir/test_expr.vim create mode 100644 uvim/src/testdir/test_expr_utf8.mnv delete mode 100644 uvim/src/testdir/test_expr_utf8.vim create mode 100644 uvim/src/testdir/test_file_perm.mnv delete mode 100644 uvim/src/testdir/test_file_perm.vim create mode 100644 uvim/src/testdir/test_file_size.mnv delete mode 100644 uvim/src/testdir/test_file_size.vim create mode 100644 uvim/src/testdir/test_filechanged.mnv delete mode 100644 uvim/src/testdir/test_filechanged.vim create mode 100644 uvim/src/testdir/test_filecopy.mnv delete mode 100644 uvim/src/testdir/test_filecopy.vim create mode 100644 uvim/src/testdir/test_fileformat.mnv delete mode 100644 uvim/src/testdir/test_fileformat.vim create mode 100644 uvim/src/testdir/test_filetype.mnv delete mode 100644 uvim/src/testdir/test_filetype.vim create mode 100644 uvim/src/testdir/test_filter_cmd.mnv delete mode 100644 uvim/src/testdir/test_filter_cmd.vim create mode 100644 uvim/src/testdir/test_filter_map.mnv delete mode 100644 uvim/src/testdir/test_filter_map.vim create mode 100644 uvim/src/testdir/test_find_complete.mnv delete mode 100644 uvim/src/testdir/test_find_complete.vim create mode 100644 uvim/src/testdir/test_findfile.mnv delete mode 100644 uvim/src/testdir/test_findfile.vim create mode 100644 uvim/src/testdir/test_fixeol.mnv delete mode 100644 uvim/src/testdir/test_fixeol.vim create mode 100644 uvim/src/testdir/test_flatten.mnv delete mode 100644 uvim/src/testdir/test_flatten.vim create mode 100644 uvim/src/testdir/test_float_func.mnv delete mode 100644 uvim/src/testdir/test_float_func.vim create mode 100644 uvim/src/testdir/test_fnameescape.mnv delete mode 100644 uvim/src/testdir/test_fnameescape.vim create mode 100644 uvim/src/testdir/test_fnamemodify.mnv delete mode 100644 uvim/src/testdir/test_fnamemodify.vim create mode 100644 uvim/src/testdir/test_fold.mnv delete mode 100644 uvim/src/testdir/test_fold.vim create mode 100644 uvim/src/testdir/test_format.mnv delete mode 100644 uvim/src/testdir/test_format.vim create mode 100644 uvim/src/testdir/test_function_lists.mnv delete mode 100644 uvim/src/testdir/test_function_lists.vim create mode 100644 uvim/src/testdir/test_functions.mnv delete mode 100644 uvim/src/testdir/test_functions.vim create mode 100644 uvim/src/testdir/test_ga.mnv delete mode 100644 uvim/src/testdir/test_ga.vim create mode 100644 uvim/src/testdir/test_getcwd.mnv delete mode 100644 uvim/src/testdir/test_getcwd.vim create mode 100644 uvim/src/testdir/test_gettext.mnv delete mode 100644 uvim/src/testdir/test_gettext.vim create mode 100644 uvim/src/testdir/test_gettext_cp1251.mnv delete mode 100644 uvim/src/testdir/test_gettext_cp1251.vim create mode 100644 uvim/src/testdir/test_gettext_make.mnv delete mode 100644 uvim/src/testdir/test_gettext_make.vim create mode 100644 uvim/src/testdir/test_gettext_makefile_in1.mnv delete mode 100644 uvim/src/testdir/test_gettext_makefile_in1.vim create mode 100644 uvim/src/testdir/test_gettext_makefile_in2.mnv delete mode 100644 uvim/src/testdir/test_gettext_makefile_in2.vim create mode 100644 uvim/src/testdir/test_gettext_makefile_in3.mnv delete mode 100644 uvim/src/testdir/test_gettext_makefile_in3.vim create mode 100644 uvim/src/testdir/test_gettext_makefile_in4.mnv delete mode 100644 uvim/src/testdir/test_gettext_makefile_in4.vim create mode 100644 uvim/src/testdir/test_gettext_utf8.mnv delete mode 100644 uvim/src/testdir/test_gettext_utf8.vim create mode 100644 uvim/src/testdir/test_getvar.mnv delete mode 100644 uvim/src/testdir/test_getvar.vim create mode 100644 uvim/src/testdir/test_gf.mnv delete mode 100644 uvim/src/testdir/test_gf.vim create mode 100644 uvim/src/testdir/test_glob2regpat.mnv delete mode 100644 uvim/src/testdir/test_glob2regpat.vim create mode 100644 uvim/src/testdir/test_global.mnv delete mode 100644 uvim/src/testdir/test_global.vim create mode 100644 uvim/src/testdir/test_gn.mnv delete mode 100644 uvim/src/testdir/test_gn.vim create mode 100644 uvim/src/testdir/test_goto.mnv delete mode 100644 uvim/src/testdir/test_goto.vim create mode 100644 uvim/src/testdir/test_gui.mnv delete mode 100644 uvim/src/testdir/test_gui.vim create mode 100644 uvim/src/testdir/test_gui_init.mnv delete mode 100644 uvim/src/testdir/test_gui_init.vim create mode 100644 uvim/src/testdir/test_hardcopy.mnv delete mode 100644 uvim/src/testdir/test_hardcopy.vim create mode 100644 uvim/src/testdir/test_help.mnv delete mode 100644 uvim/src/testdir/test_help.vim create mode 100644 uvim/src/testdir/test_help_tagjump.mnv delete mode 100644 uvim/src/testdir/test_help_tagjump.vim create mode 100644 uvim/src/testdir/test_hide.mnv delete mode 100644 uvim/src/testdir/test_hide.vim create mode 100644 uvim/src/testdir/test_highlight.mnv delete mode 100644 uvim/src/testdir/test_highlight.vim create mode 100644 uvim/src/testdir/test_history.mnv delete mode 100644 uvim/src/testdir/test_history.vim create mode 100644 uvim/src/testdir/test_hlsearch.mnv delete mode 100644 uvim/src/testdir/test_hlsearch.vim create mode 100644 uvim/src/testdir/test_iminsert.mnv delete mode 100644 uvim/src/testdir/test_iminsert.vim create mode 100644 uvim/src/testdir/test_increment.mnv delete mode 100644 uvim/src/testdir/test_increment.vim create mode 100644 uvim/src/testdir/test_increment_dbcs.mnv delete mode 100644 uvim/src/testdir/test_increment_dbcs.vim create mode 100644 uvim/src/testdir/test_indent.mnv delete mode 100644 uvim/src/testdir/test_indent.vim create mode 100644 uvim/src/testdir/test_input.mnv delete mode 100644 uvim/src/testdir/test_input.vim create mode 100644 uvim/src/testdir/test_ins_complete.mnv delete mode 100644 uvim/src/testdir/test_ins_complete.vim create mode 100644 uvim/src/testdir/test_ins_complete_no_halt.mnv delete mode 100644 uvim/src/testdir/test_ins_complete_no_halt.vim create mode 100644 uvim/src/testdir/test_interrupt.mnv delete mode 100644 uvim/src/testdir/test_interrupt.vim create mode 100644 uvim/src/testdir/test_job_fails.mnv delete mode 100644 uvim/src/testdir/test_job_fails.vim create mode 100644 uvim/src/testdir/test_join.mnv delete mode 100644 uvim/src/testdir/test_join.vim create mode 100644 uvim/src/testdir/test_json.mnv delete mode 100644 uvim/src/testdir/test_json.vim create mode 100644 uvim/src/testdir/test_jumplist.mnv delete mode 100644 uvim/src/testdir/test_jumplist.vim create mode 100644 uvim/src/testdir/test_lambda.mnv delete mode 100644 uvim/src/testdir/test_lambda.vim create mode 100644 uvim/src/testdir/test_langmap.mnv delete mode 100644 uvim/src/testdir/test_langmap.vim create mode 100644 uvim/src/testdir/test_largefile.mnv delete mode 100644 uvim/src/testdir/test_largefile.vim create mode 100644 uvim/src/testdir/test_let.mnv delete mode 100644 uvim/src/testdir/test_let.vim create mode 100644 uvim/src/testdir/test_lineending.mnv delete mode 100644 uvim/src/testdir/test_lineending.vim create mode 100644 uvim/src/testdir/test_lispindent.mnv delete mode 100644 uvim/src/testdir/test_lispindent.vim create mode 100644 uvim/src/testdir/test_listchars.mnv delete mode 100644 uvim/src/testdir/test_listchars.vim create mode 100644 uvim/src/testdir/test_listdict.mnv delete mode 100644 uvim/src/testdir/test_listdict.vim create mode 100644 uvim/src/testdir/test_listener.mnv delete mode 100644 uvim/src/testdir/test_listener.vim create mode 100644 uvim/src/testdir/test_listlbr.mnv delete mode 100644 uvim/src/testdir/test_listlbr.vim create mode 100644 uvim/src/testdir/test_listlbr_utf8.mnv delete mode 100644 uvim/src/testdir/test_listlbr_utf8.vim create mode 100644 uvim/src/testdir/test_lua.mnv delete mode 100644 uvim/src/testdir/test_lua.vim create mode 100644 uvim/src/testdir/test_makeencoding.mnv delete mode 100644 uvim/src/testdir/test_makeencoding.vim create mode 100644 uvim/src/testdir/test_map_functions.mnv delete mode 100644 uvim/src/testdir/test_map_functions.vim create mode 100644 uvim/src/testdir/test_mapping.mnv delete mode 100644 uvim/src/testdir/test_mapping.vim create mode 100644 uvim/src/testdir/test_marks.mnv delete mode 100644 uvim/src/testdir/test_marks.vim create mode 100644 uvim/src/testdir/test_match.mnv delete mode 100644 uvim/src/testdir/test_match.vim create mode 100644 uvim/src/testdir/test_matchadd_conceal.mnv delete mode 100644 uvim/src/testdir/test_matchadd_conceal.vim create mode 100644 uvim/src/testdir/test_matchadd_conceal_utf8.mnv delete mode 100644 uvim/src/testdir/test_matchadd_conceal_utf8.vim create mode 100644 uvim/src/testdir/test_matchfuzzy.mnv delete mode 100644 uvim/src/testdir/test_matchfuzzy.vim create mode 100644 uvim/src/testdir/test_memory_usage.mnv delete mode 100644 uvim/src/testdir/test_memory_usage.vim create mode 100644 uvim/src/testdir/test_menu.mnv delete mode 100644 uvim/src/testdir/test_menu.vim create mode 100644 uvim/src/testdir/test_messages.mnv delete mode 100644 uvim/src/testdir/test_messages.vim create mode 100644 uvim/src/testdir/test_method.mnv delete mode 100644 uvim/src/testdir/test_method.vim create mode 100644 uvim/src/testdir/test_mksession.mnv delete mode 100644 uvim/src/testdir/test_mksession.vim create mode 100644 uvim/src/testdir/test_mksession_utf8.mnv delete mode 100644 uvim/src/testdir/test_mksession_utf8.vim create mode 100644 uvim/src/testdir/test_mnv9_assign.mnv create mode 100644 uvim/src/testdir/test_mnv9_builtin.mnv create mode 100644 uvim/src/testdir/test_mnv9_class.mnv create mode 100644 uvim/src/testdir/test_mnv9_cmd.mnv create mode 100644 uvim/src/testdir/test_mnv9_disassemble.mnv create mode 100644 uvim/src/testdir/test_mnv9_enum.mnv create mode 100644 uvim/src/testdir/test_mnv9_expr.mnv create mode 100644 uvim/src/testdir/test_mnv9_fails.mnv create mode 100644 uvim/src/testdir/test_mnv9_func.mnv create mode 100644 uvim/src/testdir/test_mnv9_generics.mnv create mode 100644 uvim/src/testdir/test_mnv9_import.mnv create mode 100644 uvim/src/testdir/test_mnv9_interface.mnv create mode 100644 uvim/src/testdir/test_mnv9_python3.mnv create mode 100644 uvim/src/testdir/test_mnv9_script.mnv create mode 100644 uvim/src/testdir/test_mnv9_typealias.mnv create mode 100644 uvim/src/testdir/test_mnvinfo.mnv create mode 100644 uvim/src/testdir/test_mnvscript.mnv create mode 100644 uvim/src/testdir/test_modeless.mnv delete mode 100644 uvim/src/testdir/test_modeless.vim create mode 100644 uvim/src/testdir/test_modeline.mnv delete mode 100644 uvim/src/testdir/test_modeline.vim create mode 100644 uvim/src/testdir/test_move.mnv delete mode 100644 uvim/src/testdir/test_move.vim create mode 100644 uvim/src/testdir/test_mswin_event.mnv delete mode 100644 uvim/src/testdir/test_mswin_event.vim create mode 100644 uvim/src/testdir/test_mzscheme.mnv delete mode 100644 uvim/src/testdir/test_mzscheme.vim create mode 100644 uvim/src/testdir/test_nested_function.mnv delete mode 100644 uvim/src/testdir/test_nested_function.vim create mode 100644 uvim/src/testdir/test_netbeans.mnv delete mode 100644 uvim/src/testdir/test_netbeans.vim create mode 100644 uvim/src/testdir/test_normal.mnv delete mode 100644 uvim/src/testdir/test_normal.vim create mode 100644 uvim/src/testdir/test_number.mnv delete mode 100644 uvim/src/testdir/test_number.vim create mode 100644 uvim/src/testdir/test_options.mnv delete mode 100644 uvim/src/testdir/test_options.vim create mode 100644 uvim/src/testdir/test_options_all.mnv delete mode 100644 uvim/src/testdir/test_options_all.vim create mode 100644 uvim/src/testdir/test_packadd.mnv delete mode 100644 uvim/src/testdir/test_packadd.vim create mode 100644 uvim/src/testdir/test_partial.mnv delete mode 100644 uvim/src/testdir/test_partial.vim create mode 100644 uvim/src/testdir/test_paste.mnv delete mode 100644 uvim/src/testdir/test_paste.vim create mode 100644 uvim/src/testdir/test_perl.mnv delete mode 100644 uvim/src/testdir/test_perl.vim create mode 100644 uvim/src/testdir/test_plugin_comment.mnv delete mode 100644 uvim/src/testdir/test_plugin_comment.vim create mode 100644 uvim/src/testdir/test_plugin_glvs.mnv delete mode 100644 uvim/src/testdir/test_plugin_glvs.vim create mode 100644 uvim/src/testdir/test_plugin_helpcurwin.mnv delete mode 100644 uvim/src/testdir/test_plugin_helpcurwin.vim create mode 100644 uvim/src/testdir/test_plugin_helptoc.mnv delete mode 100644 uvim/src/testdir/test_plugin_helptoc.vim create mode 100644 uvim/src/testdir/test_plugin_man.mnv delete mode 100644 uvim/src/testdir/test_plugin_man.vim create mode 100644 uvim/src/testdir/test_plugin_matchparen.mnv delete mode 100644 uvim/src/testdir/test_plugin_matchparen.vim create mode 100644 uvim/src/testdir/test_plugin_netrw.mnv delete mode 100644 uvim/src/testdir/test_plugin_netrw.vim create mode 100644 uvim/src/testdir/test_plugin_osc52.mnv delete mode 100644 uvim/src/testdir/test_plugin_osc52.vim create mode 100644 uvim/src/testdir/test_plugin_tar.mnv delete mode 100644 uvim/src/testdir/test_plugin_tar.vim create mode 100644 uvim/src/testdir/test_plugin_termdebug.mnv delete mode 100644 uvim/src/testdir/test_plugin_termdebug.vim create mode 100644 uvim/src/testdir/test_plugin_tohtml.mnv delete mode 100644 uvim/src/testdir/test_plugin_tohtml.vim create mode 100644 uvim/src/testdir/test_plugin_tutor.mnv delete mode 100644 uvim/src/testdir/test_plugin_tutor.vim create mode 100644 uvim/src/testdir/test_plugin_zip.mnv delete mode 100644 uvim/src/testdir/test_plugin_zip.vim create mode 100644 uvim/src/testdir/test_plus_arg_edit.mnv delete mode 100644 uvim/src/testdir/test_plus_arg_edit.vim create mode 100644 uvim/src/testdir/test_popup.mnv delete mode 100644 uvim/src/testdir/test_popup.vim create mode 100644 uvim/src/testdir/test_popupwin.mnv delete mode 100644 uvim/src/testdir/test_popupwin.vim create mode 100644 uvim/src/testdir/test_popupwin_textprop.mnv delete mode 100644 uvim/src/testdir/test_popupwin_textprop.vim create mode 100644 uvim/src/testdir/test_preview.mnv delete mode 100644 uvim/src/testdir/test_preview.vim create mode 100644 uvim/src/testdir/test_profile.mnv delete mode 100644 uvim/src/testdir/test_profile.vim create mode 100644 uvim/src/testdir/test_prompt_buffer.mnv delete mode 100644 uvim/src/testdir/test_prompt_buffer.vim create mode 100644 uvim/src/testdir/test_put.mnv delete mode 100644 uvim/src/testdir/test_put.vim create mode 100644 uvim/src/testdir/test_python2.mnv delete mode 100644 uvim/src/testdir/test_python2.vim create mode 100644 uvim/src/testdir/test_python3.mnv delete mode 100644 uvim/src/testdir/test_python3.vim create mode 100644 uvim/src/testdir/test_pyx2.mnv delete mode 100644 uvim/src/testdir/test_pyx2.vim create mode 100644 uvim/src/testdir/test_pyx3.mnv delete mode 100644 uvim/src/testdir/test_pyx3.vim create mode 100644 uvim/src/testdir/test_quickfix.mnv delete mode 100644 uvim/src/testdir/test_quickfix.vim create mode 100644 uvim/src/testdir/test_quotestar.mnv delete mode 100644 uvim/src/testdir/test_quotestar.vim create mode 100644 uvim/src/testdir/test_random.mnv delete mode 100644 uvim/src/testdir/test_random.vim create mode 100644 uvim/src/testdir/test_recover.mnv delete mode 100644 uvim/src/testdir/test_recover.vim create mode 100644 uvim/src/testdir/test_regex_char_classes.mnv delete mode 100644 uvim/src/testdir/test_regex_char_classes.vim create mode 100644 uvim/src/testdir/test_regexp_latin.mnv delete mode 100644 uvim/src/testdir/test_regexp_latin.vim create mode 100644 uvim/src/testdir/test_regexp_utf8.mnv delete mode 100644 uvim/src/testdir/test_regexp_utf8.vim create mode 100644 uvim/src/testdir/test_registers.mnv delete mode 100644 uvim/src/testdir/test_registers.vim create mode 100644 uvim/src/testdir/test_reltime.mnv delete mode 100644 uvim/src/testdir/test_reltime.vim create mode 100644 uvim/src/testdir/test_remote.mnv delete mode 100644 uvim/src/testdir/test_remote.vim create mode 100644 uvim/src/testdir/test_rename.mnv delete mode 100644 uvim/src/testdir/test_rename.vim create mode 100644 uvim/src/testdir/test_restricted.mnv delete mode 100644 uvim/src/testdir/test_restricted.vim create mode 100644 uvim/src/testdir/test_retab.mnv delete mode 100644 uvim/src/testdir/test_retab.vim create mode 100644 uvim/src/testdir/test_ruby.mnv delete mode 100644 uvim/src/testdir/test_ruby.vim create mode 100644 uvim/src/testdir/test_scriptnames.mnv delete mode 100644 uvim/src/testdir/test_scriptnames.vim create mode 100644 uvim/src/testdir/test_scroll_opt.mnv delete mode 100644 uvim/src/testdir/test_scroll_opt.vim create mode 100644 uvim/src/testdir/test_scrollbind.mnv delete mode 100644 uvim/src/testdir/test_scrollbind.vim create mode 100644 uvim/src/testdir/test_search.mnv delete mode 100644 uvim/src/testdir/test_search.vim create mode 100644 uvim/src/testdir/test_search_stat.mnv delete mode 100644 uvim/src/testdir/test_search_stat.vim create mode 100644 uvim/src/testdir/test_searchpos.mnv delete mode 100644 uvim/src/testdir/test_searchpos.vim create mode 100644 uvim/src/testdir/test_selectmode.mnv delete mode 100644 uvim/src/testdir/test_selectmode.vim create mode 100644 uvim/src/testdir/test_set.mnv delete mode 100644 uvim/src/testdir/test_set.vim create mode 100644 uvim/src/testdir/test_sha256.mnv delete mode 100644 uvim/src/testdir/test_sha256.vim create mode 100644 uvim/src/testdir/test_shell.mnv delete mode 100644 uvim/src/testdir/test_shell.vim create mode 100644 uvim/src/testdir/test_shift.mnv delete mode 100644 uvim/src/testdir/test_shift.vim create mode 100644 uvim/src/testdir/test_shortpathname.mnv delete mode 100644 uvim/src/testdir/test_shortpathname.vim create mode 100644 uvim/src/testdir/test_signals.mnv delete mode 100644 uvim/src/testdir/test_signals.vim create mode 100644 uvim/src/testdir/test_signs.mnv delete mode 100644 uvim/src/testdir/test_signs.vim create mode 100644 uvim/src/testdir/test_sleep.mnv delete mode 100644 uvim/src/testdir/test_sleep.vim create mode 100644 uvim/src/testdir/test_smartindent.mnv delete mode 100644 uvim/src/testdir/test_smartindent.vim create mode 100644 uvim/src/testdir/test_sort.mnv delete mode 100644 uvim/src/testdir/test_sort.vim create mode 100644 uvim/src/testdir/test_sound.mnv delete mode 100644 uvim/src/testdir/test_sound.vim create mode 100644 uvim/src/testdir/test_source.mnv delete mode 100644 uvim/src/testdir/test_source.vim create mode 100644 uvim/src/testdir/test_source_utf8.mnv delete mode 100644 uvim/src/testdir/test_source_utf8.vim create mode 100644 uvim/src/testdir/test_spell.mnv delete mode 100644 uvim/src/testdir/test_spell.vim create mode 100644 uvim/src/testdir/test_spell_utf8.mnv delete mode 100644 uvim/src/testdir/test_spell_utf8.vim create mode 100644 uvim/src/testdir/test_spellfile.mnv delete mode 100644 uvim/src/testdir/test_spellfile.vim create mode 100644 uvim/src/testdir/test_spellrare.mnv delete mode 100644 uvim/src/testdir/test_spellrare.vim create mode 100644 uvim/src/testdir/test_stacktrace.mnv delete mode 100644 uvim/src/testdir/test_stacktrace.vim create mode 100644 uvim/src/testdir/test_startup.mnv delete mode 100644 uvim/src/testdir/test_startup.vim create mode 100644 uvim/src/testdir/test_startup_utf8.mnv delete mode 100644 uvim/src/testdir/test_startup_utf8.vim create mode 100644 uvim/src/testdir/test_stat.mnv delete mode 100644 uvim/src/testdir/test_stat.vim create mode 100644 uvim/src/testdir/test_statusline.mnv delete mode 100644 uvim/src/testdir/test_statusline.vim create mode 100644 uvim/src/testdir/test_statuslineopt.mnv delete mode 100644 uvim/src/testdir/test_statuslineopt.vim create mode 100644 uvim/src/testdir/test_substitute.mnv delete mode 100644 uvim/src/testdir/test_substitute.vim create mode 100644 uvim/src/testdir/test_suspend.mnv delete mode 100644 uvim/src/testdir/test_suspend.vim create mode 100644 uvim/src/testdir/test_swap.mnv delete mode 100644 uvim/src/testdir/test_swap.vim create mode 100644 uvim/src/testdir/test_syn_attr.mnv delete mode 100644 uvim/src/testdir/test_syn_attr.vim create mode 100644 uvim/src/testdir/test_syntax.mnv delete mode 100644 uvim/src/testdir/test_syntax.vim create mode 100644 uvim/src/testdir/test_system.mnv delete mode 100644 uvim/src/testdir/test_system.vim create mode 100644 uvim/src/testdir/test_tab.mnv delete mode 100644 uvim/src/testdir/test_tab.vim create mode 100644 uvim/src/testdir/test_tabline.mnv delete mode 100644 uvim/src/testdir/test_tabline.vim create mode 100644 uvim/src/testdir/test_tabpage.mnv delete mode 100644 uvim/src/testdir/test_tabpage.vim create mode 100644 uvim/src/testdir/test_tabpanel.mnv delete mode 100644 uvim/src/testdir/test_tabpanel.vim create mode 100644 uvim/src/testdir/test_tagcase.mnv delete mode 100644 uvim/src/testdir/test_tagcase.vim create mode 100644 uvim/src/testdir/test_tagfunc.mnv delete mode 100644 uvim/src/testdir/test_tagfunc.vim create mode 100644 uvim/src/testdir/test_tagjump.mnv delete mode 100644 uvim/src/testdir/test_tagjump.vim create mode 100644 uvim/src/testdir/test_taglist.mnv delete mode 100644 uvim/src/testdir/test_taglist.vim create mode 100644 uvim/src/testdir/test_tcl.mnv delete mode 100644 uvim/src/testdir/test_tcl.vim create mode 100644 uvim/src/testdir/test_termcodes.mnv delete mode 100644 uvim/src/testdir/test_termcodes.vim create mode 100644 uvim/src/testdir/test_termencoding.mnv delete mode 100644 uvim/src/testdir/test_termencoding.vim create mode 100644 uvim/src/testdir/test_terminal.mnv delete mode 100644 uvim/src/testdir/test_terminal.vim create mode 100644 uvim/src/testdir/test_terminal2.mnv delete mode 100644 uvim/src/testdir/test_terminal2.vim create mode 100644 uvim/src/testdir/test_terminal3.mnv delete mode 100644 uvim/src/testdir/test_terminal3.vim create mode 100644 uvim/src/testdir/test_terminal_fail.mnv delete mode 100644 uvim/src/testdir/test_terminal_fail.vim create mode 100644 uvim/src/testdir/test_textformat.mnv delete mode 100644 uvim/src/testdir/test_textformat.vim create mode 100644 uvim/src/testdir/test_textobjects.mnv delete mode 100644 uvim/src/testdir/test_textobjects.vim create mode 100644 uvim/src/testdir/test_textprop.mnv delete mode 100644 uvim/src/testdir/test_textprop.vim create mode 100644 uvim/src/testdir/test_timers.mnv delete mode 100644 uvim/src/testdir/test_timers.vim create mode 100644 uvim/src/testdir/test_true_false.mnv delete mode 100644 uvim/src/testdir/test_true_false.vim create mode 100644 uvim/src/testdir/test_trycatch.mnv delete mode 100644 uvim/src/testdir/test_trycatch.vim create mode 100644 uvim/src/testdir/test_tuple.mnv delete mode 100644 uvim/src/testdir/test_tuple.vim create mode 100644 uvim/src/testdir/test_undo.mnv delete mode 100644 uvim/src/testdir/test_undo.vim create mode 100644 uvim/src/testdir/test_uniq.mnv delete mode 100644 uvim/src/testdir/test_uniq.vim create mode 100644 uvim/src/testdir/test_unlet.mnv delete mode 100644 uvim/src/testdir/test_unlet.vim create mode 100644 uvim/src/testdir/test_user_func.mnv delete mode 100644 uvim/src/testdir/test_user_func.vim create mode 100644 uvim/src/testdir/test_usercommands.mnv delete mode 100644 uvim/src/testdir/test_usercommands.vim create mode 100644 uvim/src/testdir/test_utf8.mnv delete mode 100644 uvim/src/testdir/test_utf8.vim create mode 100644 uvim/src/testdir/test_utf8_comparisons.mnv delete mode 100644 uvim/src/testdir/test_utf8_comparisons.vim create mode 100644 uvim/src/testdir/test_vartabs.mnv delete mode 100644 uvim/src/testdir/test_vartabs.vim create mode 100644 uvim/src/testdir/test_version.mnv delete mode 100644 uvim/src/testdir/test_version.vim delete mode 100644 uvim/src/testdir/test_vim9_assign.vim delete mode 100644 uvim/src/testdir/test_vim9_builtin.vim delete mode 100644 uvim/src/testdir/test_vim9_class.vim delete mode 100644 uvim/src/testdir/test_vim9_cmd.vim delete mode 100644 uvim/src/testdir/test_vim9_disassemble.vim delete mode 100644 uvim/src/testdir/test_vim9_enum.vim delete mode 100644 uvim/src/testdir/test_vim9_expr.vim delete mode 100644 uvim/src/testdir/test_vim9_fails.vim delete mode 100644 uvim/src/testdir/test_vim9_func.vim delete mode 100644 uvim/src/testdir/test_vim9_generics.vim delete mode 100644 uvim/src/testdir/test_vim9_import.vim delete mode 100644 uvim/src/testdir/test_vim9_interface.vim delete mode 100644 uvim/src/testdir/test_vim9_python3.vim delete mode 100644 uvim/src/testdir/test_vim9_script.vim delete mode 100644 uvim/src/testdir/test_vim9_typealias.vim delete mode 100644 uvim/src/testdir/test_viminfo.vim delete mode 100644 uvim/src/testdir/test_vimscript.vim create mode 100644 uvim/src/testdir/test_virtualedit.mnv delete mode 100644 uvim/src/testdir/test_virtualedit.vim create mode 100644 uvim/src/testdir/test_visual.mnv delete mode 100644 uvim/src/testdir/test_visual.vim create mode 100644 uvim/src/testdir/test_wayland.mnv delete mode 100644 uvim/src/testdir/test_wayland.vim create mode 100644 uvim/src/testdir/test_winbar.mnv delete mode 100644 uvim/src/testdir/test_winbar.vim create mode 100644 uvim/src/testdir/test_winbuf_close.mnv delete mode 100644 uvim/src/testdir/test_winbuf_close.vim create mode 100644 uvim/src/testdir/test_window_cmd.mnv delete mode 100644 uvim/src/testdir/test_window_cmd.vim create mode 100644 uvim/src/testdir/test_window_id.mnv delete mode 100644 uvim/src/testdir/test_window_id.vim create mode 100644 uvim/src/testdir/test_windows_home.mnv delete mode 100644 uvim/src/testdir/test_windows_home.vim create mode 100644 uvim/src/testdir/test_winfixbuf.mnv delete mode 100644 uvim/src/testdir/test_winfixbuf.vim create mode 100644 uvim/src/testdir/test_wnext.mnv delete mode 100644 uvim/src/testdir/test_wnext.vim create mode 100644 uvim/src/testdir/test_wordcount.mnv delete mode 100644 uvim/src/testdir/test_wordcount.vim create mode 100644 uvim/src/testdir/test_writefile.mnv delete mode 100644 uvim/src/testdir/test_writefile.vim create mode 100644 uvim/src/testdir/test_xdg.mnv delete mode 100644 uvim/src/testdir/test_xdg.vim create mode 100644 uvim/src/testdir/test_xxd.mnv delete mode 100644 uvim/src/testdir/test_xxd.vim create mode 100644 uvim/src/testdir/util/amiga.mnv delete mode 100644 uvim/src/testdir/util/amiga.vim create mode 100644 uvim/src/testdir/util/check.mnv delete mode 100644 uvim/src/testdir/util/check.vim create mode 100644 uvim/src/testdir/util/color_ramp.mnv delete mode 100644 uvim/src/testdir/util/color_ramp.vim create mode 100644 uvim/src/testdir/util/dos.mnv delete mode 100644 uvim/src/testdir/util/dos.vim create mode 100644 uvim/src/testdir/util/gen_opt_test.mnv delete mode 100644 uvim/src/testdir/util/gen_opt_test.vim create mode 100644 uvim/src/testdir/util/gui_init.mnv delete mode 100644 uvim/src/testdir/util/gui_init.vim create mode 100644 uvim/src/testdir/util/gui_preinit.mnv delete mode 100644 uvim/src/testdir/util/gui_preinit.vim create mode 100644 uvim/src/testdir/util/mnv9.mnv create mode 100644 uvim/src/testdir/util/mouse.mnv delete mode 100644 uvim/src/testdir/util/mouse.vim create mode 100644 uvim/src/testdir/util/popupbounce.mnv delete mode 100644 uvim/src/testdir/util/popupbounce.vim create mode 100644 uvim/src/testdir/util/screendump.mnv delete mode 100644 uvim/src/testdir/util/screendump.vim create mode 100644 uvim/src/testdir/util/script_util.mnv delete mode 100644 uvim/src/testdir/util/script_util.vim create mode 100644 uvim/src/testdir/util/setup.mnv delete mode 100644 uvim/src/testdir/util/setup.vim create mode 100644 uvim/src/testdir/util/setup_gui.mnv delete mode 100644 uvim/src/testdir/util/setup_gui.vim create mode 100644 uvim/src/testdir/util/shared.mnv delete mode 100644 uvim/src/testdir/util/shared.vim create mode 100644 uvim/src/testdir/util/socketserver.mnv delete mode 100644 uvim/src/testdir/util/socketserver.vim create mode 100644 uvim/src/testdir/util/summarize.mnv delete mode 100644 uvim/src/testdir/util/summarize.vim create mode 100644 uvim/src/testdir/util/term_util.mnv delete mode 100644 uvim/src/testdir/util/term_util.vim create mode 100644 uvim/src/testdir/util/unix.mnv delete mode 100644 uvim/src/testdir/util/unix.vim create mode 100644 uvim/src/testdir/util/view_util.mnv delete mode 100644 uvim/src/testdir/util/view_util.vim delete mode 100644 uvim/src/testdir/util/vim9.vim create mode 100644 uvim/src/testdir/util/vms.mnv delete mode 100644 uvim/src/testdir/util/vms.vim create mode 100644 uvim/src/testdir/util/window_manager.mnv delete mode 100644 uvim/src/testdir/util/window_manager.vim create mode 100644 uvim/src/testdir/viewdumps.mnv delete mode 100644 uvim/src/testdir/viewdumps.vim (limited to 'uvim/src/testdir') diff --git a/uvim/src/testdir/Make_all.mak b/uvim/src/testdir/Make_all.mak index 28a5ec663a..97388d20a1 100644 --- a/uvim/src/testdir/Make_all.mak +++ b/uvim/src/testdir/Make_all.mak @@ -37,40 +37,40 @@ SCRIPTS_TINY_OUT = \ test28.out \ test29.out -# Tests for Vim9 script. -TEST_VIM9 = \ - test_vim9_assign \ - test_vim9_builtin \ - test_vim9_class \ - test_vim9_cmd \ - test_vim9_disassemble \ - test_vim9_enum \ - test_vim9_expr \ - test_vim9_fails \ - test_vim9_func \ - test_vim9_generics \ - test_vim9_import \ - test_vim9_interface \ - test_vim9_python3 \ - test_vim9_script \ - test_vim9_typealias +# Tests for MNV9 script. +TEST_MNV9 = \ + test_mnv9_assign \ + test_mnv9_builtin \ + test_mnv9_class \ + test_mnv9_cmd \ + test_mnv9_disassemble \ + test_mnv9_enum \ + test_mnv9_expr \ + test_mnv9_fails \ + test_mnv9_func \ + test_mnv9_generics \ + test_mnv9_import \ + test_mnv9_interface \ + test_mnv9_python3 \ + test_mnv9_script \ + test_mnv9_typealias -TEST_VIM9_RES = \ - test_vim9_assign.res \ - test_vim9_builtin.res \ - test_vim9_class.res \ - test_vim9_cmd.res \ - test_vim9_disassemble.res \ - test_vim9_enum.res \ - test_vim9_expr.res \ - test_vim9_fails.res \ - test_vim9_func.res \ - test_vim9_generics.res \ - test_vim9_import.res \ - test_vim9_interface.res \ - test_vim9_python3.res \ - test_vim9_script.res \ - test_vim9_typealias.res +TEST_MNV9_RES = \ + test_mnv9_assign.res \ + test_mnv9_builtin.res \ + test_mnv9_class.res \ + test_mnv9_cmd.res \ + test_mnv9_disassemble.res \ + test_mnv9_enum.res \ + test_mnv9_expr.res \ + test_mnv9_fails.res \ + test_mnv9_func.res \ + test_mnv9_generics.res \ + test_mnv9_import.res \ + test_mnv9_interface.res \ + test_mnv9_python3.res \ + test_mnv9_script.res \ + test_mnv9_typealias.res # Benchmark scripts. SCRIPTS_BENCH = test_bench_regexp.res @@ -349,9 +349,9 @@ NEW_TESTS = \ test_utf8_comparisons \ test_vartabs \ test_version \ - $(TEST_VIM9) \ - test_viminfo \ - test_vimscript \ + $(TEST_MNV9) \ + test_mnvinfo \ + test_mnvscript \ test_virtualedit \ test_visual \ test_wayland \ @@ -370,7 +370,7 @@ NEW_TESTS = \ test_alot_utf8 \ test_alot -# Test targets that use runtest.vim. +# Test targets that use runtest.mnv. # Keep test_alot*.res as the last one, sort the others. # test_largefile.res is omitted, it uses too much resources to run on CI. NEW_TESTS_RES = \ @@ -608,9 +608,9 @@ NEW_TESTS_RES = \ test_user_func.res \ test_usercommands.res \ test_vartabs.res \ - $(TEST_VIM9_RES) \ - test_viminfo.res \ - test_vimscript.res \ + $(TEST_MNV9_RES) \ + test_mnvinfo.res \ + test_mnvscript.res \ test_virtualedit.res \ test_visual.res \ test_wayland.res \ diff --git a/uvim/src/testdir/Make_amiga.mak b/uvim/src/testdir/Make_amiga.mak index 6ffc12dfce..a5cc13fd95 100644 --- a/uvim/src/testdir/Make_amiga.mak +++ b/uvim/src/testdir/Make_amiga.mak @@ -1,9 +1,9 @@ # -# Makefile to run all tests for Vim, on Amiga +# Makefile to run all tests for MNV, on Amiga # # Requires "rm", "csh" and "diff"! -VIMPROG = /vim +MNVPROG = /mnv default: nongui @@ -11,17 +11,17 @@ include Make_all.mak SCRIPTS = $(SCRIPTS_TINY_OUT) -.SUFFIXES: .in .out .res .vim +.SUFFIXES: .in .out .res .mnv nongui: /tmp $(SCRIPTS) csh -c echo ALL DONE clean: - csh -c \rm -rf *.out Xdir1 Xfind XfakeHOME Xdotest test.ok viminfo + csh -c \rm -rf *.out Xdir1 Xfind XfakeHOME Xdotest test.ok mnvinfo .in.out: copy $*.ok test.ok - $(VIMPROG) -u util/amiga.vim -U NONE --noplugin --not-a-term -s dotest.in $*.in + $(MNVPROG) -u util/amiga.mnv -U NONE --noplugin --not-a-term -s dotest.in $*.in diff test.out $*.ok rename test.out $*.out -delete X#? ALL QUIET diff --git a/uvim/src/testdir/Make_ming.mak b/uvim/src/testdir/Make_ming.mak index 8d54500dec..1f0fed3598 100644 --- a/uvim/src/testdir/Make_ming.mak +++ b/uvim/src/testdir/Make_ming.mak @@ -1,5 +1,5 @@ # -# Makefile to run all tests for Vim, on Dos-like machines +# Makefile to run all tests for MNV, on Dos-like machines # with sh.exe or zsh.exe in the path or not. # # Author: Bill McCarthy @@ -15,21 +15,21 @@ MV = move /y CP = copy /y CAT = type -VIMPROG = ..\\vim +MNVPROG = ..\\mnv default: nongui include Make_all.mak # Explicit dependencies. -test_options_all.res: opt_test.vim +test_options_all.res: opt_test.mnv TEST_OUTFILES = $(SCRIPTS_TINY_OUT) DOSTMP = dostmp # Keep $(DOSTMP)/*.in .PRECIOUS: $(patsubst %.out, $(DOSTMP)/%.in, $(TEST_OUTFILES)) -.SUFFIXES: .in .out .res .vim +.SUFFIXES: .in .out .res .mnv # Add --gui-dialog-file to avoid getting stuck in a dialog. COMMON_ARGS = $(NO_INITS) --gui-dialog-file guidialog @@ -46,7 +46,7 @@ report: @rem without the +eval feature test_result.log is a copy of test.log @if exist test.log ( copy /y test.log test_result.log > nul ) \ else ( echo No failures reported > test_result.log ) - $(VIMPROG) -u NONE $(COMMON_ARGS) -S util\summarize.vim messages + $(MNVPROG) -u NONE $(COMMON_ARGS) -S util\summarize.mnv messages -if exist starttime del starttime @echo. @echo Test results: @@ -62,7 +62,7 @@ $(NEW_TESTS): -if exist test.log del test.log -if exist messages del messages -if exist starttime del starttime - @$(MAKE) -f Make_ming.mak $@.res VIMPROG=$(VIMPROG) --no-print-directory + @$(MAKE) -f Make_ming.mak $@.res MNVPROG=$(MNVPROG) --no-print-directory @type messages @if exist test.log exit 1 @@ -81,13 +81,13 @@ clean: -@if exist XfakeHOME $(DELDIR) XfakeHOME -@if exist X* $(DEL) X* -@for /d %%i in (X*) do @rd /s/q %%i - -@if exist viminfo $(DEL) viminfo + -@if exist mnvinfo $(DEL) mnvinfo -@if exist test.log $(DEL) test.log -@if exist test_result.log del test_result.log -@if exist messages $(DEL) messages -@if exist starttime $(DEL) starttime -@if exist benchmark.out del benchmark.out - -@if exist opt_test.vim $(DEL) opt_test.vim + -@if exist opt_test.mnv $(DEL) opt_test.mnv -@if exist gen_opt_test.log $(DEL) gen_opt_test.log -@if exist guidialog $(DEL) guidialog -@if exist guidialogfile $(DEL) guidialogfile @@ -106,7 +106,7 @@ tinytests: $(SCRIPTS_TINY_OUT) $(DOSTMP)/%.in : %.in if not exist $(DOSTMP)\nul mkdir $(DOSTMP) if exist $(DOSTMP)\$< $(DEL) $(DOSTMP)\$< - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) "+set ff=dos|f $@|wq" $< + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) "+set ff=dos|f $@|wq" $< # For each input file dostmp/test99.in run the tests. # This moves test99.in to test99.in.bak temporarily. @@ -116,7 +116,7 @@ $(DOSTMP)/%.in : %.in $(MV) $(notdir $<) $(notdir $<).bak > NUL $(CP) $(DOSTMP)\$(notdir $<) $(notdir $<) > NUL $(CP) $(basename $@).ok test.ok > NUL - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) -s dotest.in $(notdir $<) + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) -s dotest.in $(notdir $<) -@if exist test.out $(MV) test.out $(DOSTMP)\$@ > NUL -@if exist $(notdir $<).bak $(MV) $(notdir $<).bak $(notdir $<) > NUL -@if exist test.ok $(DEL) test.ok @@ -124,8 +124,8 @@ $(DOSTMP)/%.in : %.in -@if exist Xfind $(DELDIR) Xfind -@if exist XfakeHOME $(DELDIR) XfakeHOME -@del X* - -@if exist viminfo del viminfo - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ + -@if exist mnvinfo del mnvinfo + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ $(DOSTMP)\$@ @diff test.out $(basename $@).ok & if errorlevel 1 \ ( $(MV) test.out $(basename $@).failed > NUL \ @@ -134,7 +134,7 @@ $(DOSTMP)/%.in : %.in else ( $(MV) test.out $(basename $@).out > NUL ) -# New style of tests uses Vim script with assert calls. These are easier +# New style of tests uses MNV script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. @@ -143,28 +143,28 @@ newtests: newtestssilent newtestssilent: $(NEW_TESTS_RES) -.vim.res: - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @$(DEL) vimcmd +.mnv.res: + @echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $*.mnv + @$(DEL) mnvcmd -test_gui.res: test_gui.vim - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $< - @$(DEL) vimcmd +test_gui.res: test_gui.mnv + @echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $< + @$(DEL) mnvcmd -test_gui_init.res: test_gui_init.vim - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u util\gui_preinit.vim -U util\gui_init.vim $(NO_PLUGINS) -S runtest.vim $< - @$(DEL) vimcmd +test_gui_init.res: test_gui_init.mnv + @echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u util\gui_preinit.mnv -U util\gui_init.mnv $(NO_PLUGINS) -S runtest.mnv $< + @$(DEL) mnvcmd -opt_test.vim: util/gen_opt_test.vim ../optiondefs.h ../../runtime/doc/options.txt - $(VIMPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $^ +opt_test.mnv: util/gen_opt_test.mnv ../optiondefs.h ../../runtime/doc/options.txt + $(MNVPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $^ @if exist gen_opt_test.log ( type gen_opt_test.log & exit /b 1 ) -test_bench_regexp.res: test_bench_regexp.vim +test_bench_regexp.res: test_bench_regexp.mnv -$(DEL) benchmark.out - @echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @$(DEL) vimcmd + @echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $*.mnv + @$(DEL) mnvcmd $(CAT) benchmark.out diff --git a/uvim/src/testdir/Make_mvc.mak b/uvim/src/testdir/Make_mvc.mak index 5b492d7dc3..1a8376d646 100644 --- a/uvim/src/testdir/Make_mvc.mak +++ b/uvim/src/testdir/Make_mvc.mak @@ -1,5 +1,5 @@ # -# Makefile to run all tests for Vim, on Dos-like machines. +# Makefile to run all tests for MNV, on Dos-like machines. # # Requires a set of Unix tools: echo, diff, etc. # @@ -8,10 +8,10 @@ !INCLUDE ..\auto\nmake\tools.mak # Testing may be done with a debug build -!IF EXIST(..\\vimd.exe) && !EXIST(..\\vim.exe) -VIMPROG = ..\\vimd.exe +!IF EXIST(..\\mnvd.exe) && !EXIST(..\\mnv.exe) +MNVPROG = ..\\mnvd.exe !ELSE -VIMPROG = ..\\vim.exe +MNVPROG = ..\\mnv.exe !ENDIF DIFF = diff.exe @@ -21,14 +21,14 @@ default: nongui !INCLUDE .\Make_all.mak # Explicit dependencies. -test_options_all.res: opt_test.vim +test_options_all.res: opt_test.mnv TEST_OUTFILES = $(SCRIPTS_TINY_OUT) DOSTMP = dostmp DOSTMP_OUTFILES = $(TEST_OUTFILES:test=dostmp\test) DOSTMP_INFILES = $(DOSTMP_OUTFILES:.out=.in) -.SUFFIXES: .in .out .res .vim +.SUFFIXES: .in .out .res .mnv # Add --gui-dialog-file to avoid getting stuck in a dialog. COMMON_ARGS = $(NO_INITS) --gui-dialog-file guidialog @@ -46,7 +46,7 @@ codestyle: -@ if exist test.log $(RM) test.log -@ if exist messages $(RM) messages -@ if exist starttime $(RM) starttime - @ $(MAKE) -lf Make_mvc.mak VIMPROG=$(VIMPROG) test_codestyle.res + @ $(MAKE) -lf Make_mvc.mak MNVPROG=$(MNVPROG) test_codestyle.res @ type messages @ if exist test.log exit 1 @@ -54,7 +54,7 @@ report: @ rem without the +eval feature test_result.log is a copy of test.log @ if exist test.log ( $(CP) test.log test_result.log > nul ) \ else ( echo No failures reported > test_result.log ) - $(VIMPROG) -u NONE $(COMMON_ARGS) -S util\summarize.vim messages + $(MNVPROG) -u NONE $(COMMON_ARGS) -S util\summarize.mnv messages - if exist starttime $(RM) starttime @ echo: @ echo Test results: @@ -70,7 +70,7 @@ $(NEW_TESTS): - if exist test.log $(RM) test.log - if exist messages $(RM) messages - if exist starttime $(RM) starttime - @ $(MAKE) -lf Make_mvc.mak VIMPROG=$(VIMPROG) $@.res + @ $(MAKE) -lf Make_mvc.mak MNVPROG=$(MNVPROG) $@.res @ type messages @ if exist test.log exit 1 @@ -89,13 +89,13 @@ clean: - if exist XfakeHOME $(RD) XfakeHOME - if exist X* $(RM) X* - for /d %i in (X*) do @$(RD) %i - - if exist viminfo $(RM) viminfo + - if exist mnvinfo $(RM) mnvinfo - if exist test.log $(RM) test.log - if exist test_result.log $(RM) test_result.log - if exist messages $(RM) messages - if exist starttime $(RM) starttime - if exist benchmark.out $(RM) benchmark.out - - if exist opt_test.vim $(RM) opt_test.vim + - if exist opt_test.mnv $(RM) opt_test.mnv - if exist gen_opt_test.log $(RM) gen_opt_test.log - if exist guidialog $(RM) guidialog - if exist guidialogfile $(RM) guidialogfile @@ -114,7 +114,7 @@ tinytests: $(SCRIPTS_TINY_OUT) $(DOSTMP_INFILES): $(*B).in if not exist $(DOSTMP)\NUL $(MKD) $(DOSTMP) if exist $@ $(RM) $@ - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) "+set ff=dos|f $@|wq" $(*B).in + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) "+set ff=dos|f $@|wq" $(*B).in # For each input file dostmp/test99.in run the tests. # This moves test99.in to test99.in.bak temporarily. @@ -124,7 +124,7 @@ $(TEST_OUTFILES): $(DOSTMP)\$(*B).in $(MV) $(*B).in $(*B).in.bak > nul $(CP) $(DOSTMP)\$(*B).in $(*B).in > nul $(CP) $(*B).ok test.ok > nul - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) -s dotest.in $(*B).in + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) -s dotest.in $(*B).in -@ if exist test.out $(MV) test.out $(DOSTMP)\$(*B).out > nul -@ if exist $(*B).in.bak $(MV) $(*B).in.bak $(*B).in > nul -@ if exist test.ok $(RM) test.ok @@ -132,8 +132,8 @@ $(TEST_OUTFILES): $(DOSTMP)\$(*B).in -@ if exist Xfind $(RD) Xfind -@ if exist XfakeHOME $(RD) XfakeHOME -@ $(RM) X* - -@ if exist viminfo $(RM) viminfo - $(VIMPROG) -u util\dos.vim $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ + -@ if exist mnvinfo $(RM) mnvinfo + $(MNVPROG) -u util\dos.mnv $(COMMON_ARGS) "+set ff=unix|f test.out|wq" \ $(DOSTMP)\$(*B).out @ $(DIFF) test.out $*.ok & if errorlevel 1 \ ( $(MV) test.out $*.failed > nul \ @@ -142,7 +142,7 @@ $(TEST_OUTFILES): $(DOSTMP)\$(*B).in else ( $(MV) test.out $*.out > nul ) -# New style of tests uses Vim script with assert calls. These are easier +# New style of tests uses MNV script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. @@ -151,32 +151,32 @@ newtests: newtestssilent newtestssilent: $(NEW_TESTS_RES) -.vim.res: - @ echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @ $(RM) vimcmd +.mnv.res: + @ echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $*.mnv + @ $(RM) mnvcmd -test_gui.res: test_gui.vim - @ echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @ $(RM) vimcmd +test_gui.res: test_gui.mnv + @ echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $*.mnv + @ $(RM) mnvcmd -test_gui_init.res: test_gui_init.vim - @ echo $(VIMPROG) > vimcmd - $(VIMPROG) -u util\gui_preinit.vim -U util\gui_init.vim $(NO_PLUGINS) \ - -S runtest.vim $*.vim - @ $(RM) vimcmd +test_gui_init.res: test_gui_init.mnv + @ echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u util\gui_preinit.mnv -U util\gui_init.mnv $(NO_PLUGINS) \ + -S runtest.mnv $*.mnv + @ $(RM) mnvcmd -opt_test.vim: util/gen_opt_test.vim ../optiondefs.h \ +opt_test.mnv: util/gen_opt_test.mnv ../optiondefs.h \ ../../runtime/doc/options.txt - $(VIMPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $** + $(MNVPROG) -e -s -u NONE $(COMMON_ARGS) --nofork -S $** @ if exist gen_opt_test.log ( type gen_opt_test.log & exit /b 1 ) -test_bench_regexp.res: test_bench_regexp.vim +test_bench_regexp.res: test_bench_regexp.mnv - if exist benchmark.out $(RM) benchmark.out - @ echo $(VIMPROG) > vimcmd - $(VIMPROG) -u NONE $(COMMON_ARGS) -S runtest.vim $*.vim - @ $(RM) vimcmd + @ echo $(MNVPROG) > mnvcmd + $(MNVPROG) -u NONE $(COMMON_ARGS) -S runtest.mnv $*.mnv + @ $(RM) mnvcmd @ if exist benchmark.out ( type benchmark.out ) -# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=79 ft=make: +# mnv: set noet sw=8 ts=8 sts=0 wm=0 tw=79 ft=make: diff --git a/uvim/src/testdir/Make_vms.mms b/uvim/src/testdir/Make_vms.mms index ad21395008..8e5d7b11da 100644 --- a/uvim/src/testdir/Make_vms.mms +++ b/uvim/src/testdir/Make_vms.mms @@ -1,5 +1,5 @@ # -# Makefile to run all tests for Vim on VMS +# Makefile to run all tests for MNV on VMS # # Authors: Zoltan Arpadffy, # Sandor Kopanyi, @@ -33,7 +33,7 @@ # Please, do not change anything below without programming experience. ####################################################################### -VIMPROG = <->vim.exe +MNVPROG = <->mnv.exe .SUFFIXES : .out .in @@ -56,7 +56,7 @@ GUI_OPTION = -g -@ write sys$output " "$*" " -@ write sys$output "-----------------------------------------------" -@ !run the test - -@ create/term/wait/nodetach mcr $(VIMPROG) $(GUI_OPTION) -u util/vms.vim --noplugin -s dotest.in $*.in + -@ create/term/wait/nodetach mcr $(MNVPROG) $(GUI_OPTION) -u util/vms.mnv --noplugin -s dotest.in $*.in -@ !analyse the result -@ directory /size/date test.out -@ if "''F$SEARCH("test.out.*")'" .NES. "" then rename/nolog test.out $*.out @@ -77,11 +77,11 @@ all : clean nolog $(START_WITH) $(SCRIPT) nolog nolog : -@ define sys$output test.log -@ write sys$output "-----------------------------------------------" - -@ write sys$output " Standard VIM test cases" + -@ write sys$output " Standard MNV test cases" -@ write sys$output "-----------------------------------------------" -@ write sys$output " OpenVMS version: ''F$GETSYI("VERSION")'" - -@ write sys$output " Vim version:" - -@ mcr $(VIMPROG) --version + -@ write sys$output " MNV version:" + -@ mcr $(MNVPROG) --version -@ write sys$output " Test date:" -@ show time -@ write sys$output "-----------------------------------------------" @@ -89,9 +89,9 @@ nolog : -@ write sys$output "-----------------------------------------------" -@ write sys$output "MAKE_VMS.MMS options:" -@ write sys$output " WANT_GUI = ""$(WANT_GUI)"" " - -@ write sys$output "Default vimrc file is util/VMS.VIM:" + -@ write sys$output "Default mnvrc file is util/VMS.MNV:" -@ write sys$output "-----------------------------------------------" - -@ type util/VMS.VIM + -@ type util/VMS.MNV clean : -@ if "''F$SEARCH("*.out")'" .NES. "" then delete/noconfirm/nolog *.out.* @@ -104,5 +104,5 @@ clean : -@ if "''F$SEARCH("*.*_sw*")'" .NES. "" then delete/noconfirm/nolog *.*_sw*.* -@ if "''F$SEARCH("*.failed")'" .NES. "" then delete/noconfirm/nolog *.failed.* -@ if "''F$SEARCH("*.rej")'" .NES. "" then delete/noconfirm/nolog *.rej.* - -@ if "''F$SEARCH("viminfo.*")'" .NES. "" then delete/noconfirm/nolog viminfo.*.* + -@ if "''F$SEARCH("mnvinfo.*")'" .NES. "" then delete/noconfirm/nolog mnvinfo.*.* diff --git a/uvim/src/testdir/Makefile b/uvim/src/testdir/Makefile index 2e1d900b88..b3f0818302 100644 --- a/uvim/src/testdir/Makefile +++ b/uvim/src/testdir/Makefile @@ -1,11 +1,11 @@ # -# Makefile to run all tests for Vim +# Makefile to run all tests for MNV # # Use console or GUI. -VIMPROG = ../vim +MNVPROG = ../mnv XXDPROG = ../xxd/xxd -# VIMPROG = ../gvim +# MNVPROG = ../gmnv SCRIPTSOURCE = ../../runtime @@ -16,12 +16,12 @@ REDIR_TEST_TO_NULL = --cmd 'au SwapExists * let v:swapchoice = "e"' | LC_ALL=C a # Uncomment this line to use valgrind for memory leaks and extra warnings. # The output goes into a file "valgrind.testN" -# Vim should be compiled with EXITFREE to avoid false warnings. +# MNV should be compiled with EXITFREE to avoid false warnings. # This will make testing about 10 times as slow. # VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=45 --log-file=valgrind.$* # To execute one test, e.g. in gdb, use something like this: -# run -f -u util/unix.vim --gui-dialog-file guidialog -U NONE --noplugin --not-a-term -S runtest.vim test_name.vim +# run -f -u util/unix.mnv --gui-dialog-file guidialog -U NONE --noplugin --not-a-term -S runtest.mnv test_name.mnv default: nongui @@ -30,9 +30,9 @@ default: nongui include Make_all.mak # Explicit dependencies. -test_options_all.res: opt_test.vim +test_options_all.res: opt_test.mnv -.SUFFIXES: .in .out .res .vim +.SUFFIXES: .in .out .res .mnv nongui: nolog tinytests newtests report @@ -48,7 +48,7 @@ report: then cp test.log test_result.log; \ else echo No failures reported > test_result.log; \ fi" - $(VIMPROG) -u NONE $(NO_INITS) -S util/summarize.vim messages $(REDIR_TEST_TO_NULL) + $(MNVPROG) -u NONE $(NO_INITS) -S util/summarize.mnv messages $(REDIR_TEST_TO_NULL) @rm -f starttime @echo @echo 'Test results:' @@ -58,7 +58,7 @@ report: else echo ALL DONE; \ fi" -$(SCRIPTS_TINY_OUT) $(NEW_TESTS_RES): $(VIMPROG) +$(SCRIPTS_TINY_OUT) $(NEW_TESTS_RES): $(MNVPROG) # For $ASAN_OPTIONS and $UBSAN_OPTIONS append the testname to it. # This assumes $ASAN_OPTIONS contains log_path as last part of the environment variable @@ -68,7 +68,7 @@ $(SCRIPTS_TINY_OUT) $(NEW_TESTS_RES): $(VIMPROG) # make test_largefile $(NEW_TESTS): rm -f $@.res $(CLEANUP_FILES) - @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $@.res VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) + @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $@.res MNVPROG=$(MNVPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) @cat messages @if test -f test.log; then \ exit 1; \ @@ -76,32 +76,32 @@ $(NEW_TESTS): codestyle: rm -f test_codestyle.res $(CLEANUP_FILES) - @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile test_codestyle.res VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) + @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile test_codestyle.res MNVPROG=$(MNVPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) @cat messages @if test -f test.log; then \ exit 1; \ fi -# Run only tests specific for Vim9 script -test_vim9: - rm -f test_vim9_*.res $(CLEANUP_FILES) - @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $(TEST_VIM9_RES) VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) +# Run only tests specific for MNV9 script +test_mnv9: + rm -f test_mnv9_*.res $(CLEANUP_FILES) + @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $(TEST_MNV9_RES) MNVPROG=$(MNVPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) @cat messages @rm -f starttime - @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile report VIMPROG=$(VIMPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) + @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile report MNVPROG=$(MNVPROG) XXDPROG=$(XXDPROG) SCRIPTSOURCE=$(SCRIPTSOURCE) @if test -f test.log; then \ exit 1; \ fi -RM_ON_RUN = test.out X* viminfo +RM_ON_RUN = test.out X* mnvinfo RM_ON_START = test.ok benchmark.out -RUN_VIMPROG = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u util/unix.vim $(NO_INITS) -s dotest.in +RUN_MNVPROG = MNVRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(MNVPROG) -f $(GUI_FLAG) -u util/unix.mnv $(NO_INITS) -s dotest.in # Delete files that may interfere with running tests. This includes some files # that may result from working on the tests, not only from running them. clean: -rm -rf *.out *.failed *.res *.rej *.orig XfakeHOME Xdir1 Xfind failed - -rm -f opt_test.vim test_result.log $(CLEANUP_FILES) + -rm -f opt_test.mnv test_result.log $(CLEANUP_FILES) -rm -f gen_opt_test.log -rm -rf $(RM_ON_RUN) $(RM_ON_START) -rm -f valgrind.* @@ -127,9 +127,9 @@ tinytests: $(SCRIPTS_TINY_OUT) @# a second, fall back to a second if it fails. @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMPROG) $*.in $(REDIR_TEST_TO_NULL) ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVPROG) $*.in $(REDIR_TEST_TO_NULL) ; \ else \ - $(RUN_VIMPROG) $*.in $(REDIR_TEST_TO_NULL) ; \ + $(RUN_MNVPROG) $*.in $(REDIR_TEST_TO_NULL) ; \ fi @# Check if the test.out file matches test.ok. @@ -143,14 +143,14 @@ tinytests: $(SCRIPTS_TINY_OUT) @/bin/sh -c "if test -f valgrind; then\ mv -f valgrind valgrind.$*; \ fi" - -rm -rf X* test.ok viminfo + -rm -rf X* test.ok mnvinfo -# New style of tests uses Vim script with assert calls. These are easier +# New style of tests uses MNV script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. # Add --gui-dialog-file to avoid getting stuck in a dialog. -RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u util/unix.vim --gui-dialog-file guidialog +RUN_MNVTEST = MNVRUNTIME=$(SCRIPTSOURCE) $(VALGRIND) $(MNVPROG) -f $(GUI_FLAG) -u util/unix.mnv --gui-dialog-file guidialog newtests: newtestssilent @/bin/sh -c "if test -f messages; then cat messages; fi" @@ -158,44 +158,44 @@ newtests: newtestssilent newtestssilent: $(NEW_TESTS_RES) -.vim.res: - @echo "$(VIMPROG)" > vimcmd - @echo "$(RUN_VIMTEST)" >> vimcmd +.mnv.res: + @echo "$(MNVPROG)" > mnvcmd + @echo "$(RUN_MNVTEST)" >> mnvcmd if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL) ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv $*.mnv $(REDIR_TEST_TO_NULL) ; \ else \ - $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL) ; \ + $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv $*.mnv $(REDIR_TEST_TO_NULL) ; \ fi - @rm vimcmd + @rm mnvcmd -test_gui.res: test_gui.vim - @echo "$(VIMPROG)" > vimcmd - @echo "$(RUN_GVIMTEST)" >> vimcmd +test_gui.res: test_gui.mnv + @echo "$(MNVPROG)" > mnvcmd + @echo "$(RUN_GMNVTEST)" >> mnvcmd if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMTEST) -u NONE $(NO_INITS) -S runtest.vim $< ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVTEST) -u NONE $(NO_INITS) -S runtest.mnv $< ; \ else \ - $(RUN_VIMTEST) -u NONE $(NO_INITS) -S runtest.vim $< ; \ + $(RUN_MNVTEST) -u NONE $(NO_INITS) -S runtest.mnv $< ; \ fi - @rm vimcmd + @rm mnvcmd -test_gui_init.res: test_gui_init.vim - @echo "$(VIMPROG)" > vimcmd - @echo "$(RUN_GVIMTEST_WITH_GVIMRC)" >> vimcmd +test_gui_init.res: test_gui_init.mnv + @echo "$(MNVPROG)" > mnvcmd + @echo "$(RUN_GMNVTEST_WITH_GMNVRC)" >> mnvcmd if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMTEST) -u util/gui_preinit.vim -U util/gui_init.vim $(NO_PLUGINS) -S runtest.vim $< ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVTEST) -u util/gui_preinit.mnv -U util/gui_init.mnv $(NO_PLUGINS) -S runtest.mnv $< ; \ else \ - $(RUN_VIMTEST) -u util/gui_preinit.vim -U util/gui_init.vim $(NO_PLUGINS) -S runtest.vim $< ; \ + $(RUN_MNVTEST) -u util/gui_preinit.mnv -U util/gui_init.mnv $(NO_PLUGINS) -S runtest.mnv $< ; \ fi - @rm vimcmd + @rm mnvcmd -GEN_OPT_DEPS = util/gen_opt_test.vim ../optiondefs.h ../../runtime/doc/options.txt +GEN_OPT_DEPS = util/gen_opt_test.mnv ../optiondefs.h ../../runtime/doc/options.txt -opt_test.vim: $(GEN_OPT_DEPS) +opt_test.mnv: $(GEN_OPT_DEPS) if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(VIMPROG) -e -s -u NONE $(NO_INITS) --nofork --gui-dialog-file guidialog -S $(GEN_OPT_DEPS) ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(MNVPROG) -e -s -u NONE $(NO_INITS) --nofork --gui-dialog-file guidialog -S $(GEN_OPT_DEPS) ; \ else \ - $(VIMPROG) -e -s -u NONE $(NO_INITS) --nofork --gui-dialog-file guidialog -S $(GEN_OPT_DEPS) ; \ + $(MNVPROG) -e -s -u NONE $(NO_INITS) --nofork --gui-dialog-file guidialog -S $(GEN_OPT_DEPS) ; \ fi @if test -f gen_opt_test.log; then \ cat gen_opt_test.log; \ @@ -204,20 +204,20 @@ opt_test.vim: $(GEN_OPT_DEPS) test_xxd.res: if test -n "$${ASAN_OPTIONS}"; then \ - XXD=$(XXDPROG); export XXD; ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim test_xxd.vim ; \ + XXD=$(XXDPROG); export XXD; ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv test_xxd.mnv ; \ else \ - XXD=$(XXDPROG); export XXD; $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim test_xxd.vim ; \ + XXD=$(XXDPROG); export XXD; $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv test_xxd.mnv ; \ fi -test_bench_regexp.res: test_bench_regexp.vim +test_bench_regexp.res: test_bench_regexp.mnv -rm -rf benchmark.out $(RM_ON_RUN) @# Sleep a moment to avoid that the xterm title is messed up. @# 200 msec is sufficient, but only modern sleep supports a fraction of @# a second, fall back to a second if it fails. @-/bin/sh -c "sleep .2 > /dev/null 2>&1 || sleep 1" if test -n "$${ASAN_OPTIONS}"; then \ - ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL) ; \ + ASAN_OPTIONS="$${ASAN_OPTIONS}_$*" UBSAN_OPTIONS="$${UBSAN_OPTIONS}_$*" $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv $*.mnv $(REDIR_TEST_TO_NULL) ; \ else \ - $(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL) ; \ + $(RUN_MNVTEST) $(NO_INITS) -S runtest.mnv $*.mnv $(REDIR_TEST_TO_NULL) ; \ fi @/bin/sh -c "if test -f benchmark.out; then cat benchmark.out; fi" diff --git a/uvim/src/testdir/README.txt b/uvim/src/testdir/README.txt index 1ae0d28ae8..e0284524a2 100644 --- a/uvim/src/testdir/README.txt +++ b/uvim/src/testdir/README.txt @@ -1,4 +1,4 @@ -This directory contains test cases for various Vim features. +This directory contains test cases for various MNV features. The auxiliary functions to perform the tests are in the util/ folder. For testing an indent script see runtime/indent/testdir/README.txt. @@ -9,7 +9,7 @@ want to separate it from other tests with comment lines. TO ADD A NEW STYLE TEST: -1) Create a test_.vim file. +1) Create a test_.mnv file. 2) Add test_.res to NEW_TESTS_RES in Make_all.mak in alphabetical order. 3) Also add an entry "test_" to NEW_TESTS in Make_all.mak. @@ -17,13 +17,13 @@ TO ADD A NEW STYLE TEST: At 2), instead of running the test separately, it can be included in "test_alot". Do this for quick tests without side effects. The test runs a -bit faster, because Vim doesn't have to be started, one Vim instance runs many +bit faster, because MNV doesn't have to be started, one MNV instance runs many tests. At 4), to run a test in GUI, add "GUI_FLAG=-g" to the make command. -What you can use (see test_assert.vim for an example): +What you can use (see test_assert.mnv for an example): - Call assert_equal(), assert_true(), assert_false(), etc. @@ -36,22 +36,22 @@ What you can use (see test_assert.vim for an example): change the source code to add an ID to the allocation. Add a new one to alloc_id_T, before aid_last. -- Use test_override() to make Vim behave differently, e.g. if char_avail() +- Use test_override() to make MNV behave differently, e.g. if char_avail() must return FALSE for a while. E.g. to trigger the CursorMovedI autocommand - event. See test_cursor_func.vim for an example. + event. See test_cursor_func.mnv for an example. - If the bug that is being tested isn't fixed yet, you can throw an exception with "Skipped" so that it's clear this still needs work. E.g.: throw "Skipped: Bug with and popupmenu not fixed yet" - The following environment variables are recognized and can be set to - influence the behavior of the test suite (see runtest.vim for details) + influence the behavior of the test suite (see runtest.mnv for details) - $TEST_MAY_FAIL=Test_channel_one - ignore those failing tests - $TEST_FILTER=Test_channel - only run test that match this pattern - $TEST_SKIP_PAT=Test_channel - skip tests that match this pattern - $TEST_NO_RETRY=yes - do not try to re-run failing tests - You can also set them in Vim: + You can also set them in MNV: :let $TEST_MAY_FAIL = 'Test_channel_one' :let $TEST_FILTER = '_set_mode' :let $TEST_SKIP_PAT = 'Test_loop_forever' @@ -59,7 +59,7 @@ What you can use (see test_assert.vim for an example): Use an empty string to revert, e.g.: :let $TEST_FILTER = '' -- See the start of runtest.vim for more help. +- See the start of runtest.mnv for more help. TO ADD A SCREEN DUMP TEST: @@ -70,7 +70,7 @@ Mostly the same as writing a new style test. Additionally, see help on OLD STYLE TESTS: -There are a few tests that are used when Vim was built without the +eval +There are a few tests that are used when MNV was built without the +eval feature. These cannot use the "assert" functions, therefore they consist of a .in file that contains Normal mode commands between STARTTEST and ENDTEST. They modify the file and the result gets written in the test.out file. This @@ -96,11 +96,11 @@ tests are successful, then this file will be an empty file. - To run a single test function from a test script: - $ ../vim -u NONE -S runtest.vim .vim + $ ../mnv -u NONE -S runtest.mnv .mnv - To execute only specific test functions, add a second argument: - $ ../vim -u NONE -S runtest.vim test_channel.vim open_delay + $ ../mnv -u NONE -S runtest.mnv test_channel.mnv open_delay - To run all the tests: @@ -110,13 +110,13 @@ tests are successful, then this file will be an empty file. > nmake -f Make_mvc.mak -- To run the tests with GUI Vim: +- To run the tests with GUI MNV: $ make GUI_FLAG=-g or - $ make VIMPROG=../gvim + $ make MNVPROG=../gmnv - To cleanup the temporary files after running the tests: @@ -126,9 +126,9 @@ tests are successful, then this file will be an empty file. VIEWING GENERATED SCREENDUMPS (local): You may also wish to look at the whole batch of failed screendumps after -running "make". Source the "viewdumps.vim" script for this task: +running "make". Source the "viewdumps.mnv" script for this task: - $ ../vim -u NONE -S viewdumps.vim \ + $ ../mnv -u NONE -S viewdumps.mnv \ [dumps/Test_xxd_*.dump ...] By default, all screendumps found in the "failed" directory will be added to @@ -159,13 +159,13 @@ directory by creating a symlink: You can now examine the extracted screendumps: - $ ./src/vim -u NONE -S src/testdir/viewdumps.vim \ + $ ./src/mnv -u NONE -S src/testdir/viewdumps.mnv \ /tmp/src/testdir/failed/*.dump VIEWING GENERATED SCREENDUMPS (submitted for a pull request): -Note: There is also a "git difftool" extension described in ./commondumps.vim. +Note: There is also a "git difftool" extension described in ./commondumps.mnv. First, you need to check out the topic branch with the proposed changes and write down a difference list between the HEAD commit (index) and its parent @@ -201,5 +201,5 @@ you can now examine the screendumps from the "failed" directory (note that new screendumps will be shown with no difference between their versions): $ cd .. - $ ../vim -u NONE -S viewdumps.vim + $ ../mnv -u NONE -S viewdumps.mnv diff --git a/uvim/src/testdir/commondumps.mnv b/uvim/src/testdir/commondumps.mnv new file mode 100644 index 0000000000..8a6bd7fd74 --- /dev/null +++ b/uvim/src/testdir/commondumps.mnv @@ -0,0 +1,229 @@ +mnv9script + +# Generate the small ASCII letters (for marking). +def SmallAlphaLetters(): list + return range(97, (97 + 25))->map((_: number, n: number) => nr2char(n, true)) +enddef + +# Query the paired position for the cursor line and use it, if available, for +# mark "`". +def TryChangingLastJumpMark(marks: dict>) + const pos: list = get(marks, line('.'), []) + if !empty(pos) + setpos("'`", pos) + endif +enddef + +# Fold the difference part and the bottom part when the top and the bottom +# parts are identical; otherwise, create a fold for the difference part and +# manage marks for disparate lines: dynamically set mark "`" to pair such +# lines and initially set "`a", "`b", etc. marks for difference part lines. +def FoldAndMarkDumpDiffParts(letters: list) + defer call('setpos', ['.', getpos('.')]) + # Shape the pattern after get_separator() from "terminal.c". + const separator: string = '^\(=\+\)\=\s\S.*\.dump\s\1$' + const start_lnum: number = search(separator, 'eW', (line('$') / 2)) + if start_lnum > 0 + const end_lnum: number = search(separator, 'eW') + if end_lnum > 0 + # Collect [0, line_nr, col_nr, 0] lists (matching the first non-blank + # column) from the difference part "bs" and assemble corresponding lists + # for the top part "as" and the bottom part "cs". + const parts: list>> = + getline((start_lnum + 1), (end_lnum - 1)) + ->map((idx: number, s: string) => + [matchlist(s, '\(^\s*\S\)')->get(1, '')->strwidth(), idx]) + ->reduce(((as: list, bs: list, cs: list) => + (xs: list>>, pair: list) => { + const col_nr: number = pair[0] + if col_nr != 0 + const idx: number = pair[1] + xs[0]->add([0, get(as, idx, as[-1]), col_nr, 0]) + xs[1]->add([0, bs[idx], col_nr, 0]) + xs[2]->add([0, get(cs, idx, cs[-1]), col_nr, 0]) + endif + return xs + })(range(1, (start_lnum - 1)), + range((start_lnum + 1), (end_lnum - 1)), + range((end_lnum + 1), line('$'))), + [[], [], []]) + if empty(parts[1]) + setlocal foldenable foldmethod=manual + exec 'normal ' .. start_lnum .. 'GzfG' + else + setlocal nofoldenable foldmethod=manual + exec ':' .. start_lnum .. ',' .. end_lnum .. 'fold' + var marks: dict> = {} + for idx in range(parts[1]->len()) + if !empty(letters) + setpos(("'" .. remove(letters, 0)), parts[1][idx]) + endif + # Point "bs" to "cs", "cs" to "as", "as" to "cs". + marks[parts[1][idx][1]] = parts[2][idx] + marks[parts[2][idx][1]] = parts[0][idx] + marks[parts[0][idx][1]] = parts[2][idx] + endfor + autocmd_add([{ + replace: true, + group: 'viewdumps', + event: 'CursorMoved', + bufnr: bufnr(), + cmd: printf('TryChangingLastJumpMark(%s)', string(marks)), + }]) + endif + endif + endif +enddef + +# See below on how to configure the git difftool extension + +# Extend "git difftool" with the capability for loading screendump files. +if v:progname =~? '\filter((_: number, fname: string) => + fname =~? '^\%(/dev/null\|.\+\.dump\)$') + ->len() == 2 + try + if argv(0) ==? '/dev/null' + term_dumpload(argv(1)) + elseif argv(1) ==? '/dev/null' + term_dumpload(argv(0)) + else + term_dumpdiff(argv(0), argv(1)) + FoldAndMarkDumpDiffParts(SmallAlphaLetters()) + endif + finally + silent bwipeout 1 2 + endtry + endif + # Always stop from further sourcing this script for "(g)mnvdiff". + finish +endif + +# CONSIDER ALTERNATIVES FOR ENABLING THE ABOVE EXTENSION. +# +# For convenience, it is assumed that there is a defined "$MNV_FORK_PATHNAME" +# environment variable holding an absolute pathname for the root directory of +# this repository. +# +# +# A. USE Git FOR CONFIGURATION. +# +# Define the following Git variables with "git config --edit --local" (where +# the "mnvdumps" name is arbitrary): +# +# ------------------------------------------------------------------------------ +# [diff] +# tool = mnvdumps +# [difftool.mnvdumps] +# cmd = mnvdiff -S "${MNV_FORK_PATHNAME:?}"/src/testdir/commondumps.mnv -o -- "$LOCAL" "$REMOTE" +# ------------------------------------------------------------------------------ +# +# Rendered screendump files (among other files) between revisions can now be +# compared, two at a time, by using "git difftool", e.g.: +# git difftool 50423ab8~1 50423ab8 +# git difftool 50423ab8~1 50423ab8 -- '**/*.dump' +# +# The raw files can also be examined: +# :all +# +# +# B. USE Bash FOR CONFIGURATION (on Debian GNU/Linux). +# +# 1. Make an alias that sources this file, e.g.: +# alias git_mnvdiff="git difftool -x 'mnvdiff -S "${MNV_FORK_PATHNAME:?}"/mnv/src/testdir/commondumps.mnv -o --'" +# +# 2. Enable programmable completion for the alias, e.g.: +# cat ~/.local/share/bash-completion/completions/git_mnvdiff +# +# ------------------------------------------------------------------------------ +# ## Consider (un)setting "$BASH_COMPLETION_USER_DIR" and/or "$XDG_DATA_HOME" so +# ## that this file can be found and sourced; look for these variables in the +# ## "/usr/share/bash-completion/bash_completion" script. +# ## +# ## Look for __git_complete() examples in the header comment of the sourced +# ## "/usr/share/bash-completion/completions/git" script. +# [ -r /usr/share/bash-completion/completions/git ] && +# . /usr/share/bash-completion/completions/git && +# __git_complete git_mnvdiff _git_difftool +# ------------------------------------------------------------------------------ +# +# Rendered screendump files (among other files) between revisions can now be +# compared, two at a time, by using the alias, e.g.: +# git_mnvdiff 50423ab8~1 50423ab8 +# git_mnvdiff 50423ab8~1 50423ab8 -- '**/*.dump' +# +# The raw files can also be examined: +# :all + +# Render a loaded screendump file or the difference of a loaded screendump +# file and its namesake file from the "dumps" directory. +def Render(letters: list) + const failed_fname: string = bufname() + try + setlocal suffixesadd=.dump + const dumps_fname: string = findfile( + fnamemodify(failed_fname, ':p:t'), + fnamemodify(failed_fname, ':p:h:h') .. '/dumps') + if filereadable(dumps_fname) + term_dumpdiff(failed_fname, dumps_fname) + FoldAndMarkDumpDiffParts(letters) + else + term_dumpload(failed_fname) + endif + finally + exec 'bwipeout ' .. failed_fname + endtry +enddef + +# Public functions +# +# Search for the "failed" directory in the passed _subtreedirname_ directories +# (usually "\" or "\") and, if found, select its passed _count_ +# occurrence, add all its "*.dump" files to the argument list and list them; +# also define a BufRead autocommand that would invoke "Render()" for every +# "*.dump" file. +def g:Init(subtreedirname: string, count: number) + # Support sourcing this script from any directory in the direct path that + # leads to the project's root directory. + const failed_path: string = finddir('failed', getcwd() .. '/**', -1) + ->filter(((cwdpath: string, parentdirname: string) => + (_: number, dirpath: string) => + cwdpath =~ parentdirname || dirpath =~ parentdirname)( + getcwd(), + subtreedirname)) + ->get(count, '') .. '/' + var error: string = null_string + if failed_path == '/' + error = 'No such directory: "failed"' + else + const failed_fnames: string = failed_path .. readdir(failed_path, + (fname: string) => fname =~ '^.\+\.dump$') + ->join(' ' .. failed_path) + if failed_fnames =~ 'failed/$' + error = 'No such file: "*.dump"' + else + exec ':0argedit ' .. failed_fnames + buffers + endif + endif + autocmd_add([{ + replace: true, + group: 'viewdumps', + event: 'BufRead', + pattern: '*.dump', + cmd: printf('Render(%s)', string(SmallAlphaLetters())), + }]) + # Unconditionally help, in case a list of filenames is passed to the + # command, the first terminal window with its BufRead event. + silent doautocmd viewdumps BufRead + if error != null_string + # Instead of sleeping, fill half a window with blanks and prompt + # hit-enter. + echom error .. repeat("\x20", + (winwidth(0) * (winheight(0) / 2) - strlen(error))) + endif +enddef + +# mnv:fdm=syntax:sw=2:ts=8:noet:nosta: diff --git a/uvim/src/testdir/commondumps.vim b/uvim/src/testdir/commondumps.vim deleted file mode 100644 index 27d59bcdd1..0000000000 --- a/uvim/src/testdir/commondumps.vim +++ /dev/null @@ -1,229 +0,0 @@ -vim9script - -# Generate the small ASCII letters (for marking). -def SmallAlphaLetters(): list - return range(97, (97 + 25))->map((_: number, n: number) => nr2char(n, true)) -enddef - -# Query the paired position for the cursor line and use it, if available, for -# mark "`". -def TryChangingLastJumpMark(marks: dict>) - const pos: list = get(marks, line('.'), []) - if !empty(pos) - setpos("'`", pos) - endif -enddef - -# Fold the difference part and the bottom part when the top and the bottom -# parts are identical; otherwise, create a fold for the difference part and -# manage marks for disparate lines: dynamically set mark "`" to pair such -# lines and initially set "`a", "`b", etc. marks for difference part lines. -def FoldAndMarkDumpDiffParts(letters: list) - defer call('setpos', ['.', getpos('.')]) - # Shape the pattern after get_separator() from "terminal.c". - const separator: string = '^\(=\+\)\=\s\S.*\.dump\s\1$' - const start_lnum: number = search(separator, 'eW', (line('$') / 2)) - if start_lnum > 0 - const end_lnum: number = search(separator, 'eW') - if end_lnum > 0 - # Collect [0, line_nr, col_nr, 0] lists (matching the first non-blank - # column) from the difference part "bs" and assemble corresponding lists - # for the top part "as" and the bottom part "cs". - const parts: list>> = - getline((start_lnum + 1), (end_lnum - 1)) - ->map((idx: number, s: string) => - [matchlist(s, '\(^\s*\S\)')->get(1, '')->strwidth(), idx]) - ->reduce(((as: list, bs: list, cs: list) => - (xs: list>>, pair: list) => { - const col_nr: number = pair[0] - if col_nr != 0 - const idx: number = pair[1] - xs[0]->add([0, get(as, idx, as[-1]), col_nr, 0]) - xs[1]->add([0, bs[idx], col_nr, 0]) - xs[2]->add([0, get(cs, idx, cs[-1]), col_nr, 0]) - endif - return xs - })(range(1, (start_lnum - 1)), - range((start_lnum + 1), (end_lnum - 1)), - range((end_lnum + 1), line('$'))), - [[], [], []]) - if empty(parts[1]) - setlocal foldenable foldmethod=manual - exec 'normal ' .. start_lnum .. 'GzfG' - else - setlocal nofoldenable foldmethod=manual - exec ':' .. start_lnum .. ',' .. end_lnum .. 'fold' - var marks: dict> = {} - for idx in range(parts[1]->len()) - if !empty(letters) - setpos(("'" .. remove(letters, 0)), parts[1][idx]) - endif - # Point "bs" to "cs", "cs" to "as", "as" to "cs". - marks[parts[1][idx][1]] = parts[2][idx] - marks[parts[2][idx][1]] = parts[0][idx] - marks[parts[0][idx][1]] = parts[2][idx] - endfor - autocmd_add([{ - replace: true, - group: 'viewdumps', - event: 'CursorMoved', - bufnr: bufnr(), - cmd: printf('TryChangingLastJumpMark(%s)', string(marks)), - }]) - endif - endif - endif -enddef - -# See below on how to configure the git difftool extension - -# Extend "git difftool" with the capability for loading screendump files. -if v:progname =~? '\filter((_: number, fname: string) => - fname =~? '^\%(/dev/null\|.\+\.dump\)$') - ->len() == 2 - try - if argv(0) ==? '/dev/null' - term_dumpload(argv(1)) - elseif argv(1) ==? '/dev/null' - term_dumpload(argv(0)) - else - term_dumpdiff(argv(0), argv(1)) - FoldAndMarkDumpDiffParts(SmallAlphaLetters()) - endif - finally - silent bwipeout 1 2 - endtry - endif - # Always stop from further sourcing this script for "(g)vimdiff". - finish -endif - -# CONSIDER ALTERNATIVES FOR ENABLING THE ABOVE EXTENSION. -# -# For convenience, it is assumed that there is a defined "$VIM_FORK_PATHNAME" -# environment variable holding an absolute pathname for the root directory of -# this repository. -# -# -# A. USE Git FOR CONFIGURATION. -# -# Define the following Git variables with "git config --edit --local" (where -# the "vimdumps" name is arbitrary): -# -# ------------------------------------------------------------------------------ -# [diff] -# tool = vimdumps -# [difftool.vimdumps] -# cmd = vimdiff -S "${VIM_FORK_PATHNAME:?}"/src/testdir/commondumps.vim -o -- "$LOCAL" "$REMOTE" -# ------------------------------------------------------------------------------ -# -# Rendered screendump files (among other files) between revisions can now be -# compared, two at a time, by using "git difftool", e.g.: -# git difftool 50423ab8~1 50423ab8 -# git difftool 50423ab8~1 50423ab8 -- '**/*.dump' -# -# The raw files can also be examined: -# :all -# -# -# B. USE Bash FOR CONFIGURATION (on Debian GNU/Linux). -# -# 1. Make an alias that sources this file, e.g.: -# alias git_vimdiff="git difftool -x 'vimdiff -S "${VIM_FORK_PATHNAME:?}"/vim/src/testdir/commondumps.vim -o --'" -# -# 2. Enable programmable completion for the alias, e.g.: -# cat ~/.local/share/bash-completion/completions/git_vimdiff -# -# ------------------------------------------------------------------------------ -# ## Consider (un)setting "$BASH_COMPLETION_USER_DIR" and/or "$XDG_DATA_HOME" so -# ## that this file can be found and sourced; look for these variables in the -# ## "/usr/share/bash-completion/bash_completion" script. -# ## -# ## Look for __git_complete() examples in the header comment of the sourced -# ## "/usr/share/bash-completion/completions/git" script. -# [ -r /usr/share/bash-completion/completions/git ] && -# . /usr/share/bash-completion/completions/git && -# __git_complete git_vimdiff _git_difftool -# ------------------------------------------------------------------------------ -# -# Rendered screendump files (among other files) between revisions can now be -# compared, two at a time, by using the alias, e.g.: -# git_vimdiff 50423ab8~1 50423ab8 -# git_vimdiff 50423ab8~1 50423ab8 -- '**/*.dump' -# -# The raw files can also be examined: -# :all - -# Render a loaded screendump file or the difference of a loaded screendump -# file and its namesake file from the "dumps" directory. -def Render(letters: list) - const failed_fname: string = bufname() - try - setlocal suffixesadd=.dump - const dumps_fname: string = findfile( - fnamemodify(failed_fname, ':p:t'), - fnamemodify(failed_fname, ':p:h:h') .. '/dumps') - if filereadable(dumps_fname) - term_dumpdiff(failed_fname, dumps_fname) - FoldAndMarkDumpDiffParts(letters) - else - term_dumpload(failed_fname) - endif - finally - exec 'bwipeout ' .. failed_fname - endtry -enddef - -# Public functions -# -# Search for the "failed" directory in the passed _subtreedirname_ directories -# (usually "\" or "\") and, if found, select its passed _count_ -# occurrence, add all its "*.dump" files to the argument list and list them; -# also define a BufRead autocommand that would invoke "Render()" for every -# "*.dump" file. -def g:Init(subtreedirname: string, count: number) - # Support sourcing this script from any directory in the direct path that - # leads to the project's root directory. - const failed_path: string = finddir('failed', getcwd() .. '/**', -1) - ->filter(((cwdpath: string, parentdirname: string) => - (_: number, dirpath: string) => - cwdpath =~ parentdirname || dirpath =~ parentdirname)( - getcwd(), - subtreedirname)) - ->get(count, '') .. '/' - var error: string = null_string - if failed_path == '/' - error = 'No such directory: "failed"' - else - const failed_fnames: string = failed_path .. readdir(failed_path, - (fname: string) => fname =~ '^.\+\.dump$') - ->join(' ' .. failed_path) - if failed_fnames =~ 'failed/$' - error = 'No such file: "*.dump"' - else - exec ':0argedit ' .. failed_fnames - buffers - endif - endif - autocmd_add([{ - replace: true, - group: 'viewdumps', - event: 'BufRead', - pattern: '*.dump', - cmd: printf('Render(%s)', string(SmallAlphaLetters())), - }]) - # Unconditionally help, in case a list of filenames is passed to the - # command, the first terminal window with its BufRead event. - silent doautocmd viewdumps BufRead - if error != null_string - # Instead of sleeping, fill half a window with blanks and prompt - # hit-enter. - echom error .. repeat("\x20", - (winwidth(0) * (winheight(0) / 2) - strlen(error))) - endif -enddef - -# vim:fdm=syntax:sw=2:ts=8:noet:nosta: diff --git a/uvim/src/testdir/crash/crash_scrollbar b/uvim/src/testdir/crash/crash_scrollbar index 1de5905228..abc91486aa 100644 --- a/uvim/src/testdir/crash/crash_scrollbar +++ b/uvim/src/testdir/crash/crash_scrollbar @@ -1,2 +1,2 @@ -" this goes to insert mode and presses key k_VerScrollbar which may cause a redraw in exmode, which used ot crash Vim -norm o€ùX +" this goes to insert mode and presses key k_VerScrollbar which may cause a redraw in exmode, which used ot crash MNV +norm o��X diff --git a/uvim/src/testdir/crash/mnv_msg_trunc_poc b/uvim/src/testdir/crash/mnv_msg_trunc_poc new file mode 100644 index 0000000000..73b04bec35 --- /dev/null +++ b/uvim/src/testdir/crash/mnv_msg_trunc_poc @@ -0,0 +1 @@ +lv\ngggggi;norm:᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌áŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒó ²ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒá Œá ŒŒá Œá ŒŒá Œá ŒŒá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá  diff --git a/uvim/src/testdir/crash/mnv_regsub_both b/uvim/src/testdir/crash/mnv_regsub_both new file mode 100644 index 0000000000..a82b205c8f --- /dev/null +++ b/uvim/src/testdir/crash/mnv_regsub_both @@ -0,0 +1,10 @@ +fu R() +sil!norm0z= +endf +cal R() +s/\%')/\=R() +d +no0 normyynore sm:vs0@vvvvvvvvvvse()dir(¼Xtest=csd{so88 +vs +0scr +so diff --git a/uvim/src/testdir/crash/mnv_regsub_both_poc b/uvim/src/testdir/crash/mnv_regsub_both_poc new file mode 100644 index 0000000000..19a57114be Binary files /dev/null and b/uvim/src/testdir/crash/mnv_regsub_both_poc differ diff --git a/uvim/src/testdir/crash/poc_tagfunc.mnv b/uvim/src/testdir/crash/poc_tagfunc.mnv new file mode 100644 index 0000000000..49d9b6f719 --- /dev/null +++ b/uvim/src/testdir/crash/poc_tagfunc.mnv @@ -0,0 +1,6 @@ +fu Tagfunc(t,f,o) + bw +endf +set tagfunc=Tagfunc +n0 +sil0norm0i diff --git a/uvim/src/testdir/crash/poc_tagfunc.vim b/uvim/src/testdir/crash/poc_tagfunc.vim deleted file mode 100644 index 49d9b6f719..0000000000 --- a/uvim/src/testdir/crash/poc_tagfunc.vim +++ /dev/null @@ -1,6 +0,0 @@ -fu Tagfunc(t,f,o) - bw -endf -set tagfunc=Tagfunc -n0 -sil0norm0i diff --git a/uvim/src/testdir/crash/vim_msg_trunc_poc b/uvim/src/testdir/crash/vim_msg_trunc_poc deleted file mode 100644 index 73b04bec35..0000000000 --- a/uvim/src/testdir/crash/vim_msg_trunc_poc +++ /dev/null @@ -1 +0,0 @@ -lv\ngggggi;norm:᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌᠌áŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒó ²ŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒáŒá Œá ŒŒá Œá ŒŒá Œá ŒŒá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá Œá  diff --git a/uvim/src/testdir/crash/vim_regsub_both b/uvim/src/testdir/crash/vim_regsub_both deleted file mode 100644 index a82b205c8f..0000000000 --- a/uvim/src/testdir/crash/vim_regsub_both +++ /dev/null @@ -1,10 +0,0 @@ -fu R() -sil!norm0z= -endf -cal R() -s/\%')/\=R() -d -no0 normyynore sm:vs0@vvvvvvvvvvse()dir(¼Xtest=csd{so88 -vs -0scr -so diff --git a/uvim/src/testdir/crash/vim_regsub_both_poc b/uvim/src/testdir/crash/vim_regsub_both_poc deleted file mode 100644 index 19a57114be..0000000000 Binary files a/uvim/src/testdir/crash/vim_regsub_both_poc and /dev/null differ diff --git a/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_01.dump b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_01.dump new file mode 100644 index 0000000000..955d030583 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_01.dump @@ -0,0 +1,9 @@ +|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 +|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 +|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 +|~+0#4040ff13&| @68 +|~| @68 +|~| @68 +|~| @68 +|~| @68 +|:+0#0000000&|v|i|m|g|r|e|p| |o|n> @58 diff --git a/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_02.dump b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_02.dump new file mode 100644 index 0000000000..a5d94eac55 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_02.dump @@ -0,0 +1,9 @@ +|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 +|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 +|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 +|~+0#4040ff13&| @68 +|~| @68 +|~| @68 +|~| @68 +|~| @68 +|:+0#0000000&|v|i|m|g| |/|o|n|/| |*|.|t|x|t> @53 diff --git a/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_03.dump b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_03.dump new file mode 100644 index 0000000000..038ceb9d95 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_03.dump @@ -0,0 +1,9 @@ +|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 +|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 +|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 +|~+0#4040ff13&| @68 +|~| @68 +|~| @68 +|~| @68 +|~| @68 +|:+0#0000000&|v|i|m|g|r|e|p|a|d@1| |"|\|<|o|n> @52 diff --git a/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_04.dump b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_04.dump new file mode 100644 index 0000000000..92dd78dd87 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_04.dump @@ -0,0 +1,9 @@ +|a+0&#ffffff0|n|o|t|h|e|r| |o|n|e| |2| @56 +|t+1&&|h|a|t+0&&| |o|n|e| |3| @59 +|t|h|e| |o|n|e| |1| @60 +|~+0#4040ff13&| @68 +|~| @68 +|~| @68 +|~| @68 +|~| @68 +|:+0#0000000&|l|v| |"|t|h|a> @61 diff --git a/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_05.dump b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_05.dump new file mode 100644 index 0000000000..e11ff574c1 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_incsearch_mnvgrep_05.dump @@ -0,0 +1,9 @@ +|a+0&#ffffff0|n|o|t+1&&|h|e|r+0&&| |o|n|e| |2| @56 +|t|h|a|t| |o|n|e| |3| @59 +|t+0&#ffff4012|h|e| +0&#ffffff0|o|n|e| |1| @60 +|~+0#4040ff13&| @68 +|~| @68 +|~| @68 +|~| @68 +|~| @68 +|:+0#0000000&|l|v|i|m|g|r|e|p|a| |"|t|h|e|"| |*@1|/|*|.|t|x|t> @44 diff --git a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_01.dump b/uvim/src/testdir/dumps/Test_incsearch_vimgrep_01.dump deleted file mode 100644 index 955d030583..0000000000 --- a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_01.dump +++ /dev/null @@ -1,9 +0,0 @@ -|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 -|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 -|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 -|~+0#4040ff13&| @68 -|~| @68 -|~| @68 -|~| @68 -|~| @68 -|:+0#0000000&|v|i|m|g|r|e|p| |o|n> @58 diff --git a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_02.dump b/uvim/src/testdir/dumps/Test_incsearch_vimgrep_02.dump deleted file mode 100644 index a5d94eac55..0000000000 --- a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_02.dump +++ /dev/null @@ -1,9 +0,0 @@ -|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 -|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 -|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 -|~+0#4040ff13&| @68 -|~| @68 -|~| @68 -|~| @68 -|~| @68 -|:+0#0000000&|v|i|m|g| |/|o|n|/| |*|.|t|x|t> @53 diff --git a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_03.dump b/uvim/src/testdir/dumps/Test_incsearch_vimgrep_03.dump deleted file mode 100644 index 038ceb9d95..0000000000 --- a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_03.dump +++ /dev/null @@ -1,9 +0,0 @@ -|a+0&#ffffff0|n|o|t|h|e|r| |o+1&&|n|e+0&&| |2| @56 -|t|h|a|t| |o+0&#ffff4012|n|e+0&#ffffff0| |3| @59 -|t|h|e| |o+0&#ffff4012|n|e+0&#ffffff0| |1| @60 -|~+0#4040ff13&| @68 -|~| @68 -|~| @68 -|~| @68 -|~| @68 -|:+0#0000000&|v|i|m|g|r|e|p|a|d@1| |"|\|<|o|n> @52 diff --git a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_04.dump b/uvim/src/testdir/dumps/Test_incsearch_vimgrep_04.dump deleted file mode 100644 index 92dd78dd87..0000000000 --- a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_04.dump +++ /dev/null @@ -1,9 +0,0 @@ -|a+0&#ffffff0|n|o|t|h|e|r| |o|n|e| |2| @56 -|t+1&&|h|a|t+0&&| |o|n|e| |3| @59 -|t|h|e| |o|n|e| |1| @60 -|~+0#4040ff13&| @68 -|~| @68 -|~| @68 -|~| @68 -|~| @68 -|:+0#0000000&|l|v| |"|t|h|a> @61 diff --git a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_05.dump b/uvim/src/testdir/dumps/Test_incsearch_vimgrep_05.dump deleted file mode 100644 index e11ff574c1..0000000000 --- a/uvim/src/testdir/dumps/Test_incsearch_vimgrep_05.dump +++ /dev/null @@ -1,9 +0,0 @@ -|a+0&#ffffff0|n|o|t+1&&|h|e|r+0&&| |o|n|e| |2| @56 -|t|h|a|t| |o|n|e| |3| @59 -|t+0&#ffff4012|h|e| +0&#ffffff0|o|n|e| |1| @60 -|~+0#4040ff13&| @68 -|~| @68 -|~| @68 -|~| @68 -|~| @68 -|:+0#0000000&|l|v|i|m|g|r|e|p|a| |"|t|h|e|"| |*@1|/|*|.|t|x|t> @44 diff --git a/uvim/src/testdir/dumps/Test_mnv9_closure_fails.dump b/uvim/src/testdir/dumps/Test_mnv9_closure_fails.dump new file mode 100644 index 0000000000..dd0103cada --- /dev/null +++ b/uvim/src/testdir/dumps/Test_mnv9_closure_fails.dump @@ -0,0 +1,6 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|0+0#0000000&| @55|0|,|0|-|1| @8|A|l@1| diff --git a/uvim/src/testdir/dumps/Test_mnv9_no_redraw.dump b/uvim/src/testdir/dumps/Test_mnv9_no_redraw.dump new file mode 100644 index 0000000000..2f02082b30 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_mnv9_no_redraw.dump @@ -0,0 +1,6 @@ +|s+0&#ffffff0|o+0#0000001#a8a8a8255|m|e| |t|e|x|t| | +0#0000000#ffffff0@64 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|'|<|,|'|>> @68 diff --git a/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_1.dump b/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_1.dump new file mode 100644 index 0000000000..e4f56239a8 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_1.dump @@ -0,0 +1,6 @@ +|~+0#4040ff13#ffffff0| @73 +|~| @73 +|~| @73 +|~| @73 +|E+0#ffffff16#e000002|1|0|7|9|:| |C|a|n@1|o|t| |d|e|c|l|a|r|e| |a| |v|a|r|i|a|b|l|e| |o|n| |t|h|e| |c|o|m@1|a|n|d| |l|i|n|e| +0#0000000#ffffff0@22 +|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35 diff --git a/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_2.dump b/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_2.dump new file mode 100644 index 0000000000..a6d516c61a --- /dev/null +++ b/uvim/src/testdir/dumps/Test_mnv9_reject_declaration_2.dump @@ -0,0 +1,6 @@ +> +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|1+0#0000000&|2|3| @53|0|,|0|-|1| @8|A|l@1| diff --git a/uvim/src/testdir/dumps/Test_mnv9_silent_echo.dump b/uvim/src/testdir/dumps/Test_mnv9_silent_echo.dump new file mode 100644 index 0000000000..f5f7927859 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_mnv9_silent_echo.dump @@ -0,0 +1,6 @@ +| +0&#ffffff0@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|:+0#0000000&|a|b|c> @70 diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_04.mnv b/uvim/src/testdir/dumps/Test_popup_setbuf_04.mnv new file mode 100644 index 0000000000..c9ce1d4c5d --- /dev/null +++ b/uvim/src/testdir/dumps/Test_popup_setbuf_04.mnv @@ -0,0 +1,4 @@ +" replace Last Change Header in help.txt +:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge +" replace Version number in help.txt +:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_04.vim b/uvim/src/testdir/dumps/Test_popup_setbuf_04.vim deleted file mode 100644 index c9ce1d4c5d..0000000000 --- a/uvim/src/testdir/dumps/Test_popup_setbuf_04.vim +++ /dev/null @@ -1,4 +0,0 @@ -" replace Last Change Header in help.txt -:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge -" replace Version number in help.txt -:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_05.mnv b/uvim/src/testdir/dumps/Test_popup_setbuf_05.mnv new file mode 100644 index 0000000000..c9ce1d4c5d --- /dev/null +++ b/uvim/src/testdir/dumps/Test_popup_setbuf_05.mnv @@ -0,0 +1,4 @@ +" replace Last Change Header in help.txt +:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge +" replace Version number in help.txt +:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_05.vim b/uvim/src/testdir/dumps/Test_popup_setbuf_05.vim deleted file mode 100644 index c9ce1d4c5d..0000000000 --- a/uvim/src/testdir/dumps/Test_popup_setbuf_05.vim +++ /dev/null @@ -1,4 +0,0 @@ -" replace Last Change Header in help.txt -:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge -" replace Version number in help.txt -:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_06.mnv b/uvim/src/testdir/dumps/Test_popup_setbuf_06.mnv new file mode 100644 index 0000000000..c9ce1d4c5d --- /dev/null +++ b/uvim/src/testdir/dumps/Test_popup_setbuf_06.mnv @@ -0,0 +1,4 @@ +" replace Last Change Header in help.txt +:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge +" replace Version number in help.txt +:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_popup_setbuf_06.vim b/uvim/src/testdir/dumps/Test_popup_setbuf_06.vim deleted file mode 100644 index c9ce1d4c5d..0000000000 --- a/uvim/src/testdir/dumps/Test_popup_setbuf_06.vim +++ /dev/null @@ -1,4 +0,0 @@ -" replace Last Change Header in help.txt -:1s/|L|a|s|t| |c|h|a|n|g|e|:| |\d|\d|\d|\d| |\w|\w|\w| |\d|\d|/|L|a|s|t| |c|h|a|n|g|e|:| |2|0|2|4| |M|a|y| |2|7|/ge -" replace Version number in help.txt -:1s/|v|e|r|s|i|o|n| |\(\d|\)\+\.|\d|\.|/|v|e|r|s|i|o|n| |9|.|1|.|/ge diff --git a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.mnv b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.mnv new file mode 100644 index 0000000000..959798ac41 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.mnv @@ -0,0 +1,9 @@ +" replace hex addresses with |0|x|f@12| +:%s/|0|x|\(\(\w\|@\)\+|\)\+/|0|x|f@12|/g + +" Only keep screen lines relevant to the actual popup and evaluation. +" Especially the top lines are too instable and cause flakiness between +" different systems and tool versions. +normal! G +normal! 8k +normal! dgg diff --git a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.vim b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.vim deleted file mode 100644 index 959798ac41..0000000000 --- a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_01.vim +++ /dev/null @@ -1,9 +0,0 @@ -" replace hex addresses with |0|x|f@12| -:%s/|0|x|\(\(\w\|@\)\+|\)\+/|0|x|f@12|/g - -" Only keep screen lines relevant to the actual popup and evaluation. -" Especially the top lines are too instable and cause flakiness between -" different systems and tool versions. -normal! G -normal! 8k -normal! dgg diff --git a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.mnv b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.mnv new file mode 100644 index 0000000000..9b38dc4dea --- /dev/null +++ b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.mnv @@ -0,0 +1,6 @@ +" Only keep screen lines relevant to the actual popup and evaluation. +" Especially the top lines are too instable and cause flakiness between +" different systems and tool versions. +normal! G +normal! 8k +normal! dgg diff --git a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.vim b/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.vim deleted file mode 100644 index 9b38dc4dea..0000000000 --- a/uvim/src/testdir/dumps/Test_termdebug_evaluate_in_popup_02.vim +++ /dev/null @@ -1,6 +0,0 @@ -" Only keep screen lines relevant to the actual popup and evaluation. -" Especially the top lines are too instable and cause flakiness between -" different systems and tool versions. -normal! G -normal! 8k -normal! dgg diff --git a/uvim/src/testdir/dumps/Test_undo_after_write_1.mnv b/uvim/src/testdir/dumps/Test_undo_after_write_1.mnv new file mode 100644 index 0000000000..62e02b338f --- /dev/null +++ b/uvim/src/testdir/dumps/Test_undo_after_write_1.mnv @@ -0,0 +1,2 @@ +" Filter that changes undo time message to "1 second ago". +6s+|\d| |s|e|c|o|n|d|s| |a|g|o| @19|+|1| |s|e|c|o|n|d| |a|g|o| @20|+e diff --git a/uvim/src/testdir/dumps/Test_undo_after_write_1.vim b/uvim/src/testdir/dumps/Test_undo_after_write_1.vim deleted file mode 100644 index 62e02b338f..0000000000 --- a/uvim/src/testdir/dumps/Test_undo_after_write_1.vim +++ /dev/null @@ -1,2 +0,0 @@ -" Filter that changes undo time message to "1 second ago". -6s+|\d| |s|e|c|o|n|d|s| |a|g|o| @19|+|1| |s|e|c|o|n|d| |a|g|o| @20|+e diff --git a/uvim/src/testdir/dumps/Test_undo_after_write_2.mnv b/uvim/src/testdir/dumps/Test_undo_after_write_2.mnv new file mode 100644 index 0000000000..b99f232048 --- /dev/null +++ b/uvim/src/testdir/dumps/Test_undo_after_write_2.mnv @@ -0,0 +1,2 @@ +" Filter that changes undo time message to "1 second ago". +6s+|\d| |s|e|c|o|n|d|s| |a|g|o| @17|+|1| |s|e|c|o|n|d| |a|g|o| @18|+e diff --git a/uvim/src/testdir/dumps/Test_undo_after_write_2.vim b/uvim/src/testdir/dumps/Test_undo_after_write_2.vim deleted file mode 100644 index b99f232048..0000000000 --- a/uvim/src/testdir/dumps/Test_undo_after_write_2.vim +++ /dev/null @@ -1,2 +0,0 @@ -" Filter that changes undo time message to "1 second ago". -6s+|\d| |s|e|c|o|n|d|s| |a|g|o| @17|+|1| |s|e|c|o|n|d| |a|g|o| @18|+e diff --git a/uvim/src/testdir/dumps/Test_verbose_system_1.mnv b/uvim/src/testdir/dumps/Test_verbose_system_1.mnv new file mode 100644 index 0000000000..c0cbe1a73a --- /dev/null +++ b/uvim/src/testdir/dumps/Test_verbose_system_1.mnv @@ -0,0 +1,5 @@ +" Filter that removes the ever changing temp directory name from the screendump +" that shows the system() command executed. +" This should be on the first line, but if it isn't there ignore the error, +" the screendump will then show the problem. +1,2s+|>|/|.*|2|>|&|1|".*+|>|.|.|.|2|>|\&|1|"+e diff --git a/uvim/src/testdir/dumps/Test_verbose_system_1.vim b/uvim/src/testdir/dumps/Test_verbose_system_1.vim deleted file mode 100644 index c0cbe1a73a..0000000000 --- a/uvim/src/testdir/dumps/Test_verbose_system_1.vim +++ /dev/null @@ -1,5 +0,0 @@ -" Filter that removes the ever changing temp directory name from the screendump -" that shows the system() command executed. -" This should be on the first line, but if it isn't there ignore the error, -" the screendump will then show the problem. -1,2s+|>|/|.*|2|>|&|1|".*+|>|.|.|.|2|>|\&|1|"+e diff --git a/uvim/src/testdir/dumps/Test_verbose_system_2.mnv b/uvim/src/testdir/dumps/Test_verbose_system_2.mnv new file mode 100644 index 0000000000..c0cbe1a73a --- /dev/null +++ b/uvim/src/testdir/dumps/Test_verbose_system_2.mnv @@ -0,0 +1,5 @@ +" Filter that removes the ever changing temp directory name from the screendump +" that shows the system() command executed. +" This should be on the first line, but if it isn't there ignore the error, +" the screendump will then show the problem. +1,2s+|>|/|.*|2|>|&|1|".*+|>|.|.|.|2|>|\&|1|"+e diff --git a/uvim/src/testdir/dumps/Test_verbose_system_2.vim b/uvim/src/testdir/dumps/Test_verbose_system_2.vim deleted file mode 100644 index c0cbe1a73a..0000000000 --- a/uvim/src/testdir/dumps/Test_verbose_system_2.vim +++ /dev/null @@ -1,5 +0,0 @@ -" Filter that removes the ever changing temp directory name from the screendump -" that shows the system() command executed. -" This should be on the first line, but if it isn't there ignore the error, -" the screendump will then show the problem. -1,2s+|>|/|.*|2|>|&|1|".*+|>|.|.|.|2|>|\&|1|"+e diff --git a/uvim/src/testdir/dumps/Test_vim9_closure_fails.dump b/uvim/src/testdir/dumps/Test_vim9_closure_fails.dump deleted file mode 100644 index dd0103cada..0000000000 --- a/uvim/src/testdir/dumps/Test_vim9_closure_fails.dump +++ /dev/null @@ -1,6 +0,0 @@ -> +0&#ffffff0@74 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|0+0#0000000&| @55|0|,|0|-|1| @8|A|l@1| diff --git a/uvim/src/testdir/dumps/Test_vim9_no_redraw.dump b/uvim/src/testdir/dumps/Test_vim9_no_redraw.dump deleted file mode 100644 index 2f02082b30..0000000000 --- a/uvim/src/testdir/dumps/Test_vim9_no_redraw.dump +++ /dev/null @@ -1,6 +0,0 @@ -|s+0&#ffffff0|o+0#0000001#a8a8a8255|m|e| |t|e|x|t| | +0#0000000#ffffff0@64 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|:+0#0000000&|'|<|,|'|>> @68 diff --git a/uvim/src/testdir/dumps/Test_vim9_reject_declaration_1.dump b/uvim/src/testdir/dumps/Test_vim9_reject_declaration_1.dump deleted file mode 100644 index e4f56239a8..0000000000 --- a/uvim/src/testdir/dumps/Test_vim9_reject_declaration_1.dump +++ /dev/null @@ -1,6 +0,0 @@ -|~+0#4040ff13#ffffff0| @73 -|~| @73 -|~| @73 -|~| @73 -|E+0#ffffff16#e000002|1|0|7|9|:| |C|a|n@1|o|t| |d|e|c|l|a|r|e| |a| |v|a|r|i|a|b|l|e| |o|n| |t|h|e| |c|o|m@1|a|n|d| |l|i|n|e| +0#0000000#ffffff0@22 -|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35 diff --git a/uvim/src/testdir/dumps/Test_vim9_reject_declaration_2.dump b/uvim/src/testdir/dumps/Test_vim9_reject_declaration_2.dump deleted file mode 100644 index a6d516c61a..0000000000 --- a/uvim/src/testdir/dumps/Test_vim9_reject_declaration_2.dump +++ /dev/null @@ -1,6 +0,0 @@ -> +0&#ffffff0@74 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|1+0#0000000&|2|3| @53|0|,|0|-|1| @8|A|l@1| diff --git a/uvim/src/testdir/dumps/Test_vim9_silent_echo.dump b/uvim/src/testdir/dumps/Test_vim9_silent_echo.dump deleted file mode 100644 index f5f7927859..0000000000 --- a/uvim/src/testdir/dumps/Test_vim9_silent_echo.dump +++ /dev/null @@ -1,6 +0,0 @@ -| +0&#ffffff0@74 -|~+0#4040ff13&| @73 -|~| @73 -|~| @73 -|~| @73 -|:+0#0000000&|a|b|c> @70 diff --git a/uvim/src/testdir/dumps/Test_xxd_color_0.mnv b/uvim/src/testdir/dumps/Test_xxd_color_0.mnv new file mode 100644 index 0000000000..7ac1f2647d --- /dev/null +++ b/uvim/src/testdir/dumps/Test_xxd_color_0.mnv @@ -0,0 +1,2 @@ +" Filter that removes the Shell Prompt from the xxd command +:1s#|\$+0&\#ffffff0| \S\+/|x@1|d|.*\n#|$+0\&\#ffffff0| #e diff --git a/uvim/src/testdir/dumps/Test_xxd_color_0.vim b/uvim/src/testdir/dumps/Test_xxd_color_0.vim deleted file mode 100644 index 7ac1f2647d..0000000000 --- a/uvim/src/testdir/dumps/Test_xxd_color_0.vim +++ /dev/null @@ -1,2 +0,0 @@ -" Filter that removes the Shell Prompt from the xxd command -:1s#|\$+0&\#ffffff0| \S\+/|x@1|d|.*\n#|$+0\&\#ffffff0| #e diff --git a/uvim/src/testdir/dumps/Test_xxd_color_1.mnv b/uvim/src/testdir/dumps/Test_xxd_color_1.mnv new file mode 100644 index 0000000000..7ac1f2647d --- /dev/null +++ b/uvim/src/testdir/dumps/Test_xxd_color_1.mnv @@ -0,0 +1,2 @@ +" Filter that removes the Shell Prompt from the xxd command +:1s#|\$+0&\#ffffff0| \S\+/|x@1|d|.*\n#|$+0\&\#ffffff0| #e diff --git a/uvim/src/testdir/dumps/Test_xxd_color_1.vim b/uvim/src/testdir/dumps/Test_xxd_color_1.vim deleted file mode 100644 index 7ac1f2647d..0000000000 --- a/uvim/src/testdir/dumps/Test_xxd_color_1.vim +++ /dev/null @@ -1,2 +0,0 @@ -" Filter that removes the Shell Prompt from the xxd command -:1s#|\$+0&\#ffffff0| \S\+/|x@1|d|.*\n#|$+0\&\#ffffff0| #e diff --git a/uvim/src/testdir/keycode_check.mnv b/uvim/src/testdir/keycode_check.mnv new file mode 100644 index 0000000000..24e6a19486 --- /dev/null +++ b/uvim/src/testdir/keycode_check.mnv @@ -0,0 +1,471 @@ +mnv9script + +# Script to get various codes that keys send, depending on the protocol used. +# +# Usage: mnv -u NONE -S keycode_check.mnv +# +# Author: Bram Moolenaar +# Last Update: 2022 Nov 15 +# +# The codes are stored in the file "keycode_check.json", so that you can +# compare the results of various terminals. +# +# You can select what protocol to enable: +# - None +# - modifyOtherKeys level 2 +# - kitty keyboard protocol + +# Change directory to where this script is, so that the json file is found +# there. +exe 'cd ' .. expand(':h') +echo 'working in directory: ' .. getcwd() + +const filename = 'keycode_check.json' + +# Dictionary of dictionaries with the results in the form: +# {'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, +# 'xterm2': {protocol: 'mok2', 'Tab': '09', 'S-Tab': '09'}, +# 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '09'}, +# } +# The values are in hex form. +var keycodes = {} + +if filereadable(filename) + keycodes = readfile(filename)->join()->json_decode() +else + # Use some dummy entries to try out with + keycodes = { + 'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, + 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '1b5b393b3275'}, + } +endif +var orig_keycodes = deepcopy(keycodes) # used to detect something changed + +# Write the "keycodes" variable in JSON form to "filename". +def WriteKeycodes() + # If the file already exists move it to become the backup file. + if filereadable(filename) + if rename(filename, filename .. '~') + echoerr $'Renaming {filename} to {filename}~ failed!' + return + endif + endif + + if writefile([json_encode(keycodes)], filename) != 0 + echoerr $'Writing {filename} failed!' + endif +enddef + +# The key entries that we want to list, in this order. +# The first item is displayed in the prompt, the second is the key in +# the keycodes dictionary. +var key_entries = [ + ['Tab', 'Tab'], + ['Shift-Tab', 'S-Tab'], + ['Ctrl-Tab', 'C-Tab'], + ['Alt-Tab', 'A-Tab'], + ['Ctrl-I', 'C-I'], + ['Shift-Ctrl-I', 'S-C-I'], + ['Esc', 'Esc'], + ['Shift-Esc', 'S-Esc'], + ['Ctrl-Esc', 'C-Esc'], + ['Alt-Esc', 'A-Esc'], + ['Space', 'Space'], + ['Shift-Space', 'S-Space'], + ['Ctrl-Space', 'C-Space'], + ['Alt-Space', 'A-Space'], + ['F3', 'F3'], + ] + +# Given a terminal name and a item name, return the text to display. +def GetItemDisplay(term: string, item: string): string + var val = get(keycodes[term], item, '') + + # see if we can pretty-print this one + var pretty = val + if val[0 : 1] == '1b' + pretty = 'ESC' + var idx = 2 + + if val[0 : 3] == '1b5b' + pretty = 'CSI' + idx = 4 + endif + + var digits = false + while idx < len(val) + var cc = val[idx : idx + 1] + var nr = str2nr('0x' .. cc, 16) + idx += 2 + if nr >= char2nr('0') && nr <= char2nr('9') + if !digits + pretty ..= ' ' + endif + digits = true + pretty ..= cc[1] + else + if nr == char2nr(';') && digits + # don't use space between semicolon and digits to keep it short + pretty ..= ';' + else + digits = false + if nr >= char2nr(' ') && nr <= char2nr('~') + # printable character + pretty ..= ' ' .. printf('%c', nr) + else + # non-printable, use hex code + pretty = val + break + endif + endif + endif + endwhile + endif + + return pretty +enddef + + +# Action: list the information in "keycodes" in a more or less nice way. +def ActionList() + var terms = keys(keycodes) + if len(terms) == 0 + echo 'No terminal results yet' + return + endif + sort(terms) + + var items = ['protocol', 'version', 'kitty', 'modkeys'] + + key_entries->copy()->map((_, v) => v[1]) + + # For each terminal compute the needed width, add two. + # You may need to increase the terminal width to avoid wrapping. + var widths = [] + for [idx, term] in items(terms) + widths[idx] = len(term) + 2 + endfor + + for item in items + for [idx, term] in items(terms) + var l = len(GetItemDisplay(term, item)) + if widths[idx] < l + 2 + widths[idx] = l + 2 + endif + endfor + endfor + + # Use one column of width 10 for the item name. + echo "\n" + echon ' ' + for [idx, term] in items(terms) + echon printf('%-' .. widths[idx] .. 's', term) + endfor + echo "\n" + + for item in items + echon printf('%8s ', item) + for [idx, term] in items(terms) + echon printf('%-' .. widths[idx] .. 's', GetItemDisplay(term, item)) + endfor + echo '' + endfor + echo "\n" +enddef + +# Convert the literal string after "raw key input" into hex form. +def Literal2hex(code: string): string + var hex = '' + for i in range(len(code)) + hex ..= printf('%02x', char2nr(code[i])) + endfor + return hex +enddef + +def GetTermName(): string + var name = input('Enter the name of the terminal: ') + return name +enddef + +# Gather key codes for terminal "name". +def DoTerm(name: string) + var proto = inputlist([$'What protocol to enable for {name}:', + '1. None', + '2. modifyOtherKeys level 2', + '3. kitty', + ]) + echo "\n" + &t_TE = "\[>4;m" + var proto_name = 'unknown' + if proto == 1 + # Request the XTQMODKEYS value and request the kitty keyboard protocol status. + &t_TI = "\[?4m" .. "\[?u" + proto_name = 'none' + elseif proto == 2 + # Enable modifyOtherKeys level 2 and request the XTQMODKEYS value. + &t_TI = "\[>4;2m" .. "\[?4m" + proto_name = 'mok2' + elseif proto == 3 + # Enable Kitty keyboard protocol and request the status. + &t_TI = "\[>1u" .. "\[?u" + proto_name = 'kitty' + else + echoerr 'invalid protocol choice' + return + endif + + # Append the request for the version response, this is used to check we have + # the results. + &t_TI ..= "\[>c" + + # Pattern that matches the line with the version response. + const version_pattern = "\\\[>\\d\\+;\\d\\+;\\d*c" + + # Pattern that matches the XTQMODKEYS response: + # CSI > 4;Pv m + # where Pv indicates the modifyOtherKeys level + const modkeys_pattern = "\\\[>4;\\dm" + + # Pattern that matches the line with the status. Currently what terminals + # return for the Kitty keyboard protocol. + const kitty_status_pattern = "\\\[?\\d\\+u" + + ch_logfile('keylog', 'w') + + # executing a dummy shell command will output t_TI + !echo >/dev/null + + # Wait until the log file has the version response. + var startTime = reltime() + var seenVersion = false + while !seenVersion + var log = readfile('keylog') + if len(log) > 2 + for line in log + if line =~ 'raw key input' + var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') + if code =~ version_pattern + seenVersion = true + echo 'Found the version response' + break + endif + endif + endfor + endif + if reltime(startTime)->reltimefloat() > 3 + # break out after three seconds + break + endif + endwhile + + echo 'seenVersion: ' seenVersion + + # Prepare the terminal entry, set protocol and clear status and version. + if !has_key(keycodes, name) + keycodes[name] = {} + endif + keycodes[name]['protocol'] = proto_name + keycodes[name]['version'] = '' + keycodes[name]['kitty'] = '' + keycodes[name]['modkeys'] = '' + + # Check the log file for a status and the version response + ch_logfile('', '') + var log = readfile('keylog') + delete('keylog') + + for line in log + if line =~ 'raw key input' + var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') + + # Check for the XTQMODKEYS response. + if code =~ modkeys_pattern + var modkeys = substitute(code, '.*\(' .. modkeys_pattern .. '\).*', '\1', '') + # We could get the level out of the response, but showing the response + # itself provides more information. + # modkeys = substitute(modkeys, '.*4;\(\d\)m', '\1', '') + + if keycodes[name]['modkeys'] != '' + echomsg 'Another modkeys found after ' .. keycodes[name]['modkeys'] + endif + keycodes[name]['modkeys'] = modkeys + endif + + # Check for kitty keyboard protocol status + if code =~ kitty_status_pattern + var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '') + # use the response itself as the status + status = Literal2hex(status) + + if keycodes[name]['kitty'] != '' + echomsg 'Another status found after ' .. keycodes[name]['kitty'] + endif + keycodes[name]['kitty'] = status + endif + + if code =~ version_pattern + var version = substitute(code, '.*\(' .. version_pattern .. '\).*', '\1', '') + keycodes[name]['version'] = Literal2hex(version) + break + endif + endif + endfor + + echo "For Alt to work you may need to press the Windows/Super key as well" + echo "When a key press doesn't get to MNV (e.g. when using Alt) press x" + + # The log of ignored typeahead is left around for debugging, start with an + # empty file here. + delete('keylog-ignore') + + for entry in key_entries + # Consume any typeahead. Wait a bit for any responses to arrive. + ch_logfile('keylog-ignore', 'a') + while 1 + sleep 100m + if getchar(1) == 0 + break + endif + while getchar(1) != 0 + getchar() + endwhile + endwhile + ch_logfile('', '') + + ch_logfile('keylog', 'w') + echo $'Press the {entry[0]} key (q to quit):' + var r = getcharstr() + ch_logfile('', '') + if r == 'q' + break + endif + + log = readfile('keylog') + delete('keylog') + if len(log) < 2 + echoerr 'failed to read result' + return + endif + var done = false + for line in log + if line =~ 'raw key input' + var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') + + # Remove any version termresponse + code = substitute(code, version_pattern, '', 'g') + + # Remove any XTGETTCAP replies. + const cappat = "\P[01]+\\k\\+=\\x*\\\\\" + code = substitute(code, cappat, '', 'g') + + # Remove any kitty status reply + code = substitute(code, kitty_status_pattern, '', 'g') + if code == '' + continue + endif + + # Convert the literal bytes into hex. If 'x' was pressed then clear + # the entry. + var hex = '' + if code != 'x' + hex = Literal2hex(code) + endif + + keycodes[name][entry[1]] = hex + done = true + break + endif + endfor + if !done + echo 'Code not found in log' + endif + endfor +enddef + +# Action: Add key codes for a new terminal. +def ActionAdd() + var name = input('Enter name of the terminal: ') + echo "\n" + if index(keys(keycodes), name) >= 0 + echoerr $'Terminal {name} already exists' + return + endif + + DoTerm(name) +enddef + +# Action: Replace key codes for an already known terminal. +def ActionReplace() + var terms = keys(keycodes) + if len(terms) == 0 + echo 'No terminal results yet' + return + endif + + var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) + echo "\n" + if choice > 0 && choice <= len(terms) + DoTerm(terms[choice - 1]) + else + echo 'invalid index' + endif +enddef + +# Action: Clear key codes for an already known terminal. +def ActionClear() + var terms = keys(keycodes) + if len(terms) == 0 + echo 'No terminal results yet' + return + endif + + var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) + echo "\n" + if choice > 0 && choice <= len(terms) + remove(keycodes, terms[choice - 1]) + else + echo 'invalid index' + endif +enddef + +# Action: Quit, possibly after saving the results first. +def ActionQuit() + # If nothing was changed just quit + if keycodes == orig_keycodes + quit + endif + + while true + var res = input("Save the changed key codes (y/n)? ") + if res == 'n' + quit + endif + if res == 'y' + WriteKeycodes() + quit + endif + echo 'invalid reply' + endwhile +enddef + +# The main loop +while true + var action = inputlist(['Select operation:', + '1. List results', + '2. Add results for a new terminal', + '3. Replace results', + '4. Clear results', + '5. Quit', + ]) + echo "\n" + if action == 1 + ActionList() + elseif action == 2 + ActionAdd() + elseif action == 3 + ActionReplace() + elseif action == 4 + ActionClear() + elseif action == 5 || action == 0 + ActionQuit() + endif +endwhile diff --git a/uvim/src/testdir/keycode_check.vim b/uvim/src/testdir/keycode_check.vim deleted file mode 100644 index 33eb6ceeb7..0000000000 --- a/uvim/src/testdir/keycode_check.vim +++ /dev/null @@ -1,471 +0,0 @@ -vim9script - -# Script to get various codes that keys send, depending on the protocol used. -# -# Usage: vim -u NONE -S keycode_check.vim -# -# Author: Bram Moolenaar -# Last Update: 2022 Nov 15 -# -# The codes are stored in the file "keycode_check.json", so that you can -# compare the results of various terminals. -# -# You can select what protocol to enable: -# - None -# - modifyOtherKeys level 2 -# - kitty keyboard protocol - -# Change directory to where this script is, so that the json file is found -# there. -exe 'cd ' .. expand(':h') -echo 'working in directory: ' .. getcwd() - -const filename = 'keycode_check.json' - -# Dictionary of dictionaries with the results in the form: -# {'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, -# 'xterm2': {protocol: 'mok2', 'Tab': '09', 'S-Tab': '09'}, -# 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '09'}, -# } -# The values are in hex form. -var keycodes = {} - -if filereadable(filename) - keycodes = readfile(filename)->join()->json_decode() -else - # Use some dummy entries to try out with - keycodes = { - 'xterm': {protocol: 'none', 'Tab': '09', 'S-Tab': '09'}, - 'kitty': {protocol: 'kitty', 'Tab': '09', 'S-Tab': '1b5b393b3275'}, - } -endif -var orig_keycodes = deepcopy(keycodes) # used to detect something changed - -# Write the "keycodes" variable in JSON form to "filename". -def WriteKeycodes() - # If the file already exists move it to become the backup file. - if filereadable(filename) - if rename(filename, filename .. '~') - echoerr $'Renaming {filename} to {filename}~ failed!' - return - endif - endif - - if writefile([json_encode(keycodes)], filename) != 0 - echoerr $'Writing {filename} failed!' - endif -enddef - -# The key entries that we want to list, in this order. -# The first item is displayed in the prompt, the second is the key in -# the keycodes dictionary. -var key_entries = [ - ['Tab', 'Tab'], - ['Shift-Tab', 'S-Tab'], - ['Ctrl-Tab', 'C-Tab'], - ['Alt-Tab', 'A-Tab'], - ['Ctrl-I', 'C-I'], - ['Shift-Ctrl-I', 'S-C-I'], - ['Esc', 'Esc'], - ['Shift-Esc', 'S-Esc'], - ['Ctrl-Esc', 'C-Esc'], - ['Alt-Esc', 'A-Esc'], - ['Space', 'Space'], - ['Shift-Space', 'S-Space'], - ['Ctrl-Space', 'C-Space'], - ['Alt-Space', 'A-Space'], - ['F3', 'F3'], - ] - -# Given a terminal name and a item name, return the text to display. -def GetItemDisplay(term: string, item: string): string - var val = get(keycodes[term], item, '') - - # see if we can pretty-print this one - var pretty = val - if val[0 : 1] == '1b' - pretty = 'ESC' - var idx = 2 - - if val[0 : 3] == '1b5b' - pretty = 'CSI' - idx = 4 - endif - - var digits = false - while idx < len(val) - var cc = val[idx : idx + 1] - var nr = str2nr('0x' .. cc, 16) - idx += 2 - if nr >= char2nr('0') && nr <= char2nr('9') - if !digits - pretty ..= ' ' - endif - digits = true - pretty ..= cc[1] - else - if nr == char2nr(';') && digits - # don't use space between semicolon and digits to keep it short - pretty ..= ';' - else - digits = false - if nr >= char2nr(' ') && nr <= char2nr('~') - # printable character - pretty ..= ' ' .. printf('%c', nr) - else - # non-printable, use hex code - pretty = val - break - endif - endif - endif - endwhile - endif - - return pretty -enddef - - -# Action: list the information in "keycodes" in a more or less nice way. -def ActionList() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - sort(terms) - - var items = ['protocol', 'version', 'kitty', 'modkeys'] - + key_entries->copy()->map((_, v) => v[1]) - - # For each terminal compute the needed width, add two. - # You may need to increase the terminal width to avoid wrapping. - var widths = [] - for [idx, term] in items(terms) - widths[idx] = len(term) + 2 - endfor - - for item in items - for [idx, term] in items(terms) - var l = len(GetItemDisplay(term, item)) - if widths[idx] < l + 2 - widths[idx] = l + 2 - endif - endfor - endfor - - # Use one column of width 10 for the item name. - echo "\n" - echon ' ' - for [idx, term] in items(terms) - echon printf('%-' .. widths[idx] .. 's', term) - endfor - echo "\n" - - for item in items - echon printf('%8s ', item) - for [idx, term] in items(terms) - echon printf('%-' .. widths[idx] .. 's', GetItemDisplay(term, item)) - endfor - echo '' - endfor - echo "\n" -enddef - -# Convert the literal string after "raw key input" into hex form. -def Literal2hex(code: string): string - var hex = '' - for i in range(len(code)) - hex ..= printf('%02x', char2nr(code[i])) - endfor - return hex -enddef - -def GetTermName(): string - var name = input('Enter the name of the terminal: ') - return name -enddef - -# Gather key codes for terminal "name". -def DoTerm(name: string) - var proto = inputlist([$'What protocol to enable for {name}:', - '1. None', - '2. modifyOtherKeys level 2', - '3. kitty', - ]) - echo "\n" - &t_TE = "\[>4;m" - var proto_name = 'unknown' - if proto == 1 - # Request the XTQMODKEYS value and request the kitty keyboard protocol status. - &t_TI = "\[?4m" .. "\[?u" - proto_name = 'none' - elseif proto == 2 - # Enable modifyOtherKeys level 2 and request the XTQMODKEYS value. - &t_TI = "\[>4;2m" .. "\[?4m" - proto_name = 'mok2' - elseif proto == 3 - # Enable Kitty keyboard protocol and request the status. - &t_TI = "\[>1u" .. "\[?u" - proto_name = 'kitty' - else - echoerr 'invalid protocol choice' - return - endif - - # Append the request for the version response, this is used to check we have - # the results. - &t_TI ..= "\[>c" - - # Pattern that matches the line with the version response. - const version_pattern = "\\\[>\\d\\+;\\d\\+;\\d*c" - - # Pattern that matches the XTQMODKEYS response: - # CSI > 4;Pv m - # where Pv indicates the modifyOtherKeys level - const modkeys_pattern = "\\\[>4;\\dm" - - # Pattern that matches the line with the status. Currently what terminals - # return for the Kitty keyboard protocol. - const kitty_status_pattern = "\\\[?\\d\\+u" - - ch_logfile('keylog', 'w') - - # executing a dummy shell command will output t_TI - !echo >/dev/null - - # Wait until the log file has the version response. - var startTime = reltime() - var seenVersion = false - while !seenVersion - var log = readfile('keylog') - if len(log) > 2 - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - if code =~ version_pattern - seenVersion = true - echo 'Found the version response' - break - endif - endif - endfor - endif - if reltime(startTime)->reltimefloat() > 3 - # break out after three seconds - break - endif - endwhile - - echo 'seenVersion: ' seenVersion - - # Prepare the terminal entry, set protocol and clear status and version. - if !has_key(keycodes, name) - keycodes[name] = {} - endif - keycodes[name]['protocol'] = proto_name - keycodes[name]['version'] = '' - keycodes[name]['kitty'] = '' - keycodes[name]['modkeys'] = '' - - # Check the log file for a status and the version response - ch_logfile('', '') - var log = readfile('keylog') - delete('keylog') - - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - - # Check for the XTQMODKEYS response. - if code =~ modkeys_pattern - var modkeys = substitute(code, '.*\(' .. modkeys_pattern .. '\).*', '\1', '') - # We could get the level out of the response, but showing the response - # itself provides more information. - # modkeys = substitute(modkeys, '.*4;\(\d\)m', '\1', '') - - if keycodes[name]['modkeys'] != '' - echomsg 'Another modkeys found after ' .. keycodes[name]['modkeys'] - endif - keycodes[name]['modkeys'] = modkeys - endif - - # Check for kitty keyboard protocol status - if code =~ kitty_status_pattern - var status = substitute(code, '.*\(' .. kitty_status_pattern .. '\).*', '\1', '') - # use the response itself as the status - status = Literal2hex(status) - - if keycodes[name]['kitty'] != '' - echomsg 'Another status found after ' .. keycodes[name]['kitty'] - endif - keycodes[name]['kitty'] = status - endif - - if code =~ version_pattern - var version = substitute(code, '.*\(' .. version_pattern .. '\).*', '\1', '') - keycodes[name]['version'] = Literal2hex(version) - break - endif - endif - endfor - - echo "For Alt to work you may need to press the Windows/Super key as well" - echo "When a key press doesn't get to Vim (e.g. when using Alt) press x" - - # The log of ignored typeahead is left around for debugging, start with an - # empty file here. - delete('keylog-ignore') - - for entry in key_entries - # Consume any typeahead. Wait a bit for any responses to arrive. - ch_logfile('keylog-ignore', 'a') - while 1 - sleep 100m - if getchar(1) == 0 - break - endif - while getchar(1) != 0 - getchar() - endwhile - endwhile - ch_logfile('', '') - - ch_logfile('keylog', 'w') - echo $'Press the {entry[0]} key (q to quit):' - var r = getcharstr() - ch_logfile('', '') - if r == 'q' - break - endif - - log = readfile('keylog') - delete('keylog') - if len(log) < 2 - echoerr 'failed to read result' - return - endif - var done = false - for line in log - if line =~ 'raw key input' - var code = substitute(line, '.*raw key input: "\([^"]*\).*', '\1', '') - - # Remove any version termresponse - code = substitute(code, version_pattern, '', 'g') - - # Remove any XTGETTCAP replies. - const cappat = "\P[01]+\\k\\+=\\x*\\\\\" - code = substitute(code, cappat, '', 'g') - - # Remove any kitty status reply - code = substitute(code, kitty_status_pattern, '', 'g') - if code == '' - continue - endif - - # Convert the literal bytes into hex. If 'x' was pressed then clear - # the entry. - var hex = '' - if code != 'x' - hex = Literal2hex(code) - endif - - keycodes[name][entry[1]] = hex - done = true - break - endif - endfor - if !done - echo 'Code not found in log' - endif - endfor -enddef - -# Action: Add key codes for a new terminal. -def ActionAdd() - var name = input('Enter name of the terminal: ') - echo "\n" - if index(keys(keycodes), name) >= 0 - echoerr $'Terminal {name} already exists' - return - endif - - DoTerm(name) -enddef - -# Action: Replace key codes for an already known terminal. -def ActionReplace() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - - var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) - echo "\n" - if choice > 0 && choice <= len(terms) - DoTerm(terms[choice - 1]) - else - echo 'invalid index' - endif -enddef - -# Action: Clear key codes for an already known terminal. -def ActionClear() - var terms = keys(keycodes) - if len(terms) == 0 - echo 'No terminal results yet' - return - endif - - var choice = inputlist(['Select:'] + terms->copy()->map((idx, arg) => (idx + 1) .. ': ' .. arg)) - echo "\n" - if choice > 0 && choice <= len(terms) - remove(keycodes, terms[choice - 1]) - else - echo 'invalid index' - endif -enddef - -# Action: Quit, possibly after saving the results first. -def ActionQuit() - # If nothing was changed just quit - if keycodes == orig_keycodes - quit - endif - - while true - var res = input("Save the changed key codes (y/n)? ") - if res == 'n' - quit - endif - if res == 'y' - WriteKeycodes() - quit - endif - echo 'invalid reply' - endwhile -enddef - -# The main loop -while true - var action = inputlist(['Select operation:', - '1. List results', - '2. Add results for a new terminal', - '3. Replace results', - '4. Clear results', - '5. Quit', - ]) - echo "\n" - if action == 1 - ActionList() - elseif action == 2 - ActionAdd() - elseif action == 3 - ActionReplace() - elseif action == 4 - ActionClear() - elseif action == 5 || action == 0 - ActionQuit() - endif -endwhile diff --git a/uvim/src/testdir/runtest.mnv b/uvim/src/testdir/runtest.mnv new file mode 100644 index 0000000000..545043ba47 --- /dev/null +++ b/uvim/src/testdir/runtest.mnv @@ -0,0 +1,691 @@ +" This script is sourced while editing the .mnv file with the tests. +" When the script is successful the .res file will be created. +" Errors are appended to the test.log file. +" +" To execute only specific test functions, add a second argument. It will be +" matched against the names of the Test_ function. E.g.: +" ../mnv -u NONE -S runtest.mnv test_channel.mnv open_delay +" The output can be found in the "messages" file. +" +" If the environment variable $TEST_FILTER is set then only test functions +" matching this pattern are executed. E.g. for sh/bash: +" export TEST_FILTER=Test_channel +" For csh: +" setenv TEST_FILTER Test_channel +" +" If the environment variable $TEST_SKIP_PAT is set then test functions +" matching this pattern will be skipped. It's the opposite of $TEST_FILTER. +" +" While working on a test you can make $TEST_NO_RETRY non-empty to not retry: +" export TEST_NO_RETRY=yes +" +" To ignore failure for tests that are known to fail in a certain environment, +" set $TEST_MAY_FAIL to a comma separated list of function names. E.g. for +" sh/bash: +" export TEST_MAY_FAIL=Test_channel_one,Test_channel_other +" The failure report will then not be included in the test.log file and +" "make test" will not fail. +" +" The test script may contain anything, only functions that start with +" "Test_" are special. These will be invoked and should contain assert +" functions. See test_assert.mnv for an example. +" +" It is possible to source other files that contain "Test_" functions. This +" can speed up testing, since MNV does not need to restart. But be careful +" that the tests do not interfere with each other. +" +" If an error cannot be detected properly with an assert function add the +" error to the v:errors list: +" call add(v:errors, 'test foo failed: Cannot find xyz') +" +" If preparation for each Test_ function is needed, define a SetUp function. +" It will be called before each Test_ function. +" +" If cleanup after each Test_ function is needed, define a TearDown function. +" It will be called after each Test_ function. +" +" When debugging a test it can be useful to add messages to v:errors: +" call add(v:errors, "this happened") + + +" Without the +eval feature we can't run these tests, bail out. +silent! while 0 + qa! +silent! endwhile + +" In the GUI we can always change the screen size. +if has('gui_running') + if has('gui_gtk') + " Use e.g. SetUp() and TearDown() to change "&guifont" when needed; + " otherwise, keep the following value to match current screendumps. + set guifont=Monospace\ 10 + endif + + func s:SetDefaultOptionsForGUIBuilds() + set columns=80 lines=25 + endfunc +else + func s:SetDefaultOptionsForGUIBuilds() + endfunc +endif + +" Check that the screen size is at least 24 x 80 characters. +if &lines < 24 || &columns < 80 + let error = 'Screen size too small! Tests require at least 24 lines with 80 characters, got ' .. &lines .. ' lines with ' .. &columns .. ' characters' + echoerr error + split test.log + $put =error + write + split messages + call append(line('$'), '') + call append(line('$'), 'From ' . expand('%') . ':') + call append(line('$'), error) + write + qa! +endif + +if has('reltime') + let s:run_start_time = reltime() + + if !filereadable('starttime') + " first test, store the overall test starting time + let s:test_start_time = localtime() + call writefile([string(s:test_start_time)], 'starttime') + else + " second or later test, read the overall test starting time + let s:test_start_time = readfile('starttime')[0]->str2nr() + endif +endif + +" Always use forward slashes. +set shellslash + +" Common with all tests on all systems. +source util/setup.mnv + +" Needed for RunningWithValgrind(). +source util/shared.mnv + +" Needed for the various Check commands +source util/check.mnv + +" For consistency run all tests with 'nocompatible' set. +" This also enables use of line continuation. +set nocp mnvinfo+=nmnvinfo + +" Use utf-8 by default, instead of whatever the system default happens to be. +" Individual tests can overrule this at the top of the file and use +" g:orig_encoding if needed. +let g:orig_encoding = &encoding +set encoding=utf-8 + +" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for +" the test_name.mnv file itself. Replace it here with a more restrictive one, +" so we still catch mistakes. +if has("win32") + " replace any '/' directory separators by '\\' + let s:test_script_fname = substitute(expand('%'), '/', '\\', 'g') +else + let s:test_script_fname = expand('%') +endif + +au! SwapExists * call HandleSwapExists() +func HandleSwapExists() + if exists('g:ignoreSwapExists') + if type(g:ignoreSwapExists) == v:t_string + let v:swapchoice = g:ignoreSwapExists + endif + return + endif + " Ignore finding a swap file for the test script (the user might be + " editing it and do ":make test_name") and the output file. + " Report finding another swap file and chose 'q' to avoid getting stuck. + if expand('') == 'messages' || expand('') =~ s:test_script_fname + let v:swapchoice = 'e' + else + call assert_report('Unexpected swap file: ' .. v:swapname) + let v:swapchoice = 'q' + endif +endfunc + +" Avoid stopping at the "hit enter" prompt +set nomore + +" Output all messages in English. +lang mess C + +" suppress menu translation +if has('gui_running') && exists('did_install_default_menus') + source $MNVRUNTIME/delmenu.mnv + set langmenu=none + source $MNVRUNTIME/menu.mnv +endif + +let s:srcdir = expand('%:p:h:h') + +if has('win32') + " avoid prompt that is long or contains a line break + let $PROMPT = '$P$G' + " On MS-Windows t_md and t_me are MNV specific escape sequences. + let s:t_bold = "\x1b[1m" + let s:t_normal = "\x1b[m" +else + let s:t_bold = &t_md + let s:t_normal = &t_me +endif + +if has('mac') + " In macOS, when starting a shell in a terminal, a bash deprecation warning + " message is displayed. This breaks the terminal test. Disable the warning + " message. + let $BASH_SILENCE_DEPRECATION_WARNING = 1 +endif + + +" Prepare for calling test_garbagecollect_now(). +" Also avoids some delays in Insert mode completion. +let v:testing = 1 + +" By default, copy each buffer line into allocated memory, so that valgrind can +" detect accessing memory before and after it. +call test_override('alloc_lines', 1) + +" Support function: get the alloc ID by name. +function GetAllocId(name) + exe 'split ' . s:srcdir . '/alloc.h' + let top = search('typedef enum') + if top == 0 + call add(v:errors, 'typedef not found in alloc.h') + endif + let lnum = search('aid_' . a:name . ',') + if lnum == 0 + call add(v:errors, 'Alloc ID ' . a:name . ' not defined') + endif + close + return lnum - top - 1 +endfunc + +" Get the list of swap files in the current directory. +func s:GetSwapFileList() + let save_dir = &directory + let &directory = '.' + let files = swapfilelist() + let &directory = save_dir + + " remove a match with runtest.mnv + let idx = indexof(files, 'v:val =~ "runtest.mnv."') + if idx >= 0 + call remove(files, idx) + endif + + return files +endfunc + +" A previous (failed) test run may have left swap files behind. Delete them +" before running tests again, they might interfere. +for name in s:GetSwapFileList() + call delete(name) +endfor +unlet! name + + +" Invoked when a test takes too much time. +func TestTimeout(id) + split test.log + call append(line('$'), '') + + let text = 'Test timed out: ' .. g:testfunc + if g:timeout_start > 0 + let text ..= strftime(' after %s seconds', localtime() - g:timeout_start) + endif + call append(line('$'), text) + write + call add(v:errors, text) + + cquit! 42 +endfunc +let g:timeout_start = 0 + +func RunTheTest(test) + let prefix = '' + if has('reltime') + let prefix = strftime('%M:%S', localtime() - s:test_start_time) .. ' ' + let g:func_start = reltime() + endif + echoconsole prefix .. 'Executing ' .. a:test + + if has('timers') + " No test should take longer than 45 seconds. If it takes longer we + " assume we are stuck and need to break out. + let test_timeout_timer = + \ timer_start(RunningWithValgrind() ? 90000 : 45000, 'TestTimeout') + let g:timeout_start = localtime() + endif + + " Avoid stopping at the "hit enter" prompt + set nomore + + " Avoid a three second wait when a message is about to be overwritten by the + " mode message. + set noshowmode + + " Clear any overrides, except "alloc_lines". + call test_override('ALL', 0) + + " Some tests wipe out buffers. To be consistent, always wipe out all + " buffers. + %bwipe! + + " Clear all children notifications in case there are stale ones left + let g:child_notification = 0 + + " The test may change the current directory. Save and restore the + " directory after executing the test. + let save_cwd = getcwd() + + " Permit "SetUp()" implementations to override default settings. + call s:SetDefaultOptionsForGUIBuilds() + + if exists("*SetUp") + try + call SetUp() + catch + call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) + endtry + endif + + let skipped = v:false + + au MNVLeavePre * call EarlyExit(g:testfunc) + if a:test =~ 'Test_nocatch_' + " Function handles errors itself. This avoids skipping commands after the + " error. + let g:skipped_reason = '' + exe 'call ' . a:test + if g:skipped_reason != '' + call add(s:messages, ' Skipped') + call add(s:skipped, 'SKIPPED ' . a:test . ': ' . g:skipped_reason) + let skipped = v:true + endif + else + try + exe 'call ' . a:test + catch /^\cskipped/ + call add(s:messages, ' Skipped') + call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) + let skipped = v:true + catch + call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) + endtry + endif + au! MNVLeavePre + + if a:test =~ '_terminal_' + " Terminal tests sometimes hang, give extra information + echoconsole 'After executing ' .. a:test + endif + + " In case 'insertmode' was set and something went wrong, make sure it is + " reset to avoid trouble with anything else. + set noinsertmode + + if exists("*TearDown") + try + call TearDown() + catch + call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) + endtry + endif + + if has('timers') + call timer_stop(test_timeout_timer) + let g:timeout_start = 0 + endif + + " Clear any autocommands and put back the catch-all for SwapExists. + au! + au SwapExists * call HandleSwapExists() + + " Check for and close any stray popup windows. + if has('popupwin') + call assert_equal([], popup_list(), 'Popup is still present') + call popup_clear(1) + endif + + if filereadable('guidialogfile') + call add(v:errors, "Unexpected dialog: " .. readfile('guidialogfile')->join('')) + call delete('guidialogfile') + endif + + " Close any extra tab pages and windows and make the current one not modified. + while tabpagenr('$') > 1 + let winid = win_getid() + quit! + if winid == win_getid() + echoerr 'Could not quit window' + break + endif + endwhile + + while 1 + let wincount = winnr('$') + if wincount == 1 + break + endif + bwipe! + if wincount == winnr('$') + " Did not manage to close a window. + only! + break + endif + endwhile + + exe 'cd ' . save_cwd + + if a:test =~ '_terminal_' + " Terminal tests sometimes hang, give extra information + echoconsole 'Finished ' . a:test + endif + + let message = 'Executed ' . a:test + if has('reltime') + let message ..= repeat(' ', 50 - len(message)) + let time = reltime(g:func_start) + if reltimefloat(time) > 0.1 + let message = s:t_bold .. message + endif + let message ..= ' in ' .. reltimestr(time) .. ' seconds' + if reltimefloat(time) > 0.1 + let message ..= s:t_normal + endif + endif + call add(s:messages, message) + let s:done += 1 + + " close any split windows + while winnr('$') > 1 + noswapfile bwipe! + endwhile + + " May be editing some buffer, wipe it out. Then we may end up in another + " buffer, continue until we end up in an empty no-name buffer without a swap + " file. + while bufname() != '' || execute('swapname') !~ 'No swap file' + let bn = bufnr() + + noswapfile bwipe! + + if bn == bufnr() + " avoid getting stuck in the same buffer + break + endif + endwhile + + if !skipped + " Check if the test has left any swap files behind. Delete them before + " running tests again, they might interfere. + let swapfiles = s:GetSwapFileList() + if len(swapfiles) > 0 + call add(s:messages, "Found swap files: " .. string(swapfiles)) + for name in swapfiles + call delete(name) + endfor + endif + endif +endfunc + +function Delete_Xtest_Files() + for file in glob('X*', v:false, v:true) + if file ==? 'XfakeHOME' + " Clean up files created by setup.mnv + call delete('XfakeHOME', 'rf') + continue + endif + " call add(v:errors, file .. " exists when it shouldn't, trying to delete it!") + call delete(file) + if !empty(glob(file, v:false, v:true)) + " call add(v:errors, file .. " still exists after trying to delete it!") + if has('unix') + call system('rm -rf ' .. file) + endif + endif + endfor +endfunc + +func AfterTheTest(func_name) + if len(v:errors) > 0 + if match(s:may_fail_list, '^' .. a:func_name) >= 0 + let s:fail_expected += 1 + call add(s:errors_expected, 'Found errors in ' . g:testfunc . ':') + call extend(s:errors_expected, v:errors) + else + let s:fail += 1 + call add(s:errors, 'Found errors in ' . g:testfunc . ':') + call extend(s:errors, v:errors) + endif + let v:errors = [] + endif +endfunc + +func EarlyExit(test) + " It's OK for the test we use to test the quit detection. + if a:test != 'Test_zz_quit_detected()' + call add(v:errors, v:errmsg) + call add(v:errors, 'Test caused MNV to exit: ' . a:test) + endif + + call FinishTesting() +endfunc + +" This function can be called by a test if it wants to abort testing. +func FinishTesting() + call AfterTheTest('') + call Delete_Xtest_Files() + + " Don't write mnvinfo on exit. + set mnvinfo= + + if s:fail == 0 && s:fail_expected == 0 + " Success, create the .res file so that make knows it's done. + exe 'split ' . fnamemodify(g:testname, ':r') . '.res' + write + endif + + if len(s:errors) > 0 + " Append errors to test.log + split test.log + call append(line('$'), '') + call append(line('$'), 'From ' . g:testname . ':') + call append(line('$'), s:errors) + write + endif + + if s:done == 0 + if s:filtered > 0 + if $TEST_FILTER != '' + let message = "NO tests match $TEST_FILTER: '" .. $TEST_FILTER .. "'" + else + let message = "ALL tests match $TEST_SKIP_PAT: '" .. $TEST_SKIP_PAT .. "'" + endif + else + let message = 'NO tests executed' + endif + else + if s:filtered > 0 + call add(s:messages, "Filtered " .. s:filtered .. " tests with $TEST_FILTER and $TEST_SKIP_PAT") + endif + let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test') + endif + if s:done > 0 && has('reltime') + let message = s:t_bold .. message .. repeat(' ', 40 - len(message)) + let message ..= ' in ' .. reltimestr(reltime(s:run_start_time)) .. ' seconds' + let message ..= s:t_normal + endif + echo message + call add(s:messages, message) + if s:fail > 0 + let message = s:fail . ' FAILED:' + echo message + call add(s:messages, message) + call extend(s:messages, s:errors) + endif + if s:fail_expected > 0 + let message = s:fail_expected . ' FAILED (matching $TEST_MAY_FAIL):' + echo message + call add(s:messages, message) + call extend(s:messages, s:errors_expected) + endif + + " Add SKIPPED messages + call extend(s:messages, s:skipped) + + " Append messages to the file "messages", but remove ANSI Escape sequences + split messages + call append(line('$'), '') + call append(line('$'), 'From ' . g:testname . ':') + call append(line('$'), s:messages->map({_, val -> substitute(val, '\%x1b[[|]\(\d\?\|\d\+\)[hm]', '', 'g')})) + write + + qall! +endfunc + +" Source the test script. First grab the file name, in case the script +" navigates away. g:testname can be used by the tests. +let g:testname = expand('%') +let s:done = 0 +let s:fail = 0 +let s:fail_expected = 0 +let s:errors = [] +let s:errors_expected = [] +let s:messages = [] +let s:skipped = [] +if expand('%') =~ 'test_mnvscript.mnv' + " this test has intentional errors, don't use try/catch. + source % +else + try + source % + catch /^\cskipped/ + call add(s:messages, ' Skipped') + call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) + catch + let s:fail += 1 + call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint) + endtry +endif + +" Delete the .res file, it may change behavior for completion +call delete(fnamemodify(g:testname, ':r') .. '.res') + +" Locate Test_ functions and execute them. +redir @q +silent function /^Test_ +redir END +let s:tests = split(substitute(@q, '\(function\|def\) \(\k*()\)', '\2', 'g')) + +" If there is an extra argument filter the function names against it. +if argc() > 1 + let s:tests = filter(s:tests, 'v:val =~ argv(1)') +endif + +" If the environment variable $TEST_FILTER is set then filter the function +" names against it. +let s:filtered = 0 +if $TEST_FILTER != '' + let s:filtered = len(s:tests) + let s:tests = filter(s:tests, 'v:val =~ $TEST_FILTER') + let s:filtered -= len(s:tests) +endif + +let s:may_fail_list = [] +if $TEST_MAY_FAIL != '' + " Split the list at commas and add () to make it match g:testfunc. + let s:may_fail_list = split($TEST_MAY_FAIL, ',')->map({i, v -> v .. '()'}) +endif + +" Execute the tests in alphabetical order. +for g:testfunc in sort(s:tests) + if $TEST_SKIP_PAT != '' && g:testfunc =~ $TEST_SKIP_PAT + call add(s:messages, g:testfunc .. ' matches $TEST_SKIP_PAT') + let s:filtered += 1 + continue + endif + + " Silence, please! + set belloff=all + let prev_error = '' + let total_errors = [] + let g:run_nr = 1 + + " A test can set g:test_is_flaky to retry running the test. + let g:test_is_flaky = 0 + + let g:check_screendump_called = v:false + + " A test can set g:max_run_nr to change the max retry count. + let g:max_run_nr = 5 + if has('mac') + let g:max_run_nr = 10 + endif + + " By default, give up if the same error occurs. A test can set + " g:giveup_same_error to 0 to not give up on the same error and keep trying. + let g:giveup_same_error = 1 + + let starttime = strftime("%H:%M:%S") + call RunTheTest(g:testfunc) + + " Repeat a flaky test. Give up when: + " - $TEST_NO_RETRY is not empty + " - it fails again with the same message + " - it fails five times (with a different message) + if len(v:errors) > 0 + \ && $TEST_NO_RETRY == '' + \ && g:test_is_flaky + while 1 + call add(s:messages, 'Found errors in ' .. g:testfunc .. ':') + call extend(s:messages, v:errors) + + let endtime = strftime("%H:%M:%S") + if has('reltime') + let suffix = $' in{reltimestr(reltime(g:func_start))} seconds' + else + let suffix = '' + endif + call add(total_errors, $'Run {g:run_nr}, {starttime} - {endtime}{suffix}:') + call extend(total_errors, v:errors) + + if g:run_nr >= g:max_run_nr || g:giveup_same_error && prev_error == v:errors[0] + call add(total_errors, 'Flaky test failed too often, giving up') + let v:errors = total_errors + break + endif + + call add(s:messages, 'Flaky test failed, running it again') + + " Flakiness is often caused by the system being very busy. Sleep a + " couple of seconds to have a higher chance of succeeding the second + " time. + let delay = g:run_nr * 2 + exe 'sleep' delay + + let prev_error = v:errors[0] + let v:errors = [] + let g:run_nr += 1 + + let starttime = strftime("%H:%M:%S") + call RunTheTest(g:testfunc) + + if len(v:errors) == 0 + " Test passed on rerun. + break + endif + endwhile + endif + + call AfterTheTest(g:testfunc) +endfor + +call FinishTesting() + +" mnv: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/runtest.vim b/uvim/src/testdir/runtest.vim deleted file mode 100644 index 7822da9150..0000000000 --- a/uvim/src/testdir/runtest.vim +++ /dev/null @@ -1,691 +0,0 @@ -" This script is sourced while editing the .vim file with the tests. -" When the script is successful the .res file will be created. -" Errors are appended to the test.log file. -" -" To execute only specific test functions, add a second argument. It will be -" matched against the names of the Test_ function. E.g.: -" ../vim -u NONE -S runtest.vim test_channel.vim open_delay -" The output can be found in the "messages" file. -" -" If the environment variable $TEST_FILTER is set then only test functions -" matching this pattern are executed. E.g. for sh/bash: -" export TEST_FILTER=Test_channel -" For csh: -" setenv TEST_FILTER Test_channel -" -" If the environment variable $TEST_SKIP_PAT is set then test functions -" matching this pattern will be skipped. It's the opposite of $TEST_FILTER. -" -" While working on a test you can make $TEST_NO_RETRY non-empty to not retry: -" export TEST_NO_RETRY=yes -" -" To ignore failure for tests that are known to fail in a certain environment, -" set $TEST_MAY_FAIL to a comma separated list of function names. E.g. for -" sh/bash: -" export TEST_MAY_FAIL=Test_channel_one,Test_channel_other -" The failure report will then not be included in the test.log file and -" "make test" will not fail. -" -" The test script may contain anything, only functions that start with -" "Test_" are special. These will be invoked and should contain assert -" functions. See test_assert.vim for an example. -" -" It is possible to source other files that contain "Test_" functions. This -" can speed up testing, since Vim does not need to restart. But be careful -" that the tests do not interfere with each other. -" -" If an error cannot be detected properly with an assert function add the -" error to the v:errors list: -" call add(v:errors, 'test foo failed: Cannot find xyz') -" -" If preparation for each Test_ function is needed, define a SetUp function. -" It will be called before each Test_ function. -" -" If cleanup after each Test_ function is needed, define a TearDown function. -" It will be called after each Test_ function. -" -" When debugging a test it can be useful to add messages to v:errors: -" call add(v:errors, "this happened") - - -" Without the +eval feature we can't run these tests, bail out. -silent! while 0 - qa! -silent! endwhile - -" In the GUI we can always change the screen size. -if has('gui_running') - if has('gui_gtk') - " Use e.g. SetUp() and TearDown() to change "&guifont" when needed; - " otherwise, keep the following value to match current screendumps. - set guifont=Monospace\ 10 - endif - - func s:SetDefaultOptionsForGUIBuilds() - set columns=80 lines=25 - endfunc -else - func s:SetDefaultOptionsForGUIBuilds() - endfunc -endif - -" Check that the screen size is at least 24 x 80 characters. -if &lines < 24 || &columns < 80 - let error = 'Screen size too small! Tests require at least 24 lines with 80 characters, got ' .. &lines .. ' lines with ' .. &columns .. ' characters' - echoerr error - split test.log - $put =error - write - split messages - call append(line('$'), '') - call append(line('$'), 'From ' . expand('%') . ':') - call append(line('$'), error) - write - qa! -endif - -if has('reltime') - let s:run_start_time = reltime() - - if !filereadable('starttime') - " first test, store the overall test starting time - let s:test_start_time = localtime() - call writefile([string(s:test_start_time)], 'starttime') - else - " second or later test, read the overall test starting time - let s:test_start_time = readfile('starttime')[0]->str2nr() - endif -endif - -" Always use forward slashes. -set shellslash - -" Common with all tests on all systems. -source util/setup.vim - -" Needed for RunningWithValgrind(). -source util/shared.vim - -" Needed for the various Check commands -source util/check.vim - -" For consistency run all tests with 'nocompatible' set. -" This also enables use of line continuation. -set nocp viminfo+=nviminfo - -" Use utf-8 by default, instead of whatever the system default happens to be. -" Individual tests can overrule this at the top of the file and use -" g:orig_encoding if needed. -let g:orig_encoding = &encoding -set encoding=utf-8 - -" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for -" the test_name.vim file itself. Replace it here with a more restrictive one, -" so we still catch mistakes. -if has("win32") - " replace any '/' directory separators by '\\' - let s:test_script_fname = substitute(expand('%'), '/', '\\', 'g') -else - let s:test_script_fname = expand('%') -endif - -au! SwapExists * call HandleSwapExists() -func HandleSwapExists() - if exists('g:ignoreSwapExists') - if type(g:ignoreSwapExists) == v:t_string - let v:swapchoice = g:ignoreSwapExists - endif - return - endif - " Ignore finding a swap file for the test script (the user might be - " editing it and do ":make test_name") and the output file. - " Report finding another swap file and chose 'q' to avoid getting stuck. - if expand('') == 'messages' || expand('') =~ s:test_script_fname - let v:swapchoice = 'e' - else - call assert_report('Unexpected swap file: ' .. v:swapname) - let v:swapchoice = 'q' - endif -endfunc - -" Avoid stopping at the "hit enter" prompt -set nomore - -" Output all messages in English. -lang mess C - -" suppress menu translation -if has('gui_running') && exists('did_install_default_menus') - source $VIMRUNTIME/delmenu.vim - set langmenu=none - source $VIMRUNTIME/menu.vim -endif - -let s:srcdir = expand('%:p:h:h') - -if has('win32') - " avoid prompt that is long or contains a line break - let $PROMPT = '$P$G' - " On MS-Windows t_md and t_me are Vim specific escape sequences. - let s:t_bold = "\x1b[1m" - let s:t_normal = "\x1b[m" -else - let s:t_bold = &t_md - let s:t_normal = &t_me -endif - -if has('mac') - " In macOS, when starting a shell in a terminal, a bash deprecation warning - " message is displayed. This breaks the terminal test. Disable the warning - " message. - let $BASH_SILENCE_DEPRECATION_WARNING = 1 -endif - - -" Prepare for calling test_garbagecollect_now(). -" Also avoids some delays in Insert mode completion. -let v:testing = 1 - -" By default, copy each buffer line into allocated memory, so that valgrind can -" detect accessing memory before and after it. -call test_override('alloc_lines', 1) - -" Support function: get the alloc ID by name. -function GetAllocId(name) - exe 'split ' . s:srcdir . '/alloc.h' - let top = search('typedef enum') - if top == 0 - call add(v:errors, 'typedef not found in alloc.h') - endif - let lnum = search('aid_' . a:name . ',') - if lnum == 0 - call add(v:errors, 'Alloc ID ' . a:name . ' not defined') - endif - close - return lnum - top - 1 -endfunc - -" Get the list of swap files in the current directory. -func s:GetSwapFileList() - let save_dir = &directory - let &directory = '.' - let files = swapfilelist() - let &directory = save_dir - - " remove a match with runtest.vim - let idx = indexof(files, 'v:val =~ "runtest.vim."') - if idx >= 0 - call remove(files, idx) - endif - - return files -endfunc - -" A previous (failed) test run may have left swap files behind. Delete them -" before running tests again, they might interfere. -for name in s:GetSwapFileList() - call delete(name) -endfor -unlet! name - - -" Invoked when a test takes too much time. -func TestTimeout(id) - split test.log - call append(line('$'), '') - - let text = 'Test timed out: ' .. g:testfunc - if g:timeout_start > 0 - let text ..= strftime(' after %s seconds', localtime() - g:timeout_start) - endif - call append(line('$'), text) - write - call add(v:errors, text) - - cquit! 42 -endfunc -let g:timeout_start = 0 - -func RunTheTest(test) - let prefix = '' - if has('reltime') - let prefix = strftime('%M:%S', localtime() - s:test_start_time) .. ' ' - let g:func_start = reltime() - endif - echoconsole prefix .. 'Executing ' .. a:test - - if has('timers') - " No test should take longer than 45 seconds. If it takes longer we - " assume we are stuck and need to break out. - let test_timeout_timer = - \ timer_start(RunningWithValgrind() ? 90000 : 45000, 'TestTimeout') - let g:timeout_start = localtime() - endif - - " Avoid stopping at the "hit enter" prompt - set nomore - - " Avoid a three second wait when a message is about to be overwritten by the - " mode message. - set noshowmode - - " Clear any overrides, except "alloc_lines". - call test_override('ALL', 0) - - " Some tests wipe out buffers. To be consistent, always wipe out all - " buffers. - %bwipe! - - " Clear all children notifications in case there are stale ones left - let g:child_notification = 0 - - " The test may change the current directory. Save and restore the - " directory after executing the test. - let save_cwd = getcwd() - - " Permit "SetUp()" implementations to override default settings. - call s:SetDefaultOptionsForGUIBuilds() - - if exists("*SetUp") - try - call SetUp() - catch - call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) - endtry - endif - - let skipped = v:false - - au VimLeavePre * call EarlyExit(g:testfunc) - if a:test =~ 'Test_nocatch_' - " Function handles errors itself. This avoids skipping commands after the - " error. - let g:skipped_reason = '' - exe 'call ' . a:test - if g:skipped_reason != '' - call add(s:messages, ' Skipped') - call add(s:skipped, 'SKIPPED ' . a:test . ': ' . g:skipped_reason) - let skipped = v:true - endif - else - try - exe 'call ' . a:test - catch /^\cskipped/ - call add(s:messages, ' Skipped') - call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) - let skipped = v:true - catch - call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) - endtry - endif - au! VimLeavePre - - if a:test =~ '_terminal_' - " Terminal tests sometimes hang, give extra information - echoconsole 'After executing ' .. a:test - endif - - " In case 'insertmode' was set and something went wrong, make sure it is - " reset to avoid trouble with anything else. - set noinsertmode - - if exists("*TearDown") - try - call TearDown() - catch - call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) - endtry - endif - - if has('timers') - call timer_stop(test_timeout_timer) - let g:timeout_start = 0 - endif - - " Clear any autocommands and put back the catch-all for SwapExists. - au! - au SwapExists * call HandleSwapExists() - - " Check for and close any stray popup windows. - if has('popupwin') - call assert_equal([], popup_list(), 'Popup is still present') - call popup_clear(1) - endif - - if filereadable('guidialogfile') - call add(v:errors, "Unexpected dialog: " .. readfile('guidialogfile')->join('')) - call delete('guidialogfile') - endif - - " Close any extra tab pages and windows and make the current one not modified. - while tabpagenr('$') > 1 - let winid = win_getid() - quit! - if winid == win_getid() - echoerr 'Could not quit window' - break - endif - endwhile - - while 1 - let wincount = winnr('$') - if wincount == 1 - break - endif - bwipe! - if wincount == winnr('$') - " Did not manage to close a window. - only! - break - endif - endwhile - - exe 'cd ' . save_cwd - - if a:test =~ '_terminal_' - " Terminal tests sometimes hang, give extra information - echoconsole 'Finished ' . a:test - endif - - let message = 'Executed ' . a:test - if has('reltime') - let message ..= repeat(' ', 50 - len(message)) - let time = reltime(g:func_start) - if reltimefloat(time) > 0.1 - let message = s:t_bold .. message - endif - let message ..= ' in ' .. reltimestr(time) .. ' seconds' - if reltimefloat(time) > 0.1 - let message ..= s:t_normal - endif - endif - call add(s:messages, message) - let s:done += 1 - - " close any split windows - while winnr('$') > 1 - noswapfile bwipe! - endwhile - - " May be editing some buffer, wipe it out. Then we may end up in another - " buffer, continue until we end up in an empty no-name buffer without a swap - " file. - while bufname() != '' || execute('swapname') !~ 'No swap file' - let bn = bufnr() - - noswapfile bwipe! - - if bn == bufnr() - " avoid getting stuck in the same buffer - break - endif - endwhile - - if !skipped - " Check if the test has left any swap files behind. Delete them before - " running tests again, they might interfere. - let swapfiles = s:GetSwapFileList() - if len(swapfiles) > 0 - call add(s:messages, "Found swap files: " .. string(swapfiles)) - for name in swapfiles - call delete(name) - endfor - endif - endif -endfunc - -function Delete_Xtest_Files() - for file in glob('X*', v:false, v:true) - if file ==? 'XfakeHOME' - " Clean up files created by setup.vim - call delete('XfakeHOME', 'rf') - continue - endif - " call add(v:errors, file .. " exists when it shouldn't, trying to delete it!") - call delete(file) - if !empty(glob(file, v:false, v:true)) - " call add(v:errors, file .. " still exists after trying to delete it!") - if has('unix') - call system('rm -rf ' .. file) - endif - endif - endfor -endfunc - -func AfterTheTest(func_name) - if len(v:errors) > 0 - if match(s:may_fail_list, '^' .. a:func_name) >= 0 - let s:fail_expected += 1 - call add(s:errors_expected, 'Found errors in ' . g:testfunc . ':') - call extend(s:errors_expected, v:errors) - else - let s:fail += 1 - call add(s:errors, 'Found errors in ' . g:testfunc . ':') - call extend(s:errors, v:errors) - endif - let v:errors = [] - endif -endfunc - -func EarlyExit(test) - " It's OK for the test we use to test the quit detection. - if a:test != 'Test_zz_quit_detected()' - call add(v:errors, v:errmsg) - call add(v:errors, 'Test caused Vim to exit: ' . a:test) - endif - - call FinishTesting() -endfunc - -" This function can be called by a test if it wants to abort testing. -func FinishTesting() - call AfterTheTest('') - call Delete_Xtest_Files() - - " Don't write viminfo on exit. - set viminfo= - - if s:fail == 0 && s:fail_expected == 0 - " Success, create the .res file so that make knows it's done. - exe 'split ' . fnamemodify(g:testname, ':r') . '.res' - write - endif - - if len(s:errors) > 0 - " Append errors to test.log - split test.log - call append(line('$'), '') - call append(line('$'), 'From ' . g:testname . ':') - call append(line('$'), s:errors) - write - endif - - if s:done == 0 - if s:filtered > 0 - if $TEST_FILTER != '' - let message = "NO tests match $TEST_FILTER: '" .. $TEST_FILTER .. "'" - else - let message = "ALL tests match $TEST_SKIP_PAT: '" .. $TEST_SKIP_PAT .. "'" - endif - else - let message = 'NO tests executed' - endif - else - if s:filtered > 0 - call add(s:messages, "Filtered " .. s:filtered .. " tests with $TEST_FILTER and $TEST_SKIP_PAT") - endif - let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test') - endif - if s:done > 0 && has('reltime') - let message = s:t_bold .. message .. repeat(' ', 40 - len(message)) - let message ..= ' in ' .. reltimestr(reltime(s:run_start_time)) .. ' seconds' - let message ..= s:t_normal - endif - echo message - call add(s:messages, message) - if s:fail > 0 - let message = s:fail . ' FAILED:' - echo message - call add(s:messages, message) - call extend(s:messages, s:errors) - endif - if s:fail_expected > 0 - let message = s:fail_expected . ' FAILED (matching $TEST_MAY_FAIL):' - echo message - call add(s:messages, message) - call extend(s:messages, s:errors_expected) - endif - - " Add SKIPPED messages - call extend(s:messages, s:skipped) - - " Append messages to the file "messages", but remove ANSI Escape sequences - split messages - call append(line('$'), '') - call append(line('$'), 'From ' . g:testname . ':') - call append(line('$'), s:messages->map({_, val -> substitute(val, '\%x1b[[|]\(\d\?\|\d\+\)[hm]', '', 'g')})) - write - - qall! -endfunc - -" Source the test script. First grab the file name, in case the script -" navigates away. g:testname can be used by the tests. -let g:testname = expand('%') -let s:done = 0 -let s:fail = 0 -let s:fail_expected = 0 -let s:errors = [] -let s:errors_expected = [] -let s:messages = [] -let s:skipped = [] -if expand('%') =~ 'test_vimscript.vim' - " this test has intentional errors, don't use try/catch. - source % -else - try - source % - catch /^\cskipped/ - call add(s:messages, ' Skipped') - call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) - catch - let s:fail += 1 - call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint) - endtry -endif - -" Delete the .res file, it may change behavior for completion -call delete(fnamemodify(g:testname, ':r') .. '.res') - -" Locate Test_ functions and execute them. -redir @q -silent function /^Test_ -redir END -let s:tests = split(substitute(@q, '\(function\|def\) \(\k*()\)', '\2', 'g')) - -" If there is an extra argument filter the function names against it. -if argc() > 1 - let s:tests = filter(s:tests, 'v:val =~ argv(1)') -endif - -" If the environment variable $TEST_FILTER is set then filter the function -" names against it. -let s:filtered = 0 -if $TEST_FILTER != '' - let s:filtered = len(s:tests) - let s:tests = filter(s:tests, 'v:val =~ $TEST_FILTER') - let s:filtered -= len(s:tests) -endif - -let s:may_fail_list = [] -if $TEST_MAY_FAIL != '' - " Split the list at commas and add () to make it match g:testfunc. - let s:may_fail_list = split($TEST_MAY_FAIL, ',')->map({i, v -> v .. '()'}) -endif - -" Execute the tests in alphabetical order. -for g:testfunc in sort(s:tests) - if $TEST_SKIP_PAT != '' && g:testfunc =~ $TEST_SKIP_PAT - call add(s:messages, g:testfunc .. ' matches $TEST_SKIP_PAT') - let s:filtered += 1 - continue - endif - - " Silence, please! - set belloff=all - let prev_error = '' - let total_errors = [] - let g:run_nr = 1 - - " A test can set g:test_is_flaky to retry running the test. - let g:test_is_flaky = 0 - - let g:check_screendump_called = v:false - - " A test can set g:max_run_nr to change the max retry count. - let g:max_run_nr = 5 - if has('mac') - let g:max_run_nr = 10 - endif - - " By default, give up if the same error occurs. A test can set - " g:giveup_same_error to 0 to not give up on the same error and keep trying. - let g:giveup_same_error = 1 - - let starttime = strftime("%H:%M:%S") - call RunTheTest(g:testfunc) - - " Repeat a flaky test. Give up when: - " - $TEST_NO_RETRY is not empty - " - it fails again with the same message - " - it fails five times (with a different message) - if len(v:errors) > 0 - \ && $TEST_NO_RETRY == '' - \ && g:test_is_flaky - while 1 - call add(s:messages, 'Found errors in ' .. g:testfunc .. ':') - call extend(s:messages, v:errors) - - let endtime = strftime("%H:%M:%S") - if has('reltime') - let suffix = $' in{reltimestr(reltime(g:func_start))} seconds' - else - let suffix = '' - endif - call add(total_errors, $'Run {g:run_nr}, {starttime} - {endtime}{suffix}:') - call extend(total_errors, v:errors) - - if g:run_nr >= g:max_run_nr || g:giveup_same_error && prev_error == v:errors[0] - call add(total_errors, 'Flaky test failed too often, giving up') - let v:errors = total_errors - break - endif - - call add(s:messages, 'Flaky test failed, running it again') - - " Flakiness is often caused by the system being very busy. Sleep a - " couple of seconds to have a higher chance of succeeding the second - " time. - let delay = g:run_nr * 2 - exe 'sleep' delay - - let prev_error = v:errors[0] - let v:errors = [] - let g:run_nr += 1 - - let starttime = strftime("%H:%M:%S") - call RunTheTest(g:testfunc) - - if len(v:errors) == 0 - " Test passed on rerun. - break - endif - endwhile - endif - - call AfterTheTest(g:testfunc) -endfor - -call FinishTesting() - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/samples/Test_tohtml_basic.c.html b/uvim/src/testdir/samples/Test_tohtml_basic.c.html index 9046d847c7..c33df84bcc 100644 --- a/uvim/src/testdir/samples/Test_tohtml_basic.c.html +++ b/uvim/src/testdir/samples/Test_tohtml_basic.c.html @@ -2,9 +2,9 @@ -/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic.c.html - - +/home/jiangyinzuo/mnv/src/testdir/Test_tohtml_basic.c.html + + @@ -18,7 +18,7 @@ a { color: inherit; } -
+
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -45,4 +45,4 @@ int main(int argc, char *argv[])
 
- + diff --git a/uvim/src/testdir/samples/Test_tohtml_basic_no_css.c.html b/uvim/src/testdir/samples/Test_tohtml_basic_no_css.c.html index 272b71248a..acbd337c10 100644 --- a/uvim/src/testdir/samples/Test_tohtml_basic_no_css.c.html +++ b/uvim/src/testdir/samples/Test_tohtml_basic_no_css.c.html @@ -2,9 +2,9 @@ -/home/jiangyinzuo/vim/src/testdir/Test_tohtml_basic_no_css.c.html - - +/home/jiangyinzuo/mnv/src/testdir/Test_tohtml_basic_no_css.c.html + + @@ -37,4 +37,4 @@ int main(int argc, char *argv[])
- + diff --git a/uvim/src/testdir/samples/matchparen.mnv b/uvim/src/testdir/samples/matchparen.mnv new file mode 100644 index 0000000000..73e2da096a --- /dev/null +++ b/uvim/src/testdir/samples/matchparen.mnv @@ -0,0 +1,234 @@ +" MNV plugin for showing matching parens +" Maintainer: The MNV Project +" Last Change: 2023 Oct 20 +" Former Maintainer: Bram Moolenaar + +" Exit quickly when: +" - this plugin was already loaded (or disabled) +" - when 'compatible' is set +if exists("g:loaded_matchparen") || &cp + finish +endif +let g:loaded_matchparen = 1 + +if !exists("g:matchparen_timeout") + let g:matchparen_timeout = 300 +endif +if !exists("g:matchparen_insert_timeout") + let g:matchparen_insert_timeout = 60 +endif + +let s:has_matchaddpos = exists('*matchaddpos') + +augroup matchparen + " Replace all matchparen autocommands + autocmd! CursorMoved,CursorMovedI,WinEnter,BufWinEnter,WinScrolled * call s:Highlight_Matching_Pair() + autocmd! WinLeave,BufLeave * call s:Remove_Matches() + if exists('##TextChanged') + autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair() + autocmd! TextChangedP * call s:Remove_Matches() + endif +augroup END + +" Skip the rest if it was already done. +if exists("*s:Highlight_Matching_Pair") + finish +endif + +let s:cpo_save = &cpo +set cpo-=C + +" The function that is invoked (very often) to define a ":match" highlighting +" for any matching paren. +func s:Highlight_Matching_Pair() + if !exists("w:matchparen_ids") + let w:matchparen_ids = [] + endif + " Remove any previous match. + call s:Remove_Matches() + + " Avoid that we remove the popup menu. + " Return when there are no colors (looks like the cursor jumps). + if pumvisible() || (&t_Co < 8 && !has("gui_running")) + return + endif + + " Get the character under the cursor and check if it's in 'matchpairs'. + let c_lnum = line('.') + let c_col = col('.') + let before = 0 + + let text = getline(c_lnum) + let matches = matchlist(text, '\(.\)\=\%'.c_col.'c\(.\=\)') + if empty(matches) + let [c_before, c] = ['', ''] + else + let [c_before, c] = matches[1:2] + endif + let plist = split(&matchpairs, '.\zs[:,]') + let i = index(plist, c) + if i < 0 + " not found, in Insert mode try character before the cursor + if c_col > 1 && (mode() == 'i' || mode() == 'R') + let before = strlen(c_before) + let c = c_before + let i = index(plist, c) + endif + if i < 0 + " not found, nothing to do + return + endif + endif + + " Figure out the arguments for searchpairpos(). + if i % 2 == 0 + let s_flags = 'nW' + let c2 = plist[i + 1] + else + let s_flags = 'nbW' + let c2 = c + let c = plist[i - 1] + endif + if c == '[' + let c = '\[' + let c2 = '\]' + endif + + " Find the match. When it was just before the cursor move it there for a + " moment. + if before > 0 + let has_getcurpos = exists("*getcurpos") + if has_getcurpos + " getcurpos() is more efficient but doesn't exist before 7.4.313. + let save_cursor = getcurpos() + else + let save_cursor = winsaveview() + endif + call cursor(c_lnum, c_col - before) + endif + + if !has("syntax") || !exists("g:syntax_on") + let s_skip = "0" + else + " Build an expression that detects whether the current cursor position is + " in certain syntax types (string, comment, etc.), for use as + " searchpairpos()'s skip argument. + " We match "escape" for special items, such as lispEscapeSpecial, and + " match "symbol" for lispBarSymbol. + let s_skip = 'synstack(".", col("."))' + \ . '->indexof({_, id -> synIDattr(id, "name") =~? ' + \ . '"string\\|character\\|singlequote\\|escape\\|symbol\\|comment"}) >= 0' + " If executing the expression determines that the cursor is currently in + " one of the syntax types, then we want searchpairpos() to find the pair + " within those syntax types (i.e., not skip). Otherwise, the cursor is + " outside of the syntax types and s_skip should keep its value so we skip + " any matching pair inside the syntax types. + " Catch if this throws E363: pattern uses more memory than 'maxmempattern'. + try + execute 'if ' . s_skip . ' | let s_skip = "0" | endif' + catch /^MNV\%((\a\+)\)\=:E363/ + " We won't find anything, so skip searching, should keep MNV responsive. + return + endtry + endif + + " Limit the search to lines visible in the window. + let stoplinebottom = line('w$') + let stoplinetop = line('w0') + if i % 2 == 0 + let stopline = stoplinebottom + else + let stopline = stoplinetop + endif + + " Limit the search time to 300 msec to avoid a hang on very long lines. + " This fails when a timeout is not supported. + if mode() == 'i' || mode() == 'R' + let timeout = exists("b:matchparen_insert_timeout") ? b:matchparen_insert_timeout : g:matchparen_insert_timeout + else + let timeout = exists("b:matchparen_timeout") ? b:matchparen_timeout : g:matchparen_timeout + endif + try + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, timeout) + catch /E118/ + " Can't use the timeout, restrict the stopline a bit more to avoid taking + " a long time on closed folds and long lines. + " The "viewable" variables give a range in which we can scroll while + " keeping the cursor at the same position. + " adjustedScrolloff accounts for very large numbers of scrolloff. + let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2]) + let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2]) + let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2]) + " one of these stoplines will be adjusted below, but the current values are + " minimal boundaries within the current window + if i % 2 == 0 + if has("byte_offset") && has("syntax_items") && &smc > 0 + let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2]) + let stopline = min([bottom_viewable, byte2line(stopbyte)]) + else + let stopline = min([bottom_viewable, c_lnum + 100]) + endif + let stoplinebottom = stopline + else + if has("byte_offset") && has("syntax_items") && &smc > 0 + let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2]) + let stopline = max([top_viewable, byte2line(stopbyte)]) + else + let stopline = max([top_viewable, c_lnum - 100]) + endif + let stoplinetop = stopline + endif + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) + endtry + + if before > 0 + if has_getcurpos + call setpos('.', save_cursor) + else + call winrestview(save_cursor) + endif + endif + + " If a match is found setup match highlighting. + if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom + if s:has_matchaddpos + call add(w:matchparen_ids, matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10)) + else + exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) . + \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/' + call add(w:matchparen_ids, 3) + endif + let w:paren_hl_on = 1 + endif +endfunction + +func s:Remove_Matches() + if exists('w:paren_hl_on') && w:paren_hl_on + while !empty(w:matchparen_ids) + silent! call remove(w:matchparen_ids, 0)->matchdelete() + endwhile + let w:paren_hl_on = 0 + endif +endfunc + +" Define commands that will disable and enable the plugin. +command DoMatchParen call s:DoMatchParen() +command NoMatchParen call s:NoMatchParen() + +func s:NoMatchParen() + let w = winnr() + noau windo silent! call matchdelete(3) + unlet! g:loaded_matchparen + exe "noau ". w . "wincmd w" + au! matchparen +endfunc + +func s:DoMatchParen() + runtime plugin/matchparen.mnv + let w = winnr() + silent windo doau CursorMoved + exe "noau ". w . "wincmd w" +endfunc + +let &cpo = s:cpo_save +unlet s:cpo_save diff --git a/uvim/src/testdir/samples/matchparen.vim b/uvim/src/testdir/samples/matchparen.vim deleted file mode 100644 index 4235a0d39b..0000000000 --- a/uvim/src/testdir/samples/matchparen.vim +++ /dev/null @@ -1,234 +0,0 @@ -" Vim plugin for showing matching parens -" Maintainer: The Vim Project -" Last Change: 2023 Oct 20 -" Former Maintainer: Bram Moolenaar - -" Exit quickly when: -" - this plugin was already loaded (or disabled) -" - when 'compatible' is set -if exists("g:loaded_matchparen") || &cp - finish -endif -let g:loaded_matchparen = 1 - -if !exists("g:matchparen_timeout") - let g:matchparen_timeout = 300 -endif -if !exists("g:matchparen_insert_timeout") - let g:matchparen_insert_timeout = 60 -endif - -let s:has_matchaddpos = exists('*matchaddpos') - -augroup matchparen - " Replace all matchparen autocommands - autocmd! CursorMoved,CursorMovedI,WinEnter,BufWinEnter,WinScrolled * call s:Highlight_Matching_Pair() - autocmd! WinLeave,BufLeave * call s:Remove_Matches() - if exists('##TextChanged') - autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair() - autocmd! TextChangedP * call s:Remove_Matches() - endif -augroup END - -" Skip the rest if it was already done. -if exists("*s:Highlight_Matching_Pair") - finish -endif - -let s:cpo_save = &cpo -set cpo-=C - -" The function that is invoked (very often) to define a ":match" highlighting -" for any matching paren. -func s:Highlight_Matching_Pair() - if !exists("w:matchparen_ids") - let w:matchparen_ids = [] - endif - " Remove any previous match. - call s:Remove_Matches() - - " Avoid that we remove the popup menu. - " Return when there are no colors (looks like the cursor jumps). - if pumvisible() || (&t_Co < 8 && !has("gui_running")) - return - endif - - " Get the character under the cursor and check if it's in 'matchpairs'. - let c_lnum = line('.') - let c_col = col('.') - let before = 0 - - let text = getline(c_lnum) - let matches = matchlist(text, '\(.\)\=\%'.c_col.'c\(.\=\)') - if empty(matches) - let [c_before, c] = ['', ''] - else - let [c_before, c] = matches[1:2] - endif - let plist = split(&matchpairs, '.\zs[:,]') - let i = index(plist, c) - if i < 0 - " not found, in Insert mode try character before the cursor - if c_col > 1 && (mode() == 'i' || mode() == 'R') - let before = strlen(c_before) - let c = c_before - let i = index(plist, c) - endif - if i < 0 - " not found, nothing to do - return - endif - endif - - " Figure out the arguments for searchpairpos(). - if i % 2 == 0 - let s_flags = 'nW' - let c2 = plist[i + 1] - else - let s_flags = 'nbW' - let c2 = c - let c = plist[i - 1] - endif - if c == '[' - let c = '\[' - let c2 = '\]' - endif - - " Find the match. When it was just before the cursor move it there for a - " moment. - if before > 0 - let has_getcurpos = exists("*getcurpos") - if has_getcurpos - " getcurpos() is more efficient but doesn't exist before 7.4.313. - let save_cursor = getcurpos() - else - let save_cursor = winsaveview() - endif - call cursor(c_lnum, c_col - before) - endif - - if !has("syntax") || !exists("g:syntax_on") - let s_skip = "0" - else - " Build an expression that detects whether the current cursor position is - " in certain syntax types (string, comment, etc.), for use as - " searchpairpos()'s skip argument. - " We match "escape" for special items, such as lispEscapeSpecial, and - " match "symbol" for lispBarSymbol. - let s_skip = 'synstack(".", col("."))' - \ . '->indexof({_, id -> synIDattr(id, "name") =~? ' - \ . '"string\\|character\\|singlequote\\|escape\\|symbol\\|comment"}) >= 0' - " If executing the expression determines that the cursor is currently in - " one of the syntax types, then we want searchpairpos() to find the pair - " within those syntax types (i.e., not skip). Otherwise, the cursor is - " outside of the syntax types and s_skip should keep its value so we skip - " any matching pair inside the syntax types. - " Catch if this throws E363: pattern uses more memory than 'maxmempattern'. - try - execute 'if ' . s_skip . ' | let s_skip = "0" | endif' - catch /^Vim\%((\a\+)\)\=:E363/ - " We won't find anything, so skip searching, should keep Vim responsive. - return - endtry - endif - - " Limit the search to lines visible in the window. - let stoplinebottom = line('w$') - let stoplinetop = line('w0') - if i % 2 == 0 - let stopline = stoplinebottom - else - let stopline = stoplinetop - endif - - " Limit the search time to 300 msec to avoid a hang on very long lines. - " This fails when a timeout is not supported. - if mode() == 'i' || mode() == 'R' - let timeout = exists("b:matchparen_insert_timeout") ? b:matchparen_insert_timeout : g:matchparen_insert_timeout - else - let timeout = exists("b:matchparen_timeout") ? b:matchparen_timeout : g:matchparen_timeout - endif - try - let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, timeout) - catch /E118/ - " Can't use the timeout, restrict the stopline a bit more to avoid taking - " a long time on closed folds and long lines. - " The "viewable" variables give a range in which we can scroll while - " keeping the cursor at the same position. - " adjustedScrolloff accounts for very large numbers of scrolloff. - let adjustedScrolloff = min([&scrolloff, (line('w$') - line('w0')) / 2]) - let bottom_viewable = min([line('$'), c_lnum + &lines - adjustedScrolloff - 2]) - let top_viewable = max([1, c_lnum-&lines+adjustedScrolloff + 2]) - " one of these stoplines will be adjusted below, but the current values are - " minimal boundaries within the current window - if i % 2 == 0 - if has("byte_offset") && has("syntax_items") && &smc > 0 - let stopbyte = min([line2byte("$"), line2byte(".") + col(".") + &smc * 2]) - let stopline = min([bottom_viewable, byte2line(stopbyte)]) - else - let stopline = min([bottom_viewable, c_lnum + 100]) - endif - let stoplinebottom = stopline - else - if has("byte_offset") && has("syntax_items") && &smc > 0 - let stopbyte = max([1, line2byte(".") + col(".") - &smc * 2]) - let stopline = max([top_viewable, byte2line(stopbyte)]) - else - let stopline = max([top_viewable, c_lnum - 100]) - endif - let stoplinetop = stopline - endif - let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) - endtry - - if before > 0 - if has_getcurpos - call setpos('.', save_cursor) - else - call winrestview(save_cursor) - endif - endif - - " If a match is found setup match highlighting. - if m_lnum > 0 && m_lnum >= stoplinetop && m_lnum <= stoplinebottom - if s:has_matchaddpos - call add(w:matchparen_ids, matchaddpos('MatchParen', [[c_lnum, c_col - before], [m_lnum, m_col]], 10)) - else - exe '3match MatchParen /\(\%' . c_lnum . 'l\%' . (c_col - before) . - \ 'c\)\|\(\%' . m_lnum . 'l\%' . m_col . 'c\)/' - call add(w:matchparen_ids, 3) - endif - let w:paren_hl_on = 1 - endif -endfunction - -func s:Remove_Matches() - if exists('w:paren_hl_on') && w:paren_hl_on - while !empty(w:matchparen_ids) - silent! call remove(w:matchparen_ids, 0)->matchdelete() - endwhile - let w:paren_hl_on = 0 - endif -endfunc - -" Define commands that will disable and enable the plugin. -command DoMatchParen call s:DoMatchParen() -command NoMatchParen call s:NoMatchParen() - -func s:NoMatchParen() - let w = winnr() - noau windo silent! call matchdelete(3) - unlet! g:loaded_matchparen - exe "noau ". w . "wincmd w" - au! matchparen -endfunc - -func s:DoMatchParen() - runtime plugin/matchparen.vim - let w = winnr() - silent windo doau CursorMoved - exe "noau ". w . "wincmd w" -endfunc - -let &cpo = s:cpo_save -unlet s:cpo_save diff --git a/uvim/src/testdir/samples/re.freeze.txt b/uvim/src/testdir/samples/re.freeze.txt index d768c23c5e..d7395e2b41 100644 --- a/uvim/src/testdir/samples/re.freeze.txt +++ b/uvim/src/testdir/samples/re.freeze.txt @@ -1,6 +1,6 @@ :set re=0 or 2 Search for the pattern: /\s\+\%#\@55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555 diff --git a/uvim/src/testdir/sautest/autoload/Test104.mnv b/uvim/src/testdir/sautest/autoload/Test104.mnv new file mode 100644 index 0000000000..d1e0e17a3b --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/Test104.mnv @@ -0,0 +1 @@ +let Test104#numvar = 123 diff --git a/uvim/src/testdir/sautest/autoload/Test104.vim b/uvim/src/testdir/sautest/autoload/Test104.vim deleted file mode 100644 index d1e0e17a3b..0000000000 --- a/uvim/src/testdir/sautest/autoload/Test104.vim +++ /dev/null @@ -1 +0,0 @@ -let Test104#numvar = 123 diff --git a/uvim/src/testdir/sautest/autoload/auto9.mnv b/uvim/src/testdir/sautest/autoload/auto9.mnv new file mode 100644 index 0000000000..9aac92755e --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/auto9.mnv @@ -0,0 +1,9 @@ +mnv9script + +export func Getsome() + return 'some' +endfunc + +export def Add42(count: number): number + return count + 42 +enddef diff --git a/uvim/src/testdir/sautest/autoload/auto9.vim b/uvim/src/testdir/sautest/autoload/auto9.vim deleted file mode 100644 index fad1fa781d..0000000000 --- a/uvim/src/testdir/sautest/autoload/auto9.vim +++ /dev/null @@ -1,9 +0,0 @@ -vim9script - -export func Getsome() - return 'some' -endfunc - -export def Add42(count: number): number - return count + 42 -enddef diff --git a/uvim/src/testdir/sautest/autoload/foo.mnv b/uvim/src/testdir/sautest/autoload/foo.mnv new file mode 100644 index 0000000000..6c7195bffe --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/foo.mnv @@ -0,0 +1,15 @@ +let g:loaded_foo_mnv += 1 + +let foo#bar = {} + +func foo#bar.echo() + let g:called_foo_bar_echo += 1 +endfunc + +func foo#addFoo(head) + return a:head .. 'foo' +endfunc + +func foo#() + return 'empty' +endfunc diff --git a/uvim/src/testdir/sautest/autoload/foo.vim b/uvim/src/testdir/sautest/autoload/foo.vim deleted file mode 100644 index 21d33a0f4d..0000000000 --- a/uvim/src/testdir/sautest/autoload/foo.vim +++ /dev/null @@ -1,15 +0,0 @@ -let g:loaded_foo_vim += 1 - -let foo#bar = {} - -func foo#bar.echo() - let g:called_foo_bar_echo += 1 -endfunc - -func foo#addFoo(head) - return a:head .. 'foo' -endfunc - -func foo#() - return 'empty' -endfunc diff --git a/uvim/src/testdir/sautest/autoload/footest.mnv b/uvim/src/testdir/sautest/autoload/footest.mnv new file mode 100644 index 0000000000..fc22fb0835 --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/footest.mnv @@ -0,0 +1,5 @@ +" Autoload script used by test_listdict.mnv, test_exists.mnv and test_let.mnv +let footest#x = 1 +func footest#F() + return 0 +endfunc diff --git a/uvim/src/testdir/sautest/autoload/footest.vim b/uvim/src/testdir/sautest/autoload/footest.vim deleted file mode 100644 index 1e78963a10..0000000000 --- a/uvim/src/testdir/sautest/autoload/footest.vim +++ /dev/null @@ -1,5 +0,0 @@ -" Autoload script used by test_listdict.vim, test_exists.vim and test_let.vim -let footest#x = 1 -func footest#F() - return 0 -endfunc diff --git a/uvim/src/testdir/sautest/autoload/globone.mnv b/uvim/src/testdir/sautest/autoload/globone.mnv new file mode 100644 index 0000000000..98c9a10582 --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/globone.mnv @@ -0,0 +1 @@ +" used by Test_globpath() diff --git a/uvim/src/testdir/sautest/autoload/globone.vim b/uvim/src/testdir/sautest/autoload/globone.vim deleted file mode 100644 index 98c9a10582..0000000000 --- a/uvim/src/testdir/sautest/autoload/globone.vim +++ /dev/null @@ -1 +0,0 @@ -" used by Test_globpath() diff --git a/uvim/src/testdir/sautest/autoload/globtwo.mnv b/uvim/src/testdir/sautest/autoload/globtwo.mnv new file mode 100644 index 0000000000..98c9a10582 --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/globtwo.mnv @@ -0,0 +1 @@ +" used by Test_globpath() diff --git a/uvim/src/testdir/sautest/autoload/globtwo.vim b/uvim/src/testdir/sautest/autoload/globtwo.vim deleted file mode 100644 index 98c9a10582..0000000000 --- a/uvim/src/testdir/sautest/autoload/globtwo.vim +++ /dev/null @@ -1 +0,0 @@ -" used by Test_globpath() diff --git a/uvim/src/testdir/sautest/autoload/sourced.mnv b/uvim/src/testdir/sautest/autoload/sourced.mnv new file mode 100644 index 0000000000..c76561cab7 --- /dev/null +++ b/uvim/src/testdir/sautest/autoload/sourced.mnv @@ -0,0 +1,4 @@ +let g:loaded_sourced_mnv += 1 +func sourced#something() +endfunc +call sourced#something() diff --git a/uvim/src/testdir/sautest/autoload/sourced.vim b/uvim/src/testdir/sautest/autoload/sourced.vim deleted file mode 100644 index aac96b11ce..0000000000 --- a/uvim/src/testdir/sautest/autoload/sourced.vim +++ /dev/null @@ -1,4 +0,0 @@ -let g:loaded_sourced_vim += 1 -func sourced#something() -endfunc -call sourced#something() diff --git a/uvim/src/testdir/test10.in b/uvim/src/testdir/test10.in index 40f8e08075..0e298676b7 100644 --- a/uvim/src/testdir/test10.in +++ b/uvim/src/testdir/test10.in @@ -1,12 +1,12 @@ -Test that vim9script also works without the +eval feature. +Test that mnv9script also works without the +eval feature. STARTTEST -:/^START/+1,/^END/-1:w! Xvim9 -:so Xvim9 +:/^START/+1,/^END/-1:w! Xmnv9 +:so Xmnv9 ENDTEST START -vim9script +mnv9script if 1 echo 'this is skipped without +eval' diff --git a/uvim/src/testdir/test29.in b/uvim/src/testdir/test29.in index 047803c60f..59b89d377d 100644 --- a/uvim/src/testdir/test29.in +++ b/uvim/src/testdir/test29.in @@ -1,5 +1,5 @@ Test for buffer name completion when 'wildoptions' contains "fuzzy" -(Confirm that Vim does not crash) +(Confirm that MNV does not crash) STARTTEST :set wildoptions=fuzzy diff --git a/uvim/src/testdir/test_alot.mnv b/uvim/src/testdir/test_alot.mnv new file mode 100644 index 0000000000..72ce104725 --- /dev/null +++ b/uvim/src/testdir/test_alot.mnv @@ -0,0 +1,31 @@ +" A series of tests that can run in one MNV invocation. +" This makes testing go faster, since MNV doesn't need to restart. + +source test_backup.mnv +source test_behave.mnv +source test_compiler.mnv +source test_ex_equal.mnv +source test_ex_undo.mnv +source test_ex_z.mnv +source test_ex_mode.mnv +source test_expand.mnv +source test_expand_dllpath.mnv +source test_expand_func.mnv +source test_file_perm.mnv +source test_fnamemodify.mnv +source test_ga.mnv +source test_glob2regpat.mnv +source test_global.mnv +source test_move.mnv +source test_put.mnv +source test_reltime.mnv +source test_searchpos.mnv +source test_set.mnv +source test_shift.mnv +source test_sha256.mnv +source test_tabline.mnv +source test_tagcase.mnv +source test_tagfunc.mnv +source test_unlet.mnv +source test_version.mnv +source test_wnext.mnv diff --git a/uvim/src/testdir/test_alot.vim b/uvim/src/testdir/test_alot.vim deleted file mode 100644 index 592ca65672..0000000000 --- a/uvim/src/testdir/test_alot.vim +++ /dev/null @@ -1,31 +0,0 @@ -" A series of tests that can run in one Vim invocation. -" This makes testing go faster, since Vim doesn't need to restart. - -source test_backup.vim -source test_behave.vim -source test_compiler.vim -source test_ex_equal.vim -source test_ex_undo.vim -source test_ex_z.vim -source test_ex_mode.vim -source test_expand.vim -source test_expand_dllpath.vim -source test_expand_func.vim -source test_file_perm.vim -source test_fnamemodify.vim -source test_ga.vim -source test_glob2regpat.vim -source test_global.vim -source test_move.vim -source test_put.vim -source test_reltime.vim -source test_searchpos.vim -source test_set.vim -source test_shift.vim -source test_sha256.vim -source test_tabline.vim -source test_tagcase.vim -source test_tagfunc.vim -source test_unlet.vim -source test_version.vim -source test_wnext.vim diff --git a/uvim/src/testdir/test_alot_latin.mnv b/uvim/src/testdir/test_alot_latin.mnv new file mode 100644 index 0000000000..7cde69f759 --- /dev/null +++ b/uvim/src/testdir/test_alot_latin.mnv @@ -0,0 +1,7 @@ +" A series of tests that can run in one MNV invocation. +" This makes testing go faster, since MNV doesn't need to restart. + +" These tests use latin1 'encoding'. Setting 'encoding' is in the individual +" files, so that they can be run by themselves. + +source test_regexp_latin.mnv diff --git a/uvim/src/testdir/test_alot_latin.vim b/uvim/src/testdir/test_alot_latin.vim deleted file mode 100644 index 23a404cac1..0000000000 --- a/uvim/src/testdir/test_alot_latin.vim +++ /dev/null @@ -1,7 +0,0 @@ -" A series of tests that can run in one Vim invocation. -" This makes testing go faster, since Vim doesn't need to restart. - -" These tests use latin1 'encoding'. Setting 'encoding' is in the individual -" files, so that they can be run by themselves. - -source test_regexp_latin.vim diff --git a/uvim/src/testdir/test_alot_utf8.mnv b/uvim/src/testdir/test_alot_utf8.mnv new file mode 100644 index 0000000000..018171b619 --- /dev/null +++ b/uvim/src/testdir/test_alot_utf8.mnv @@ -0,0 +1,14 @@ +" A series of tests that can run in one MNV invocation. +" This makes testing go faster, since MNV doesn't need to restart. + +" These tests use utf8 'encoding'. Setting 'encoding' is already done in +" runtest.mnv. + +source test_charsearch_utf8.mnv +source test_expr_utf8.mnv +source test_mksession_utf8.mnv +source test_regexp_utf8.mnv +source test_source_utf8.mnv +source test_startup_utf8.mnv +source test_utf8.mnv +source test_utf8_comparisons.mnv diff --git a/uvim/src/testdir/test_alot_utf8.vim b/uvim/src/testdir/test_alot_utf8.vim deleted file mode 100644 index 77f5ede4c8..0000000000 --- a/uvim/src/testdir/test_alot_utf8.vim +++ /dev/null @@ -1,14 +0,0 @@ -" A series of tests that can run in one Vim invocation. -" This makes testing go faster, since Vim doesn't need to restart. - -" These tests use utf8 'encoding'. Setting 'encoding' is already done in -" runtest.vim. - -source test_charsearch_utf8.vim -source test_expr_utf8.vim -source test_mksession_utf8.vim -source test_regexp_utf8.vim -source test_source_utf8.vim -source test_startup_utf8.vim -source test_utf8.vim -source test_utf8_comparisons.vim diff --git a/uvim/src/testdir/test_arabic.mnv b/uvim/src/testdir/test_arabic.mnv new file mode 100644 index 0000000000..8a3f1c033c --- /dev/null +++ b/uvim/src/testdir/test_arabic.mnv @@ -0,0 +1,592 @@ +" Simplistic testing of Arabic mode. +" NOTE: This just checks if the code works. If you know Arabic please add +" functional tests that check the shaping works with real text. + +CheckFeature arabic + +" Return list of Unicode characters at line lnum. +" Combining characters are treated as a single item. +func s:get_chars(lnum) + call cursor(a:lnum, 1) + let chars = [] + let numchars = strchars(getline('.'), 1) + for i in range(1, numchars) + exe 'norm ' i . '|' + let c = execute('ascii') + let c = substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g') + let c = substitute(c, ',\s*Oct\(al\)\=\s\d*\(, Digr ..\)\=', '', 'g') + call add(chars, c) + endfor + return chars +endfunc + +func Test_arabic_toggle() + set arabic + call assert_equal(1, &rightleft) + call assert_equal(1, &arabicshape) + call assert_equal('arabic', &keymap) + call assert_equal(1, &delcombine) + + set iminsert=1 imsearch=1 + set arabic& + call assert_equal(0, &rightleft) + call assert_equal(1, &arabicshape) + call assert_equal('arabic', &keymap) + call assert_equal(1, &delcombine) + call assert_equal(0, &iminsert) + call assert_equal(-1, &imsearch) + + set arabicshape& keymap= delcombine& +endfunc + +func Test_arabic_input() + new + set arabic + " Typing sghl in Arabic insert mode should show the + " Arabic word 'Salaam' i.e. 'peace', spelled: + " SEEN, LAM, ALEF, MEEM. + " See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left + call feedkeys('isghl!', 'tx') + call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0]) + call assert_equal([ + \ 'U+0633', + \ 'U+0644 U+0627', + \ 'U+0645', + \ 'U+21'], s:get_chars(1)) + + " Without shaping, it should give individual Arabic letters. + set noarabicshape + call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0]) + call assert_equal([ + \ 'U+0633', + \ 'U+0644', + \ 'U+0627', + \ 'U+0645', + \ 'U+21'], s:get_chars(1)) + + set arabic& arabicshape& + bwipe! +endfunc + +func Test_arabic_toggle_keymap() + new + set arabic + call feedkeys("i12\12\12abcd", 'tx') + call assert_match("^ *.*ﺷ212121$", ScreenLines(1, &columns)[0]) + call assert_equal('121212شلاؤي', getline('.')) + set arabic& + bwipe! +endfunc + +func Test_delcombine() + new + set arabic + call feedkeys("isghl\\", 'tx') + call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0]) + call assert_equal(['U+0633', 'U+0644'], s:get_chars(1)) + + " Now the same with 'nodelcombine' + set nodelcombine + %d + call feedkeys("isghl\\", 'tx') + call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0]) + call assert_equal(['U+0633'], s:get_chars(1)) + set arabic& + bwipe! +endfunc + +" Values from src/arabic.h (not all used yet) +let s:a_COMMA = "\u060C" +let s:a_SEMICOLON = "\u061B" +let s:a_QUESTION = "\u061F" +let s:a_HAMZA = "\u0621" +let s:a_ALEF_MADDA = "\u0622" +let s:a_ALEF_HAMZA_ABOVE = "\u0623" +let s:a_WAW_HAMZA = "\u0624" +let s:a_ALEF_HAMZA_BELOW = "\u0625" +let s:a_YEH_HAMZA = "\u0626" +let s:a_ALEF = "\u0627" +let s:a_BEH = "\u0628" +let s:a_TEH_MARBUTA = "\u0629" +let s:a_TEH = "\u062a" +let s:a_THEH = "\u062b" +let s:a_JEEM = "\u062c" +let s:a_HAH = "\u062d" +let s:a_KHAH = "\u062e" +let s:a_DAL = "\u062f" +let s:a_THAL = "\u0630" +let s:a_REH = "\u0631" +let s:a_ZAIN = "\u0632" +let s:a_SEEN = "\u0633" +let s:a_SHEEN = "\u0634" +let s:a_SAD = "\u0635" +let s:a_DAD = "\u0636" +let s:a_TAH = "\u0637" +let s:a_ZAH = "\u0638" +let s:a_AIN = "\u0639" +let s:a_GHAIN = "\u063a" +let s:a_TATWEEL = "\u0640" +let s:a_FEH = "\u0641" +let s:a_QAF = "\u0642" +let s:a_KAF = "\u0643" +let s:a_LAM = "\u0644" +let s:a_MEEM = "\u0645" +let s:a_NOON = "\u0646" +let s:a_HEH = "\u0647" +let s:a_WAW = "\u0648" +let s:a_ALEF_MAKSURA = "\u0649" +let s:a_YEH = "\u064a" + +let s:a_FATHATAN = "\u064b" +let s:a_DAMMATAN = "\u064c" +let s:a_KASRATAN = "\u064d" +let s:a_FATHA = "\u064e" +let s:a_DAMMA = "\u064f" +let s:a_KASRA = "\u0650" +let s:a_SHADDA = "\u0651" +let s:a_SUKUN = "\u0652" + +let s:a_MADDA_ABOVE = "\u0653" +let s:a_HAMZA_ABOVE = "\u0654" +let s:a_HAMZA_BELOW = "\u0655" + +let s:a_ZERO = "\u0660" +let s:a_ONE = "\u0661" +let s:a_TWO = "\u0662" +let s:a_THREE = "\u0663" +let s:a_FOUR = "\u0664" +let s:a_FIVE = "\u0665" +let s:a_SIX = "\u0666" +let s:a_SEVEN = "\u0667" +let s:a_EIGHT = "\u0668" +let s:a_NINE = "\u0669" +let s:a_PERCENT = "\u066a" +let s:a_DECIMAL = "\u066b" +let s:a_THOUSANDS = "\u066c" +let s:a_STAR = "\u066d" +let s:a_MINI_ALEF = "\u0670" + +let s:a_s_FATHATAN = "\ufe70" +let s:a_m_TATWEEL_FATHATAN = "\ufe71" +let s:a_s_DAMMATAN = "\ufe72" + +let s:a_s_KASRATAN = "\ufe74" + +let s:a_s_FATHA = "\ufe76" +let s:a_m_FATHA = "\ufe77" +let s:a_s_DAMMA = "\ufe78" +let s:a_m_DAMMA = "\ufe79" +let s:a_s_KASRA = "\ufe7a" +let s:a_m_KASRA = "\ufe7b" +let s:a_s_SHADDA = "\ufe7c" +let s:a_m_SHADDA = "\ufe7d" +let s:a_s_SUKUN = "\ufe7e" +let s:a_m_SUKUN = "\ufe7f" + +let s:a_s_HAMZA = "\ufe80" +let s:a_s_ALEF_MADDA = "\ufe81" +let s:a_f_ALEF_MADDA = "\ufe82" +let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83" +let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84" +let s:a_s_WAW_HAMZA = "\ufe85" +let s:a_f_WAW_HAMZA = "\ufe86" +let s:a_s_ALEF_HAMZA_BELOW = "\ufe87" +let s:a_f_ALEF_HAMZA_BELOW = "\ufe88" +let s:a_s_YEH_HAMZA = "\ufe89" +let s:a_f_YEH_HAMZA = "\ufe8a" +let s:a_i_YEH_HAMZA = "\ufe8b" +let s:a_m_YEH_HAMZA = "\ufe8c" +let s:a_s_ALEF = "\ufe8d" +let s:a_f_ALEF = "\ufe8e" +let s:a_s_BEH = "\ufe8f" +let s:a_f_BEH = "\ufe90" +let s:a_i_BEH = "\ufe91" +let s:a_m_BEH = "\ufe92" +let s:a_s_TEH_MARBUTA = "\ufe93" +let s:a_f_TEH_MARBUTA = "\ufe94" +let s:a_s_TEH = "\ufe95" +let s:a_f_TEH = "\ufe96" +let s:a_i_TEH = "\ufe97" +let s:a_m_TEH = "\ufe98" +let s:a_s_THEH = "\ufe99" +let s:a_f_THEH = "\ufe9a" +let s:a_i_THEH = "\ufe9b" +let s:a_m_THEH = "\ufe9c" +let s:a_s_JEEM = "\ufe9d" +let s:a_f_JEEM = "\ufe9e" +let s:a_i_JEEM = "\ufe9f" +let s:a_m_JEEM = "\ufea0" +let s:a_s_HAH = "\ufea1" +let s:a_f_HAH = "\ufea2" +let s:a_i_HAH = "\ufea3" +let s:a_m_HAH = "\ufea4" +let s:a_s_KHAH = "\ufea5" +let s:a_f_KHAH = "\ufea6" +let s:a_i_KHAH = "\ufea7" +let s:a_m_KHAH = "\ufea8" +let s:a_s_DAL = "\ufea9" +let s:a_f_DAL = "\ufeaa" +let s:a_s_THAL = "\ufeab" +let s:a_f_THAL = "\ufeac" +let s:a_s_REH = "\ufead" +let s:a_f_REH = "\ufeae" +let s:a_s_ZAIN = "\ufeaf" +let s:a_f_ZAIN = "\ufeb0" +let s:a_s_SEEN = "\ufeb1" +let s:a_f_SEEN = "\ufeb2" +let s:a_i_SEEN = "\ufeb3" +let s:a_m_SEEN = "\ufeb4" +let s:a_s_SHEEN = "\ufeb5" +let s:a_f_SHEEN = "\ufeb6" +let s:a_i_SHEEN = "\ufeb7" +let s:a_m_SHEEN = "\ufeb8" +let s:a_s_SAD = "\ufeb9" +let s:a_f_SAD = "\ufeba" +let s:a_i_SAD = "\ufebb" +let s:a_m_SAD = "\ufebc" +let s:a_s_DAD = "\ufebd" +let s:a_f_DAD = "\ufebe" +let s:a_i_DAD = "\ufebf" +let s:a_m_DAD = "\ufec0" +let s:a_s_TAH = "\ufec1" +let s:a_f_TAH = "\ufec2" +let s:a_i_TAH = "\ufec3" +let s:a_m_TAH = "\ufec4" +let s:a_s_ZAH = "\ufec5" +let s:a_f_ZAH = "\ufec6" +let s:a_i_ZAH = "\ufec7" +let s:a_m_ZAH = "\ufec8" +let s:a_s_AIN = "\ufec9" +let s:a_f_AIN = "\ufeca" +let s:a_i_AIN = "\ufecb" +let s:a_m_AIN = "\ufecc" +let s:a_s_GHAIN = "\ufecd" +let s:a_f_GHAIN = "\ufece" +let s:a_i_GHAIN = "\ufecf" +let s:a_m_GHAIN = "\ufed0" +let s:a_s_FEH = "\ufed1" +let s:a_f_FEH = "\ufed2" +let s:a_i_FEH = "\ufed3" +let s:a_m_FEH = "\ufed4" +let s:a_s_QAF = "\ufed5" +let s:a_f_QAF = "\ufed6" +let s:a_i_QAF = "\ufed7" +let s:a_m_QAF = "\ufed8" +let s:a_s_KAF = "\ufed9" +let s:a_f_KAF = "\ufeda" +let s:a_i_KAF = "\ufedb" +let s:a_m_KAF = "\ufedc" +let s:a_s_LAM = "\ufedd" +let s:a_f_LAM = "\ufede" +let s:a_i_LAM = "\ufedf" +let s:a_m_LAM = "\ufee0" +let s:a_s_MEEM = "\ufee1" +let s:a_f_MEEM = "\ufee2" +let s:a_i_MEEM = "\ufee3" +let s:a_m_MEEM = "\ufee4" +let s:a_s_NOON = "\ufee5" +let s:a_f_NOON = "\ufee6" +let s:a_i_NOON = "\ufee7" +let s:a_m_NOON = "\ufee8" +let s:a_s_HEH = "\ufee9" +let s:a_f_HEH = "\ufeea" +let s:a_i_HEH = "\ufeeb" +let s:a_m_HEH = "\ufeec" +let s:a_s_WAW = "\ufeed" +let s:a_f_WAW = "\ufeee" +let s:a_s_ALEF_MAKSURA = "\ufeef" +let s:a_f_ALEF_MAKSURA = "\ufef0" +let s:a_s_YEH = "\ufef1" +let s:a_f_YEH = "\ufef2" +let s:a_i_YEH = "\ufef3" +let s:a_m_YEH = "\ufef4" +let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5" +let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6" +let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7" +let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8" +let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9" +let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa" +let s:a_s_LAM_ALEF = "\ufefb" +let s:a_f_LAM_ALEF = "\ufefc" + +let s:a_BYTE_ORDER_MARK = "\ufeff" + +func Test_shape_initial() + new + set arabicshape + + " Shaping arabic {testchar} non-arabic Tests chg_c_a2i(). + " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result + for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA], + \ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA], + \ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA], + \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE], + \ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA], + \ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW], + \ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF], + \ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA], + \ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL], + \ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL], + \ [s:a_REH, s:a_s_GHAIN, s:a_s_REH], + \ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN], + \ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL], + \ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW], + \ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA], + \ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH], + \ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH], + \ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH], + \ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM], + \ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH], + \ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH], + \ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN], + \ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN], + \ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD], + \ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD], + \ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH], + \ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH], + \ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN], + \ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN], + \ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH], + \ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF], + \ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF], + \ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM], + \ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM], + \ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON], + \ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH], + \ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH], + \ ] + call setline(1, s:a_GHAIN . pair[0] . ' ') + call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +func Test_shape_isolated() + new + set arabicshape + + " Shaping non-arabic {testchar} non-arabic Tests chg_c_a2s(). + " pair[0] = testchar, pair[1] = current-result + for pair in [[s:a_HAMZA, s:a_s_HAMZA], + \ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA], + \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE], + \ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA], + \ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW], + \ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA], + \ [s:a_ALEF, s:a_s_ALEF], + \ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA], + \ [s:a_DAL, s:a_s_DAL], + \ [s:a_THAL, s:a_s_THAL], + \ [s:a_REH, s:a_s_REH], + \ [s:a_ZAIN, s:a_s_ZAIN], + \ [s:a_TATWEEL, s:a_TATWEEL], + \ [s:a_WAW, s:a_s_WAW], + \ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA], + \ [s:a_BEH, s:a_s_BEH], + \ [s:a_TEH, s:a_s_TEH], + \ [s:a_THEH, s:a_s_THEH], + \ [s:a_JEEM, s:a_s_JEEM], + \ [s:a_HAH, s:a_s_HAH], + \ [s:a_KHAH, s:a_s_KHAH], + \ [s:a_SEEN, s:a_s_SEEN], + \ [s:a_SHEEN, s:a_s_SHEEN], + \ [s:a_SAD, s:a_s_SAD], + \ [s:a_DAD, s:a_s_DAD], + \ [s:a_TAH, s:a_s_TAH], + \ [s:a_ZAH, s:a_s_ZAH], + \ [s:a_AIN, s:a_s_AIN], + \ [s:a_GHAIN, s:a_s_GHAIN], + \ [s:a_FEH, s:a_s_FEH], + \ [s:a_QAF, s:a_s_QAF], + \ [s:a_KAF, s:a_s_KAF], + \ [s:a_LAM, s:a_s_LAM], + \ [s:a_MEEM, s:a_s_MEEM], + \ [s:a_NOON, s:a_s_NOON], + \ [s:a_HEH, s:a_s_HEH], + \ [s:a_YEH, s:a_s_YEH], + \ ] + call setline(1, ' ' . pair[0] . ' ') + call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +func Test_shape_iso_to_medial() + new + set arabicshape + + " Shaping arabic {testchar} arabic Tests chg_c_a2m(). + " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result, + " pair[3] = previous-result + for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH], + \[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH], + \[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH], + \[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH], + \[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH], + \[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH], + \[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH], + \[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH], + \[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH], + \[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH], + \[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH], + \[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH], + \[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH], + \[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH], + \[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH], + \[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH], + \[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH], + \[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH], + \[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH], + \[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH], + \[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH], + \[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH], + \[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH], + \[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH], + \[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH], + \[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH], + \[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH], + \[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH], + \[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH], + \[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH], + \[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH], + \[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH], + \[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH], + \[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH], + \[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH], + \[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH], + \[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH], + \ ] + call setline(1, s:a_GHAIN . pair[0] . s:a_BEH) + call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +func Test_shape_final() + new + set arabicshape + + " Shaping arabic {testchar} arabic Tests chg_c_a2f(). + " pair[0] = testchar, pair[1] = current-result, pair[2] = previous-result + for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH], + \[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH], + \[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH], + \[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH], + \[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH], + \[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH], + \[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH], + \[s:a_BEH, s:a_f_BEH, s:a_i_BEH], + \[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH], + \[s:a_TEH, s:a_f_TEH, s:a_i_BEH], + \[s:a_THEH, s:a_f_THEH, s:a_i_BEH], + \[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH], + \[s:a_HAH, s:a_f_HAH, s:a_i_BEH], + \[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH], + \[s:a_DAL, s:a_f_DAL, s:a_i_BEH], + \[s:a_THAL, s:a_f_THAL, s:a_i_BEH], + \[s:a_REH, s:a_f_REH, s:a_i_BEH], + \[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH], + \[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH], + \[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH], + \[s:a_SAD, s:a_f_SAD, s:a_i_BEH], + \[s:a_DAD, s:a_f_DAD, s:a_i_BEH], + \[s:a_TAH, s:a_f_TAH, s:a_i_BEH], + \[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH], + \[s:a_AIN, s:a_f_AIN, s:a_i_BEH], + \[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH], + \[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH], + \[s:a_FEH, s:a_f_FEH, s:a_i_BEH], + \[s:a_QAF, s:a_f_QAF, s:a_i_BEH], + \[s:a_KAF, s:a_f_KAF, s:a_i_BEH], + \[s:a_LAM, s:a_f_LAM, s:a_i_BEH], + \[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH], + \[s:a_NOON, s:a_f_NOON, s:a_i_BEH], + \[s:a_HEH, s:a_f_HEH, s:a_i_BEH], + \[s:a_WAW, s:a_f_WAW, s:a_i_BEH], + \[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH], + \[s:a_YEH, s:a_f_YEH, s:a_i_BEH], + \ ] + call setline(1, ' ' . pair[0] . s:a_BEH) + call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +func Test_shape_combination_final() + new + set arabicshape + + " Shaping arabic {testchar} arabic Tests chg_c_laa2f(). + " pair[0] = testchar, pair[1] = current-result + for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE], + \ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE], + \ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW], + \ [s:a_ALEF, s:a_f_LAM_ALEF], + \ ] + " The test char is a composing char, put on s:a_LAM. + call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH) + call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +func Test_shape_combination_isolated() + new + set arabicshape + + " Shaping arabic {testchar} arabic Tests chg_c_laa2i(). + " pair[0] = testchar, pair[1] = current-result + for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE], + \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE], + \ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW], + \ [s:a_ALEF, s:a_s_LAM_ALEF], + \ ] + " The test char is a composing char, put on s:a_LAM. + call setline(1, ' ' . s:a_LAM . pair[0] . ' ') + call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3)) + endfor + + set arabicshape& + bwipe! +endfunc + +" Test for entering arabic character in a search command +func Test_arabic_chars_in_search_cmd() + new + set arabic + call feedkeys("i\nsghl!\mnv\", 'tx') + call cursor(1, 1) + call feedkeys("/^sghl!\mnv$\\", 'tx') + call assert_equal([2, 1], [line('.'), col('.')]) + + " Try searching in left-to-right mode + set rightleftcmd= + call cursor(1, 1) + call feedkeys("/^sghl!\mnv$\", 'tx') + call assert_equal([2, 1], [line('.'), col('.')]) + + set rightleftcmd& + set rightleft& + set arabic& + bwipe! +endfunc + +func Test_W17_arabic_requires_utf8() + let save_enc = &encoding + set encoding=latin1 arabic + call assert_match('^W17:', GetMessages()[-1]) + set arabic& + let &encoding = save_enc +endfunc + +" mnv: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_arabic.vim b/uvim/src/testdir/test_arabic.vim deleted file mode 100644 index 8758e98886..0000000000 --- a/uvim/src/testdir/test_arabic.vim +++ /dev/null @@ -1,592 +0,0 @@ -" Simplistic testing of Arabic mode. -" NOTE: This just checks if the code works. If you know Arabic please add -" functional tests that check the shaping works with real text. - -CheckFeature arabic - -" Return list of Unicode characters at line lnum. -" Combining characters are treated as a single item. -func s:get_chars(lnum) - call cursor(a:lnum, 1) - let chars = [] - let numchars = strchars(getline('.'), 1) - for i in range(1, numchars) - exe 'norm ' i . '|' - let c = execute('ascii') - let c = substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g') - let c = substitute(c, ',\s*Oct\(al\)\=\s\d*\(, Digr ..\)\=', '', 'g') - call add(chars, c) - endfor - return chars -endfunc - -func Test_arabic_toggle() - set arabic - call assert_equal(1, &rightleft) - call assert_equal(1, &arabicshape) - call assert_equal('arabic', &keymap) - call assert_equal(1, &delcombine) - - set iminsert=1 imsearch=1 - set arabic& - call assert_equal(0, &rightleft) - call assert_equal(1, &arabicshape) - call assert_equal('arabic', &keymap) - call assert_equal(1, &delcombine) - call assert_equal(0, &iminsert) - call assert_equal(-1, &imsearch) - - set arabicshape& keymap= delcombine& -endfunc - -func Test_arabic_input() - new - set arabic - " Typing sghl in Arabic insert mode should show the - " Arabic word 'Salaam' i.e. 'peace', spelled: - " SEEN, LAM, ALEF, MEEM. - " See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left - call feedkeys('isghl!', 'tx') - call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0]) - call assert_equal([ - \ 'U+0633', - \ 'U+0644 U+0627', - \ 'U+0645', - \ 'U+21'], s:get_chars(1)) - - " Without shaping, it should give individual Arabic letters. - set noarabicshape - call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0]) - call assert_equal([ - \ 'U+0633', - \ 'U+0644', - \ 'U+0627', - \ 'U+0645', - \ 'U+21'], s:get_chars(1)) - - set arabic& arabicshape& - bwipe! -endfunc - -func Test_arabic_toggle_keymap() - new - set arabic - call feedkeys("i12\12\12abcd", 'tx') - call assert_match("^ *.*ﺷ212121$", ScreenLines(1, &columns)[0]) - call assert_equal('121212شلاؤي', getline('.')) - set arabic& - bwipe! -endfunc - -func Test_delcombine() - new - set arabic - call feedkeys("isghl\\", 'tx') - call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0]) - call assert_equal(['U+0633', 'U+0644'], s:get_chars(1)) - - " Now the same with 'nodelcombine' - set nodelcombine - %d - call feedkeys("isghl\\", 'tx') - call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0]) - call assert_equal(['U+0633'], s:get_chars(1)) - set arabic& - bwipe! -endfunc - -" Values from src/arabic.h (not all used yet) -let s:a_COMMA = "\u060C" -let s:a_SEMICOLON = "\u061B" -let s:a_QUESTION = "\u061F" -let s:a_HAMZA = "\u0621" -let s:a_ALEF_MADDA = "\u0622" -let s:a_ALEF_HAMZA_ABOVE = "\u0623" -let s:a_WAW_HAMZA = "\u0624" -let s:a_ALEF_HAMZA_BELOW = "\u0625" -let s:a_YEH_HAMZA = "\u0626" -let s:a_ALEF = "\u0627" -let s:a_BEH = "\u0628" -let s:a_TEH_MARBUTA = "\u0629" -let s:a_TEH = "\u062a" -let s:a_THEH = "\u062b" -let s:a_JEEM = "\u062c" -let s:a_HAH = "\u062d" -let s:a_KHAH = "\u062e" -let s:a_DAL = "\u062f" -let s:a_THAL = "\u0630" -let s:a_REH = "\u0631" -let s:a_ZAIN = "\u0632" -let s:a_SEEN = "\u0633" -let s:a_SHEEN = "\u0634" -let s:a_SAD = "\u0635" -let s:a_DAD = "\u0636" -let s:a_TAH = "\u0637" -let s:a_ZAH = "\u0638" -let s:a_AIN = "\u0639" -let s:a_GHAIN = "\u063a" -let s:a_TATWEEL = "\u0640" -let s:a_FEH = "\u0641" -let s:a_QAF = "\u0642" -let s:a_KAF = "\u0643" -let s:a_LAM = "\u0644" -let s:a_MEEM = "\u0645" -let s:a_NOON = "\u0646" -let s:a_HEH = "\u0647" -let s:a_WAW = "\u0648" -let s:a_ALEF_MAKSURA = "\u0649" -let s:a_YEH = "\u064a" - -let s:a_FATHATAN = "\u064b" -let s:a_DAMMATAN = "\u064c" -let s:a_KASRATAN = "\u064d" -let s:a_FATHA = "\u064e" -let s:a_DAMMA = "\u064f" -let s:a_KASRA = "\u0650" -let s:a_SHADDA = "\u0651" -let s:a_SUKUN = "\u0652" - -let s:a_MADDA_ABOVE = "\u0653" -let s:a_HAMZA_ABOVE = "\u0654" -let s:a_HAMZA_BELOW = "\u0655" - -let s:a_ZERO = "\u0660" -let s:a_ONE = "\u0661" -let s:a_TWO = "\u0662" -let s:a_THREE = "\u0663" -let s:a_FOUR = "\u0664" -let s:a_FIVE = "\u0665" -let s:a_SIX = "\u0666" -let s:a_SEVEN = "\u0667" -let s:a_EIGHT = "\u0668" -let s:a_NINE = "\u0669" -let s:a_PERCENT = "\u066a" -let s:a_DECIMAL = "\u066b" -let s:a_THOUSANDS = "\u066c" -let s:a_STAR = "\u066d" -let s:a_MINI_ALEF = "\u0670" - -let s:a_s_FATHATAN = "\ufe70" -let s:a_m_TATWEEL_FATHATAN = "\ufe71" -let s:a_s_DAMMATAN = "\ufe72" - -let s:a_s_KASRATAN = "\ufe74" - -let s:a_s_FATHA = "\ufe76" -let s:a_m_FATHA = "\ufe77" -let s:a_s_DAMMA = "\ufe78" -let s:a_m_DAMMA = "\ufe79" -let s:a_s_KASRA = "\ufe7a" -let s:a_m_KASRA = "\ufe7b" -let s:a_s_SHADDA = "\ufe7c" -let s:a_m_SHADDA = "\ufe7d" -let s:a_s_SUKUN = "\ufe7e" -let s:a_m_SUKUN = "\ufe7f" - -let s:a_s_HAMZA = "\ufe80" -let s:a_s_ALEF_MADDA = "\ufe81" -let s:a_f_ALEF_MADDA = "\ufe82" -let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83" -let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84" -let s:a_s_WAW_HAMZA = "\ufe85" -let s:a_f_WAW_HAMZA = "\ufe86" -let s:a_s_ALEF_HAMZA_BELOW = "\ufe87" -let s:a_f_ALEF_HAMZA_BELOW = "\ufe88" -let s:a_s_YEH_HAMZA = "\ufe89" -let s:a_f_YEH_HAMZA = "\ufe8a" -let s:a_i_YEH_HAMZA = "\ufe8b" -let s:a_m_YEH_HAMZA = "\ufe8c" -let s:a_s_ALEF = "\ufe8d" -let s:a_f_ALEF = "\ufe8e" -let s:a_s_BEH = "\ufe8f" -let s:a_f_BEH = "\ufe90" -let s:a_i_BEH = "\ufe91" -let s:a_m_BEH = "\ufe92" -let s:a_s_TEH_MARBUTA = "\ufe93" -let s:a_f_TEH_MARBUTA = "\ufe94" -let s:a_s_TEH = "\ufe95" -let s:a_f_TEH = "\ufe96" -let s:a_i_TEH = "\ufe97" -let s:a_m_TEH = "\ufe98" -let s:a_s_THEH = "\ufe99" -let s:a_f_THEH = "\ufe9a" -let s:a_i_THEH = "\ufe9b" -let s:a_m_THEH = "\ufe9c" -let s:a_s_JEEM = "\ufe9d" -let s:a_f_JEEM = "\ufe9e" -let s:a_i_JEEM = "\ufe9f" -let s:a_m_JEEM = "\ufea0" -let s:a_s_HAH = "\ufea1" -let s:a_f_HAH = "\ufea2" -let s:a_i_HAH = "\ufea3" -let s:a_m_HAH = "\ufea4" -let s:a_s_KHAH = "\ufea5" -let s:a_f_KHAH = "\ufea6" -let s:a_i_KHAH = "\ufea7" -let s:a_m_KHAH = "\ufea8" -let s:a_s_DAL = "\ufea9" -let s:a_f_DAL = "\ufeaa" -let s:a_s_THAL = "\ufeab" -let s:a_f_THAL = "\ufeac" -let s:a_s_REH = "\ufead" -let s:a_f_REH = "\ufeae" -let s:a_s_ZAIN = "\ufeaf" -let s:a_f_ZAIN = "\ufeb0" -let s:a_s_SEEN = "\ufeb1" -let s:a_f_SEEN = "\ufeb2" -let s:a_i_SEEN = "\ufeb3" -let s:a_m_SEEN = "\ufeb4" -let s:a_s_SHEEN = "\ufeb5" -let s:a_f_SHEEN = "\ufeb6" -let s:a_i_SHEEN = "\ufeb7" -let s:a_m_SHEEN = "\ufeb8" -let s:a_s_SAD = "\ufeb9" -let s:a_f_SAD = "\ufeba" -let s:a_i_SAD = "\ufebb" -let s:a_m_SAD = "\ufebc" -let s:a_s_DAD = "\ufebd" -let s:a_f_DAD = "\ufebe" -let s:a_i_DAD = "\ufebf" -let s:a_m_DAD = "\ufec0" -let s:a_s_TAH = "\ufec1" -let s:a_f_TAH = "\ufec2" -let s:a_i_TAH = "\ufec3" -let s:a_m_TAH = "\ufec4" -let s:a_s_ZAH = "\ufec5" -let s:a_f_ZAH = "\ufec6" -let s:a_i_ZAH = "\ufec7" -let s:a_m_ZAH = "\ufec8" -let s:a_s_AIN = "\ufec9" -let s:a_f_AIN = "\ufeca" -let s:a_i_AIN = "\ufecb" -let s:a_m_AIN = "\ufecc" -let s:a_s_GHAIN = "\ufecd" -let s:a_f_GHAIN = "\ufece" -let s:a_i_GHAIN = "\ufecf" -let s:a_m_GHAIN = "\ufed0" -let s:a_s_FEH = "\ufed1" -let s:a_f_FEH = "\ufed2" -let s:a_i_FEH = "\ufed3" -let s:a_m_FEH = "\ufed4" -let s:a_s_QAF = "\ufed5" -let s:a_f_QAF = "\ufed6" -let s:a_i_QAF = "\ufed7" -let s:a_m_QAF = "\ufed8" -let s:a_s_KAF = "\ufed9" -let s:a_f_KAF = "\ufeda" -let s:a_i_KAF = "\ufedb" -let s:a_m_KAF = "\ufedc" -let s:a_s_LAM = "\ufedd" -let s:a_f_LAM = "\ufede" -let s:a_i_LAM = "\ufedf" -let s:a_m_LAM = "\ufee0" -let s:a_s_MEEM = "\ufee1" -let s:a_f_MEEM = "\ufee2" -let s:a_i_MEEM = "\ufee3" -let s:a_m_MEEM = "\ufee4" -let s:a_s_NOON = "\ufee5" -let s:a_f_NOON = "\ufee6" -let s:a_i_NOON = "\ufee7" -let s:a_m_NOON = "\ufee8" -let s:a_s_HEH = "\ufee9" -let s:a_f_HEH = "\ufeea" -let s:a_i_HEH = "\ufeeb" -let s:a_m_HEH = "\ufeec" -let s:a_s_WAW = "\ufeed" -let s:a_f_WAW = "\ufeee" -let s:a_s_ALEF_MAKSURA = "\ufeef" -let s:a_f_ALEF_MAKSURA = "\ufef0" -let s:a_s_YEH = "\ufef1" -let s:a_f_YEH = "\ufef2" -let s:a_i_YEH = "\ufef3" -let s:a_m_YEH = "\ufef4" -let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5" -let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6" -let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7" -let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8" -let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9" -let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa" -let s:a_s_LAM_ALEF = "\ufefb" -let s:a_f_LAM_ALEF = "\ufefc" - -let s:a_BYTE_ORDER_MARK = "\ufeff" - -func Test_shape_initial() - new - set arabicshape - - " Shaping arabic {testchar} non-arabic Tests chg_c_a2i(). - " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result - for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA], - \ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA], - \ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA], - \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE], - \ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA], - \ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW], - \ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF], - \ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA], - \ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL], - \ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL], - \ [s:a_REH, s:a_s_GHAIN, s:a_s_REH], - \ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN], - \ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL], - \ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW], - \ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA], - \ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH], - \ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH], - \ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH], - \ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM], - \ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH], - \ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH], - \ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN], - \ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN], - \ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD], - \ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD], - \ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH], - \ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH], - \ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN], - \ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN], - \ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH], - \ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF], - \ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF], - \ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM], - \ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM], - \ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON], - \ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH], - \ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH], - \ ] - call setline(1, s:a_GHAIN . pair[0] . ' ') - call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -func Test_shape_isolated() - new - set arabicshape - - " Shaping non-arabic {testchar} non-arabic Tests chg_c_a2s(). - " pair[0] = testchar, pair[1] = current-result - for pair in [[s:a_HAMZA, s:a_s_HAMZA], - \ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA], - \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE], - \ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA], - \ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW], - \ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA], - \ [s:a_ALEF, s:a_s_ALEF], - \ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA], - \ [s:a_DAL, s:a_s_DAL], - \ [s:a_THAL, s:a_s_THAL], - \ [s:a_REH, s:a_s_REH], - \ [s:a_ZAIN, s:a_s_ZAIN], - \ [s:a_TATWEEL, s:a_TATWEEL], - \ [s:a_WAW, s:a_s_WAW], - \ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA], - \ [s:a_BEH, s:a_s_BEH], - \ [s:a_TEH, s:a_s_TEH], - \ [s:a_THEH, s:a_s_THEH], - \ [s:a_JEEM, s:a_s_JEEM], - \ [s:a_HAH, s:a_s_HAH], - \ [s:a_KHAH, s:a_s_KHAH], - \ [s:a_SEEN, s:a_s_SEEN], - \ [s:a_SHEEN, s:a_s_SHEEN], - \ [s:a_SAD, s:a_s_SAD], - \ [s:a_DAD, s:a_s_DAD], - \ [s:a_TAH, s:a_s_TAH], - \ [s:a_ZAH, s:a_s_ZAH], - \ [s:a_AIN, s:a_s_AIN], - \ [s:a_GHAIN, s:a_s_GHAIN], - \ [s:a_FEH, s:a_s_FEH], - \ [s:a_QAF, s:a_s_QAF], - \ [s:a_KAF, s:a_s_KAF], - \ [s:a_LAM, s:a_s_LAM], - \ [s:a_MEEM, s:a_s_MEEM], - \ [s:a_NOON, s:a_s_NOON], - \ [s:a_HEH, s:a_s_HEH], - \ [s:a_YEH, s:a_s_YEH], - \ ] - call setline(1, ' ' . pair[0] . ' ') - call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -func Test_shape_iso_to_medial() - new - set arabicshape - - " Shaping arabic {testchar} arabic Tests chg_c_a2m(). - " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result, - " pair[3] = previous-result - for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH], - \[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH], - \[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH], - \[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH], - \[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH], - \[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH], - \[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH], - \[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH], - \[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH], - \[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH], - \[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH], - \[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH], - \[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH], - \[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH], - \[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH], - \[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH], - \[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH], - \[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH], - \[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH], - \[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH], - \[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH], - \[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH], - \[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH], - \[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH], - \[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH], - \[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH], - \[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH], - \[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH], - \[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH], - \[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH], - \[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH], - \[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH], - \[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH], - \[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH], - \[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH], - \[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH], - \[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH], - \ ] - call setline(1, s:a_GHAIN . pair[0] . s:a_BEH) - call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -func Test_shape_final() - new - set arabicshape - - " Shaping arabic {testchar} arabic Tests chg_c_a2f(). - " pair[0] = testchar, pair[1] = current-result, pair[2] = previous-result - for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH], - \[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH], - \[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH], - \[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH], - \[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH], - \[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH], - \[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH], - \[s:a_BEH, s:a_f_BEH, s:a_i_BEH], - \[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH], - \[s:a_TEH, s:a_f_TEH, s:a_i_BEH], - \[s:a_THEH, s:a_f_THEH, s:a_i_BEH], - \[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH], - \[s:a_HAH, s:a_f_HAH, s:a_i_BEH], - \[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH], - \[s:a_DAL, s:a_f_DAL, s:a_i_BEH], - \[s:a_THAL, s:a_f_THAL, s:a_i_BEH], - \[s:a_REH, s:a_f_REH, s:a_i_BEH], - \[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH], - \[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH], - \[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH], - \[s:a_SAD, s:a_f_SAD, s:a_i_BEH], - \[s:a_DAD, s:a_f_DAD, s:a_i_BEH], - \[s:a_TAH, s:a_f_TAH, s:a_i_BEH], - \[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH], - \[s:a_AIN, s:a_f_AIN, s:a_i_BEH], - \[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH], - \[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH], - \[s:a_FEH, s:a_f_FEH, s:a_i_BEH], - \[s:a_QAF, s:a_f_QAF, s:a_i_BEH], - \[s:a_KAF, s:a_f_KAF, s:a_i_BEH], - \[s:a_LAM, s:a_f_LAM, s:a_i_BEH], - \[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH], - \[s:a_NOON, s:a_f_NOON, s:a_i_BEH], - \[s:a_HEH, s:a_f_HEH, s:a_i_BEH], - \[s:a_WAW, s:a_f_WAW, s:a_i_BEH], - \[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH], - \[s:a_YEH, s:a_f_YEH, s:a_i_BEH], - \ ] - call setline(1, ' ' . pair[0] . s:a_BEH) - call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -func Test_shape_combination_final() - new - set arabicshape - - " Shaping arabic {testchar} arabic Tests chg_c_laa2f(). - " pair[0] = testchar, pair[1] = current-result - for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE], - \ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE], - \ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW], - \ [s:a_ALEF, s:a_f_LAM_ALEF], - \ ] - " The test char is a composing char, put on s:a_LAM. - call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH) - call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -func Test_shape_combination_isolated() - new - set arabicshape - - " Shaping arabic {testchar} arabic Tests chg_c_laa2i(). - " pair[0] = testchar, pair[1] = current-result - for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE], - \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE], - \ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW], - \ [s:a_ALEF, s:a_s_LAM_ALEF], - \ ] - " The test char is a composing char, put on s:a_LAM. - call setline(1, ' ' . s:a_LAM . pair[0] . ' ') - call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3)) - endfor - - set arabicshape& - bwipe! -endfunc - -" Test for entering arabic character in a search command -func Test_arabic_chars_in_search_cmd() - new - set arabic - call feedkeys("i\nsghl!\vim\", 'tx') - call cursor(1, 1) - call feedkeys("/^sghl!\vim$\\", 'tx') - call assert_equal([2, 1], [line('.'), col('.')]) - - " Try searching in left-to-right mode - set rightleftcmd= - call cursor(1, 1) - call feedkeys("/^sghl!\vim$\", 'tx') - call assert_equal([2, 1], [line('.'), col('.')]) - - set rightleftcmd& - set rightleft& - set arabic& - bwipe! -endfunc - -func Test_W17_arabic_requires_utf8() - let save_enc = &encoding - set encoding=latin1 arabic - call assert_match('^W17:', GetMessages()[-1]) - set arabic& - let &encoding = save_enc -endfunc - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_arglist.mnv b/uvim/src/testdir/test_arglist.mnv new file mode 100644 index 0000000000..fad3db45db --- /dev/null +++ b/uvim/src/testdir/test_arglist.mnv @@ -0,0 +1,821 @@ +" Test argument list commands + +func Reset_arglist() + args a | %argd +endfunc + +func Test_argidx() + args a b c + last + call assert_equal(2, argidx()) + %argdelete + call assert_equal(0, argidx()) + " doing it again doesn't result in an error + %argdelete + call assert_equal(0, argidx()) + call assert_fails('2argdelete', 'E16:') + + args a b c + call assert_equal(0, argidx()) + next + call assert_equal(1, argidx()) + next + call assert_equal(2, argidx()) + 1argdelete + call assert_equal(1, argidx()) + 1argdelete + call assert_equal(0, argidx()) + 1argdelete + call assert_equal(0, argidx()) +endfunc + +func Test_argadd() + call Reset_arglist() + + %argdelete + argadd a b c + call assert_equal(0, argidx()) + + %argdelete + argadd a + call assert_equal(0, argidx()) + argadd b c d + call assert_equal(0, argidx()) + + call Init_abc() + argadd x + call Assert_argc(['a', 'b', 'x', 'c']) + call assert_equal(1, argidx()) + + call Init_abc() + 0argadd x + call Assert_argc(['x', 'a', 'b', 'c']) + call assert_equal(2, argidx()) + + call Init_abc() + 1argadd x + call Assert_argc(['a', 'x', 'b', 'c']) + call assert_equal(2, argidx()) + + call Init_abc() + $argadd x + call Assert_argc(['a', 'b', 'c', 'x']) + call assert_equal(1, argidx()) + + call Init_abc() + $argadd x + +2argadd y + call Assert_argc(['a', 'b', 'c', 'x', 'y']) + call assert_equal(1, argidx()) + + %argd + edit d + arga + call assert_equal(1, len(argv())) + call assert_equal('d', get(argv(), 0, '')) + + %argd + edit some\ file + arga + call assert_equal(1, len(argv())) + call assert_equal('some file', get(argv(), 0, '')) + + %argd + new + arga + call assert_equal(0, len(argv())) + + if has('unix') + call assert_fails('argadd `Xdoes_not_exist`', 'E479:') + endif +endfunc + +func Test_argadd_empty_curbuf() + new + let curbuf = bufnr('%') + call writefile(['test', 'Xargadd'], 'Xargadd', 'D') + " must not re-use the current buffer. + argadd Xargadd + call assert_equal(curbuf, bufnr('%')) + call assert_equal('', bufname('%')) + call assert_equal(1, '$'->line()) + rew + call assert_notequal(curbuf, '%'->bufnr()) + call assert_equal('Xargadd', '%'->bufname()) + call assert_equal(2, line('$')) + + %argd + bwipe! +endfunc + +func Init_abc() + args a b c + next +endfunc + +func Assert_argc(l) + call assert_equal(len(a:l), argc()) + let i = 0 + while i < len(a:l) && i < argc() + call assert_equal(a:l[i], argv(i)) + let i += 1 + endwhile +endfunc + +" Test for [count]argument and [count]argdelete commands +" Ported from the test_argument_count.in test script +func Test_argument() + call Reset_arglist() + + let save_hidden = &hidden + set hidden + + let g:buffers = [] + augroup TEST + au BufEnter * call add(buffers, expand('%:t')) + augroup END + + argadd a b c d + $argu + $-argu + -argu + 1argu + +2argu + + augroup TEST + au! + augroup END + + call assert_equal(['d', 'c', 'b', 'a', 'c'], g:buffers) + + call assert_equal("\na b [c] d ", execute(':args')) + + .argd + call assert_equal(['a', 'b', 'd'], argv()) + + -argd + call assert_equal(['a', 'd'], argv()) + + $argd + call assert_equal(['a'], argv()) + + 1arga c + 1arga b + $argu + $arga x + call assert_equal(['a', 'b', 'c', 'x'], argv()) + + 0arga y + call assert_equal(['y', 'a', 'b', 'c', 'x'], argv()) + + %argd + call assert_equal([], argv()) + + arga a b c d e f + 2,$-argd + call assert_equal(['a', 'f'], argv()) + + let &hidden = save_hidden + + let save_columns = &columns + let &columns = 79 + try + exe 'args ' .. join(range(1, 81)) + call assert_equal(join([ + \ '', + \ '[1] 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 ', + \ '2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 ', + \ '3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 ', + \ '4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 ', + \ '5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ', + \ ], "\n"), + \ execute('args')) + + " No trailing newline with one item per row. + let long_arg = repeat('X', 81) + exe 'args ' .. long_arg + call assert_equal("\n[".long_arg.']', execute('args')) + finally + let &columns = save_columns + endtry + + " Setting argument list should fail when the current buffer has unsaved + " changes + %argd + enew! + set modified + call assert_fails('args x y z', 'E37:') + args! x y z + call assert_equal(['x', 'y', 'z'], argv()) + call assert_equal('x', expand('%:t')) + + last | enew | argu + call assert_equal('z', expand('%:t')) + + %argdelete + call assert_fails('argument', 'E163:') +endfunc + +func Test_list_arguments() + call Reset_arglist() + + " four args half the screen width makes two lines with two columns + let aarg = repeat('a', &columns / 2 - 4) + let barg = repeat('b', &columns / 2 - 4) + let carg = repeat('c', &columns / 2 - 4) + let darg = repeat('d', &columns / 2 - 4) + exe 'argadd ' aarg barg carg darg + + redir => result + args + redir END + call assert_match('\[' . aarg . '] \+' . carg . '\n' . barg . ' \+' . darg, trim(result)) + + " if one arg is longer than half the screen make one column + exe 'argdel' aarg + let aarg = repeat('a', &columns / 2 + 2) + exe '0argadd' aarg + redir => result + args + redir END + call assert_match(aarg . '\n\[' . barg . ']\n' . carg . '\n' . darg, trim(result)) + + %argdelete +endfunc + +func Test_args_with_quote() + " Only on Unix can a file name include a double quote. + CheckUnix + + args \"foobar + call assert_equal('"foobar', argv(0)) + %argdelete +endfunc + +" Test for 0argadd and 0argedit +" Ported from the test_argument_0count.in test script +func Test_zero_argadd() + call Reset_arglist() + + arga a b c d + 2argu + 0arga added + call assert_equal(['added', 'a', 'b', 'c', 'd'], argv()) + + 2argu + arga third + call assert_equal(['added', 'a', 'third', 'b', 'c', 'd'], argv()) + + %argd + arga a b c d + 2argu + 0arge edited + call assert_equal(['edited', 'a', 'b', 'c', 'd'], argv()) + + 2argu + arga third + call assert_equal(['edited', 'a', 'third', 'b', 'c', 'd'], argv()) + + 2argu + argedit file\ with\ spaces another file + call assert_equal(['edited', 'a', 'file with spaces', 'another', 'file', 'third', 'b', 'c', 'd'], argv()) + call assert_equal('file with spaces', expand('%')) +endfunc + +" Test for argc() +func Test_argc() + call Reset_arglist() + call assert_equal(0, argc()) + argadd a b + call assert_equal(2, argc()) +endfunc + +" Test for arglistid() +func Test_arglistid() + call Reset_arglist() + arga a b + call assert_equal(0, arglistid()) + split + arglocal + call assert_equal(1, arglistid()) + tabnew | tabfirst + call assert_equal(0, arglistid(2)) + call assert_equal(1, arglistid(1, 1)) + call assert_equal(0, arglistid(2, 1)) + call assert_equal(1, arglistid(1, 2)) + tabonly | only | enew! + argglobal + call assert_equal(0, arglistid()) +endfunc + +" Tests for argv() and argc() +func Test_argv() + call Reset_arglist() + call assert_equal([], argv()) + call assert_equal("", argv(2)) + call assert_equal(0, argc()) + argadd a b c d + call assert_equal(4, argc()) + call assert_equal('c', argv(2)) + + let w1_id = win_getid() + split + let w2_id = win_getid() + arglocal + args e f g + tabnew + let w3_id = win_getid() + split + let w4_id = win_getid() + argglobal + tabfirst + call assert_equal(4, argc(w1_id)) + call assert_equal('b', argv(1, w1_id)) + call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w1_id)) + + call assert_equal(3, argc(w2_id)) + call assert_equal('f', argv(1, w2_id)) + call assert_equal(['e', 'f', 'g'], argv(-1, w2_id)) + + call assert_equal(3, argc(w3_id)) + call assert_equal('e', argv(0, w3_id)) + call assert_equal(['e', 'f', 'g'], argv(-1, w3_id)) + + call assert_equal(4, argc(w4_id)) + call assert_equal('c', argv(2, w4_id)) + call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w4_id)) + + call assert_equal(4, argc(-1)) + call assert_equal(3, argc()) + call assert_equal('d', argv(3, -1)) + call assert_equal(['a', 'b', 'c', 'd'], argv(-1, -1)) + tabonly | only | enew! + " Negative test cases + call assert_equal(-1, argc(100)) + call assert_equal('', argv(1, 100)) + call assert_equal([], argv(-1, 100)) + call assert_equal('', argv(10, -1)) + %argdelete +endfunc + +" Test for the :argedit command +func Test_argedit() + call Reset_arglist() + argedit a + call assert_equal(['a'], argv()) + call assert_equal('a', expand('%:t')) + argedit b + call assert_equal(['a', 'b'], argv()) + call assert_equal('b', expand('%:t')) + argedit a + call assert_equal(['a', 'b', 'a'], argv()) + call assert_equal('a', expand('%:t')) + " When file name case is ignored, an existing buffer with only case + " difference is re-used. + argedit C D + call assert_equal('C', expand('%:t')) + call assert_equal(['a', 'b', 'a', 'C', 'D'], argv()) + argedit c + if has('fname_case') + call assert_equal(['a', 'b', 'a', 'C', 'c', 'D'], argv()) + else + call assert_equal(['a', 'b', 'a', 'C', 'C', 'D'], argv()) + endif + 0argedit x + if has('fname_case') + call assert_equal(['x', 'a', 'b', 'a', 'C', 'c', 'D'], argv()) + else + call assert_equal(['x', 'a', 'b', 'a', 'C', 'C', 'D'], argv()) + endif + enew! | set modified + call assert_fails('argedit y', 'E37:') + argedit! y + if has('fname_case') + call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'c', 'D'], argv()) + else + call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'C', 'D'], argv()) + endif + %argd + bwipe! C + bwipe! D + + " :argedit reuses the current buffer if it is empty + %argd + " make sure to use a new buffer number for x when it is loaded + bw! x + new + let a = bufnr() + argedit x + call assert_equal(a, bufnr()) + call assert_equal('x', bufname()) + %argd + bw! x +endfunc + +" Test for the :argdedupe command +func Test_argdedupe() + call Reset_arglist() + argdedupe + call assert_equal([], argv()) + + args a a a aa b b a b aa + argdedupe + call assert_equal(['a', 'aa', 'b'], argv()) + + args a b c + argdedupe + call assert_equal(['a', 'b', 'c'], argv()) + + args a + argdedupe + call assert_equal(['a'], argv()) + + args a A b B + argdedupe + if has('fname_case') + call assert_equal(['a', 'A', 'b', 'B'], argv()) + else + call assert_equal(['a', 'b'], argv()) + endif + + args a b a c a b + last + argdedupe + next + call assert_equal('c', expand('%:t')) + + args a ./a + argdedupe + call assert_equal(['a'], argv()) + + %argd +endfunc + +" Test for the :argdelete command +func Test_argdelete() + call Reset_arglist() + args aa a aaa b bb + argdelete a* + call assert_equal(['b', 'bb'], argv()) + call assert_equal('aa', expand('%:t')) + last + argdelete % + call assert_equal(['b'], argv()) + call assert_fails('argdelete', 'E610:') + call assert_fails('1,100argdelete', 'E16:') + call assert_fails('argdel /\)/', 'E55:') + call assert_fails('1argdel 1', 'E474:') + + call Reset_arglist() + args a b c d + next + argdel + call Assert_argc(['a', 'c', 'd']) + %argdel + + call assert_fails('argdel does_not_exist', 'E480:') +endfunc + +func Test_argdelete_completion() + args foo bar + + call feedkeys(":argdelete \\\"\", 'tx') + call assert_equal('"argdelete bar foo', @:) + + call feedkeys(":argdelete x \\\"\", 'tx') + call assert_equal('"argdelete x bar foo', @:) + + %argd +endfunc + +" Tests for the :next, :prev, :first, :last, :rewind commands +func Test_argpos() + call Reset_arglist() + args a b c d + last + call assert_equal(3, argidx()) + call assert_fails('next', 'E165:') + prev + call assert_equal(2, argidx()) + Next + call assert_equal(1, argidx()) + first + call assert_equal(0, argidx()) + call assert_fails('prev', 'E164:') + 3next + call assert_equal(3, argidx()) + rewind + call assert_equal(0, argidx()) + %argd +endfunc + +" Test for autocommand that redefines the argument list, when doing ":all". +func Test_arglist_autocmd() + autocmd BufReadPost Xxx2 next Xxx2 Xxx1 + call writefile(['test file Xxx1'], 'Xxx1', 'D') + call writefile(['test file Xxx2'], 'Xxx2', 'D') + call writefile(['test file Xxx3'], 'Xxx3', 'D') + + new + " redefine arglist; go to Xxx1 + next! Xxx1 Xxx2 Xxx3 + " open window for all args; Reading Xxx2 will try to change the arglist and + " that will fail + call assert_fails("all", "E1156:") + call assert_equal('test file Xxx1', getline(1)) + wincmd w + call assert_equal('test file Xxx2', getline(1)) + wincmd w + call assert_equal('test file Xxx3', getline(1)) + + autocmd! BufReadPost Xxx2 + enew! | only + argdelete Xxx* + bwipe! Xxx1 Xxx2 Xxx3 +endfunc + +func Test_arg_all_expand() + call writefile(['test file Xxx1'], 'Xx x', 'D') + next notexist Xx\ x runtest.mnv + call assert_equal('notexist Xx\ x runtest.mnv', expand('##')) +endfunc + +func Test_large_arg() + " Argument longer or equal to the number of columns used to cause + " access to invalid memory. + exe 'argadd ' .repeat('x', &columns) + args +endfunc + +func Test_argdo() + next! Xa.c Xb.c Xc.c + new + + let g:bufenter = 0 + let g:bufleave = 0 + autocmd BufEnter * let g:bufenter += 1 + autocmd BufLeave * let g:bufleave += 1 + + let l = [] + argdo call add(l, expand('%')) + call assert_equal(['Xa.c', 'Xb.c', 'Xc.c'], l) + call assert_equal(3, g:bufenter) + call assert_equal(3, g:bufleave) + + let g:bufenter = 0 + let g:bufleave = 0 + + set eventignore=BufEnter,BufLeave + let l = [] + argdo call add(l, expand('%')) + call assert_equal(['Xa.c', 'Xb.c', 'Xc.c'], l) + call assert_equal(0, g:bufenter) + call assert_equal(0, g:bufleave) + call assert_equal('BufEnter,BufLeave', &eventignore) + set eventignore& + + autocmd! BufEnter + autocmd! BufLeave + unlet g:bufenter + unlet g:bufleave + bwipe Xa.c Xb.c Xc.c +endfunc + +" Test for quitting MNV with unedited files in the argument list +func Test_quit_with_arglist() + CheckRunMNVInTerminal + + let buf = RunMNVInTerminal('', {'rows': 6}) + call term_sendkeys(buf, ":set nomore\n") + call term_sendkeys(buf, ":args a b c\n") + call term_sendkeys(buf, ":quit\n") + call TermWait(buf) + call WaitForAssert({-> assert_match('^E173:', term_getline(buf, 6))}) + call StopMNVInTerminal(buf) + + " Try :confirm quit with unedited files in arglist + let buf = RunMNVInTerminal('', {'rows': 6}) + call term_sendkeys(buf, ":set nomore\n") + call term_sendkeys(buf, ":args a b c\n") + call term_sendkeys(buf, ":confirm quit\n") + call TermWait(buf) + call WaitForAssert({-> assert_match('^\[Y\]es, (N)o: *$', + \ term_getline(buf, 6))}) + call term_sendkeys(buf, "N") + call TermWait(buf) + call term_sendkeys(buf, ":confirm quit\n") + call WaitForAssert({-> assert_match('^\[Y\]es, (N)o: *$', + \ term_getline(buf, 6))}) + call term_sendkeys(buf, "Y") + call TermWait(buf) + call WaitForAssert({-> assert_equal("finished", term_getstatus(buf))}) + only! + " When this test fails, swap files are left behind which breaks subsequent + " tests + call delete('.a.swp') + call delete('.b.swp') + call delete('.c.swp') +endfunc + +" Test for ":all" not working when in the cmdline window +func Test_all_not_allowed_from_cmdwin() + au BufEnter * all + next x + " Use try/catch here, somehow assert_fails() doesn't work on MS-Windows + " console. + let caught = 'no' + try + exe ":norm! 7q?apat\" + catch /E11:/ + let caught = 'yes' + endtry + call assert_equal('yes', caught) + au! BufEnter +endfunc + +func Test_clear_arglist_in_all() + n 0 00 000 0000 00000 000000 + au WinNew 0 n 0 + call assert_fails("all", "E1156:") + au! * +endfunc + +" Test for the :all command +func Test_all_command() + %argdelete + + " :all command should not close windows with files in the argument list, + " but can rearrange the windows. + args Xargnew1 Xargnew2 + %bw! + edit Xargold1 + split Xargnew1 + let Xargnew1_winid = win_getid() + split Xargold2 + split Xargnew2 + let Xargnew2_winid = win_getid() + split Xargold3 + all + call assert_equal(2, winnr('$')) + call assert_equal([Xargnew1_winid, Xargnew2_winid], + \ [win_getid(1), win_getid(2)]) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2)]) + + " :all command should close windows for files which are not in the + " argument list in the current tab page. + %bw! + edit Xargold1 + split Xargold2 + tabedit Xargold3 + split Xargold4 + tabedit Xargold5 + tabfirst + all + call assert_equal(3, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargold4'), bufnr('Xargold3')], tabpagebuflist(2)) + call assert_equal([bufnr('Xargold5')], tabpagebuflist(3)) + + " :tab all command should close windows for files which are not in the + " argument list across all the tab pages. + %bw! + edit Xargold1 + split Xargold2 + tabedit Xargold3 + split Xargold4 + tabedit Xargold5 + tabfirst + args Xargnew1 Xargnew2 + tab all + call assert_equal(2, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) + + " If a count is specified, then :all should open only that many windows. + %bw! + args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 + all 3 + call assert_equal(3, winnr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2'), bufnr('Xargnew3')], + \ [winbufnr(1), winbufnr(2), winbufnr(3)]) + + " The :all command should not open more than 'tabpagemax' tab pages. + " If there are more files, then they should be opened in the last tab page. + %bw! + set tabpagemax=3 + tab all + call assert_equal(3, tabpagenr('$')) + call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) + call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) + call assert_equal([bufnr('Xargnew3'), bufnr('Xargnew4'), bufnr('Xargnew5')], + \ tabpagebuflist(3)) + set tabpagemax& + + " Without the 'hidden' option, modified buffers should not be closed. + args Xargnew1 Xargnew2 + %bw! + edit Xargtemp1 + call setline(1, 'temp buffer 1') + split Xargtemp2 + call setline(1, 'temp buffer 2') + all + call assert_equal(4, winnr('$')) + call assert_equal([bufnr('Xargtemp2'), bufnr('Xargtemp1'), bufnr('Xargnew1'), + \ bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2), winbufnr(3), winbufnr(4)]) + + " With the 'hidden' option set, both modified and unmodified buffers in + " closed windows should be hidden. + set hidden + all + call assert_equal(2, winnr('$')) + call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], + \ [winbufnr(1), winbufnr(2)]) + call assert_equal([1, 1, 0, 0], [getbufinfo('Xargtemp1')[0].hidden, + \ getbufinfo('Xargtemp2')[0].hidden, + \ getbufinfo('Xargnew1')[0].hidden, + \ getbufinfo('Xargnew2')[0].hidden]) + set nohidden + + " When 'winheight' is set to a large value, :all should open only one + " window. + args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 + %bw! + set winheight=9999 + call assert_fails('all', 'E36:') + call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) + set winheight& + + " When 'winwidth' is set to a large value, :vert all should open only one + " window. + %bw! + set winwidth=9999 + call assert_fails('vert all', 'E36:') + call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) + set winwidth& + + " empty argument list tests + %bw! + %argdelete + call assert_equal('', execute('args')) + all + call assert_equal(1, winnr('$')) + + %argdelete + %bw! +endfunc + +" Test for deleting buffer when creating an arglist. This was accessing freed +" memory +func Test_crash_arglist_uaf() + "%argdelete + new one + au BufAdd XUAFlocal :bw + arglocal XUAFlocal + au! BufAdd + bw! XUAFlocal + + au BufAdd XUAFlocal2 :bw + new two + new three + arglocal + argadd XUAFlocal2 Xfoobar + bw! XUAFlocal2 + bw! two + + au! BufAdd +endfunc + +" This was using freed memory again +func Test_crash_arglist_uaf2() + new + au BufAdd XUAFlocal :bw + arglocal XUAFlocal + redraw! + put ='abc' + 2# + au! BufAdd +endfunc + +func Test_arglist_w_locked_unlock() + au BufAdd * split + + args a + call assert_equal(2, winnr('$')) + wincmd p + quit + call assert_equal(1, winnr('$')) + + argedit b + call assert_equal(2, winnr('$')) + wincmd p + quit + call assert_equal(1, winnr('$')) + + %argd + %bw! + au! BufAdd +endfunc + +" mnv: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_arglist.vim b/uvim/src/testdir/test_arglist.vim deleted file mode 100644 index f62d2cfabf..0000000000 --- a/uvim/src/testdir/test_arglist.vim +++ /dev/null @@ -1,821 +0,0 @@ -" Test argument list commands - -func Reset_arglist() - args a | %argd -endfunc - -func Test_argidx() - args a b c - last - call assert_equal(2, argidx()) - %argdelete - call assert_equal(0, argidx()) - " doing it again doesn't result in an error - %argdelete - call assert_equal(0, argidx()) - call assert_fails('2argdelete', 'E16:') - - args a b c - call assert_equal(0, argidx()) - next - call assert_equal(1, argidx()) - next - call assert_equal(2, argidx()) - 1argdelete - call assert_equal(1, argidx()) - 1argdelete - call assert_equal(0, argidx()) - 1argdelete - call assert_equal(0, argidx()) -endfunc - -func Test_argadd() - call Reset_arglist() - - %argdelete - argadd a b c - call assert_equal(0, argidx()) - - %argdelete - argadd a - call assert_equal(0, argidx()) - argadd b c d - call assert_equal(0, argidx()) - - call Init_abc() - argadd x - call Assert_argc(['a', 'b', 'x', 'c']) - call assert_equal(1, argidx()) - - call Init_abc() - 0argadd x - call Assert_argc(['x', 'a', 'b', 'c']) - call assert_equal(2, argidx()) - - call Init_abc() - 1argadd x - call Assert_argc(['a', 'x', 'b', 'c']) - call assert_equal(2, argidx()) - - call Init_abc() - $argadd x - call Assert_argc(['a', 'b', 'c', 'x']) - call assert_equal(1, argidx()) - - call Init_abc() - $argadd x - +2argadd y - call Assert_argc(['a', 'b', 'c', 'x', 'y']) - call assert_equal(1, argidx()) - - %argd - edit d - arga - call assert_equal(1, len(argv())) - call assert_equal('d', get(argv(), 0, '')) - - %argd - edit some\ file - arga - call assert_equal(1, len(argv())) - call assert_equal('some file', get(argv(), 0, '')) - - %argd - new - arga - call assert_equal(0, len(argv())) - - if has('unix') - call assert_fails('argadd `Xdoes_not_exist`', 'E479:') - endif -endfunc - -func Test_argadd_empty_curbuf() - new - let curbuf = bufnr('%') - call writefile(['test', 'Xargadd'], 'Xargadd', 'D') - " must not re-use the current buffer. - argadd Xargadd - call assert_equal(curbuf, bufnr('%')) - call assert_equal('', bufname('%')) - call assert_equal(1, '$'->line()) - rew - call assert_notequal(curbuf, '%'->bufnr()) - call assert_equal('Xargadd', '%'->bufname()) - call assert_equal(2, line('$')) - - %argd - bwipe! -endfunc - -func Init_abc() - args a b c - next -endfunc - -func Assert_argc(l) - call assert_equal(len(a:l), argc()) - let i = 0 - while i < len(a:l) && i < argc() - call assert_equal(a:l[i], argv(i)) - let i += 1 - endwhile -endfunc - -" Test for [count]argument and [count]argdelete commands -" Ported from the test_argument_count.in test script -func Test_argument() - call Reset_arglist() - - let save_hidden = &hidden - set hidden - - let g:buffers = [] - augroup TEST - au BufEnter * call add(buffers, expand('%:t')) - augroup END - - argadd a b c d - $argu - $-argu - -argu - 1argu - +2argu - - augroup TEST - au! - augroup END - - call assert_equal(['d', 'c', 'b', 'a', 'c'], g:buffers) - - call assert_equal("\na b [c] d ", execute(':args')) - - .argd - call assert_equal(['a', 'b', 'd'], argv()) - - -argd - call assert_equal(['a', 'd'], argv()) - - $argd - call assert_equal(['a'], argv()) - - 1arga c - 1arga b - $argu - $arga x - call assert_equal(['a', 'b', 'c', 'x'], argv()) - - 0arga y - call assert_equal(['y', 'a', 'b', 'c', 'x'], argv()) - - %argd - call assert_equal([], argv()) - - arga a b c d e f - 2,$-argd - call assert_equal(['a', 'f'], argv()) - - let &hidden = save_hidden - - let save_columns = &columns - let &columns = 79 - try - exe 'args ' .. join(range(1, 81)) - call assert_equal(join([ - \ '', - \ '[1] 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 ', - \ '2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 ', - \ '3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 ', - \ '4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 ', - \ '5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ', - \ ], "\n"), - \ execute('args')) - - " No trailing newline with one item per row. - let long_arg = repeat('X', 81) - exe 'args ' .. long_arg - call assert_equal("\n[".long_arg.']', execute('args')) - finally - let &columns = save_columns - endtry - - " Setting argument list should fail when the current buffer has unsaved - " changes - %argd - enew! - set modified - call assert_fails('args x y z', 'E37:') - args! x y z - call assert_equal(['x', 'y', 'z'], argv()) - call assert_equal('x', expand('%:t')) - - last | enew | argu - call assert_equal('z', expand('%:t')) - - %argdelete - call assert_fails('argument', 'E163:') -endfunc - -func Test_list_arguments() - call Reset_arglist() - - " four args half the screen width makes two lines with two columns - let aarg = repeat('a', &columns / 2 - 4) - let barg = repeat('b', &columns / 2 - 4) - let carg = repeat('c', &columns / 2 - 4) - let darg = repeat('d', &columns / 2 - 4) - exe 'argadd ' aarg barg carg darg - - redir => result - args - redir END - call assert_match('\[' . aarg . '] \+' . carg . '\n' . barg . ' \+' . darg, trim(result)) - - " if one arg is longer than half the screen make one column - exe 'argdel' aarg - let aarg = repeat('a', &columns / 2 + 2) - exe '0argadd' aarg - redir => result - args - redir END - call assert_match(aarg . '\n\[' . barg . ']\n' . carg . '\n' . darg, trim(result)) - - %argdelete -endfunc - -func Test_args_with_quote() - " Only on Unix can a file name include a double quote. - CheckUnix - - args \"foobar - call assert_equal('"foobar', argv(0)) - %argdelete -endfunc - -" Test for 0argadd and 0argedit -" Ported from the test_argument_0count.in test script -func Test_zero_argadd() - call Reset_arglist() - - arga a b c d - 2argu - 0arga added - call assert_equal(['added', 'a', 'b', 'c', 'd'], argv()) - - 2argu - arga third - call assert_equal(['added', 'a', 'third', 'b', 'c', 'd'], argv()) - - %argd - arga a b c d - 2argu - 0arge edited - call assert_equal(['edited', 'a', 'b', 'c', 'd'], argv()) - - 2argu - arga third - call assert_equal(['edited', 'a', 'third', 'b', 'c', 'd'], argv()) - - 2argu - argedit file\ with\ spaces another file - call assert_equal(['edited', 'a', 'file with spaces', 'another', 'file', 'third', 'b', 'c', 'd'], argv()) - call assert_equal('file with spaces', expand('%')) -endfunc - -" Test for argc() -func Test_argc() - call Reset_arglist() - call assert_equal(0, argc()) - argadd a b - call assert_equal(2, argc()) -endfunc - -" Test for arglistid() -func Test_arglistid() - call Reset_arglist() - arga a b - call assert_equal(0, arglistid()) - split - arglocal - call assert_equal(1, arglistid()) - tabnew | tabfirst - call assert_equal(0, arglistid(2)) - call assert_equal(1, arglistid(1, 1)) - call assert_equal(0, arglistid(2, 1)) - call assert_equal(1, arglistid(1, 2)) - tabonly | only | enew! - argglobal - call assert_equal(0, arglistid()) -endfunc - -" Tests for argv() and argc() -func Test_argv() - call Reset_arglist() - call assert_equal([], argv()) - call assert_equal("", argv(2)) - call assert_equal(0, argc()) - argadd a b c d - call assert_equal(4, argc()) - call assert_equal('c', argv(2)) - - let w1_id = win_getid() - split - let w2_id = win_getid() - arglocal - args e f g - tabnew - let w3_id = win_getid() - split - let w4_id = win_getid() - argglobal - tabfirst - call assert_equal(4, argc(w1_id)) - call assert_equal('b', argv(1, w1_id)) - call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w1_id)) - - call assert_equal(3, argc(w2_id)) - call assert_equal('f', argv(1, w2_id)) - call assert_equal(['e', 'f', 'g'], argv(-1, w2_id)) - - call assert_equal(3, argc(w3_id)) - call assert_equal('e', argv(0, w3_id)) - call assert_equal(['e', 'f', 'g'], argv(-1, w3_id)) - - call assert_equal(4, argc(w4_id)) - call assert_equal('c', argv(2, w4_id)) - call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w4_id)) - - call assert_equal(4, argc(-1)) - call assert_equal(3, argc()) - call assert_equal('d', argv(3, -1)) - call assert_equal(['a', 'b', 'c', 'd'], argv(-1, -1)) - tabonly | only | enew! - " Negative test cases - call assert_equal(-1, argc(100)) - call assert_equal('', argv(1, 100)) - call assert_equal([], argv(-1, 100)) - call assert_equal('', argv(10, -1)) - %argdelete -endfunc - -" Test for the :argedit command -func Test_argedit() - call Reset_arglist() - argedit a - call assert_equal(['a'], argv()) - call assert_equal('a', expand('%:t')) - argedit b - call assert_equal(['a', 'b'], argv()) - call assert_equal('b', expand('%:t')) - argedit a - call assert_equal(['a', 'b', 'a'], argv()) - call assert_equal('a', expand('%:t')) - " When file name case is ignored, an existing buffer with only case - " difference is re-used. - argedit C D - call assert_equal('C', expand('%:t')) - call assert_equal(['a', 'b', 'a', 'C', 'D'], argv()) - argedit c - if has('fname_case') - call assert_equal(['a', 'b', 'a', 'C', 'c', 'D'], argv()) - else - call assert_equal(['a', 'b', 'a', 'C', 'C', 'D'], argv()) - endif - 0argedit x - if has('fname_case') - call assert_equal(['x', 'a', 'b', 'a', 'C', 'c', 'D'], argv()) - else - call assert_equal(['x', 'a', 'b', 'a', 'C', 'C', 'D'], argv()) - endif - enew! | set modified - call assert_fails('argedit y', 'E37:') - argedit! y - if has('fname_case') - call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'c', 'D'], argv()) - else - call assert_equal(['x', 'y', 'y', 'a', 'b', 'a', 'C', 'C', 'D'], argv()) - endif - %argd - bwipe! C - bwipe! D - - " :argedit reuses the current buffer if it is empty - %argd - " make sure to use a new buffer number for x when it is loaded - bw! x - new - let a = bufnr() - argedit x - call assert_equal(a, bufnr()) - call assert_equal('x', bufname()) - %argd - bw! x -endfunc - -" Test for the :argdedupe command -func Test_argdedupe() - call Reset_arglist() - argdedupe - call assert_equal([], argv()) - - args a a a aa b b a b aa - argdedupe - call assert_equal(['a', 'aa', 'b'], argv()) - - args a b c - argdedupe - call assert_equal(['a', 'b', 'c'], argv()) - - args a - argdedupe - call assert_equal(['a'], argv()) - - args a A b B - argdedupe - if has('fname_case') - call assert_equal(['a', 'A', 'b', 'B'], argv()) - else - call assert_equal(['a', 'b'], argv()) - endif - - args a b a c a b - last - argdedupe - next - call assert_equal('c', expand('%:t')) - - args a ./a - argdedupe - call assert_equal(['a'], argv()) - - %argd -endfunc - -" Test for the :argdelete command -func Test_argdelete() - call Reset_arglist() - args aa a aaa b bb - argdelete a* - call assert_equal(['b', 'bb'], argv()) - call assert_equal('aa', expand('%:t')) - last - argdelete % - call assert_equal(['b'], argv()) - call assert_fails('argdelete', 'E610:') - call assert_fails('1,100argdelete', 'E16:') - call assert_fails('argdel /\)/', 'E55:') - call assert_fails('1argdel 1', 'E474:') - - call Reset_arglist() - args a b c d - next - argdel - call Assert_argc(['a', 'c', 'd']) - %argdel - - call assert_fails('argdel does_not_exist', 'E480:') -endfunc - -func Test_argdelete_completion() - args foo bar - - call feedkeys(":argdelete \\\"\", 'tx') - call assert_equal('"argdelete bar foo', @:) - - call feedkeys(":argdelete x \\\"\", 'tx') - call assert_equal('"argdelete x bar foo', @:) - - %argd -endfunc - -" Tests for the :next, :prev, :first, :last, :rewind commands -func Test_argpos() - call Reset_arglist() - args a b c d - last - call assert_equal(3, argidx()) - call assert_fails('next', 'E165:') - prev - call assert_equal(2, argidx()) - Next - call assert_equal(1, argidx()) - first - call assert_equal(0, argidx()) - call assert_fails('prev', 'E164:') - 3next - call assert_equal(3, argidx()) - rewind - call assert_equal(0, argidx()) - %argd -endfunc - -" Test for autocommand that redefines the argument list, when doing ":all". -func Test_arglist_autocmd() - autocmd BufReadPost Xxx2 next Xxx2 Xxx1 - call writefile(['test file Xxx1'], 'Xxx1', 'D') - call writefile(['test file Xxx2'], 'Xxx2', 'D') - call writefile(['test file Xxx3'], 'Xxx3', 'D') - - new - " redefine arglist; go to Xxx1 - next! Xxx1 Xxx2 Xxx3 - " open window for all args; Reading Xxx2 will try to change the arglist and - " that will fail - call assert_fails("all", "E1156:") - call assert_equal('test file Xxx1', getline(1)) - wincmd w - call assert_equal('test file Xxx2', getline(1)) - wincmd w - call assert_equal('test file Xxx3', getline(1)) - - autocmd! BufReadPost Xxx2 - enew! | only - argdelete Xxx* - bwipe! Xxx1 Xxx2 Xxx3 -endfunc - -func Test_arg_all_expand() - call writefile(['test file Xxx1'], 'Xx x', 'D') - next notexist Xx\ x runtest.vim - call assert_equal('notexist Xx\ x runtest.vim', expand('##')) -endfunc - -func Test_large_arg() - " Argument longer or equal to the number of columns used to cause - " access to invalid memory. - exe 'argadd ' .repeat('x', &columns) - args -endfunc - -func Test_argdo() - next! Xa.c Xb.c Xc.c - new - - let g:bufenter = 0 - let g:bufleave = 0 - autocmd BufEnter * let g:bufenter += 1 - autocmd BufLeave * let g:bufleave += 1 - - let l = [] - argdo call add(l, expand('%')) - call assert_equal(['Xa.c', 'Xb.c', 'Xc.c'], l) - call assert_equal(3, g:bufenter) - call assert_equal(3, g:bufleave) - - let g:bufenter = 0 - let g:bufleave = 0 - - set eventignore=BufEnter,BufLeave - let l = [] - argdo call add(l, expand('%')) - call assert_equal(['Xa.c', 'Xb.c', 'Xc.c'], l) - call assert_equal(0, g:bufenter) - call assert_equal(0, g:bufleave) - call assert_equal('BufEnter,BufLeave', &eventignore) - set eventignore& - - autocmd! BufEnter - autocmd! BufLeave - unlet g:bufenter - unlet g:bufleave - bwipe Xa.c Xb.c Xc.c -endfunc - -" Test for quitting Vim with unedited files in the argument list -func Test_quit_with_arglist() - CheckRunVimInTerminal - - let buf = RunVimInTerminal('', {'rows': 6}) - call term_sendkeys(buf, ":set nomore\n") - call term_sendkeys(buf, ":args a b c\n") - call term_sendkeys(buf, ":quit\n") - call TermWait(buf) - call WaitForAssert({-> assert_match('^E173:', term_getline(buf, 6))}) - call StopVimInTerminal(buf) - - " Try :confirm quit with unedited files in arglist - let buf = RunVimInTerminal('', {'rows': 6}) - call term_sendkeys(buf, ":set nomore\n") - call term_sendkeys(buf, ":args a b c\n") - call term_sendkeys(buf, ":confirm quit\n") - call TermWait(buf) - call WaitForAssert({-> assert_match('^\[Y\]es, (N)o: *$', - \ term_getline(buf, 6))}) - call term_sendkeys(buf, "N") - call TermWait(buf) - call term_sendkeys(buf, ":confirm quit\n") - call WaitForAssert({-> assert_match('^\[Y\]es, (N)o: *$', - \ term_getline(buf, 6))}) - call term_sendkeys(buf, "Y") - call TermWait(buf) - call WaitForAssert({-> assert_equal("finished", term_getstatus(buf))}) - only! - " When this test fails, swap files are left behind which breaks subsequent - " tests - call delete('.a.swp') - call delete('.b.swp') - call delete('.c.swp') -endfunc - -" Test for ":all" not working when in the cmdline window -func Test_all_not_allowed_from_cmdwin() - au BufEnter * all - next x - " Use try/catch here, somehow assert_fails() doesn't work on MS-Windows - " console. - let caught = 'no' - try - exe ":norm! 7q?apat\" - catch /E11:/ - let caught = 'yes' - endtry - call assert_equal('yes', caught) - au! BufEnter -endfunc - -func Test_clear_arglist_in_all() - n 0 00 000 0000 00000 000000 - au WinNew 0 n 0 - call assert_fails("all", "E1156:") - au! * -endfunc - -" Test for the :all command -func Test_all_command() - %argdelete - - " :all command should not close windows with files in the argument list, - " but can rearrange the windows. - args Xargnew1 Xargnew2 - %bw! - edit Xargold1 - split Xargnew1 - let Xargnew1_winid = win_getid() - split Xargold2 - split Xargnew2 - let Xargnew2_winid = win_getid() - split Xargold3 - all - call assert_equal(2, winnr('$')) - call assert_equal([Xargnew1_winid, Xargnew2_winid], - \ [win_getid(1), win_getid(2)]) - call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], - \ [winbufnr(1), winbufnr(2)]) - - " :all command should close windows for files which are not in the - " argument list in the current tab page. - %bw! - edit Xargold1 - split Xargold2 - tabedit Xargold3 - split Xargold4 - tabedit Xargold5 - tabfirst - all - call assert_equal(3, tabpagenr('$')) - call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], tabpagebuflist(1)) - call assert_equal([bufnr('Xargold4'), bufnr('Xargold3')], tabpagebuflist(2)) - call assert_equal([bufnr('Xargold5')], tabpagebuflist(3)) - - " :tab all command should close windows for files which are not in the - " argument list across all the tab pages. - %bw! - edit Xargold1 - split Xargold2 - tabedit Xargold3 - split Xargold4 - tabedit Xargold5 - tabfirst - args Xargnew1 Xargnew2 - tab all - call assert_equal(2, tabpagenr('$')) - call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) - call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) - - " If a count is specified, then :all should open only that many windows. - %bw! - args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 - all 3 - call assert_equal(3, winnr('$')) - call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2'), bufnr('Xargnew3')], - \ [winbufnr(1), winbufnr(2), winbufnr(3)]) - - " The :all command should not open more than 'tabpagemax' tab pages. - " If there are more files, then they should be opened in the last tab page. - %bw! - set tabpagemax=3 - tab all - call assert_equal(3, tabpagenr('$')) - call assert_equal([bufnr('Xargnew1')], tabpagebuflist(1)) - call assert_equal([bufnr('Xargnew2')], tabpagebuflist(2)) - call assert_equal([bufnr('Xargnew3'), bufnr('Xargnew4'), bufnr('Xargnew5')], - \ tabpagebuflist(3)) - set tabpagemax& - - " Without the 'hidden' option, modified buffers should not be closed. - args Xargnew1 Xargnew2 - %bw! - edit Xargtemp1 - call setline(1, 'temp buffer 1') - split Xargtemp2 - call setline(1, 'temp buffer 2') - all - call assert_equal(4, winnr('$')) - call assert_equal([bufnr('Xargtemp2'), bufnr('Xargtemp1'), bufnr('Xargnew1'), - \ bufnr('Xargnew2')], - \ [winbufnr(1), winbufnr(2), winbufnr(3), winbufnr(4)]) - - " With the 'hidden' option set, both modified and unmodified buffers in - " closed windows should be hidden. - set hidden - all - call assert_equal(2, winnr('$')) - call assert_equal([bufnr('Xargnew1'), bufnr('Xargnew2')], - \ [winbufnr(1), winbufnr(2)]) - call assert_equal([1, 1, 0, 0], [getbufinfo('Xargtemp1')[0].hidden, - \ getbufinfo('Xargtemp2')[0].hidden, - \ getbufinfo('Xargnew1')[0].hidden, - \ getbufinfo('Xargnew2')[0].hidden]) - set nohidden - - " When 'winheight' is set to a large value, :all should open only one - " window. - args Xargnew1 Xargnew2 Xargnew3 Xargnew4 Xargnew5 - %bw! - set winheight=9999 - call assert_fails('all', 'E36:') - call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) - set winheight& - - " When 'winwidth' is set to a large value, :vert all should open only one - " window. - %bw! - set winwidth=9999 - call assert_fails('vert all', 'E36:') - call assert_equal([1, bufnr('Xargnew1')], [winnr('$'), winbufnr(1)]) - set winwidth& - - " empty argument list tests - %bw! - %argdelete - call assert_equal('', execute('args')) - all - call assert_equal(1, winnr('$')) - - %argdelete - %bw! -endfunc - -" Test for deleting buffer when creating an arglist. This was accessing freed -" memory -func Test_crash_arglist_uaf() - "%argdelete - new one - au BufAdd XUAFlocal :bw - arglocal XUAFlocal - au! BufAdd - bw! XUAFlocal - - au BufAdd XUAFlocal2 :bw - new two - new three - arglocal - argadd XUAFlocal2 Xfoobar - bw! XUAFlocal2 - bw! two - - au! BufAdd -endfunc - -" This was using freed memory again -func Test_crash_arglist_uaf2() - new - au BufAdd XUAFlocal :bw - arglocal XUAFlocal - redraw! - put ='abc' - 2# - au! BufAdd -endfunc - -func Test_arglist_w_locked_unlock() - au BufAdd * split - - args a - call assert_equal(2, winnr('$')) - wincmd p - quit - call assert_equal(1, winnr('$')) - - argedit b - call assert_equal(2, winnr('$')) - wincmd p - quit - call assert_equal(1, winnr('$')) - - %argd - %bw! - au! BufAdd -endfunc - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_assert.mnv b/uvim/src/testdir/test_assert.mnv new file mode 100644 index 0000000000..6587fee4ec --- /dev/null +++ b/uvim/src/testdir/test_assert.mnv @@ -0,0 +1,527 @@ +" Test that the methods used for testing work. + +func Test_assert_false() + call assert_equal(0, assert_false(0)) + call assert_equal(0, assert_false(v:false)) + call assert_equal(0, v:false->assert_false()) + + call assert_equal(1, assert_false(123)) + call assert_match("Expected False but got 123", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, 123->assert_false()) + call assert_match("Expected False but got 123", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_true() + call assert_equal(0, assert_true(1)) + call assert_equal(0, assert_true(123)) + call assert_equal(0, assert_true(v:true)) + call assert_equal(0, v:true->assert_true()) + + call assert_equal(1, assert_true(0)) + call assert_match("Expected True but got 0", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, 0->assert_true()) + call assert_match("Expected True but got 0", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_equal() + let s = 'foo' + call assert_equal(0, assert_equal('foo', s)) + let n = 4 + call assert_equal(0, assert_equal(4, n)) + let l = [1, 2, 3] + call assert_equal(0, assert_equal([1, 2, 3], l)) + call assert_equal(test_null_list(), test_null_list()) + call assert_equal(test_null_list(), []) + call assert_equal([], test_null_list()) + + let s = 'foo' + call assert_equal(1, assert_equal('bar', s)) + call assert_match("Expected 'bar' but got 'foo'", v:errors[0]) + call remove(v:errors, 0) + + let s = 'αβγ' + call assert_equal(1, assert_equal('δεζ', s)) + call assert_match("Expected 'δεζ' but got 'αβγ'", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX') + call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal('ΩωωωωωωωωωωωωωωωωωωωωωΩ', 'ΩψψψψψψψψψψψψψψψψψψψψψψψψψΩ') + call assert_match("Expected 'Ω\\\\\\[ω occurs 21 times]Ω' but got 'Ω\\\\\\[ψ occurs 25 times]Ω'", v:errors[0]) + call remove(v:errors, 0) + + " special characters are escaped + call assert_equal("\b\e\f\n\t\r\\\x01\x7f", 'x') + call assert_match('Expected ''\\b\\e\\f\\n\\t\\r\\\\\\x01\\x7f'' but got ''x''', v:errors[0]) + call remove(v:errors, 0) + + " many composing characters are handled properly + call setline(1, ' ') + norm 100grÝ€ + call assert_equal(1, getline(1)) + call assert_match("Expected 1 but got '.* occurs 100 times]'", v:errors[0]) + call remove(v:errors, 0) + bwipe! +endfunc + +func Test_assert_equal_dict() + call assert_equal(0, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 1})) + + call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 3})) + call assert_match("Expected {'one': 1} but got {'one': 3} - 1 equal item omitted", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 22, one: 11})) + call assert_match("Expected {'one': 1, 'two': 2} but got {'one': 11, 'two': 22}", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_equal(#{}, #{two: 2, one: 1})) + call assert_match("Expected {} but got {'one': 1, 'two': 2}", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_equal(#{two: 2, one: 1}, #{})) + call assert_match("Expected {'one': 1, 'two': 2} but got {}", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_equalfile() + call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz')) + call assert_match("E485: Can't read file abcabc", v:errors[0]) + call remove(v:errors, 0) + + let goodtext = ["one", "two", "three"] + call writefile(goodtext, 'Xone', 'D') + call assert_equal(1, 'Xone'->assert_equalfile('xyzxyz')) + call assert_match("E485: Can't read file xyzxyz", v:errors[0]) + call remove(v:errors, 0) + + call writefile(goodtext, 'Xtwo', 'D') + call assert_equal(0, assert_equalfile('Xone', 'Xtwo')) + + call writefile([goodtext[0]], 'Xone') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match("first file is shorter", v:errors[0]) + call remove(v:errors, 0) + + call writefile(goodtext, 'Xone') + call writefile([goodtext[0]], 'Xtwo') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match("second file is shorter", v:errors[0]) + call remove(v:errors, 0) + + call writefile(['1234X89'], 'Xone') + call writefile(['1234Y89'], 'Xtwo') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match('difference at byte 4, line 1 after "1234X" vs "1234Y"', v:errors[0]) + call remove(v:errors, 0) + + call writefile([repeat('x', 234) .. 'X'], 'Xone') + call writefile([repeat('x', 234) .. 'Y'], 'Xtwo') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + let xes = repeat('x', 134) + call assert_match('difference at byte 234, line 1 after "' .. xes .. 'X" vs "' .. xes .. 'Y"', v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_equalfile('Xone', 'Xtwo', 'a message')) + call assert_match("a message: difference at byte 234, line 1 after", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_notequal() + let n = 4 + call assert_equal(0, assert_notequal('foo', n)) + let s = 'foo' + call assert_equal(0, assert_notequal([1, 2, 3], s)) + + call assert_equal(1, assert_notequal('foo', s)) + call assert_match("Expected not equal to 'foo'", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_report() + call assert_equal(1, assert_report('something is wrong')) + call assert_match('something is wrong', v:errors[0]) + call remove(v:errors, 0) + call assert_equal(1, 'also wrong'->assert_report()) + call assert_match('also wrong', v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_exception() + try + nocommand + catch + call assert_equal(0, assert_exception('E492:')) + endtry + + try + nocommand + catch + call assert_equal(1, assert_exception('E12345:')) + endtry + call assert_match("Expected 'E12345:' but got 'MNV:E492: ", v:errors[0]) + call remove(v:errors, 0) + + try + nocommand + catch + try + " illegal argument, get NULL for error + call assert_equal(1, assert_exception([])) + catch + call assert_equal(0, assert_exception('E730:')) + endtry + endtry + + call assert_equal(1, assert_exception('E492:')) + call assert_match('v:exception is not set', v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_wrong_error_type() + let save_verrors = v:errors + let v:['errors'] = {'foo': 3} + call assert_equal('yes', 'no') + let verrors = v:errors + let v:errors = save_verrors + call assert_equal(type([]), type(verrors)) +endfunc + +func Test_compare_fail() + let s:v = {} + let s:x = {"a": s:v} + let s:v["b"] = s:x + let s:w = {"c": s:x, "d": ''} + try + call assert_equal(s:w, '') + catch + call assert_equal(0, assert_exception('E724:')) + call assert_match("Expected NULL but got ''", v:errors[0]) + call remove(v:errors, 0) + endtry +endfunc + +func Test_match() + call assert_equal(0, assert_match('^f.*b.*r$', 'foobar')) + + call assert_equal(1, assert_match('bar.*foo', 'foobar')) + call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_match('bar.*foo', 'foobar', 'wrong')) + call assert_match('wrong', v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, 'foobar'->assert_match('bar.*foo', 'wrong')) + call assert_match('wrong', v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_notmatch() + call assert_equal(0, assert_notmatch('foo', 'bar')) + call assert_equal(0, assert_notmatch('^foobar$', 'foobars')) + + call assert_equal(1, assert_notmatch('foo', 'foobar')) + call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, 'foobar'->assert_notmatch('foo')) + call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_fail_fails() + call assert_equal(1, assert_fails('xxx', 'E12345')) + call assert_match("Expected 'E12345' but got 'E492:", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_fails('xxx', 'E9876', 'stupid')) + call assert_match("stupid: Expected 'E9876' but got 'E492:", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_fails('xxx', ['E9876'])) + call assert_match("Expected 'E9876' but got 'E492:", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_fails('xxx', ['E492:', 'E9876'])) + call assert_match("Expected 'E9876' but got 'E492:", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, assert_fails('echo', '', 'echo command')) + call assert_match("command did not fail: echo command", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(1, 'echo'->assert_fails('', 'echo command')) + call assert_match("command did not fail: echo command", v:errors[0]) + call remove(v:errors, 0) + + try + call assert_equal(1, assert_fails('xxx', [])) + catch + let exp = v:exception + endtry + call assert_match("E856: \"assert_fails()\" second argument", exp) + + try + call assert_equal(1, assert_fails('xxx', ['1', '2', '3'])) + catch + let exp = v:exception + endtry + call assert_match("E856: \"assert_fails()\" second argument", exp) + + try + call assert_equal(1, assert_fails('xxx', test_null_list())) + catch + let exp = v:exception + endtry + call assert_match("E856: \"assert_fails()\" second argument", exp) + + try + call assert_equal(1, assert_fails('xxx', [])) + catch + let exp = v:exception + endtry + call assert_match("E856: \"assert_fails()\" second argument", exp) + + try + call assert_equal(1, assert_fails('xxx', #{one: 1})) + catch + let exp = v:exception + endtry + call assert_match("E1222: String or List required for argument 2", exp) + + try + call assert_equal(0, assert_fails('xxx', [#{one: 1}])) + catch + let exp = v:exception + endtry + call assert_match("E731: Using a Dictionary as a String", exp) + + let exp = '' + try + call assert_equal(0, assert_fails('xxx', ['E492', #{one: 1}])) + catch + let exp = v:exception + endtry + call assert_match("E731: Using a Dictionary as a String", exp) + + try + call assert_equal(1, assert_fails('xxx', 'E492', '', 'burp')) + catch + let exp = v:exception + endtry + call assert_match("E1210: Number required for argument 4", exp) + + try + call assert_equal(1, assert_fails('xxx', 'E492', '', 54, 123)) + catch + let exp = v:exception + endtry + call assert_match("E1174: String required for argument 5", exp) + + call assert_equal(1, assert_fails('c0', ['', '\(.\)\1'])) + call assert_match("Expected '\\\\\\\\(.\\\\\\\\)\\\\\\\\1' but got 'E939: Positive count required: c0': c0", v:errors[0]) + call remove(v:errors, 0) + + " Test for matching the line number and the script name in an error message + call writefile(['', 'call Xnonexisting()'], 'Xassertfails.mnv', 'D') + call assert_fails('source Xassertfails.mnv', 'E117:', '', 10) + call assert_match("Expected 10 but got 2", v:errors[0]) + call remove(v:errors, 0) + call assert_fails('source Xassertfails.mnv', 'E117:', '', 2, 'Xabc') + call assert_match("Expected 'Xabc' but got .*Xassertfails.mnv", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_wrong_arg_emsg_off() + CheckFeature folding + + new + call setline(1, ['foo', 'bar']) + 1,2fold + + " This used to crash MNV + let &l:foldtext = 'assert_match({}, {})' + redraw! + + let &l:foldtext = 'assert_equalfile({}, {})' + redraw! + + bwipe! +endfunc + +func Test_assert_fails_in_try_block() + try + call assert_equal(0, assert_fails('throw "error"')) + endtry +endfunc + +" Test that assert_fails() in a timer does not cause a hit-enter prompt. +" Requires using a terminal, in regular tests the hit-enter prompt won't be +" triggered. +func Test_assert_fails_in_timer() + CheckRunMNVInTerminal + + let buf = RunMNVInTerminal('', {'rows': 6}) + let cmd = ":call timer_start(0, {-> assert_fails('call', 'E471:')})" + call term_sendkeys(buf, cmd) + call WaitForAssert({-> assert_equal(cmd, term_getline(buf, 6))}) + call term_sendkeys(buf, "\") + call TermWait(buf, 100) + call assert_match('E471: Argument required', term_getline(buf, 6)) + + call StopMNVInTerminal(buf) +endfunc + +" Check that a typed assert_equal() doesn't prepend an unnecessary ':'. +func Test_assert_equal_typed() + let after =<< trim END + call feedkeys(":call assert_equal(0, 1)\", 't') + call feedkeys(":call writefile(v:errors, 'Xerrors')\", 't') + call feedkeys(":qa!\", 't') + END + call assert_equal(1, RunMNV([], after, '')) + call assert_equal(['Expected 0 but got 1'], readfile('Xerrors')) + + call delete('Xerrors') +endfunc + +func Test_assert_beeps() + new + call assert_equal(0, assert_beeps('normal h')) + + call assert_equal(1, assert_beeps('normal 0')) + call assert_match("command did not beep: normal 0", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(0, 'normal h'->assert_beeps()) + call assert_equal(1, 'normal 0'->assert_beeps()) + call assert_match("command did not beep: normal 0", v:errors[0]) + call remove(v:errors, 0) + + bwipe +endfunc + +func Test_assert_nobeep() + call assert_equal(1, assert_nobeep('normal! cr')) + call assert_match("command did beep: normal! cr", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_inrange() + call assert_equal(0, assert_inrange(7, 7, 7)) + call assert_equal(0, assert_inrange(5, 7, 5)) + call assert_equal(0, assert_inrange(5, 7, 6)) + call assert_equal(0, assert_inrange(5, 7, 7)) + + call assert_equal(1, assert_inrange(5, 7, 4)) + call assert_match("Expected range 5 - 7, but got 4", v:errors[0]) + call remove(v:errors, 0) + call assert_equal(1, assert_inrange(5, 7, 8)) + call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) + call remove(v:errors, 0) + + call assert_equal(0, 5->assert_inrange(5, 7)) + call assert_equal(0, 7->assert_inrange(5, 7)) + call assert_equal(1, 8->assert_inrange(5, 7)) + call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) + call remove(v:errors, 0) + + call assert_fails('call assert_inrange(1, 1)', 'E119:') + + call assert_equal(0, assert_inrange(7.0, 7, 7)) + call assert_equal(0, assert_inrange(7, 7.0, 7)) + call assert_equal(0, assert_inrange(7, 7, 7.0)) + call assert_equal(0, assert_inrange(5, 7, 5.0)) + call assert_equal(0, assert_inrange(5, 7, 6.0)) + call assert_equal(0, assert_inrange(5, 7, 7.0)) + + call assert_equal(1, assert_inrange(5, 7, 4.0)) + call assert_match("Expected range 5.0 - 7.0, but got 4.0", v:errors[0]) + call remove(v:errors, 0) + call assert_equal(1, assert_inrange(5, 7, 8.0)) + call assert_match("Expected range 5.0 - 7.0, but got 8.0", v:errors[0]) + call remove(v:errors, 0) + + " Use a custom message + call assert_equal(1, assert_inrange(5, 7, 8, "Higher")) + call assert_match("Higher: Expected range 5 - 7, but got 8", v:errors[0]) + call remove(v:errors, 0) + call assert_equal(1, assert_inrange(5, 7, 8.0, "Higher")) + call assert_match("Higher: Expected range 5.0 - 7.0, but got 8.0", v:errors[0]) + call remove(v:errors, 0) + + " Invalid arguments + call assert_fails("call assert_inrange([], 2, 3)", 'E1219:') + call assert_fails("call assert_inrange(1, [], 3)", 'E1219:') + call assert_fails("call assert_inrange(1, 2, [])", 'E1219:') +endfunc + +func Test_assert_with_msg() + call assert_equal('foo', 'bar', 'testing') + call assert_match("testing: Expected 'foo' but got 'bar'", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_override() + call test_override('char_avail', 1) + eval 1->test_override('redraw') + call test_override('ALL', 0) + call assert_fails("call test_override('xxx', 1)", 'E475:') + call assert_fails("call test_override('redraw', 'yes')", 'E1210:') +endfunc + +func Test_mouse_position() + let save_mouse = &mouse + set mouse=a + new + call setline(1, ['line one', 'line two']) + call assert_equal([0, 1, 1, 0], getpos('.')) + call test_setmouse(1, 5) + call feedkeys("\", "xt") + call assert_equal([0, 1, 5, 0], getpos('.')) + call test_setmouse(2, 20) + call feedkeys("\", "xt") + call assert_equal([0, 2, 8, 0], getpos('.')) + call test_setmouse(5, 1) + call feedkeys("\", "xt") + call assert_equal([0, 2, 1, 0], getpos('.')) + call assert_fails('call test_setmouse("", 2)', 'E474:') + call assert_fails('call test_setmouse(1, "")', 'E474:') + bwipe! + let &mouse = save_mouse +endfunc + +func Test_user_is_happy() + smile + sleep 300m +endfunc + +" Test for the test_alloc_fail() function +func Test_test_alloc_fail() + call assert_fails('call test_alloc_fail([], 1, 1)', 'E474:') + call assert_fails('call test_alloc_fail(10, [], 1)', 'E474:') + call assert_fails('call test_alloc_fail(10, 1, [])', 'E474:') + call assert_fails('call test_alloc_fail(999999, 1, 1)', 'E474:') +endfunc + +" Test for the test_option_not_set() function +func Test_test_option_not_set() + call assert_fails('call test_option_not_set("Xinvalidopt")', 'E475:') +endfunc + +" Must be last. +func Test_zz_quit_detected() + " Verify that if a test function ends MNV the test script detects this. + quit +endfunc + +" mnv: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_assert.vim b/uvim/src/testdir/test_assert.vim deleted file mode 100644 index b3e640c11f..0000000000 --- a/uvim/src/testdir/test_assert.vim +++ /dev/null @@ -1,527 +0,0 @@ -" Test that the methods used for testing work. - -func Test_assert_false() - call assert_equal(0, assert_false(0)) - call assert_equal(0, assert_false(v:false)) - call assert_equal(0, v:false->assert_false()) - - call assert_equal(1, assert_false(123)) - call assert_match("Expected False but got 123", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, 123->assert_false()) - call assert_match("Expected False but got 123", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_true() - call assert_equal(0, assert_true(1)) - call assert_equal(0, assert_true(123)) - call assert_equal(0, assert_true(v:true)) - call assert_equal(0, v:true->assert_true()) - - call assert_equal(1, assert_true(0)) - call assert_match("Expected True but got 0", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, 0->assert_true()) - call assert_match("Expected True but got 0", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_equal() - let s = 'foo' - call assert_equal(0, assert_equal('foo', s)) - let n = 4 - call assert_equal(0, assert_equal(4, n)) - let l = [1, 2, 3] - call assert_equal(0, assert_equal([1, 2, 3], l)) - call assert_equal(test_null_list(), test_null_list()) - call assert_equal(test_null_list(), []) - call assert_equal([], test_null_list()) - - let s = 'foo' - call assert_equal(1, assert_equal('bar', s)) - call assert_match("Expected 'bar' but got 'foo'", v:errors[0]) - call remove(v:errors, 0) - - let s = 'αβγ' - call assert_equal(1, assert_equal('δεζ', s)) - call assert_match("Expected 'δεζ' but got 'αβγ'", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal('XxxxxxxxxxxxxxxxxxxxxxX', 'XyyyyyyyyyyyyyyyyyyyyyyyyyX') - call assert_match("Expected 'X\\\\\\[x occurs 21 times]X' but got 'X\\\\\\[y occurs 25 times]X'", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal('ΩωωωωωωωωωωωωωωωωωωωωωΩ', 'ΩψψψψψψψψψψψψψψψψψψψψψψψψψΩ') - call assert_match("Expected 'Ω\\\\\\[ω occurs 21 times]Ω' but got 'Ω\\\\\\[ψ occurs 25 times]Ω'", v:errors[0]) - call remove(v:errors, 0) - - " special characters are escaped - call assert_equal("\b\e\f\n\t\r\\\x01\x7f", 'x') - call assert_match('Expected ''\\b\\e\\f\\n\\t\\r\\\\\\x01\\x7f'' but got ''x''', v:errors[0]) - call remove(v:errors, 0) - - " many composing characters are handled properly - call setline(1, ' ') - norm 100grÝ€ - call assert_equal(1, getline(1)) - call assert_match("Expected 1 but got '.* occurs 100 times]'", v:errors[0]) - call remove(v:errors, 0) - bwipe! -endfunc - -func Test_assert_equal_dict() - call assert_equal(0, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 1})) - - call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 2, one: 3})) - call assert_match("Expected {'one': 1} but got {'one': 3} - 1 equal item omitted", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_equal(#{one: 1, two: 2}, #{two: 22, one: 11})) - call assert_match("Expected {'one': 1, 'two': 2} but got {'one': 11, 'two': 22}", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_equal(#{}, #{two: 2, one: 1})) - call assert_match("Expected {} but got {'one': 1, 'two': 2}", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_equal(#{two: 2, one: 1}, #{})) - call assert_match("Expected {'one': 1, 'two': 2} but got {}", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_equalfile() - call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz')) - call assert_match("E485: Can't read file abcabc", v:errors[0]) - call remove(v:errors, 0) - - let goodtext = ["one", "two", "three"] - call writefile(goodtext, 'Xone', 'D') - call assert_equal(1, 'Xone'->assert_equalfile('xyzxyz')) - call assert_match("E485: Can't read file xyzxyz", v:errors[0]) - call remove(v:errors, 0) - - call writefile(goodtext, 'Xtwo', 'D') - call assert_equal(0, assert_equalfile('Xone', 'Xtwo')) - - call writefile([goodtext[0]], 'Xone') - call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) - call assert_match("first file is shorter", v:errors[0]) - call remove(v:errors, 0) - - call writefile(goodtext, 'Xone') - call writefile([goodtext[0]], 'Xtwo') - call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) - call assert_match("second file is shorter", v:errors[0]) - call remove(v:errors, 0) - - call writefile(['1234X89'], 'Xone') - call writefile(['1234Y89'], 'Xtwo') - call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) - call assert_match('difference at byte 4, line 1 after "1234X" vs "1234Y"', v:errors[0]) - call remove(v:errors, 0) - - call writefile([repeat('x', 234) .. 'X'], 'Xone') - call writefile([repeat('x', 234) .. 'Y'], 'Xtwo') - call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) - let xes = repeat('x', 134) - call assert_match('difference at byte 234, line 1 after "' .. xes .. 'X" vs "' .. xes .. 'Y"', v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_equalfile('Xone', 'Xtwo', 'a message')) - call assert_match("a message: difference at byte 234, line 1 after", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_notequal() - let n = 4 - call assert_equal(0, assert_notequal('foo', n)) - let s = 'foo' - call assert_equal(0, assert_notequal([1, 2, 3], s)) - - call assert_equal(1, assert_notequal('foo', s)) - call assert_match("Expected not equal to 'foo'", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_report() - call assert_equal(1, assert_report('something is wrong')) - call assert_match('something is wrong', v:errors[0]) - call remove(v:errors, 0) - call assert_equal(1, 'also wrong'->assert_report()) - call assert_match('also wrong', v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_exception() - try - nocommand - catch - call assert_equal(0, assert_exception('E492:')) - endtry - - try - nocommand - catch - call assert_equal(1, assert_exception('E12345:')) - endtry - call assert_match("Expected 'E12345:' but got 'Vim:E492: ", v:errors[0]) - call remove(v:errors, 0) - - try - nocommand - catch - try - " illegal argument, get NULL for error - call assert_equal(1, assert_exception([])) - catch - call assert_equal(0, assert_exception('E730:')) - endtry - endtry - - call assert_equal(1, assert_exception('E492:')) - call assert_match('v:exception is not set', v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_wrong_error_type() - let save_verrors = v:errors - let v:['errors'] = {'foo': 3} - call assert_equal('yes', 'no') - let verrors = v:errors - let v:errors = save_verrors - call assert_equal(type([]), type(verrors)) -endfunc - -func Test_compare_fail() - let s:v = {} - let s:x = {"a": s:v} - let s:v["b"] = s:x - let s:w = {"c": s:x, "d": ''} - try - call assert_equal(s:w, '') - catch - call assert_equal(0, assert_exception('E724:')) - call assert_match("Expected NULL but got ''", v:errors[0]) - call remove(v:errors, 0) - endtry -endfunc - -func Test_match() - call assert_equal(0, assert_match('^f.*b.*r$', 'foobar')) - - call assert_equal(1, assert_match('bar.*foo', 'foobar')) - call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_match('bar.*foo', 'foobar', 'wrong')) - call assert_match('wrong', v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, 'foobar'->assert_match('bar.*foo', 'wrong')) - call assert_match('wrong', v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_notmatch() - call assert_equal(0, assert_notmatch('foo', 'bar')) - call assert_equal(0, assert_notmatch('^foobar$', 'foobars')) - - call assert_equal(1, assert_notmatch('foo', 'foobar')) - call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, 'foobar'->assert_notmatch('foo')) - call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_fail_fails() - call assert_equal(1, assert_fails('xxx', 'E12345')) - call assert_match("Expected 'E12345' but got 'E492:", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_fails('xxx', 'E9876', 'stupid')) - call assert_match("stupid: Expected 'E9876' but got 'E492:", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_fails('xxx', ['E9876'])) - call assert_match("Expected 'E9876' but got 'E492:", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_fails('xxx', ['E492:', 'E9876'])) - call assert_match("Expected 'E9876' but got 'E492:", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, assert_fails('echo', '', 'echo command')) - call assert_match("command did not fail: echo command", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(1, 'echo'->assert_fails('', 'echo command')) - call assert_match("command did not fail: echo command", v:errors[0]) - call remove(v:errors, 0) - - try - call assert_equal(1, assert_fails('xxx', [])) - catch - let exp = v:exception - endtry - call assert_match("E856: \"assert_fails()\" second argument", exp) - - try - call assert_equal(1, assert_fails('xxx', ['1', '2', '3'])) - catch - let exp = v:exception - endtry - call assert_match("E856: \"assert_fails()\" second argument", exp) - - try - call assert_equal(1, assert_fails('xxx', test_null_list())) - catch - let exp = v:exception - endtry - call assert_match("E856: \"assert_fails()\" second argument", exp) - - try - call assert_equal(1, assert_fails('xxx', [])) - catch - let exp = v:exception - endtry - call assert_match("E856: \"assert_fails()\" second argument", exp) - - try - call assert_equal(1, assert_fails('xxx', #{one: 1})) - catch - let exp = v:exception - endtry - call assert_match("E1222: String or List required for argument 2", exp) - - try - call assert_equal(0, assert_fails('xxx', [#{one: 1}])) - catch - let exp = v:exception - endtry - call assert_match("E731: Using a Dictionary as a String", exp) - - let exp = '' - try - call assert_equal(0, assert_fails('xxx', ['E492', #{one: 1}])) - catch - let exp = v:exception - endtry - call assert_match("E731: Using a Dictionary as a String", exp) - - try - call assert_equal(1, assert_fails('xxx', 'E492', '', 'burp')) - catch - let exp = v:exception - endtry - call assert_match("E1210: Number required for argument 4", exp) - - try - call assert_equal(1, assert_fails('xxx', 'E492', '', 54, 123)) - catch - let exp = v:exception - endtry - call assert_match("E1174: String required for argument 5", exp) - - call assert_equal(1, assert_fails('c0', ['', '\(.\)\1'])) - call assert_match("Expected '\\\\\\\\(.\\\\\\\\)\\\\\\\\1' but got 'E939: Positive count required: c0': c0", v:errors[0]) - call remove(v:errors, 0) - - " Test for matching the line number and the script name in an error message - call writefile(['', 'call Xnonexisting()'], 'Xassertfails.vim', 'D') - call assert_fails('source Xassertfails.vim', 'E117:', '', 10) - call assert_match("Expected 10 but got 2", v:errors[0]) - call remove(v:errors, 0) - call assert_fails('source Xassertfails.vim', 'E117:', '', 2, 'Xabc') - call assert_match("Expected 'Xabc' but got .*Xassertfails.vim", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_wrong_arg_emsg_off() - CheckFeature folding - - new - call setline(1, ['foo', 'bar']) - 1,2fold - - " This used to crash Vim - let &l:foldtext = 'assert_match({}, {})' - redraw! - - let &l:foldtext = 'assert_equalfile({}, {})' - redraw! - - bwipe! -endfunc - -func Test_assert_fails_in_try_block() - try - call assert_equal(0, assert_fails('throw "error"')) - endtry -endfunc - -" Test that assert_fails() in a timer does not cause a hit-enter prompt. -" Requires using a terminal, in regular tests the hit-enter prompt won't be -" triggered. -func Test_assert_fails_in_timer() - CheckRunVimInTerminal - - let buf = RunVimInTerminal('', {'rows': 6}) - let cmd = ":call timer_start(0, {-> assert_fails('call', 'E471:')})" - call term_sendkeys(buf, cmd) - call WaitForAssert({-> assert_equal(cmd, term_getline(buf, 6))}) - call term_sendkeys(buf, "\") - call TermWait(buf, 100) - call assert_match('E471: Argument required', term_getline(buf, 6)) - - call StopVimInTerminal(buf) -endfunc - -" Check that a typed assert_equal() doesn't prepend an unnecessary ':'. -func Test_assert_equal_typed() - let after =<< trim END - call feedkeys(":call assert_equal(0, 1)\", 't') - call feedkeys(":call writefile(v:errors, 'Xerrors')\", 't') - call feedkeys(":qa!\", 't') - END - call assert_equal(1, RunVim([], after, '')) - call assert_equal(['Expected 0 but got 1'], readfile('Xerrors')) - - call delete('Xerrors') -endfunc - -func Test_assert_beeps() - new - call assert_equal(0, assert_beeps('normal h')) - - call assert_equal(1, assert_beeps('normal 0')) - call assert_match("command did not beep: normal 0", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(0, 'normal h'->assert_beeps()) - call assert_equal(1, 'normal 0'->assert_beeps()) - call assert_match("command did not beep: normal 0", v:errors[0]) - call remove(v:errors, 0) - - bwipe -endfunc - -func Test_assert_nobeep() - call assert_equal(1, assert_nobeep('normal! cr')) - call assert_match("command did beep: normal! cr", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_assert_inrange() - call assert_equal(0, assert_inrange(7, 7, 7)) - call assert_equal(0, assert_inrange(5, 7, 5)) - call assert_equal(0, assert_inrange(5, 7, 6)) - call assert_equal(0, assert_inrange(5, 7, 7)) - - call assert_equal(1, assert_inrange(5, 7, 4)) - call assert_match("Expected range 5 - 7, but got 4", v:errors[0]) - call remove(v:errors, 0) - call assert_equal(1, assert_inrange(5, 7, 8)) - call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) - call remove(v:errors, 0) - - call assert_equal(0, 5->assert_inrange(5, 7)) - call assert_equal(0, 7->assert_inrange(5, 7)) - call assert_equal(1, 8->assert_inrange(5, 7)) - call assert_match("Expected range 5 - 7, but got 8", v:errors[0]) - call remove(v:errors, 0) - - call assert_fails('call assert_inrange(1, 1)', 'E119:') - - call assert_equal(0, assert_inrange(7.0, 7, 7)) - call assert_equal(0, assert_inrange(7, 7.0, 7)) - call assert_equal(0, assert_inrange(7, 7, 7.0)) - call assert_equal(0, assert_inrange(5, 7, 5.0)) - call assert_equal(0, assert_inrange(5, 7, 6.0)) - call assert_equal(0, assert_inrange(5, 7, 7.0)) - - call assert_equal(1, assert_inrange(5, 7, 4.0)) - call assert_match("Expected range 5.0 - 7.0, but got 4.0", v:errors[0]) - call remove(v:errors, 0) - call assert_equal(1, assert_inrange(5, 7, 8.0)) - call assert_match("Expected range 5.0 - 7.0, but got 8.0", v:errors[0]) - call remove(v:errors, 0) - - " Use a custom message - call assert_equal(1, assert_inrange(5, 7, 8, "Higher")) - call assert_match("Higher: Expected range 5 - 7, but got 8", v:errors[0]) - call remove(v:errors, 0) - call assert_equal(1, assert_inrange(5, 7, 8.0, "Higher")) - call assert_match("Higher: Expected range 5.0 - 7.0, but got 8.0", v:errors[0]) - call remove(v:errors, 0) - - " Invalid arguments - call assert_fails("call assert_inrange([], 2, 3)", 'E1219:') - call assert_fails("call assert_inrange(1, [], 3)", 'E1219:') - call assert_fails("call assert_inrange(1, 2, [])", 'E1219:') -endfunc - -func Test_assert_with_msg() - call assert_equal('foo', 'bar', 'testing') - call assert_match("testing: Expected 'foo' but got 'bar'", v:errors[0]) - call remove(v:errors, 0) -endfunc - -func Test_override() - call test_override('char_avail', 1) - eval 1->test_override('redraw') - call test_override('ALL', 0) - call assert_fails("call test_override('xxx', 1)", 'E475:') - call assert_fails("call test_override('redraw', 'yes')", 'E1210:') -endfunc - -func Test_mouse_position() - let save_mouse = &mouse - set mouse=a - new - call setline(1, ['line one', 'line two']) - call assert_equal([0, 1, 1, 0], getpos('.')) - call test_setmouse(1, 5) - call feedkeys("\", "xt") - call assert_equal([0, 1, 5, 0], getpos('.')) - call test_setmouse(2, 20) - call feedkeys("\", "xt") - call assert_equal([0, 2, 8, 0], getpos('.')) - call test_setmouse(5, 1) - call feedkeys("\", "xt") - call assert_equal([0, 2, 1, 0], getpos('.')) - call assert_fails('call test_setmouse("", 2)', 'E474:') - call assert_fails('call test_setmouse(1, "")', 'E474:') - bwipe! - let &mouse = save_mouse -endfunc - -func Test_user_is_happy() - smile - sleep 300m -endfunc - -" Test for the test_alloc_fail() function -func Test_test_alloc_fail() - call assert_fails('call test_alloc_fail([], 1, 1)', 'E474:') - call assert_fails('call test_alloc_fail(10, [], 1)', 'E474:') - call assert_fails('call test_alloc_fail(10, 1, [])', 'E474:') - call assert_fails('call test_alloc_fail(999999, 1, 1)', 'E474:') -endfunc - -" Test for the test_option_not_set() function -func Test_test_option_not_set() - call assert_fails('call test_option_not_set("Xinvalidopt")', 'E475:') -endfunc - -" Must be last. -func Test_zz_quit_detected() - " Verify that if a test function ends Vim the test script detects this. - quit -endfunc - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_autochdir.mnv b/uvim/src/testdir/test_autochdir.mnv new file mode 100644 index 0000000000..eddd29679f --- /dev/null +++ b/uvim/src/testdir/test_autochdir.mnv @@ -0,0 +1,120 @@ +" Test 'autochdir' behavior + +CheckOption autochdir + +func Test_set_filename() + let cwd = getcwd() + call test_autochdir() + set acd + + let s:li = [] + autocmd DirChanged auto call add(s:li, "autocd") + autocmd DirChanged auto call add(s:li, expand("")) + + new + w samples/Xtest + call assert_equal("Xtest", expand('%')) + call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', '')) + call assert_equal(["autocd", getcwd()], s:li) + + bwipe! + au! DirChanged + set noacd + call chdir(cwd) + call delete('samples/Xtest') +endfunc + +func Test_set_filename_other_window() + let cwd = getcwd() + call test_autochdir() + call mkdir('Xa', 'R') + call mkdir('Xb', 'R') + call mkdir('Xc', 'R') + try + args Xa/aaa.txt Xb/bbb.txt + set acd + let winid = win_getid() + snext + call assert_equal('Xb', substitute(getcwd(), '.*/\([^/]*\)$', '\1', '')) + call win_execute(winid, 'file ' .. cwd .. '/Xc/ccc.txt') + call assert_equal('Xb', substitute(getcwd(), '.*/\([^/]*\)$', '\1', '')) + finally + set noacd + call chdir(cwd) + bwipe! aaa.txt + bwipe! bbb.txt + bwipe! ccc.txt + endtry +endfunc + +func Test_acd_win_execute() + let cwd = getcwd() + set acd + call test_autochdir() + + call mkdir('XacdDir', 'R') + let winid = win_getid() + new XacdDir/file + call assert_match('testdir.XacdDir$', getcwd()) + cd .. + call assert_match('testdir$', getcwd()) + call win_execute(winid, 'echo') + call assert_match('testdir$', getcwd()) + + bwipe! + set noacd + call chdir(cwd) +endfunc + +func Test_verbose_pwd() + let cwd = getcwd() + call test_autochdir() + + edit global.txt + call assert_match('\[global\].*testdir$', execute('verbose pwd')) + + call mkdir('Xautodir', 'R') + split Xautodir/local.txt + lcd Xautodir + call assert_match('\[window\].*testdir[/\\]Xautodir', execute('verbose pwd')) + + set acd + wincmd w + call assert_match('\[autochdir\].*testdir$', execute('verbose pwd')) + execute 'tcd' cwd + call assert_match('\[tabpage\].*testdir$', execute('verbose pwd')) + execute 'cd' cwd + call assert_match('\[global\].*testdir$', execute('verbose pwd')) + execute 'lcd' cwd + call assert_match('\[window\].*testdir$', execute('verbose pwd')) + edit + call assert_match('\[autochdir\].*testdir$', execute('verbose pwd')) + enew + wincmd w + call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) + wincmd w + call assert_match('\[window\].*testdir$', execute('verbose pwd')) + wincmd w + call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) + set noacd + call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) + wincmd w + call assert_match('\[window\].*testdir$', execute('verbose pwd')) + execute 'cd' cwd + call assert_match('\[global\].*testdir$', execute('verbose pwd')) + wincmd w + call assert_match('\[window\].*testdir[/\\]Xautodir', execute('verbose pwd')) + + bwipe! + call chdir(cwd) +endfunc + +func Test_multibyte() + " using an invalid character should not cause a crash + set wic + call assert_fails('tc �����*', has('win32') ? 'E480:' : 'E344:') + set nowic +endfunc + + +" mnv: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_autochdir.vim b/uvim/src/testdir/test_autochdir.vim deleted file mode 100644 index a9cb66b2ce..0000000000 --- a/uvim/src/testdir/test_autochdir.vim +++ /dev/null @@ -1,120 +0,0 @@ -" Test 'autochdir' behavior - -CheckOption autochdir - -func Test_set_filename() - let cwd = getcwd() - call test_autochdir() - set acd - - let s:li = [] - autocmd DirChanged auto call add(s:li, "autocd") - autocmd DirChanged auto call add(s:li, expand("")) - - new - w samples/Xtest - call assert_equal("Xtest", expand('%')) - call assert_equal("samples", substitute(getcwd(), '.*/\(\k*\)', '\1', '')) - call assert_equal(["autocd", getcwd()], s:li) - - bwipe! - au! DirChanged - set noacd - call chdir(cwd) - call delete('samples/Xtest') -endfunc - -func Test_set_filename_other_window() - let cwd = getcwd() - call test_autochdir() - call mkdir('Xa', 'R') - call mkdir('Xb', 'R') - call mkdir('Xc', 'R') - try - args Xa/aaa.txt Xb/bbb.txt - set acd - let winid = win_getid() - snext - call assert_equal('Xb', substitute(getcwd(), '.*/\([^/]*\)$', '\1', '')) - call win_execute(winid, 'file ' .. cwd .. '/Xc/ccc.txt') - call assert_equal('Xb', substitute(getcwd(), '.*/\([^/]*\)$', '\1', '')) - finally - set noacd - call chdir(cwd) - bwipe! aaa.txt - bwipe! bbb.txt - bwipe! ccc.txt - endtry -endfunc - -func Test_acd_win_execute() - let cwd = getcwd() - set acd - call test_autochdir() - - call mkdir('XacdDir', 'R') - let winid = win_getid() - new XacdDir/file - call assert_match('testdir.XacdDir$', getcwd()) - cd .. - call assert_match('testdir$', getcwd()) - call win_execute(winid, 'echo') - call assert_match('testdir$', getcwd()) - - bwipe! - set noacd - call chdir(cwd) -endfunc - -func Test_verbose_pwd() - let cwd = getcwd() - call test_autochdir() - - edit global.txt - call assert_match('\[global\].*testdir$', execute('verbose pwd')) - - call mkdir('Xautodir', 'R') - split Xautodir/local.txt - lcd Xautodir - call assert_match('\[window\].*testdir[/\\]Xautodir', execute('verbose pwd')) - - set acd - wincmd w - call assert_match('\[autochdir\].*testdir$', execute('verbose pwd')) - execute 'tcd' cwd - call assert_match('\[tabpage\].*testdir$', execute('verbose pwd')) - execute 'cd' cwd - call assert_match('\[global\].*testdir$', execute('verbose pwd')) - execute 'lcd' cwd - call assert_match('\[window\].*testdir$', execute('verbose pwd')) - edit - call assert_match('\[autochdir\].*testdir$', execute('verbose pwd')) - enew - wincmd w - call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) - wincmd w - call assert_match('\[window\].*testdir$', execute('verbose pwd')) - wincmd w - call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) - set noacd - call assert_match('\[autochdir\].*testdir[/\\]Xautodir', execute('verbose pwd')) - wincmd w - call assert_match('\[window\].*testdir$', execute('verbose pwd')) - execute 'cd' cwd - call assert_match('\[global\].*testdir$', execute('verbose pwd')) - wincmd w - call assert_match('\[window\].*testdir[/\\]Xautodir', execute('verbose pwd')) - - bwipe! - call chdir(cwd) -endfunc - -func Test_multibyte() - " using an invalid character should not cause a crash - set wic - call assert_fails('tc û¦*', has('win32') ? 'E480:' : 'E344:') - set nowic -endfunc - - -" vim: shiftwidth=2 sts=2 expandtab diff --git a/uvim/src/testdir/test_autocmd.mnv b/uvim/src/testdir/test_autocmd.mnv new file mode 100644 index 0000000000..680f1300a4 --- /dev/null +++ b/uvim/src/testdir/test_autocmd.mnv @@ -0,0 +1,5970 @@ +" Tests for autocommands + +source util/screendump.mnv +import './util/mnv9.mnv' as v9 + +func s:cleanup_buffers() abort + for bnr in range(1, bufnr('$')) + if bufloaded(bnr) && bufnr('%') != bnr + execute 'bd! ' . bnr + endif + endfor +endfunc + +func CleanUpTestAuGroup() + augroup testing + au! + augroup END + augroup! testing +endfunc + +func Test_mnv_did_enter() + call assert_false(v:mnv_did_enter) + + " This script will never reach the main loop, can't check if v:mnv_did_enter + " becomes one. +endfunc + +" Test for the CursorHold autocmd +func Test_CursorHold_autocmd() + CheckRunMNVInTerminal + call writefile(['one', 'two', 'three'], 'XoneTwoThree', 'D') + let before =<< trim END + set updatetime=10 + au CursorHold * call writefile([line('.')], 'XCHoutput', 'a') + END + call writefile(before, 'XCHinit', 'D') + let buf = RunMNVInTerminal('-S XCHinit XoneTwoThree', {}) + call term_sendkeys(buf, "G") + call term_wait(buf, 50) + call term_sendkeys(buf, "gg") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1'], readfile('XCHoutput')[-1:-1])}) + call term_sendkeys(buf, "j") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1', '2'], readfile('XCHoutput')[-2:-1])}) + call term_sendkeys(buf, "j") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1', '2', '3'], readfile('XCHoutput')[-3:-1])}) + call StopMNVInTerminal(buf) + + call delete('XCHoutput') +endfunc + +if has('timers') + + func ExitInsertMode(id) + call feedkeys("\") + endfunc + + func Test_cursorhold_insert() + " depends on timing + let g:test_is_flaky = 1 + + " Need to move the cursor. + call feedkeys("ggG", "xt") + + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(200, 'ExitInsertMode') + call feedkeys('a', 'x!') + sleep 30m + call assert_equal(1, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_with_timer_interrupt() + CheckFeature job + " Need to move the cursor. + call feedkeys("ggG", "xt") + + " Confirm the timer invoked in exit_cb of the job doesn't disturb + " CursorHoldI event. + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=100 + call job_start(has('win32') ? 'cmd /D /c echo:' : 'echo', + \ {'exit_cb': {-> timer_start(200, 'ExitInsertMode')}}) + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_ctrl_x() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(100, 'ExitInsertMode') + " CursorHoldI does not trigger after CTRL-X + call feedkeys("a\", 'x!') + call assert_equal(0, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_ctrl_g_U() + au CursorHoldI * : + set updatetime=20 + new + call timer_start(100, { -> feedkeys("\foo\", 't') }) + call feedkeys("i()\U", 'tx!') + sleep 200m + call assert_equal('(foo)', getline(1)) + undo + call assert_equal('', getline(1)) + + bwipe! + au! CursorHoldI + set updatetime& + endfunc + + func Test_OptionSet_modeline() + call test_override('starting', 1) + au! OptionSet + augroup set_tabstop + au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")}) + augroup END + call writefile(['mnv: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline', 'D') + set modeline + let v:errmsg = '' + call assert_fails('split XoptionsetModeline', 'E12:') + call assert_equal(7, &ts) + call assert_equal('', v:errmsg) + + augroup set_tabstop + au! + augroup END + bwipe! + set ts& + call test_override('starting', 0) + endfunc + +endif "has('timers') + +func Test_bufunload() + augroup test_bufunload_group + autocmd! + autocmd BufUnload * call add(s:li, "bufunload") + autocmd BufDelete * call add(s:li, "bufdelete") + autocmd BufWipeout * call add(s:li, "bufwipeout") + augroup END + + let s:li = [] + new + setlocal bufhidden= + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li = [] + new + setlocal bufhidden=delete + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li = [] + new + setlocal bufhidden=unload + bwipeout + call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) + + au! test_bufunload_group + augroup! test_bufunload_group +endfunc + +" SEGV occurs in older versions. (At least 7.4.2005 or older) +func Test_autocmd_bufunload_with_tabnext() + tabedit + tabfirst + + augroup test_autocmd_bufunload_with_tabnext_group + autocmd! + autocmd BufUnload tabnext + augroup END + + quit + call assert_equal(2, tabpagenr('$')) + + autocmd! test_autocmd_bufunload_with_tabnext_group + augroup! test_autocmd_bufunload_with_tabnext_group + tablast + quit +endfunc + +func Test_argdelete_in_next() + au BufNew,BufEnter,BufLeave,BufWinEnter * argdel + call assert_fails('next a b', 'E1156:') + au! BufNew,BufEnter,BufLeave,BufWinEnter * +endfunc + +func Test_autocmd_bufwinleave_with_tabfirst() + tabedit + augroup sample + autocmd! + autocmd BufWinLeave tabfirst + augroup END + call setline(1, ['a', 'b', 'c']) + edit! a.txt + tabclose +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +func Test_autocmd_bufunload_avoiding_SEGV_01() + split aa.txt + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + call assert_fails('edit bb.txt', 'E937:') + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! aa.txt + bwipe! bb.txt +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +func Test_autocmd_bufunload_avoiding_SEGV_02() + setlocal buftype=nowrite + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + normal! i1 + call assert_fails('edit a.txt', 'E517:') + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! a.txt +endfunc + +func Test_autocmd_dummy_wipeout() + " prepare files + call writefile([''], 'Xdummywipetest1.txt', 'D') + call writefile([''], 'Xdummywipetest2.txt', 'D') + augroup test_bufunload_group + autocmd! + autocmd BufUnload * call add(s:li, "bufunload") + autocmd BufDelete * call add(s:li, "bufdelete") + autocmd BufWipeout * call add(s:li, "bufwipeout") + augroup END + + let s:li = [] + split Xdummywipetest1.txt + silent! mnvgrep /notmatched/ Xdummywipetest* + call assert_equal(["bufunload", "bufwipeout"], s:li) + + bwipeout + au! test_bufunload_group + augroup! test_bufunload_group +endfunc + +func Test_win_tab_autocmd() + let g:record = [] + + defer CleanUpTestAuGroup() + augroup testing + au WinNewPre * call add(g:record, 'WinNewPre') + au WinNew * call add(g:record, 'WinNew') + au WinClosed * call add(g:record, 'WinClosed') + au WinEnter * call add(g:record, 'WinEnter') + au WinLeave * call add(g:record, 'WinLeave') + au TabNew * call add(g:record, 'TabNew') + au TabClosed * call add(g:record, 'TabClosed') + au TabEnter * call add(g:record, 'TabEnter') + au TabLeave * call add(g:record, 'TabLeave') + augroup END + + split + tabnew + close + close + + call assert_equal([ + \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter', + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter', + \ 'WinLeave', 'WinClosed', 'WinEnter' + \ ], g:record) + + let g:record = [] + tabnew somefile + tabnext + bwipe somefile + + call assert_equal([ + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', + \ 'WinClosed', 'TabClosed' + \ ], g:record) + + let g:record = [] + copen + help + tabnext + vnew + + call assert_equal([ + \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter', + \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter', + \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter' + \ ], g:record) + + unlet g:record +endfunc + +func Test_WinNewPre() + " Test that the old window layout can be accessed before a new window is created. + let g:layouts_pre = [] + let g:layouts_post = [] + augroup testing + au WinNewPre * call add(g:layouts_pre, winlayout()) + au WinNew * call add(g:layouts_post, winlayout()) + augroup END + defer CleanUpTestAuGroup() + split + call assert_notequal(g:layouts_pre[0], g:layouts_post[0]) + split + call assert_equal(g:layouts_pre[1], g:layouts_post[0]) + call assert_notequal(g:layouts_pre[1], g:layouts_post[1]) + " not triggered for tabnew + tabnew + call assert_equal(2, len(g:layouts_pre)) + unlet g:layouts_pre + unlet g:layouts_post + + " Test modifying window layout during WinNewPre throws. + let g:caught = 0 + augroup testing + au! + au WinNewPre * split + augroup END + try + vnew + catch + let g:caught += 1 + endtry + augroup testing + au! + au WinNewPre * tabnew + augroup END + try + vnew + catch + let g:caught += 1 + endtry + augroup testing + au! + au WinNewPre * close + augroup END + try + vnew + catch + let g:caught += 1 + endtry + augroup testing + au! + au WinNewPre * tabclose + augroup END + try + vnew + catch + let g:caught += 1 + endtry + call assert_equal(4, g:caught) + unlet g:caught +endfunc + +func Test_WinResized() + CheckRunMNVInTerminal + + let lines =<< trim END + set scrolloff=0 + call setline(1, ['111', '222']) + vnew + call setline(1, ['aaa', 'bbb']) + new + call setline(1, ['foo', 'bar']) + + let g:resized = 0 + au WinResized * let g:resized += 1 + + func WriteResizedEvent() + call writefile([json_encode(v:event)], 'XresizeEvent') + endfunc + au WinResized * call WriteResizedEvent() + END + call writefile(lines, 'Xtest_winresized', 'D') + let buf = RunMNVInTerminal('-S Xtest_winresized', {'rows': 10}) + + " redraw now to avoid a redraw after the :echo command + call term_sendkeys(buf, ":redraw!\") + call TermWait(buf) + + call term_sendkeys(buf, ":echo g:resized\") + call WaitForAssert({-> assert_match('^0$', term_getline(buf, 10))}, 1000) + + " increase window height, two windows will be reported + call term_sendkeys(buf, "\+") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:resized\") + call WaitForAssert({-> assert_match('^1$', term_getline(buf, 10))}, 1000) + + let event = readfile('XresizeEvent')[0]->json_decode() + call assert_equal({ + \ 'windows': [1002, 1001], + \ }, event) + + " increase window width, three windows will be reported + call term_sendkeys(buf, "\>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:resized\") + call WaitForAssert({-> assert_match('^2$', term_getline(buf, 10))}, 1000) + + let event = readfile('XresizeEvent')[0]->json_decode() + call assert_equal({ + \ 'windows': [1002, 1001, 1000], + \ }, event) + + call delete('XresizeEvent') + call StopMNVInTerminal(buf) +endfunc + +func Test_WinScrolled() + CheckRunMNVInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + for ii in range(1, 18) + call setline(ii, repeat(nr2char(96 + ii), ii * 2)) + endfor + let win_id = win_getid() + let g:matched = v:false + func WriteScrollEvent() + call writefile([json_encode(v:event)], 'XscrollEvent') + endfunc + execute 'au WinScrolled' win_id 'let g:matched = v:true' + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + au WinScrolled * let g:amatch = str2nr(expand('')) + au WinScrolled * let g:afile = str2nr(expand('')) + au WinScrolled * call WriteScrollEvent() + END + call writefile(lines, 'Xtest_winscrolled', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled', {'rows': 6}) + + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000) + + " Scroll left/right in Normal mode. + call term_sendkeys(buf, "zlzh:echo g:scrolled\") + call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': -1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll up/down in Normal mode. + call term_sendkeys(buf, "\\:echo g:scrolled\") + call WaitForAssert({-> assert_match('^4 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll up/down in Insert mode. + call term_sendkeys(buf, "Mi\\\i\\\") + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^6 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll the window horizontally to focus the last letter of the third line + " containing only six characters. Moving to the previous and shorter lines + " should trigger another autocommand as MNV has to make them visible. + call term_sendkeys(buf, "5zl2k") + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^8 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': -5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Ensure the command was triggered for the specified window ID. + call term_sendkeys(buf, ":echo g:matched\") + call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000) + + " Ensure the expansion of and matches the window ID. + call term_sendkeys(buf, ":echo g:amatch == win_id && g:afile == win_id\") + call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000) + + call delete('XscrollEvent') + call StopMNVInTerminal(buf) +endfunc + +func Test_WinScrolled_mouse() + CheckRunMNVInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard= + call setline(1, ['foo']->repeat(32)) + split + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + END + call writefile(lines, 'Xtest_winscrolled_mouse', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10}) + + " With the upper split focused, send a scroll-down event to the unfocused one. + call test_setmouse(7, 1) + call term_sendkeys(buf, "\") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000) + + " Again, but this time while we're in insert mode. + call term_sendkeys(buf, "i\\") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000) + + call StopMNVInTerminal(buf) +endfunc + +func Test_WinScrolled_close_curwin() + CheckRunMNVInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + call setline(1, ['aaa', 'bbb']) + vsplit + au WinScrolled * close + au MNVLeave * call writefile(['123456'], 'Xtestout') + END + call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6}) + + " This was using freed memory + call term_sendkeys(buf, "\") + call TermWait(buf) + call StopMNVInTerminal(buf) + + " check the startup script finished to the end + call assert_equal(['123456'], readfile('Xtestout')) + call delete('Xtestout') +endfunc + +func Test_WinScrolled_once_only() + CheckScreendump + CheckRunMNVInTerminal + + let lines =<< trim END + set cmdheight=2 + call setline(1, ['aaa', 'bbb']) + let trigger_count = 0 + func ShowInfo(id) + echo g:trigger_count g:winid winlayout() + endfunc + + vsplit + split + " use a timer to show the info after a redraw + au WinScrolled * let trigger_count += 1 | let winid = expand('') | call timer_start(100, 'ShowInfo') + wincmd j + wincmd l + END + call writefile(lines, 'Xtest_winscrolled_once', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {}) + + call StopMNVInTerminal(buf) +endfunc + +" Check that WinScrolled is not triggered immediately when defined and there +" are split windows. +func Test_WinScrolled_not_when_defined() + CheckScreendump + CheckRunMNVInTerminal + + let lines =<< trim END + call setline(1, ['aaa', 'bbb']) + echo 'nothing happened' + func ShowTriggered(id) + echo 'triggered' + endfunc + END + call writefile(lines, 'Xtest_winscrolled_not', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2}) + call term_sendkeys(buf, ":split\") + call TermWait(buf) + " use a timer to show the message after redrawing + call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {}) + + call StopMNVInTerminal(buf) +endfunc + +func Test_WinScrolled_long_wrapped() + CheckRunMNVInTerminal + + let lines =<< trim END + set scrolloff=0 + let height = winheight(0) + let width = winwidth(0) + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + call setline(1, repeat('foo', height * width)) + call cursor(1, height * width) + END + call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6}) + + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, 'gj') + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^1 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, '0') + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, '$') + call term_sendkeys(buf, ":echo g:scrolled\") + call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000) + + call StopMNVInTerminal(buf) +endfunc + +func Test_WinScrolled_diff() + CheckRunMNVInTerminal + + let lines =<< trim END + set diffopt+=foldcolumn:0 + call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) + vnew + call setline(1, ['d', 'e', 'f', 'g', 'h', 'i']) + windo diffthis + func WriteScrollEvent() + call writefile([json_encode(v:event)], 'XscrollEvent') + endfunc + au WinScrolled * call WriteScrollEvent() + END + call writefile(lines, 'Xtest_winscrolled_diff', 'D') + let buf = RunMNVInTerminal('-S Xtest_winscrolled_diff', {'rows': 8}) + + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_match('^d', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -1, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "2\") + call WaitForAssert({-> assert_match('^f', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 2, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -2, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_match('^g', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "2\") + call WaitForAssert({-> assert_match('^e', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 3, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': -1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call StopMNVInTerminal(buf) + call delete('XscrollEvent') +endfunc + +func Test_WinClosed() + " Test that the pattern is matched against the closed window's ID, and both + " and are set to it. + new + let winid = win_getid() + let g:matched = v:false + augroup test-WinClosed + autocmd! + execute 'autocmd WinClosed' winid 'let g:matched = v:true' + autocmd WinClosed * let g:amatch = str2nr(expand('')) + autocmd WinClosed * let g:afile = str2nr(expand('')) + augroup END + close + call assert_true(g:matched) + call assert_equal(winid, g:amatch) + call assert_equal(winid, g:afile) + + " Test that WinClosed is non-recursive. + new + new + call assert_equal(3, winnr('$')) + let g:triggered = 0 + augroup test-WinClosed + autocmd! + autocmd WinClosed * let g:triggered += 1 + autocmd WinClosed * 2 wincmd c + augroup END + close + call assert_equal(1, winnr('$')) + call assert_equal(1, g:triggered) + + autocmd! test-WinClosed + augroup! test-WinClosed + unlet g:matched + unlet g:amatch + unlet g:afile + unlet g:triggered +endfunc + +func Test_WinClosed_throws() + vnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + +func Test_WinClosed_throws_with_tabs() + tabnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + +" This used to trigger WinClosed twice for the same window, and the window's +" buffer was NULL in the second autocommand. +func Test_WinClosed_switch_tab() + edit Xa + split Xb + split Xc + tab split + new + augroup test-WinClosed + autocmd WinClosed * tabprev | bwipe! + augroup END + close + " Check that the tabline has been fully removed + call assert_equal([1, 1], win_screenpos(0)) + + autocmd! test-WinClosed + augroup! test-WinClosed + %bwipe! +endfunc + +" This used to trigger WinClosed/WinLeave/BufLeave twice for the same window, +" and the window's buffer was NULL in the second autocommand. +func Run_test_BufUnload_close_other(extra_cmd) + let oldtab = tabpagenr() + tabnew Xb1 + let g:tab = tabpagenr() + let g:w1 = win_getid() + new Xb2 + let g:w2 = win_getid() + let g:log = [] + exe a:extra_cmd + + augroup test-BufUnload-close-other + autocmd BufUnload * ++nested ++once bwipe! Xb1 + for event in ['WinClosed', 'BufLeave', 'WinLeave', 'TabLeave'] + exe $'autocmd {event} * call tabpagebuflist(g:tab)' + exe $'autocmd {event} * let g:log += ["{event}:" .. expand("")]' + endfor + augroup END + + close + " WinClosed is triggered once for each of the 2 closed windows. + " Others are only triggered once. + call assert_equal(['BufLeave:Xb2', 'WinLeave:Xb2', $'WinClosed:{g:w2}', + \ $'WinClosed:{g:w1}', 'TabLeave:Xb2'], g:log) + call assert_equal(oldtab, tabpagenr()) + call assert_equal([0, 0], win_id2tabwin(g:w1)) + call assert_equal([0, 0], win_id2tabwin(g:w2)) + + unlet g:tab + unlet g:w1 + unlet g:w2 + unlet g:log + autocmd! test-BufUnload-close-other + augroup! test-BufUnload-close-other + %bwipe! +endfunc + +func Test_BufUnload_close_other() + call Run_test_BufUnload_close_other('') + call Run_test_BufUnload_close_other('setlocal bufhidden=wipe') +endfunc + +func Run_test_BufUnload_tabonly(first_cmd) + exe a:first_cmd + tabnew Xa + setlocal bufhidden=wipe + tabprevious + autocmd BufWinLeave Xa ++once tabnext + autocmd BufUnload Xa ++once tabonly + tabonly + + %bwipe! +endfunc + +func Test_BufUnload_tabonly() + " This used to dereference a NULL curbuf. + call Run_test_BufUnload_tabonly('setlocal bufhidden=hide') + " This used to dereference a NULL firstbuf. + call Run_test_BufUnload_tabonly('setlocal bufhidden=wipe') +endfunc + +func Run_test_BufUnload_tabonly_nested(second_autocmd) + file Xa + tabnew Xb + setlocal bufhidden=wipe + tabnew Xc + setlocal bufhidden=wipe + autocmd BufUnload Xb ++once ++nested bwipe! Xa + exe $'autocmd BufUnload Xa ++once ++nested {a:second_autocmd}' + autocmd BufWinLeave Xc ++once tabnext + tabfirst + 2tabclose + + %bwipe! +endfunc + +func Test_BufUnload_tabonly_nested() + " These used to cause heap-use-after-free. + call Run_test_BufUnload_tabonly_nested('tabonly') + call Run_test_BufUnload_tabonly_nested('tabonly | tabprevious') +endfunc + +func s:AddAnAutocmd() + augroup mnvBarTest + au BufReadCmd * echo 'hello' + augroup END + call assert_equal(3, len(split(execute('au mnvBarTest'), "\n"))) +endfunc + +func Test_early_bar() + " test that a bar is recognized before the {event} + call s:AddAnAutocmd() + augroup mnvBarTest | au! | let done = 77 | augroup END + call assert_equal(1, len(split(execute('au mnvBarTest'), "\n"))) + call assert_equal(77, done) + + call s:AddAnAutocmd() + augroup mnvBarTest| au!| let done = 88 | augroup END + call assert_equal(1, len(split(execute('au mnvBarTest'), "\n"))) + call assert_equal(88, done) + + " test that a bar is recognized after the {event} + call s:AddAnAutocmd() + augroup mnvBarTest| au!BufReadCmd| let done = 99 | augroup END + call assert_equal(1, len(split(execute('au mnvBarTest'), "\n"))) + call assert_equal(99, done) + + " test that a bar is recognized after the {group} + call s:AddAnAutocmd() + au! mnvBarTest|echo 'hello' + call assert_equal(1, len(split(execute('au mnvBarTest'), "\n"))) +endfunc + +func RemoveGroup() + autocmd! StartOK + augroup! StartOK +endfunc + +func Test_augroup_warning() + augroup TheWarning + au MNVEnter * echo 'entering' + augroup END + call assert_match("TheWarning.*MNVEnter", execute('au MNVEnter')) + redir => res + augroup! TheWarning + redir END + call assert_match("W19:", res) + call assert_match("-Deleted-.*MNVEnter", execute('au MNVEnter')) + + " check "Another" does not take the pace of the deleted entry + augroup Another + augroup END + call assert_match("-Deleted-.*MNVEnter", execute('au MNVEnter')) + augroup! Another + + " no warning for postpone aucmd delete + augroup StartOK + au MNVEnter * call RemoveGroup() + augroup END + call assert_match("StartOK.*MNVEnter", execute('au MNVEnter')) + redir => res + doautocmd MNVEnter + redir END + call assert_notmatch("W19:", res) + au! MNVEnter + + call assert_fails('augroup!', 'E471:') +endfunc + +func Test_BufReadCmdHelp() + " This used to cause access to free memory + au BufReadCmd * e +h + help + + au! BufReadCmd +endfunc + +func Test_BufReadCmdHelpJump() + " This used to cause access to free memory + au BufReadCmd * e +h{ + " } to fix highlighting + call assert_fails('help', 'E434:') + + au! BufReadCmd +endfunc + +" BufReadCmd is triggered for a "nofile" buffer. Check all values. +func Test_BufReadCmdNofile() + for val in ['nofile', + \ 'nowrite', + \ 'acwrite', + \ 'quickfix', + \ 'help', + \ 'terminal', + \ 'prompt', + \ 'popup', + \ ] + new somefile + exe 'set buftype=' .. val + au BufReadCmd somefile call setline(1, 'triggered') + edit + call assert_equal('triggered', getline(1)) + + au! BufReadCmd + bwipe! + endfor +endfunc + +func Test_augroup_deleted() + " This caused a crash before E936 was introduced + augroup x + call assert_fails('augroup! x', 'E936:') + au MNVEnter * echo + augroup end + augroup! x + call assert_match("-Deleted-.*MNVEnter", execute('au MNVEnter')) + au! MNVEnter +endfunc + +" Tests for autocommands on :close command. +" This used to be in test13. +func Test_three_windows() + " Clean up buffers, because in some cases this function fails. + call s:cleanup_buffers() + + " Write three files and open them, each in a window. + " Then go to next window, with autocommand that deletes the previous one. + " Do this twice, writing the file. + e! Xtestje1 + call setline(1, 'testje1') + w + sp Xtestje2 + call setline(1, 'testje2') + w + sp Xtestje3 + call setline(1, 'testje3') + w + wincmd w + au WinLeave Xtestje2 bwipe + wincmd w + call assert_equal('Xtestje1', expand('%')) + + au WinLeave Xtestje1 bwipe Xtestje3 + close + call assert_equal('Xtestje1', expand('%')) + + " Test deleting the buffer on a Unload event. If this goes wrong there + " will be the ATTENTION prompt. + e Xtestje1 + au! + au! BufUnload Xtestje1 bwipe + call assert_fails('e Xtestje3', 'E937:') + call assert_equal('Xtestje3', expand('%')) + + e Xtestje2 + sp Xtestje1 + call assert_fails('e', 'E937:') + call assert_equal('Xtestje1', expand('%')) + + " Test changing buffers in a BufWipeout autocommand. If this goes wrong + " there are ml_line errors and/or a Crash. + au! + only + e Xanother + e Xtestje1 + bwipe Xtestje2 + bwipe Xtestje3 + au BufWipeout Xtestje1 buf Xtestje1 + bwipe + call assert_equal('Xanother', expand('%')) + + only + help + wincmd w + 1quit + call assert_equal('Xanother', expand('%')) + + au! + enew + call delete('Xtestje1') + call delete('Xtestje2') + call delete('Xtestje3') +endfunc + +func Test_BufEnter() + au! BufEnter + au Bufenter * let val = val . '+' + let g:val = '' + split NewFile + call assert_equal('+', g:val) + bwipe! + call assert_equal('++', g:val) + + " Also get BufEnter when editing a directory + call mkdir('Xbufenterdir', 'D') + split Xbufenterdir + call assert_equal('+++', g:val) + + " On MS-Windows we can't edit the directory, make sure we wipe the right + " buffer. + bwipe! Xbufenterdir + au! BufEnter + + " Editing a "nofile" buffer doesn't read the file but does trigger BufEnter + " for historic reasons. Also test other 'buftype' values. + for val in ['nofile', + \ 'nowrite', + \ 'acwrite', + \ 'quickfix', + \ 'help', + \ 'terminal', + \ 'prompt', + \ 'popup', + \ ] + new somefile + exe 'set buftype=' .. val + au BufEnter somefile call setline(1, 'some text') + edit + call assert_equal('some text', getline(1)) + bwipe! + au! BufEnter + endfor + + new + new + autocmd BufEnter * ++once close + call assert_fails('close', 'E1312:') + + au! BufEnter + only +endfunc + +func Test_autocmd_SessLoadPre() + tabnew + set noswapfile + mksession! Session.mnv + + call assert_false(exists('g:session_loaded_var')) + + let content =<< trim [CODE] + set nocp noswapfile + + func! Assert(cond, msg) + if !a:cond + echomsg "ASSERT_FAIL: " .. a:msg + else + echomsg "ASSERT_OK: " .. a:msg + endif + endfunc + + func! OnSessionLoadPre() + call Assert(!exists('g:session_loaded_var'), + \ 'SessionLoadPre: var NOT set') + endfunc + au SessionLoadPre * call OnSessionLoadPre() + + func! OnSessionLoadPost() + call Assert(exists('g:session_loaded_var'), + \ 'SessionLoadPost: var IS set') + echomsg "SessionLoadPost DONE" + endfunc + au SessionLoadPost * call OnSessionLoadPost() + + func! WriteErrors() + call writefile([execute("messages")], "XerrorsPost") + endfunc + au MNVLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xmnvrc', 'D') + + call writefile( + \ ['let g:session_loaded_var = 1'], + \ 'Sessionx.mnv', + \ 'b' + \ ) + + " --- Run child MNV --- + call system( + \ GetMNVCommand('Xmnvrc') + \ .. ' --not-a-term --noplugins -S Session.mnv -c cq' + \ ) + + call WaitForAssert({-> assert_true(filereadable('XerrorsPost'))}) + + let errors = join(readfile('XerrorsPost'), "\n") + call assert_notmatch('ASSERT_FAIL', errors) + call assert_match('ASSERT_OK: SessionLoadPre: var NOT set', errors) + call assert_match('ASSERT_OK: SessionLoadPost: var IS set', errors) + call assert_match('SessionLoadPost DONE', errors) + + set swapfile + for file in ['Session.mnv', 'Sessionx.mnv', 'XerrorsPost'] + call delete(file) + endfor +endfunc + +" Closing a window might cause an endless loop +" E814 for older MNVs +func Test_autocmd_bufwipe_in_SessLoadPost() + edit Xtest + tabnew + file Xsomething + set noswapfile + mksession! + + let content =<< trim [CODE] + call test_override('ui_delay', 10) + set nocp noswapfile + let v:swapchoice = "e" + augroup test_autocmd_sessionload + autocmd! + autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!" + augroup END + + func WriteErrors() + call writefile([execute("messages")], "XerrorsBwipe") + endfunc + au MNVLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xmnvrc', 'D') + call system(GetMNVCommand('Xmnvrc') .. ' --not-a-term --noplugins -S Session.mnv -c cq') + sleep 100m + let errors = join(readfile('XerrorsBwipe')) + call assert_match('E814:', errors) + + set swapfile + for file in ['Session.mnv', 'XerrorsBwipe'] + call delete(file) + endfor +endfunc + +" Using :blast and :ball for many events caused a crash, because b_nwindows was +" not incremented correctly. +func Test_autocmd_blast_badd() + let content =<< trim [CODE] + au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,MNVEnter foo* blast + edit foo1 + au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,MNVEnter foo* ball + edit foo2 + call writefile(['OK'], 'XerrorsBlast') + qall + [CODE] + + call writefile(content, 'XblastBall', 'D') + call system(GetMNVCommand() .. ' --clean -S XblastBall') + sleep 100m + call assert_match('OK', readfile('XerrorsBlast')->join()) + + call delete('XerrorsBlast') +endfunc + +" SEGV occurs in older versions. +func Test_autocmd_bufwipe_in_SessLoadPost2() + tabnew + set noswapfile + mksession! + + let content =<< trim [CODE] + set nocp noswapfile + function! DeleteInactiveBufs() + tabfirst + let tabblist = [] + for i in range(1, tabpagenr(''$'')) + call extend(tabblist, tabpagebuflist(i)) + endfor + for b in range(1, bufnr(''$'')) + if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'') + exec ''bwipeout '' . b + endif + endfor + echomsg "SessionLoadPost DONE" + endfunction + au SessionLoadPost * call DeleteInactiveBufs() + + func WriteErrors() + call writefile([execute("messages")], "XerrorsPost") + endfunc + au MNVLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xmnvrc', 'D') + call system(GetMNVCommand('Xmnvrc') .. ' --not-a-term --noplugins -S Session.mnv -c cq') + sleep 100m + let errors = join(readfile('XerrorsPost')) + " This probably only ever matches on unix. + call assert_notmatch('Caught deadly signal SEGV', errors) + call assert_match('SessionLoadPost DONE', errors) + + set swapfile + for file in ['Session.mnv', 'XerrorsPost'] + call delete(file) + endfor +endfunc + +func Test_empty_doau() + doau \| +endfunc + +func s:AutoCommandOptionSet(match) + let template = "Option: <%s>, OldVal: <%s>, OldValLocal: <%s>, OldValGlobal: <%s>, NewVal: <%s>, Scope: <%s>, Command: <%s>\n" + let item = remove(g:options, 0) + let expected = printf(template, item[0], item[1], item[2], item[3], item[4], item[5], item[6]) + let actual = printf(template, a:match, v:option_old, v:option_oldlocal, v:option_oldglobal, v:option_new, v:option_type, v:option_command) + let g:opt = [expected, actual] + "call assert_equal(expected, actual) +endfunc + +func Test_OptionSet() + CheckOption autochdir + + badd test_autocmd.mnv + + call test_override('starting', 1) + set nocp + au OptionSet * :call s:AutoCommandOptionSet(expand("")) + + " 1: Setting number option" + let g:options = [['number', 0, 0, 0, 1, 'global', 'set']] + set nu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 2: Setting local number option" + let g:options = [['number', 1, 1, '', 0, 'local', 'setlocal']] + setlocal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 3: Setting global number option" + let g:options = [['number', 1, '', 1, 0, 'global', 'setglobal']] + setglobal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 4: Setting local autoindent option" + let g:options = [['autoindent', 0, 0, '', 1, 'local', 'setlocal']] + setlocal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 5: Setting global autoindent option" + let g:options = [['autoindent', 0, '', 0, 1, 'global', 'setglobal']] + setglobal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 6: Setting global autoindent option" + let g:options = [['autoindent', 1, 1, 1, 0, 'global', 'set']] + set ai! + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 6a: Setting global autoindent option" + let g:options = [['autoindent', 1, 1, 0, 0, 'global', 'set']] + noa setlocal ai + noa setglobal noai + set ai! + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " Should not print anything, use :noa + " 7: don't trigger OptionSet" + let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']] + noa set nonu + call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 8: Setting several global list and number option" + let g:options = [['list', 0, 0, 0, 1, 'global', 'set'], ['number', 0, 0, 0, 1, 'global', 'set']] + set list nu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 9: don't trigger OptionSet" + let g:options = [['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']] + noa set nolist nonu + call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 10: Setting global acd" + let g:options = [['autochdir', 0, 0, '', 1, 'local', 'setlocal']] + setlocal acd + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 11: Setting global autoread (also sets local value)" + let g:options = [['autoread', 0, 0, 0, 1, 'global', 'set']] + set ar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 12: Setting local autoread" + let g:options = [['autoread', 1, 1, '', 1, 'local', 'setlocal']] + setlocal ar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 13: Setting global autoread" + let g:options = [['autoread', 1, '', 1, 0, 'global', 'setglobal']] + setglobal invar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 14: Setting option backspace through :let" + let g:options = [['backspace', 'indent,eol,start', 'indent,eol,start', 'indent,eol,start', '', 'global', 'set']] + let &bs = '' + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 15: Setting option backspace through setbufvar()" + let g:options = [['backup', 0, 0, '', 1, 'local', 'setlocal']] + " try twice, first time, shouldn't trigger because option name is invalid, + " second time, it should trigger + let bnum = bufnr('%') + call assert_fails("call setbufvar(bnum, '&l:bk', 1)", 'E355:') + " should trigger, use correct option name + call setbufvar(bnum, '&backup', 1) + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 16: Setting number option using setwinvar" + let g:options = [['number', 0, 0, '', 1, 'local', 'setlocal']] + call setwinvar(0, '&number', 1) + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 17: Setting key option, shouldn't trigger" + let g:options = [['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']] + setlocal key=blah + setlocal key= + call assert_equal([['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 18a: Setting string global option" + let oldval = &backupext + let g:options = [['backupext', oldval, oldval, oldval, 'foo', 'global', 'set']] + set backupext=foo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 18b: Resetting string global option" + let g:options = [['backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set']] + set backupext& + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 18c: Setting global string global option" + let g:options = [['backupext', oldval, '', oldval, 'bar', 'global', 'setglobal']] + setglobal backupext=bar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 18d: Setting local string global option" + " As this is a global option this sets the global value even though + " :setlocal is used! + noa set backupext& " Reset global and local value (without triggering autocmd) + let g:options = [['backupext', oldval, oldval, '', 'baz', 'local', 'setlocal']] + setlocal backupext=baz + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 18e: Setting again string global option" + noa setglobal backupext=ext_global " Reset global and local value (without triggering autocmd) + noa setlocal backupext=ext_local " Sets the global(!) value! + let g:options = [['backupext', 'ext_local', 'ext_local', 'ext_local', 'fuu', 'global', 'set']] + set backupext=fuu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 19a: Setting string global-local (to buffer) option" + let oldval = &tags + let g:options = [['tags', oldval, oldval, oldval, 'tagpath', 'global', 'set']] + set tags=tagpath + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 19b: Resetting string global-local (to buffer) option" + let g:options = [['tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set']] + set tags& + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 19c: Setting global string global-local (to buffer) option " + let g:options = [['tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal']] + setglobal tags=tagpath1 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 19d: Setting local string global-local (to buffer) option" + let g:options = [['tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal']] + setlocal tags=tagpath2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 19e: Setting again string global-local (to buffer) option" + " Note: v:option_old is the old global value for global-local string options + " but the old local value for all other kinds of options. + noa setglobal tags=tag_global " Reset global and local value (without triggering autocmd) + noa setlocal tags=tag_local + let g:options = [['tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set']] + set tags=tagpath + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 19f: Setting string global-local (to buffer) option to an empty string" + " Note: v:option_old is the old global value for global-local string options + " but the old local value for all other kinds of options. + noa set tags=tag_global " Reset global and local value (without triggering autocmd) + noa setlocal tags= " empty string + let g:options = [['tags', 'tag_global', '', 'tag_global', 'tagpath', 'global', 'set']] + set tags=tagpath + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 20a: Setting string local (to buffer) option" + let oldval = &spelllang + let g:options = [['spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set']] + set spelllang=elvish,klingon + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 20b: Resetting string local (to buffer) option" + let g:options = [['spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set']] + set spelllang& + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 20c: Setting global string local (to buffer) option" + let g:options = [['spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal']] + setglobal spelllang=elvish + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 20d: Setting local string local (to buffer) option" + noa set spelllang& " Reset global and local value (without triggering autocmd) + let g:options = [['spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal']] + setlocal spelllang=klingon + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 20e: Setting again string local (to buffer) option" + " Note: v:option_old is the old global value for global-local string options + " but the old local value for all other kinds of options. + noa setglobal spelllang=spellglobal " Reset global and local value (without triggering autocmd) + noa setlocal spelllang=spelllocal + let g:options = [['spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set']] + set spelllang=foo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 21a: Setting string global-local (to window) option" + let oldval = &statusline + let g:options = [['statusline', oldval, oldval, oldval, 'foo', 'global', 'set']] + set statusline=foo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 21b: Resetting string global-local (to window) option" + " Note: v:option_old is the old global value for global-local string options + " but the old local value for all other kinds of options. + let g:options = [['statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set']] + set statusline& + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 21c: Setting global string global-local (to window) option" + let g:options = [['statusline', oldval, '', oldval, 'bar', 'global', 'setglobal']] + setglobal statusline=bar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 21d: Setting local string global-local (to window) option" + noa set statusline& " Reset global and local value (without triggering autocmd) + let g:options = [['statusline', oldval, oldval, '', 'baz', 'local', 'setlocal']] + setlocal statusline=baz + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 21e: Setting again string global-local (to window) option" + " Note: v:option_old is the old global value for global-local string options + " but the old local value for all other kinds of options. + noa setglobal statusline=bar " Reset global and local value (without triggering autocmd) + noa setlocal statusline=baz + let g:options = [['statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set']] + set statusline=foo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 22a: Setting string local (to window) option" + let oldval = &foldignore + let g:options = [['foldignore', oldval, oldval, oldval, 'fo', 'global', 'set']] + set foldignore=fo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 22b: Resetting string local (to window) option" + let g:options = [['foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set']] + set foldignore& + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 22c: Setting global string local (to window) option" + let g:options = [['foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal']] + setglobal foldignore=bar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 22d: Setting local string local (to window) option" + noa set foldignore& " Reset global and local value (without triggering autocmd) + let g:options = [['foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal']] + setlocal foldignore=baz + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 22e: Setting again string local (to window) option" + noa setglobal foldignore=glob " Reset global and local value (without triggering autocmd) + noa setlocal foldignore=loc + let g:options = [['foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set']] + set foldignore=fo + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 23a: Setting global number global option" + noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd) + noa setlocal cmdheight=1 " Sets the global(!) value! + let g:options = [['cmdheight', '1', '', '1', '2', 'global', 'setglobal']] + setglobal cmdheight=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 23b: Setting local number global option" + noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd) + noa setlocal cmdheight=1 " Sets the global(!) value! + let g:options = [['cmdheight', '1', '1', '', '2', 'local', 'setlocal']] + setlocal cmdheight=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 23c: Setting again number global option" + noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd) + noa setlocal cmdheight=1 " Sets the global(!) value! + let g:options = [['cmdheight', '1', '1', '1', '2', 'global', 'set']] + set cmdheight=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 23d: Setting again number global option" + noa set cmdheight=8 " Reset global and local value (without triggering autocmd) + let g:options = [['cmdheight', '8', '8', '8', '2', 'global', 'set']] + set cmdheight=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 24a: Setting global number global-local (to buffer) option" + noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd) + noa setlocal undolevels=1 + let g:options = [['undolevels', '8', '', '8', '2', 'global', 'setglobal']] + setglobal undolevels=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 24b: Setting local number global-local (to buffer) option" + noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd) + noa setlocal undolevels=1 + let g:options = [['undolevels', '1', '1', '', '2', 'local', 'setlocal']] + setlocal undolevels=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 24c: Setting again number global-local (to buffer) option" + noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd) + noa setlocal undolevels=1 + let g:options = [['undolevels', '1', '1', '8', '2', 'global', 'set']] + set undolevels=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 24d: Setting again global number global-local (to buffer) option" + noa set undolevels=8 " Reset global and local value (without triggering autocmd) + let g:options = [['undolevels', '8', '8', '8', '2', 'global', 'set']] + set undolevels=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 25a: Setting global number local (to buffer) option" + noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd) + noa setlocal wrapmargin=1 + let g:options = [['wrapmargin', '8', '', '8', '2', 'global', 'setglobal']] + setglobal wrapmargin=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 25b: Setting local number local (to buffer) option" + noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd) + noa setlocal wrapmargin=1 + let g:options = [['wrapmargin', '1', '1', '', '2', 'local', 'setlocal']] + setlocal wrapmargin=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 25c: Setting again number local (to buffer) option" + noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd) + noa setlocal wrapmargin=1 + let g:options = [['wrapmargin', '1', '1', '8', '2', 'global', 'set']] + set wrapmargin=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 25d: Setting again global number local (to buffer) option" + noa set wrapmargin=8 " Reset global and local value (without triggering autocmd) + let g:options = [['wrapmargin', '8', '8', '8', '2', 'global', 'set']] + set wrapmargin=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 26: Setting number global-local (to window) option. + " Such option does currently not exist. + + + " 27a: Setting global number local (to window) option" + noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd) + noa setlocal foldcolumn=1 + let g:options = [['foldcolumn', '8', '', '8', '2', 'global', 'setglobal']] + setglobal foldcolumn=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 27b: Setting local number local (to window) option" + noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd) + noa setlocal foldcolumn=1 + let g:options = [['foldcolumn', '1', '1', '', '2', 'local', 'setlocal']] + setlocal foldcolumn=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 27c: Setting again number local (to window) option" + noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd) + noa setlocal foldcolumn=1 + let g:options = [['foldcolumn', '1', '1', '8', '2', 'global', 'set']] + set foldcolumn=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 27d: Setting again global number local (to window) option" + noa set foldcolumn=8 " Reset global and local value (without triggering autocmd) + let g:options = [['foldcolumn', '8', '8', '8', '2', 'global', 'set']] + set foldcolumn=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 28a: Setting global boolean global option" + noa setglobal nowrapscan " Reset global and local value (without triggering autocmd) + noa setlocal wrapscan " Sets the global(!) value! + let g:options = [['wrapscan', '1', '', '1', '0', 'global', 'setglobal']] + setglobal nowrapscan + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 28b: Setting local boolean global option" + noa setglobal nowrapscan " Reset global and local value (without triggering autocmd) + noa setlocal wrapscan " Sets the global(!) value! + let g:options = [['wrapscan', '1', '1', '', '0', 'local', 'setlocal']] + setlocal nowrapscan + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 28c: Setting again boolean global option" + noa setglobal nowrapscan " Reset global and local value (without triggering autocmd) + noa setlocal wrapscan " Sets the global(!) value! + let g:options = [['wrapscan', '1', '1', '1', '0', 'global', 'set']] + set nowrapscan + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 28d: Setting again global boolean global option" + noa set nowrapscan " Reset global and local value (without triggering autocmd) + let g:options = [['wrapscan', '0', '0', '0', '1', 'global', 'set']] + set wrapscan + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 29a: Setting global boolean global-local (to buffer) option" + noa setglobal noautoread " Reset global and local value (without triggering autocmd) + noa setlocal autoread + let g:options = [['autoread', '0', '', '0', '1', 'global', 'setglobal']] + setglobal autoread + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 29b: Setting local boolean global-local (to buffer) option" + noa setglobal noautoread " Reset global and local value (without triggering autocmd) + noa setlocal autoread + let g:options = [['autoread', '1', '1', '', '0', 'local', 'setlocal']] + setlocal noautoread + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 29c: Setting again boolean global-local (to buffer) option" + noa setglobal noautoread " Reset global and local value (without triggering autocmd) + noa setlocal autoread + let g:options = [['autoread', '1', '1', '0', '1', 'global', 'set']] + set autoread + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 29d: Setting again global boolean global-local (to buffer) option" + noa set noautoread " Reset global and local value (without triggering autocmd) + let g:options = [['autoread', '0', '0', '0', '1', 'global', 'set']] + set autoread + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 30a: Setting global boolean local (to buffer) option" + noa setglobal nocindent " Reset global and local value (without triggering autocmd) + noa setlocal cindent + let g:options = [['cindent', '0', '', '0', '1', 'global', 'setglobal']] + setglobal cindent + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 30b: Setting local boolean local (to buffer) option" + noa setglobal nocindent " Reset global and local value (without triggering autocmd) + noa setlocal cindent + let g:options = [['cindent', '1', '1', '', '0', 'local', 'setlocal']] + setlocal nocindent + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 30c: Setting again boolean local (to buffer) option" + noa setglobal nocindent " Reset global and local value (without triggering autocmd) + noa setlocal cindent + let g:options = [['cindent', '1', '1', '0', '1', 'global', 'set']] + set cindent + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 30d: Setting again global boolean local (to buffer) option" + noa set nocindent " Reset global and local value (without triggering autocmd) + let g:options = [['cindent', '0', '0', '0', '1', 'global', 'set']] + set cindent + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 31: Setting boolean global-local (to window) option + " Currently no such option exists. + + + " 32a: Setting global boolean local (to window) option" + noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd) + noa setlocal cursorcolumn + let g:options = [['cursorcolumn', '0', '', '0', '1', 'global', 'setglobal']] + setglobal cursorcolumn + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 32b: Setting local boolean local (to window) option" + noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd) + noa setlocal cursorcolumn + let g:options = [['cursorcolumn', '1', '1', '', '0', 'local', 'setlocal']] + setlocal nocursorcolumn + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 32c: Setting again boolean local (to window) option" + noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd) + noa setlocal cursorcolumn + let g:options = [['cursorcolumn', '1', '1', '0', '1', 'global', 'set']] + set cursorcolumn + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 32d: Setting again global boolean local (to window) option" + noa set nocursorcolumn " Reset global and local value (without triggering autocmd) + let g:options = [['cursorcolumn', '0', '0', '0', '1', 'global', 'set']] + set cursorcolumn + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " 33: Test autocommands when an option value is converted internally. + noa set backspace=1 " Reset global and local value (without triggering autocmd) + let g:options = [['backspace', 'indent,eol', 'indent,eol', 'indent,eol', '2', 'global', 'set']] + set backspace=2 + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + + " Cleanup + au! OptionSet + " set tags& + for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp', 'backupext', 'tags', 'spelllang', 'statusline', 'foldignore', 'cmdheight', 'undolevels', 'wrapmargin', 'foldcolumn', 'wrapscan', 'autoread', 'cindent', 'cursorcolumn'] + exe printf(":set %s&mnv", opt) + endfor + call test_override('starting', 0) + delfunc! AutoCommandOptionSet +endfunc + +func Test_OptionSet_diffmode() + call test_override('starting', 1) + " 18: Changing an option when entering diff mode + new + au OptionSet diff :let &l:cul = v:option_new + + call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) + call assert_equal(0, &l:cul) + diffthis + call assert_equal(1, &l:cul) + + vnew + call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) + call assert_equal(0, &l:cul) + diffthis + call assert_equal(1, &l:cul) + + diffoff + call assert_equal(0, &l:cul) + call assert_equal(1, getwinvar(2, '&l:cul')) + bw! + + call assert_equal(1, &l:cul) + diffoff! + call assert_equal(0, &l:cul) + call assert_equal(0, getwinvar(1, '&l:cul')) + bw! + + " Cleanup + au! OptionSet + call test_override('starting', 0) +endfunc + +func Test_OptionSet_diffmode_close() + call test_override('starting', 1) + " 19: Try to close the current window when entering diff mode + " should not segfault + new + au OptionSet diff close + + call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) + call assert_fails(':diffthis', 'E788:') + call assert_equal(1, &diff) + vnew + call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) + call assert_fails(':diffthis', 'E788:') + call assert_equal(1, &diff) + set diffopt-=closeoff + bw! + call assert_fails(':diffoff!', 'E788:') + bw! + + " Cleanup + au! OptionSet + call test_override('starting', 0) + "delfunc! AutoCommandOptionSet +endfunc + +" Test for Bufleave autocommand that deletes the buffer we are about to edit. +func Test_BufleaveWithDelete() + new | edit XbufLeave1 + + augroup test_bufleavewithdelete + autocmd! + autocmd BufLeave XbufLeave1 bwipe XbufLeave2 + augroup END + + call assert_fails('edit XbufLeave2', 'E143:') + call assert_equal('XbufLeave1', bufname('%')) + + autocmd! test_bufleavewithdelete BufLeave XbufLeave1 + augroup! test_bufleavewithdelete + + new + bwipe! XbufLeave1 +endfunc + +" Test for autocommand that changes the buffer list, when doing ":ball". +func Test_Acmd_BufAll() + enew! + %bwipe! + call writefile(['Test file Xxx1'], 'Xxx1', 'D') + call writefile(['Test file Xxx2'], 'Xxx2', 'D') + call writefile(['Test file Xxx3'], 'Xxx3', 'D') + + " Add three files to the buffer list + split Xxx1 + close + split Xxx2 + close + split Xxx3 + close + + " Wipe the buffer when the buffer is opened + au BufReadPost Xxx2 bwipe + + call append(0, 'Test file Xxx4') + ball + + call assert_equal(2, winnr('$')) + call assert_equal('Xxx1', bufname(winbufnr(winnr('$')))) + wincmd t + + au! BufReadPost + %bwipe! + enew! | only +endfunc + +" Test for autocommand that changes current buffer on BufEnter event. +" Check if modelines are interpreted for the correct buffer. +func Test_Acmd_BufEnter() + %bwipe! + call writefile(['start of test file Xxx1', + \ "\this is a test", + \ 'end of test file Xxx1'], 'Xxx1', 'D') + call writefile(['start of test file Xxx2', + \ 'mnv: set noai :', + \ "\this is a test", + \ 'end of test file Xxx2'], 'Xxx2', 'D') + + au BufEnter Xxx2 brew + set ai modeline modelines=3 + edit Xxx1 + " edit Xxx2, autocmd will do :brew + edit Xxx2 + exe "normal G?this is a\" + " Append text with autoindent to this file + normal othis should be auto-indented + call assert_equal("\this should be auto-indented", getline('.')) + call assert_equal(3, line('.')) + " Remove autocmd and edit Xxx2 again + au! BufEnter Xxx2 + buf! Xxx2 + exe "normal G?this is a\" + " append text without autoindent to Xxx + normal othis should be in column 1 + call assert_equal("this should be in column 1", getline('.')) + call assert_equal(4, line('.')) + + %bwipe! + set ai&mnv modeline&mnv modelines&mnv +endfunc + +" Test for issue #57 +" do not move cursor on when autoindent is set +func Test_ai_CTRL_O() + enew! + set ai + let save_fo = &fo + set fo+=r + exe "normal o# abcdef\2hi\\d0\" + exe "normal o# abcdef\2hi\d0\" + call assert_equal(['# abc', 'def', 'def'], getline(2, 4)) + + set ai&mnv + let &fo = save_fo + enew! +endfunc + +" Test for autocommand that deletes the current buffer on BufLeave event. +" Also test deleting the last buffer, should give a new, empty buffer. +func Test_BufLeave_Wipe() + %bwipe! + let content = ['start of test file Xxx', + \ 'this is a test', + \ 'end of test file Xxx'] + call writefile(content, 'Xxx1', 'D') + call writefile(content, 'Xxx2', 'D') + + au BufLeave Xxx2 bwipe + edit Xxx1 + split Xxx2 + " delete buffer Xxx2, we should be back to Xxx1 + bwipe + call assert_equal('Xxx1', bufname('%')) + call assert_equal(1, winnr('$')) + + " Create an alternate buffer + %write! test.out + call assert_equal('test.out', bufname('#')) + " delete alternate buffer + bwipe test.out + call assert_equal('Xxx1', bufname('%')) + call assert_equal('', bufname('#')) + + au BufLeave Xxx1 bwipe + " delete current buffer, get an empty one + bwipe! + call assert_equal(1, line('$')) + call assert_equal('', bufname('%')) + let g:bufinfo = getbufinfo() + call assert_equal(1, len(g:bufinfo)) + + call delete('test.out') + %bwipe + au! BufLeave + + " check that bufinfo doesn't contain a pointer to freed memory + call test_garbagecollect_now() +endfunc + +func Test_QuitPre() + edit Xfoo + let winid = win_getid(winnr()) + split Xbar + au! QuitPre * let g:afile = expand('') + " Close the other window, should be correct. + exe win_id2win(winid) . 'q' + call assert_equal('Xfoo', g:afile) + + unlet g:afile + bwipe Xfoo + bwipe Xbar +endfunc + +func Test_Cmdline_Trigger() + autocmd CmdlineLeavePre : let g:log = "CmdlineLeavePre" + autocmd CmdlineLeave : let g:log2 = "CmdlineLeave" + new + let g:log = '' + let g:log2 = '' + nnoremap echo "hello" + call feedkeys("\", 'x') + call assert_equal('', g:log) + call assert_equal('', g:log2) + nunmap + + let g:log = '' + let g:log2 = '' + nnoremap :echo "hello" + call feedkeys("\", 'x') + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + nunmap + + let g:log = '' + let g:log2 = '' + call feedkeys(":\", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + let g:log = '' + let g:log2 = '' + split + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + let g:log = '' + let g:log2 = '' + close + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + let g:log = '' + let g:log2 = '' + tabnew + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + let g:log = '' + let g:log2 = '' + split + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + let g:log = '' + let g:log2 = '' + tabclose + call assert_equal('', g:log) + call feedkeys(":echo hello", "tx") + call assert_equal('CmdlineLeavePre', g:log) + call assert_equal('CmdlineLeave', g:log2) + + autocmd CmdlineLeavePre * let g:cmdline += [getcmdline()] + + for end_keys in ["\", "\", "\", "\", "\", + \ "\\", "\\"] + let g:cmdline = [] + let g:log = '' + let g:log2 = '' + call assert_equal('', g:log) + let keys = $':echo "hello"{end_keys}' + let msg = keytrans(keys) + call feedkeys(keys, "tx") + call assert_equal(['echo "hello"'], g:cmdline, msg) + call assert_equal('CmdlineLeavePre', g:log, msg) + call assert_equal('CmdlineLeave', g:log2, msg) + endfor + + let g:cmdline = [] + call feedkeys(":let c = input('? ')\ABCDE\", "tx") + call assert_equal(["let c = input('? ')", 'ABCDE'], g:cmdline) + + au! CmdlineLeavePre + unlet! g:cmdline + unlet! g:log + unlet! g:log2 + bw! +endfunc + +" Ensure :cabbr does not cause a spurious CmdlineLeavePre. +func Test_CmdlineLeavePre_cabbr() + " For unknown reason this fails intermittently on MS-Windows + CheckNotMSWindows + CheckFeature terminal + let buf = term_start([GetMNVProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3}) + call assert_equal('running', term_getstatus(buf)) + call term_sendkeys(buf, ":let g:a=0\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":cabbr v v\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":command! -nargs=* Foo echo\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":au! CmdlineLeavePre * :let g:a+=1\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":Foo v\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":echo g:a\") + call term_wait(buf, 50) + call WaitForAssert({-> assert_match('^2.*$', term_getline(buf, 3))}) + bwipe! +endfunc + +func Test_Cmdline() + au! CmdlineChanged : let g:text = getcmdline() + let g:text = 0 + call feedkeys(":echom 'hello'\", 'xt') + call assert_equal("echom 'hello'", g:text) + au! CmdlineChanged + + au! CmdlineChanged : let g:entered = expand('') + let g:entered = 0 + call feedkeys(":echom 'hello'\", 'xt') + call assert_equal(':', g:entered) + au! CmdlineChanged + + autocmd CmdlineChanged : let g:log += [getcmdline()] + + let g:log = [] + cnoremap call setcmdline('ls') + call feedkeys(":\", 'xt') + call assert_equal(['ls'], g:log) + cunmap + + let g:log = [] + call feedkeys(":sign \\\\\\\", 'xt') + call assert_equal([ + \ 's', + \ 'si', + \ 'sig', + \ 'sign', + \ 'sign ', + \ 'sign define', + \ 'sign jump', + \ 'sign list', + \ 'sign jump', + \ 'sign define', + \ 'sign ', + \ ], g:log) + let g:log = [] + set wildmenu wildoptions+=pum + call feedkeys(":sign \\\\\\", 'xt') + call assert_equal([ + \ 's', + \ 'si', + \ 'sig', + \ 'sign', + \ 'sign ', + \ 'sign unplace', + \ 'sign jump', + \ 'sign define', + \ 'sign undefine', + \ 'sign unplace', + \ ], g:log) + set wildmenu& wildoptions& + + let g:log = [] + let @r = 'abc' + call feedkeys(":0\r1\\r2\\r3\", 'xt') + call assert_equal([ + \ '0', + \ '0a', + \ '0ab', + \ '0abc', + \ '0abc1', + \ '0abc1abc', + \ '0abc1abc2', + \ '0abc1abc2abc', + \ '0abc1abc2abc3', + \ ], g:log) + + " should trigger CmdlineChanged + let g:log = [] + call feedkeys(":foo\\\\\", 'xt') + call assert_equal([ + \ 'f', + \ 'fo', + \ 'foo', + \ 'fo', + \ 'f', + \ ], g:log) + + unlet g:log + au! CmdlineChanged + + au! CmdlineEnter : let g:entered = expand('') + au! CmdlineLeave : let g:left = expand('') + au! CmdlineLeavePre : let g:leftpre = expand('') + let g:entered = 0 + let g:left = 0 + let g:leftpre = 0 + call feedkeys(":echo 'hello'\", 'xt') + call assert_equal(':', g:entered) + call assert_equal(':', g:left) + call assert_equal(':', g:leftpre) + au! CmdlineEnter + au! CmdlineLeave + au! CmdlineLeavePre + + let save_shellslash = &shellslash + set noshellslash + au! CmdlineEnter / let g:entered = expand('') + au! CmdlineLeave / let g:left = expand('') + au! CmdlineLeavePre / let g:leftpre = expand('') + let g:entered = 0 + let g:left = 0 + let g:leftpre = 0 + new + call setline(1, 'hello') + call feedkeys("/hello\", 'xt') + call assert_equal('/', g:entered) + call assert_equal('/', g:left) + call assert_equal('/', g:leftpre) + bwipe! + au! CmdlineEnter + au! CmdlineLeave + au! CmdlineLeavePre + let &shellslash = save_shellslash + + let g:left = "cancelled" + let g:leftpre = "cancelled" + au! CmdlineLeave : let g:left = "triggered" + au! CmdlineLeavePre : let g:leftpre = "triggered" + call feedkeys(":echo 'hello'\", 'xt') + call assert_equal('triggered', g:left) + call assert_equal('triggered', g:leftpre) + let g:left = "cancelled" + let g:leftpre = "cancelled" + au! CmdlineLeave : let g:left = "triggered" + call feedkeys(":echo 'hello'\", 'xt') + call assert_equal('triggered', g:left) + call assert_equal('triggered', g:leftpre) + au! CmdlineLeave + au! CmdlineLeavePre + + au! CursorMovedC : let g:pos += [getcmdpos()] + let g:pos = [] + call feedkeys(":foo bar baz\\\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 9, 5, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 1], g:pos) + let g:pos = [] + call feedkeys(":hello\\=''\\\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4, 5], g:pos) + let g:pos = [] + call feedkeys(":12345678\=setcmdpos(3)??''\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3], g:pos) + let g:pos = [] + call feedkeys(":12345678\=setcmdpos(3)??''\\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 3, 2], g:pos) + au! CursorMovedC + + " setcmdpos() is no-op inside an autocommand + au! CursorMovedC : let g:pos += [getcmdpos()] | call setcmdpos(1) + let g:pos = [] + call feedkeys(":hello\\\", 'xt') + call assert_equal([2, 3, 4, 5, 6, 5, 4], g:pos) + au! CursorMovedC + + unlet g:entered + unlet g:left + unlet g:pos +endfunc + +" Test for BufWritePre autocommand that deletes or unloads the buffer. +func Test_BufWritePre() + %bwipe + au BufWritePre Xxx1 bunload + au BufWritePre Xxx2 bwipe + + call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1', 'D') + call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2', 'D') + + edit Xtest + e! Xxx2 + bdel Xtest + e Xxx1 + " write it, will unload it and give an error msg + call assert_fails('w', 'E203:') + call assert_equal('Xxx2', bufname('%')) + edit Xtest + e! Xxx2 + bwipe Xtest + " write it, will delete the buffer and give an error msg + call assert_fails('w', 'E203:') + call assert_equal('Xxx1', bufname('%')) + au! BufWritePre +endfunc + +" Test for BufUnload autocommand that unloads all the other buffers +func Test_bufunload_all() + let g:test_is_flaky = 1 + call writefile(['Test file Xxx1'], 'Xxx1', 'D') + call writefile(['Test file Xxx2'], 'Xxx2', 'D') + + let content =<< trim [CODE] + func UnloadAllBufs() + let i = 1 + while i <= bufnr('$') + if i != bufnr('%') && bufloaded(i) + exe i . 'bunload' + endif + let i += 1 + endwhile + endfunc + au BufUnload * call UnloadAllBufs() + au MNVLeave * call writefile(['Test Finished'], 'Xout') + edit Xxx1 + split Xxx2 + q + [CODE] + + call writefile(content, 'Xbunloadtest', 'D') + + call delete('Xout') + call system(GetMNVCommandClean() .. ' -N --not-a-term -S Xbunloadtest') + call assert_true(filereadable('Xout')) + + call delete('Xout') +endfunc + +" Some tests for buffer-local autocommands +func Test_buflocal_autocmd() + let g:bname = '' + edit xx + au BufLeave let g:bname = expand("%") + " here, autocommand for xx should trigger. + " but autocommand shall not apply to buffer named . + edit somefile + call assert_equal('xx', g:bname) + let g:bname = '' + " here, autocommand shall be auto-deleted + bwipe xx + " autocmd should not trigger + edit xx + call assert_equal('', g:bname) + " autocmd should not trigger + edit somefile + call assert_equal('', g:bname) + enew + unlet g:bname +endfunc + +" Test for "*Cmd" autocommands +func Test_Cmd_Autocmds() + call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx', 'D') + + enew! + au BufReadCmd XtestA 0r Xxx|$del + edit XtestA " will read text of Xxd instead + call assert_equal('start of Xxx', getline(1)) + + au BufWriteCmd XtestA call append(line("$"), "write") + write " will append a line to the file + call assert_equal('write', getline('$')) + call assert_fails('read XtestA', 'E484:') " should not read anything + call assert_equal('write', getline(4)) + + " now we have: + " 1 start of Xxx + " 2 abc2 + " 3 end of Xxx + " 4 write + + au FileReadCmd XtestB '[r Xxx + 2r XtestB " will read Xxx below line 2 instead + call assert_equal('start of Xxx', getline(3)) + + " now we have: + " 1 start of Xxx + " 2 abc2 + " 3 start of Xxx + " 4 abc2 + " 5 end of Xxx + " 6 end of Xxx + " 7 write + + au FileWriteCmd XtestC '[,']copy $ + normal 4GA1 + 4,5w XtestC " will copy lines 4 and 5 to the end + call assert_equal("\tabc21", getline(8)) + call assert_fails('r XtestC', 'E484:') " should not read anything + call assert_equal("end of Xxx", getline(9)) + + " now we have: + " 1 start of Xxx + " 2 abc2 + " 3 start of Xxx + " 4 abc21 + " 5 end of Xxx + " 6 end of Xxx + " 7 write + " 8 abc21 + " 9 end of Xxx + + let g:lines = [] + au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']"))) + w >>XtestD " will add lines to 'lines' + call assert_equal(9, len(g:lines)) + call assert_fails('$r XtestD', 'E484:') " should not read anything + call assert_equal(9, line('$')) + call assert_equal('end of Xxx', getline('$')) + + au BufReadCmd XtestE 0r Xxx|$del + sp XtestE " split window with test.out + call assert_equal('end of Xxx', getline(3)) + + let g:lines = [] + exe "normal 2Goasdf\\\" + au BufWriteCmd XtestE call extend(g:lines, getline(0, '$')) + wall " will write other window to 'lines' + call assert_equal(4, len(g:lines), g:lines) + call assert_equal('asdf', g:lines[2]) + + au! BufReadCmd + au! BufWriteCmd + au! FileReadCmd + au! FileWriteCmd + au! FileAppendCmd + %bwipe! + enew! +endfunc + +func s:ReadFile() + setl noswapfile nomodified + let filename = resolve(expand(":p")) + execute 'read' fnameescape(filename) + 1d_ + exe 'file' fnameescape(filename) + setl buftype=acwrite +endfunc + +func s:WriteFile() + let filename = resolve(expand(":p")) + setl buftype= + noautocmd execute 'write' fnameescape(filename) + setl buftype=acwrite + setl nomodified +endfunc + +func Test_BufReadCmd() + autocmd BufReadCmd *.test call s:ReadFile() + autocmd BufWriteCmd *.test call s:WriteFile() + + call writefile(['one', 'two', 'three'], 'Xcmd.test', 'D') + edit Xcmd.test + set noruler + call assert_match('Xcmd.test" line 1 of 3', execute('file')) + set ruler + call assert_match('Xcmd.test" 3 lines --33%--', execute('file')) + normal! Gofour + write + call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test')) + + bwipe! + au! BufReadCmd + au! BufWriteCmd +endfunc + +func Test_BufWriteCmd() + autocmd BufWriteCmd Xbufwritecmd let g:written = 1 + new + file Xbufwritecmd + set buftype=acwrite + call mkdir('Xbufwritecmd', 'D') + write + " BufWriteCmd should be triggered even if a directory has the same name + call assert_equal(1, g:written) + unlet g:written + au! BufWriteCmd + bwipe! +endfunc + +func SetChangeMarks(start, end) + exe a:start .. 'mark [' + exe a:end .. 'mark ]' +endfunc + +" Verify the effects of autocmds on '[ and '] +func Test_change_mark_in_autocmds() + edit! Xtest + call feedkeys("ia\b\c\d\u\", 'xtn') + + call SetChangeMarks(2, 3) + write + call assert_equal([1, 4], [line("'["), line("']")]) + + call SetChangeMarks(2, 3) + au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")]) + write + au! BufWritePre + + if has('unix') + write XtestFilter + write >> XtestFilter + + call SetChangeMarks(2, 3) + " Marks are set to the entire range of the write + au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")]) + " '[ is adjusted to just before the line that will receive the filtered + " data + au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")]) + " The filtered data is read into the buffer, and the source lines are + " still present, so the range is after the source lines + au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")]) + %!cat XtestFilter + " After the filtered data is read, the original lines are deleted + call assert_equal([1, 8], [line("'["), line("']")]) + au! FilterWritePre,FilterReadPre,FilterReadPost + undo + + call SetChangeMarks(1, 4) + au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")]) + au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")]) + au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")]) + 2,3!cat XtestFilter + call assert_equal([2, 9], [line("'["), line("']")]) + au! FilterWritePre,FilterReadPre,FilterReadPost + undo + + call delete('XtestFilter') + endif + + call SetChangeMarks(1, 4) + au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")]) + 2,3write Xtest2 + au! FileWritePre + + call SetChangeMarks(2, 3) + au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")]) + write >> Xtest2 + au! FileAppendPre + + call SetChangeMarks(1, 4) + au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")]) + 2,3write >> Xtest2 + au! FileAppendPre + + call SetChangeMarks(1, 1) + au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")]) + au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")]) + 3read Xtest2 + au! FileReadPre,FileReadPost + undo + + call SetChangeMarks(4, 4) + " When the line is 0, it's adjusted to 1 + au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")]) + au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")]) + 0read Xtest2 + au! FileReadPre,FileReadPost + undo + + call SetChangeMarks(4, 4) + " When the line is 0, it's adjusted to 1 + au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")]) + au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")]) + 1read Xtest2 + au! FileReadPre,FileReadPost + undo + + bwipe! + call delete('Xtest') + call delete('Xtest2') +endfunc + +func Test_Filter_noshelltemp() + CheckExecutable cat + + enew! + call setline(1, ['a', 'b', 'c', 'd']) + + let shelltemp = &shelltemp + set shelltemp + + let g:filter_au = 0 + au FilterWritePre * let g:filter_au += 1 + au FilterReadPre * let g:filter_au += 1 + au FilterReadPost * let g:filter_au += 1 + %!cat + call assert_equal(3, g:filter_au) + + if has('filterpipe') + set noshelltemp + + let g:filter_au = 0 + au FilterWritePre * let g:filter_au += 1 + au FilterReadPre * let g:filter_au += 1 + au FilterReadPost * let g:filter_au += 1 + %!cat + call assert_equal(0, g:filter_au) + endif + + au! FilterWritePre,FilterReadPre,FilterReadPost + let &shelltemp = shelltemp + bwipe! +endfunc + +func Test_TextYankPost() + enew! + call setline(1, ['foo']) + + let g:event = [] + au TextYankPost * let g:event = copy(v:event) + + call assert_equal({}, v:event) + call assert_fails('let v:event = {}', 'E46:') + call assert_fails('let v:event.mykey = 0', 'E742:') + + norm "ayiw + call assert_equal( + \ #{regcontents: ['foo'], regname: 'a', operator: 'y', + \ regtype: 'v', visual: v:false, inclusive: v:true}, + \ g:event) + norm y_ + call assert_equal( + \ #{regcontents: ['foo'], regname: '', operator: 'y', regtype: 'V', + \ visual: v:false, inclusive: v:false}, + \ g:event) + norm Vy + call assert_equal( + \ #{regcontents: ['foo'], regname: '', operator: 'y', regtype: 'V', + \ visual: v:true, inclusive: v:true}, + \ g:event) + call feedkeys("\y", 'x') + call assert_equal( + \ #{regcontents: ['f'], regname: '', operator: 'y', regtype: "\x161", + \ visual: v:true, inclusive: v:true}, + \ g:event) + norm "xciwbar + call assert_equal( + \ #{regcontents: ['foo'], regname: 'x', operator: 'c', regtype: 'v', + \ visual: v:false, inclusive: v:true}, + \ g:event) + norm "bdiw + call assert_equal( + \ #{regcontents: ['bar'], regname: 'b', operator: 'd', regtype: 'v', + \ visual: v:false, inclusive: v:true}, + \ g:event) + + call setline(1, 'foobar') + " exclusive motion + norm $"ay0 + call assert_equal( + \ #{regcontents: ['fooba'], regname: 'a', operator: 'y', regtype: 'v', + \ visual: v:false, inclusive: v:false}, + \ g:event) + " inclusive motion + norm 0"ay$ + call assert_equal( + \ #{regcontents: ['foobar'], regname: 'a', operator: 'y', regtype: 'v', + \ visual: v:false, inclusive: v:true}, + \ g:event) + + call assert_equal({}, v:event) + + if has('clipboard_working') && !has('gui_running') + " Test that when the visual selection is automatically copied to clipboard + " register a TextYankPost is emitted + call setline(1, ['foobar']) + + let @* = '' + set clipboard=autoselect + exe "norm! ggviw\" + call assert_equal( + \ #{regcontents: ['foobar'], regname: '*', operator: 'y', + \ regtype: 'v', visual: v:true, inclusive: v:false}, + \ g:event) + + let @+ = '' + set clipboard=autoselectplus + exe "norm! ggviw\" + call assert_equal( + \ #{regcontents: ['foobar'], regname: '+', operator: 'y', + \ regtype: 'v', visual: v:true, inclusive: v:false}, + \ g:event) + + set clipboard&mnv + endif + + au! TextYankPost + unlet g:event + bwipe! +endfunc + +func Test_autocommand_all_events() + call assert_fails('au * * bwipe', 'E1155:') + call assert_fails('au * x bwipe', 'E1155:') + call assert_fails('au! * x bwipe', 'E1155:') +endfunc + +func Test_autocmd_user() + au User MyEvent let s:res = [expand(""), expand("")] + doautocmd User MyEvent + call assert_equal(['MyEvent', 'MyEvent'], s:res) + au! User + unlet s:res +endfunc + +func Test_autocmd_user_clear_group() + CheckRunMNVInTerminal + + let lines =<< trim END + autocmd! User + for i in range(1, 999) + exe 'autocmd User ' .. 'Foo' .. i .. ' bar' + endfor + au CmdlineLeave : call timer_start(0, {-> execute('autocmd! User')}) + END + call writefile(lines, 'XautoUser', 'D') + let buf = RunMNVInTerminal('-S XautoUser', {'rows': 10}) + + " this was using freed memory + call term_sendkeys(buf, ":autocmd User\") + call TermWait(buf, 50) + call term_sendkeys(buf, "G") + + call StopMNVInTerminal(buf) +endfunc + +func Test_autocmd_CmdlineLeave_unlet() + CheckRunMNVInTerminal + + let lines =<< trim END + for i in range(1, 999) + exe 'let g:var' .. i '=' i + endfor + au CmdlineLeave : call timer_start(0, {-> execute('unlet g:var990')}) + END + call writefile(lines, 'XleaveUnlet', 'D') + let buf = RunMNVInTerminal('-S XleaveUnlet', {'rows': 10}) + + " this was using freed memory + call term_sendkeys(buf, ":let g:\") + call TermWait(buf, 50) + call term_sendkeys(buf, "G") + call TermWait(buf, 50) + call term_sendkeys(buf, "\") " for the hit-enter prompt + + call StopMNVInTerminal(buf) +endfunc + +function s:Before_test_dirchanged() + augroup test_dirchanged + autocmd! + augroup END + let s:li = [] + let s:dir_this = getcwd() + let s:dir_foo = s:dir_this . '/Xfoo' + call mkdir(s:dir_foo) + let s:dir_bar = s:dir_this . '/Xbar' + call mkdir(s:dir_bar) +endfunc + +function s:After_test_dirchanged() + call chdir(s:dir_this) + call delete(s:dir_foo, 'd') + call delete(s:dir_bar, 'd') + augroup test_dirchanged + autocmd! + augroup END +endfunc + +function Test_dirchanged_global() + call s:Before_test_dirchanged() + autocmd test_dirchanged DirChangedPre global call add(s:li, expand("") .. " pre cd " .. v:event.directory) + autocmd test_dirchanged DirChanged global call add(s:li, "cd:") + autocmd test_dirchanged DirChanged global call add(s:li, expand("")) + call chdir(s:dir_foo) + let expected = ["global pre cd " .. s:dir_foo, "cd:", s:dir_foo] + call assert_equal(expected, s:li) + call chdir(s:dir_foo) + call assert_equal(expected, s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(expected, s:li) + + exe 'cd ' .. s:dir_foo + exe 'cd ' .. s:dir_bar + autocmd! test_dirchanged DirChanged global let g:result = expand("") + cd - + call assert_equal(s:dir_foo, substitute(g:result, '\\', '/', 'g')) + + call s:After_test_dirchanged() +endfunc + +function Test_dirchanged_local() + call s:Before_test_dirchanged() + autocmd test_dirchanged DirChanged window call add(s:li, "lcd:") + autocmd test_dirchanged DirChanged window call add(s:li, expand("")) + call chdir(s:dir_foo) + call assert_equal([], s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(["lcd:", s:dir_bar], s:li) + exe 'lcd ' .. fnameescape(s:dir_bar) + call assert_equal(["lcd:", s:dir_bar], s:li) + call s:After_test_dirchanged() +endfunc + +function Test_dirchanged_auto() + CheckOption autochdir + call s:Before_test_dirchanged() + call test_autochdir() + autocmd test_dirchanged DirChangedPre auto call add(s:li, "pre cd " .. v:event.directory) + autocmd test_dirchanged DirChanged auto call add(s:li, "auto:") + autocmd test_dirchanged DirChanged auto call add(s:li, expand("")) + set acd + cd .. + call assert_equal([], s:li) + exe 'edit ' . s:dir_foo . '/Xautofile' + call assert_equal(s:dir_foo, getcwd()) + let expected = ["pre cd " .. s:dir_foo, "auto:", s:dir_foo] + call assert_equal(expected, s:li) + set noacd + bwipe! + call s:After_test_dirchanged() +endfunc + +" Test TextChangedI and TextChangedP +func Test_ChangedP() + new + call setline(1, ['foo', 'bar', 'foobar']) + call test_override("char_avail", 1) + set complete=. completeopt=menuone + + func! TextChangedAutocmd(char) + let g:autocmd .= a:char + endfunc + + " TextChanged will not be triggered, only check that it isn't. + au! TextChanged :call TextChangedAutocmd('N') + au! TextChangedI :call TextChangedAutocmd('I') + au! TextChangedP :call TextChangedAutocmd('P') + + call cursor(3, 1) + let g:autocmd = '' + call feedkeys("o\", 'tnix') + call assert_equal('I', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf", 'tnix') + call assert_equal('II', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\", 'tnix') + call assert_equal('IIP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\", 'tnix') + call assert_equal('IIPP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\\", 'tnix') + call assert_equal('IIPPP', g:autocmd) + + let g:autocmd = '' + call feedkeys("Sf\\\\", 'tnix') + call assert_equal('IIPPPP', g:autocmd) + + call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$')) + " TODO: how should it handle completeopt=noinsert,noselect? + + " CleanUp + call test_override("char_avail", 0) + au! TextChanged + au! TextChangedI + au! TextChangedP + delfu TextChangedAutocmd + unlet! g:autocmd + set complete&mnv completeopt&mnv + + bw! +endfunc + +let g:setline_handled = v:false +func SetLineOne() + if !g:setline_handled + call setline(1, "(x)") + let g:setline_handled = v:true + endif +endfunc + +func Test_TextChangedI_with_setline() + new + call test_override('char_avail', 1) + autocmd TextChangedI call SetLineOne() + call feedkeys("i(\\", 'tx') + call assert_equal('(', getline(1)) + call assert_equal('x)', getline(2)) + undo + call assert_equal('', getline(1)) + call assert_equal('', getline(2)) + + call test_override('char_avail', 0) + bwipe! +endfunc + +func Test_TextChanged_with_norm() + " For unknown reason this fails on MS-Windows + CheckNotMSWindows + CheckFeature terminal + let buf = term_start([GetMNVProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3}) + call assert_equal('running', term_getstatus(buf)) + call term_sendkeys(buf, ":let g:a=0\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":au! TextChanged * :let g:a+=1\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":norm! ia\") + call term_wait(buf, 50) + call term_sendkeys(buf, ":echo g:a\") + call term_wait(buf, 50) + call WaitForAssert({-> assert_match('^1.*$', term_getline(buf, 3))}) + bwipe! +endfunc + +func Test_Changed_FirstTime() + CheckFeature terminal + CheckNotGui + " Starting a terminal to run MNV is always considered flaky. + let g:test_is_flaky = 1 + + " Prepare file for TextChanged event. + call writefile([''], 'Xchanged.txt', 'D') + let buf = term_start([GetMNVProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3}) + call assert_equal('running', term_getstatus(buf)) + " Wait for the ruler (in the status line) to be shown. + " In ConPTY, there is additional character which is drawn up to the width of + " the screen. + if has('conpty') + call WaitForAssert({-> assert_match('\ assert_match('\ call writefile(['No'], 'Xchanged.txt')\") + call term_sendkeys(buf, "\\:qa!\") + call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) + call assert_equal([''], readfile('Xchanged.txt')) + + " clean up + bwipe! +endfunc + +func Test_autocmd_nested() + let g:did_nested = 0 + defer CleanUpTestAuGroup() + augroup testing + au WinNew * edit somefile + au BufNew * let g:did_nested = 1 + augroup END + split + call assert_equal(0, g:did_nested) + close + bwipe! somefile + + " old nested argument still works + augroup testing + au! + au WinNew * nested edit somefile + au BufNew * let g:did_nested = 1 + augroup END + split + call assert_equal(1, g:did_nested) + close + bwipe! somefile + + " New ++nested argument works + augroup Testing + au! + au WinNew * ++nested edit somefile + au BufNew * let g:did_nested = 1 + augroup END + split + call assert_equal(1, g:did_nested) + close + bwipe! somefile + + " nested without ++ does not work in MNV9 script + call assert_fails('mnv9cmd au WinNew * nested echo fails', 'E1078:') + + augroup Testing + au! + augroup END + + call assert_fails('au WinNew * ++nested ++nested echo bad', 'E983:') + call assert_fails('au WinNew * nested nested echo bad', 'E983:') +endfunc + +func Test_autocmd_nested_cursor_invalid() + set laststatus=0 + copen + cclose + call setline(1, ['foo', 'bar', 'baz']) + 3 + augroup nested_inv + autocmd User foo ++nested copen + autocmd BufAdd * let &laststatus = 2 - &laststatus + augroup END + doautocmd User foo + + augroup nested_inv + au! + augroup END + set laststatus& + cclose + bwipe! +endfunc + +func Test_autocmd_nested_keeps_cursor_pos() + enew + call setline(1, 'foo') + autocmd User foo ++nested normal! $a + autocmd InsertLeave * : + doautocmd User foo + call assert_equal([0, 1, 3, 0], getpos('.')) + + bwipe! +endfunc + +func Test_autocmd_nested_switch_window() + " run this in a separate MNV so that SafeState works + CheckRunMNVInTerminal + CheckScreendump + + let lines =<< trim END + mnv9script + ['()']->writefile('Xautofile') + autocmd MNVEnter * ++nested edit Xautofile | split + autocmd BufReadPost * autocmd SafeState * ++once foldclosed('.') + autocmd WinEnter * matchadd('ErrorMsg', 'pat') + END + call writefile(lines, 'Xautoscript', 'D') + let buf = RunMNVInTerminal('-S Xautoscript', {'rows': 10}) + call VerifyScreenDump(buf, 'Test_autocmd_nested_switch', {}) + + call StopMNVInTerminal(buf) + call delete('Xautofile') +endfunc + +func Test_autocmd_once() + " Without ++once WinNew triggers twice + let g:did_split = 0 + augroup Testing + au WinNew * let g:did_split += 1 + augroup END + split + split + call assert_equal(2, g:did_split) + call assert_true(exists('#WinNew')) + close + close + + " With ++once WinNew triggers once + let g:did_split = 0 + augroup Testing + au! + au WinNew * ++once let g:did_split += 1 + augroup END + split + split + call assert_equal(1, g:did_split) + call assert_false(exists('#WinNew')) + close + close + + call assert_fails('au WinNew * ++once ++once echo bad', 'E983:') +endfunc + +func Test_autocmd_bufreadpre() + new + let b:bufreadpre = 1 + call append(0, range(1000)) + w! XAutocmdBufReadPre.txt + autocmd BufReadPre :let b:bufreadpre += 1 + norm! 500gg + sp + norm! 1000gg + wincmd p + let g:wsv1 = winsaveview() + wincmd p + let g:wsv2 = winsaveview() + " triggers BufReadPre, should not move the cursor in either window + " The topline may change one line in a large window. + edit + call assert_inrange(g:wsv2.topline - 1, g:wsv2.topline + 1, winsaveview().topline) + call assert_equal(g:wsv2.lnum, winsaveview().lnum) + call assert_equal(2, b:bufreadpre) + wincmd p + call assert_equal(g:wsv1.topline, winsaveview().topline) + call assert_equal(g:wsv1.lnum, winsaveview().lnum) + call assert_equal(2, b:bufreadpre) + " Now set the cursor position in an BufReadPre autocommand + " (even though the position will be invalid, this should make MNV reset the + " cursor position in the other window. + wincmd p + set cpo+=g + " won't do anything, but try to set the cursor on an invalid lnum + autocmd BufReadPre :norm! 70gg + " triggers BufReadPre, should not move the cursor in either window + e + call assert_equal(1, winsaveview().topline) + call assert_equal(1, winsaveview().lnum) + call assert_equal(3, b:bufreadpre) + wincmd p + call assert_equal(g:wsv1.topline, winsaveview().topline) + call assert_equal(g:wsv1.lnum, winsaveview().lnum) + call assert_equal(3, b:bufreadpre) + close + close + call delete('XAutocmdBufReadPre.txt') + set cpo-=g +endfunc + +" FileChangedShell tested in test_filechanged.mnv + +" Tests for the following autocommands: +" - FileWritePre writing a compressed file +" - FileReadPost reading a compressed file +" - BufNewFile reading a file template +" - BufReadPre decompressing the file to be read +" - FilterReadPre substituting characters in the temp file +" - FilterReadPost substituting characters after filtering +" - FileReadPre set options for decompression +" - FileReadPost decompress the file +func Test_ReadWrite_Autocmds() + " Run this test only on Unix-like systems and if gzip is available + CheckUnix + CheckExecutable gzip + + " Make $GZIP empty, "-v" would cause trouble. + let $GZIP = "" + + " Use a FileChangedShell autocommand to avoid a prompt for 'Xtestfile.gz' + " being modified outside of MNV (noticed on Solaris). + au FileChangedShell * echo 'caught FileChangedShell' + + " Test for the FileReadPost, FileWritePre and FileWritePost autocmds + augroup Test1 + au! + au FileWritePre *.gz '[,']!gzip + au FileWritePost *.gz undo + au FileReadPost *.gz '[,']!gzip -d + augroup END + + new + set bin + call append(0, [ + \ 'line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 10 Abcdefghijklmnopqrstuvwxyz' + \ ]) + 1,9write! Xtestfile.gz + enew! | close + + new + " Read and decompress the testfile + 0read Xtestfile.gz + call assert_equal([ + \ 'line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 10 Abcdefghijklmnopqrstuvwxyz' + \ ], getline(1, 9)) + enew! | close + + augroup Test1 + au! + augroup END + + " Test for the FileAppendPre and FileAppendPost autocmds + augroup Test2 + au! + au BufNewFile *.c read Xtest.c + au FileAppendPre *.out '[,']s/new/NEW/ + au FileAppendPost *.out !cat Xtest.c >> test.out + augroup END + + call writefile(['/*', ' * Here is a new .c file', ' */'], 'Xtest.c', 'D') + new foo.c " should load Xtest.c + call assert_equal(['/*', ' * Here is a new .c file', ' */'], getline(2, 4)) + w! >> test.out " append it to the output file + + let contents = readfile('test.out') + call assert_equal(' * Here is a NEW .c file', contents[2]) + call assert_equal(' * Here is a new .c file', contents[5]) + + call delete('test.out') + enew! | close + augroup Test2 + au! + augroup END + + " Test for the BufReadPre and BufReadPost autocmds + augroup Test3 + au! + " setup autocommands to decompress before reading and re-compress + " afterwards + au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand("")) + au BufReadPre *.gz call rename(expand(":r"), expand("")) + au BufReadPost *.gz call rename(expand(""), expand(":r")) + au BufReadPost *.gz exe '!gzip ' . shellescape(expand(":r")) + augroup END + + e! Xtestfile.gz " Edit compressed file + call assert_equal([ + \ 'line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 10 Abcdefghijklmnopqrstuvwxyz' + \ ], getline(1, 9)) + + w! >> test.out " Append it to the output file + + augroup Test3 + au! + augroup END + + " Test for the FilterReadPre and FilterReadPost autocmds. + set shelltemp " need temp files here + augroup Test4 + au! + au FilterReadPre *.out call rename(expand(""), expand("") . ".t") + au FilterReadPre *.out exe 'silent !sed s/e/E/ ' . shellescape(expand("")) . ".t >" . shellescape(expand("")) + au FilterReadPre *.out exe 'silent !rm ' . shellescape(expand("")) . '.t' + au FilterReadPost *.out '[,']s/x/X/g + augroup END + + e! test.out " Edit the output file + 1,$!cat + call assert_equal([ + \ 'linE 2 AbcdefghijklmnopqrstuvwXyz', + \ 'linE 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + \ 'linE 4 AbcdefghijklmnopqrstuvwXyz', + \ 'linE 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + \ 'linE 6 AbcdefghijklmnopqrstuvwXyz', + \ 'linE 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + \ 'linE 8 AbcdefghijklmnopqrstuvwXyz', + \ 'linE 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + \ 'linE 10 AbcdefghijklmnopqrstuvwXyz' + \ ], getline(1, 9)) + call assert_equal([ + \ 'line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 10 Abcdefghijklmnopqrstuvwxyz' + \ ], readfile('test.out')) + + augroup Test4 + au! + augroup END + set shelltemp&mnv + + " Test for the FileReadPre and FileReadPost autocmds. + augroup Test5 + au! + au FileReadPre *.gz exe 'silent !gzip -d ' . shellescape(expand("")) + au FileReadPre *.gz call rename(expand(":r"), expand("")) + au FileReadPost *.gz '[,']s/l/L/ + augroup END + + new + 0r Xtestfile.gz " Read compressed file + call assert_equal([ + \ 'Line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'Line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'Line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'Line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'Line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'Line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'Line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'Line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'Line 10 Abcdefghijklmnopqrstuvwxyz' + \ ], getline(1, 9)) + call assert_equal([ + \ 'line 2 Abcdefghijklmnopqrstuvwxyz', + \ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 4 Abcdefghijklmnopqrstuvwxyz', + \ 'line 5 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 6 Abcdefghijklmnopqrstuvwxyz', + \ 'line 7 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 8 Abcdefghijklmnopqrstuvwxyz', + \ 'line 9 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + \ 'line 10 Abcdefghijklmnopqrstuvwxyz' + \ ], readfile('Xtestfile.gz')) + + augroup Test5 + au! + augroup END + + au! FileChangedShell + call delete('Xtestfile.gz') + call delete('test.out') +endfunc + +func Test_throw_in_BufWritePre() + new + call setline(1, ['one', 'two', 'three']) + call assert_false(filereadable('Xthefile')) + augroup throwing + au BufWritePre X* throw 'do not write' + augroup END + try + w Xthefile + catch + let caught = 1 + endtry + call assert_equal(1, caught) + call assert_false(filereadable('Xthefile')) + + bwipe! + au! throwing +endfunc + +func Test_autocmd_in_try_block() + call mkdir('Xintrydir', 'R') + au BufEnter * let g:fname = expand('%') + try + edit Xintrydir/ + endtry + call assert_match('Xintrydir', g:fname) + + unlet g:fname + au! BufEnter +endfunc + +func Test_autocmd_SafeState() + CheckRunMNVInTerminal + + let lines =<< trim END + let g:safe = 0 + let g:again = '' + au SafeState * let g:safe += 1 + au SafeStateAgain * let g:again ..= 'x' + func CallTimer() + call timer_start(10, {id -> execute('let g:again ..= "t"')}) + endfunc + END + call writefile(lines, 'XSafeState', 'D') + let buf = RunMNVInTerminal('-S XSafeState', #{rows: 6}) + + " Sometimes we loop to handle a K_IGNORE, SafeState may be triggered once or + " more often. + call term_sendkeys(buf, ":echo g:safe\") + call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000) + + " SafeStateAgain should be invoked at least three times + call term_sendkeys(buf, ":echo g:again\") + call WaitForAssert({-> assert_match('^xxx', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, ":let g:again = ''\:call CallTimer()\") + call TermWait(buf, 50) + call term_sendkeys(buf, ":\") + call TermWait(buf, 50) + call term_sendkeys(buf, ":echo g:again\") + call WaitForAssert({-> assert_match('xtx', term_getline(buf, 6))}, 1000) + + call StopMNVInTerminal(buf) +endfunc + +func Test_autocmd_CmdWinEnter() + CheckRunMNVInTerminal + + let lines =<< trim END + augroup mnvHints | au! | augroup END + let b:dummy_var = 'This is a dummy' + autocmd CmdWinEnter * quit + let winnr = winnr('$') + END + let filename = 'XCmdWinEnter' + call writefile(lines, filename) + let buf = RunMNVInTerminal('-S '.filename, #{rows: 6}) + + call term_sendkeys(buf, "q:") + call TermWait(buf) + call term_sendkeys(buf, ":echo b:dummy_var\") + call WaitForAssert({-> assert_match('^This is a dummy', term_getline(buf, 6))}, 2000) + call term_sendkeys(buf, ":echo &buftype\") + call WaitForAssert({-> assert_notmatch('^nofile', term_getline(buf, 6))}, 1000) + call term_sendkeys(buf, ":echo winnr\") + call WaitForAssert({-> assert_match('^1', term_getline(buf, 6))}, 1000) + + " clean up + call StopMNVInTerminal(buf) + call delete(filename) +endfunc + +func Test_autocmd_was_using_freed_memory() + CheckFeature quickfix + + pedit xx + n x + augroup winenter + au WinEnter * if winnr('$') > 2 | quit | endif + augroup END + split + + augroup winenter + au! WinEnter + augroup END + + bwipe xx + bwipe x + pclose +endfunc + +func Test_BufWrite_lockmarks() + let g:test_is_flaky = 1 + edit! Xtest + call setline(1, ['a', 'b', 'c', 'd']) + + " :lockmarks preserves the marks + call SetChangeMarks(2, 3) + lockmarks write + call assert_equal([2, 3], [line("'["), line("']")]) + + " *WritePre autocmds get the correct line range, but lockmarks preserves the + " original values for the user + augroup lockmarks + au! + au BufWritePre,FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")]) + au FileWritePre * call assert_equal([3, 4], [line("'["), line("']")]) + augroup END + + lockmarks write + call assert_equal([2, 3], [line("'["), line("']")]) + + if executable('cat') + lockmarks %!cat + call assert_equal([2, 3], [line("'["), line("']")]) + endif + + lockmarks 3,4write Xtest2 + call assert_equal([2, 3], [line("'["), line("']")]) + + au! lockmarks + augroup! lockmarks + call delete('Xtest') + call delete('Xtest2') +endfunc + +func Test_FileType_spell() + if !isdirectory('/tmp') + throw "Skipped: requires /tmp directory" + endif + + " this was crashing with an invalid free() + setglobal spellfile=/tmp/en.utf-8.add + augroup crash + autocmd! + autocmd BufNewFile,BufReadPost crashfile setf somefiletype + autocmd BufNewFile,BufReadPost crashfile set ft=anotherfiletype + autocmd FileType anotherfiletype setlocal spell + augroup END + func! NoCrash() abort + edit /tmp/crashfile + endfunc + call NoCrash() + + au! crash + setglobal spellfile= +endfunc + +" this was wiping out the current buffer and using freed memory +func Test_SpellFileMissing_bwipe() + next 0 + au SpellFileMissing 0 bwipe + call assert_fails('set spell spelllang=0', 'E937:') + + au! SpellFileMissing + set nospell spelllang=en + bwipe +endfunc + +" Test closing a window or editing another buffer from a FileChangedRO handler +" in a readonly buffer +func Test_FileChangedRO_winclose() + call test_override('ui_delay', 10) + + augroup FileChangedROTest + au! + autocmd FileChangedRO * quit + augroup END + new + set readonly + call assert_fails('normal i', 'E788:') + close + augroup! FileChangedROTest + + augroup FileChangedROTest + au! + autocmd FileChangedRO * edit Xrofile + augroup END + new + set readonly + call assert_fails('normal i', 'E788:') + close + augroup! FileChangedROTest + call test_override('ALL', 0) +endfunc + +func LogACmd() + call add(g:logged, line('$')) +endfunc + +func Test_TermChanged() + CheckNotGui + + enew! + tabnew + call setline(1, ['a', 'b', 'c', 'd']) + $ + au TermChanged * call LogACmd() + let g:logged = [] + let term_save = &term + set term=xterm + call assert_equal([1, 4], g:logged) + + au! TermChanged + let &term = term_save + bwipe! +endfunc + +" Test for FileReadCmd autocmd +func Test_autocmd_FileReadCmd() + func ReadFileCmd() + call append(line('$'), "v:cmdarg = " .. v:cmdarg) + endfunc + augroup FileReadCmdTest + au! + au FileReadCmd Xtest call ReadFileCmd() + augroup END + + new + read ++bin Xtest + read ++nobin Xtest + read ++edit Xtest + read ++bad=keep Xtest + read ++bad=drop Xtest + read ++bad=- Xtest + read ++ff=unix Xtest + read ++ff=dos Xtest + read ++ff=mac Xtest + read ++enc=utf-8 Xtest + + call assert_equal(['', + \ 'v:cmdarg = ++bin', + \ 'v:cmdarg = ++nobin', + \ 'v:cmdarg = ++edit', + \ 'v:cmdarg = ++bad=keep', + \ 'v:cmdarg = ++bad=drop', + \ 'v:cmdarg = ++bad=-', + \ 'v:cmdarg = ++ff=unix', + \ 'v:cmdarg = ++ff=dos', + \ 'v:cmdarg = ++ff=mac', + \ 'v:cmdarg = ++enc=utf-8'], getline(1, '$')) + + bwipe! + augroup FileReadCmdTest + au! + augroup END + delfunc ReadFileCmd +endfunc + +" Test for passing invalid arguments to autocmd +func Test_autocmd_invalid_args() + " Additional character after * for event + call assert_fails('autocmd *a Xinvfile set ff=unix', 'E215:') + augroup Test + augroup END + " Invalid autocmd event + call assert_fails('autocmd Bufabc Xinvfile set ft=mnv', 'E216:') + " Invalid autocmd event in a autocmd group + call assert_fails('autocmd Test Bufabc Xinvfile set ft=mnv', 'E216:') + augroup! Test + " Execute all autocmds + call assert_fails('doautocmd * BufEnter', 'E217:') + call assert_fails('augroup! x1a2b3', 'E367:') + call assert_fails('autocmd BufNew pwd', 'E680:') + call assert_fails('autocmd BufNew \) set ff=unix', 'E55:') +endfunc + +" Test for deep nesting of autocmds +func Test_autocmd_deep_nesting() + autocmd BufEnter Xdeepfile doautocmd BufEnter Xdeepfile + call assert_fails('doautocmd BufEnter Xdeepfile', 'E218:') + autocmd! BufEnter Xdeepfile +endfunc + +" Tests for SigUSR1 autocmd event, which is only available on posix systems. +func Test_autocmd_sigusr1() + CheckUnix + " FIXME: should this work on MacOS M1? + CheckNotMacM1 + CheckExecutable /bin/kill + + let g:sigusr1_passed = 0 + au SigUSR1 * let g:sigusr1_passed = 1 + call system('/bin/kill -s usr1 ' . getpid()) + call WaitForAssert({-> assert_true(g:sigusr1_passed)}) + + au! SigUSR1 + unlet g:sigusr1_passed +endfunc + +" Test for BufReadPre autocmd deleting the file +func Test_BufReadPre_delfile() + augroup TestAuCmd + au! + autocmd BufReadPre XbufreadPre call delete('XbufreadPre') + augroup END + call writefile([], 'XbufreadPre', 'D') + call assert_fails('new XbufreadPre', 'E200:') + call assert_equal('XbufreadPre', @%) + call assert_equal(1, &readonly) + + augroup TestAuCmd + au! + augroup END + close! +endfunc + +" Test for BufReadPre autocmd changing the current buffer +func Test_BufReadPre_changebuf() + augroup TestAuCmd + au! + autocmd BufReadPre Xchangebuf edit Xsomeotherfile + augroup END + call writefile([], 'Xchangebuf', 'D') + call assert_fails('new Xchangebuf', 'E201:') + call assert_equal('Xsomeotherfile', @%) + call assert_equal(1, &readonly) + + augroup TestAuCmd + au! + augroup END + close! +endfunc + +" Test for BufWipeout autocmd changing the current buffer when reading a file +" in an empty buffer with 'f' flag in 'cpo' +func Test_BufDelete_changebuf() + new + augroup TestAuCmd + au! + autocmd BufWipeout * let bufnr = bufadd('somefile') | exe "b " .. bufnr + augroup END + let save_cpo = &cpo + set cpo+=f + call assert_fails('r Xchangebuf', ['E812:', 'E484:']) + call assert_equal('somefile', @%) + let &cpo = save_cpo + augroup TestAuCmd + au! + augroup END + close! +endfunc + +" Test for the temporary internal window used to execute autocmds +func Test_autocmd_window() + %bw! + edit one.txt + tabnew two.txt + vnew three.txt + tabnew four.txt + tabprevious + let g:blist = [] + augroup aucmd_win_test1 + au! + au BufEnter * call add(g:blist, [expand(''), + \ win_gettype(bufwinnr(expand('')))]) + augroup END + + doautoall BufEnter + call assert_equal([ + \ ['one.txt', 'autocmd'], + \ ['two.txt', ''], + \ ['four.txt', 'autocmd'], + \ ['three.txt', ''], + \ ], g:blist) + + augroup aucmd_win_test1 + au! + augroup END + augroup! aucmd_win_test1 + %bw! +endfunc + +" Test for trying to close the temporary window used for executing an autocmd +func Test_close_autocmd_window() + %bw! + edit one.txt + tabnew two.txt + augroup aucmd_win_test2 + au! + au BufEnter * if expand('') == 'one.txt' | 1close | endif + augroup END + + call assert_fails('doautoall BufEnter', 'E813:') + + augroup aucmd_win_test2 + au! + augroup END + augroup! aucmd_win_test2 + %bwipe! +endfunc + +" Test for trying to close the tab that has the temporary window for exeucing +" an autocmd. +func Test_close_autocmd_tab() + edit one.txt + tabnew two.txt + augroup aucmd_win_test + au! + au BufEnter * if expand('') == 'one.txt' | tabfirst | tabonly | endif + augroup END + + call assert_fails('doautoall BufEnter', 'E813:') + + tabonly + augroup aucmd_win_test + au! + augroup END + augroup! aucmd_win_test + %bwipe! +endfunc + +func Test_Visual_doautoall_redraw() + call setline(1, ['a', 'b']) + new + wincmd p + call feedkeys("G\", 'txn') + autocmd User Explode ++once redraw + doautoall User Explode + %bwipe! +endfunc + +func Test_get_Visual_selection_in_curbuf_autocmd() + call test_override('starting', 1) + new + autocmd OptionSet list let b:text = getregion(getpos('.'), getpos('v')) + call setline(1, 'foo bar baz') + + normal! gg0fbvtb + setlocal list + call assert_equal(['bar '], b:text) + exe "normal! \" + + normal! v0 + call setbufvar('%', '&list', v:false) + call assert_equal(['foo bar '], b:text) + exe "normal! \" + + autocmd! OptionSet list + bwipe! + call test_override('starting', 0) +endfunc + +" This was using freed memory. +func Test_BufNew_arglocal() + arglocal + au BufNew * arglocal + call assert_fails('drop xx', 'E1156:') + + au! BufNew +endfunc + +func Test_autocmd_closes_window() + au BufNew,BufWinLeave * e %e + file yyy + au BufNew,BufWinLeave * ball + n xxx + + %bwipe + au! BufNew + au! BufWinLeave +endfunc + +func Test_autocmd_quit_psearch() + sn aa bb + augroup aucmd_win_test + au! + au BufEnter,BufLeave,BufNew,WinEnter,WinLeave,WinNew * if winnr('$') > 1 | q | endif + augroup END + ps / + + augroup aucmd_win_test + au! + augroup END + new + pclose +endfunc + +" Fuzzer found some strange combination that caused a crash. +func Test_autocmd_normal_mess() + " For unknown reason this hangs on MS-Windows + CheckNotMSWindows + + augroup aucmd_normal_test + au BufLeave,BufWinLeave,BufHidden,BufUnload,BufDelete,BufWipeout * norm 7q/qc + augroup END + call assert_fails('o4', 'E1159:') + silent! H + call assert_fails('e xx', 'E1159:') + normal G + + augroup aucmd_normal_test + au! + augroup END +endfunc + +func Test_autocmd_closing_cmdwin() + " For unknown reason this hangs on MS-Windows + CheckNotMSWindows + + au BufWinLeave * nested q + call assert_fails("norm 7q?\n", 'E855:') + + au! BufWinLeave + new + only +endfunc + +func Test_autocmd_mnvgrep() + augroup aucmd_mnvgrep + au QuickfixCmdPre,BufNew,BufReadCmd * sb + au QuickfixCmdPre,BufNew,BufReadCmd * q9 + augroup END + call assert_fails('lv ?a? foo', 'E926:') + + augroup aucmd_mnvgrep + au! + augroup END +endfunc + +func Test_autocmd_with_block() + augroup block_testing + au BufReadPost *.xml { + setlocal matchpairs+=<:> + /^@ / call win_gotoid(g:window_id) + tabprevious + +tabclose + + unlet g:window_id + au! BufWipeout + %bwipe! +endfunc + +func Test_autocmd_prevent_buf_wipe() + " Xa must be the first buffer so that win_close_othertab() puts it in + " another window, which causes wiping the buffer to fail. + %bwipe! + + file Xa + call setline(1, 'foo') + setlocal bufhidden=wipe + tabnew Xb + setlocal bufhidden=wipe + autocmd BufUnload Xa ++once ++nested tabonly + autocmd BufWinLeave Xb ++once tabnext + tabfirst + + edit! Xc + call assert_equal('Xc', bufname('%')) + tabnext + call assert_equal('Xa', bufname('%')) + call assert_equal("\n\"Xa\" --No lines in buffer--", execute('file')) + + %bwipe! +endfunc + +func Test_v_event_readonly() + autocmd CompleteChanged * let v:event.width = 0 + call assert_fails("normal! i\\", 'E46:') + au! CompleteChanged + + autocmd DirChangedPre * let v:event.directory = '' + call assert_fails('cd .', 'E46:') + au! DirChangedPre + + autocmd ModeChanged * let v:event.new_mode = '' + call assert_fails('normal! cc', 'E46:') + au! ModeChanged + + autocmd TextYankPost * let v:event.operator = '' + call assert_fails('normal! yy', 'E46:') + au! TextYankPost +endfunc + +" Test for ModeChanged pattern +func Test_mode_changes() + let g:index = 0 + let g:mode_seq = ['n', 'i', 'n', 'v', 'V', 'i', 'ix', 'i', 'ic', 'i', 'n', 'no', 'noV', 'n', 'V', 'v', 's', 'n'] + func! TestMode() + call assert_equal(g:mode_seq[g:index], get(v:event, "old_mode")) + call assert_equal(g:mode_seq[g:index + 1], get(v:event, "new_mode")) + call assert_equal(mode(1), get(v:event, "new_mode")) + let g:index += 1 + endfunc + + au ModeChanged * :call TestMode() + let g:n_to_any = 0 + au ModeChanged n:* let g:n_to_any += 1 + call feedkeys("i\vVca\\\\ggdV\G", 'tnix') + + let g:V_to_v = 0 + au ModeChanged V:v let g:V_to_v += 1 + call feedkeys("Vv\\", 'tnix') + call assert_equal(len(filter(g:mode_seq[1:], {idx, val -> val == 'n'})), g:n_to_any) + call assert_equal(1, g:V_to_v) + call assert_equal(len(g:mode_seq) - 1, g:index) + + let g:n_to_i = 0 + au ModeChanged n:i let g:n_to_i += 1 + let g:n_to_niI = 0 + au ModeChanged i:niI let g:n_to_niI += 1 + let g:niI_to_i = 0 + au ModeChanged niI:i let g:niI_to_i += 1 + let g:nany_to_i = 0 + au ModeChanged n*:i let g:nany_to_i += 1 + let g:i_to_n = 0 + au ModeChanged i:n let g:i_to_n += 1 + let g:nori_to_any = 0 + au ModeChanged [ni]:* let g:nori_to_any += 1 + let g:i_to_any = 0 + au ModeChanged i:* let g:i_to_any += 1 + let g:index = 0 + let g:mode_seq = ['n', 'i', 'niI', 'i', 'n'] + call feedkeys("a\l\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + call assert_equal(1, g:n_to_i) + call assert_equal(1, g:n_to_niI) + call assert_equal(1, g:niI_to_i) + call assert_equal(2, g:nany_to_i) + call assert_equal(1, g:i_to_n) + call assert_equal(2, g:i_to_any) + call assert_equal(3, g:nori_to_any) + + if has('terminal') + let g:mode_seq += ['c', 'n', 't', 'nt', 'c', 'nt', 'n'] + call feedkeys(":term\\N:bd!\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + call assert_equal(1, g:n_to_i) + call assert_equal(1, g:n_to_niI) + call assert_equal(1, g:niI_to_i) + call assert_equal(2, g:nany_to_i) + call assert_equal(1, g:i_to_n) + call assert_equal(2, g:i_to_any) + call assert_equal(5, g:nori_to_any) + endif + + let g:n_to_c = 0 + au ModeChanged n:c let g:n_to_c += 1 + let g:c_to_n = 0 + au ModeChanged c:n let g:c_to_n += 1 + let g:mode_seq += ['c', 'n', 'c', 'n'] + call feedkeys("q:\\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + call assert_equal(2, g:n_to_c) + call assert_equal(2, g:c_to_n) + + let g:n_to_v = 0 + au ModeChanged n:v let g:n_to_v += 1 + let g:v_to_n = 0 + au ModeChanged v:n let g:v_to_n += 1 + let g:mode_seq += ['v', 'n'] + call feedkeys("v\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + call assert_equal(1, g:n_to_v) + call assert_equal(1, g:v_to_n) + + let g:mode_seq += ['c', 'cr', 'c', 'cr', 'n'] + call feedkeys(":\\\\", 'tnix') + call assert_equal(len(g:mode_seq) - 1, g:index) + + au! ModeChanged + delfunc TestMode + unlet! g:mode_seq + unlet! g:index + unlet! g:n_to_any + unlet! g:V_to_v + unlet! g:n_to_i + unlet! g:n_to_niI + unlet! g:niI_to_i + unlet! g:nany_to_i + unlet! g:i_to_n + unlet! g:nori_to_any + unlet! g:i_to_any + unlet! g:n_to_c + unlet! g:c_to_n + unlet! g:n_to_v + unlet! g:v_to_n +endfunc + +func Test_recursive_ModeChanged() + au! ModeChanged * norm 0u + sil! norm  + au! ModeChanged +endfunc + +func Test_ModeChanged_starts_visual() + " This was triggering ModeChanged before setting VIsual, causing a crash. + au! ModeChanged * norm 0u + sil! norm  + + au! ModeChanged +endfunc + +func Test_noname_autocmd() + augroup test_noname_autocmd_group + autocmd! + autocmd BufEnter * call add(s:li, ["BufEnter", expand("")]) + autocmd BufDelete * call add(s:li, ["BufDelete", expand("")]) + autocmd BufLeave * call add(s:li, ["BufLeave", expand("")]) + autocmd BufUnload * call add(s:li, ["BufUnload", expand("")]) + autocmd BufWipeout * call add(s:li, ["BufWipeout", expand("")]) + augroup END + + let s:li = [] + edit foo + call assert_equal([['BufUnload', ''], ['BufDelete', ''], ['BufWipeout', ''], ['BufEnter', 'foo']], s:li) + + au! test_noname_autocmd_group + augroup! test_noname_autocmd_group +endfunc + +" Test for the autocmd_get() function +func Test_autocmd_get() + augroup TestAutoCmdFns + au! + autocmd BufAdd *.mnv echo "bufadd-mnv" + autocmd BufAdd *.py echo "bufadd-py" + autocmd BufHidden *.mnv echo "bufhidden" + augroup END + augroup TestAutoCmdFns2 + autocmd BufAdd *.mnv echo "bufadd-mnv-2" + autocmd BufRead *.a1b2c3 echo "bufadd-mnv-2" + augroup END + + let l = autocmd_get() + call assert_true(l->len() > 0) + + " Test for getting all the autocmds in a group + let expected = [ + \ #{cmd: 'echo "bufadd-mnv"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, once: v:false, + \ event: 'BufAdd'}, + \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns', + \ pattern: '*.py', nested: v:false, once: v:false, + \ event: 'BufAdd'}, + \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, + \ once: v:false, event: 'BufHidden'}] + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'})) + + " Test for getting autocmds for all the patterns in a group + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns', + \ event: '*'})) + + " Test for getting autocmds for an event in a group + let expected = [ + \ #{cmd: 'echo "bufadd-mnv"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, once: v:false, + \ event: 'BufAdd'}, + \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns', + \ pattern: '*.py', nested: v:false, once: v:false, + \ event: 'BufAdd'}] + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns', + \ event: 'BufAdd'})) + + " Test for getting the autocmds for all the events in a group for particular + " pattern + call assert_equal([{'cmd': 'echo "bufadd-py"', 'group': 'TestAutoCmdFns', + \ 'pattern': '*.py', 'nested': v:false, 'once': v:false, + \ 'event': 'BufAdd'}], + \ autocmd_get(#{group: 'TestAutoCmdFns', event: '*', pattern: '*.py'})) + + " Test for getting the autocmds for an events in a group for particular + " pattern + let l = autocmd_get(#{group: 'TestAutoCmdFns', event: 'BufAdd', + \ pattern: '*.mnv'}) + call assert_equal([ + \ #{cmd: 'echo "bufadd-mnv"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, once: v:false, + \ event: 'BufAdd'}], l) + + " Test for getting the autocmds for a pattern in a group + let l = autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.mnv'}) + call assert_equal([ + \ #{cmd: 'echo "bufadd-mnv"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, once: v:false, + \ event: 'BufAdd'}, + \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, + \ once: v:false, event: 'BufHidden'}], l) + + " Test for getting the autocmds for a pattern in all the groups + let l = autocmd_get(#{pattern: '*.a1b2c3'}) + call assert_equal([{'cmd': 'echo "bufadd-mnv-2"', 'group': 'TestAutoCmdFns2', + \ 'pattern': '*.a1b2c3', 'nested': v:false, 'once': v:false, + \ 'event': 'BufRead'}], l) + + " Test for getting autocmds for a pattern without any autocmds + call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns', + \ pattern: '*.abc'})) + call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns', + \ event: 'BufAdd', pattern: '*.abc'})) + call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns', + \ event: 'BufWipeout'})) + + " Test for getting autocmds after removing one inside an autocmd + func CheckAutocmdGet() + augroup TestAutoCmdFns + autocmd! BufAdd *.mnv + augroup END + + let expected = [ + \ #{cmd: 'echo "bufadd-py"', group: 'TestAutoCmdFns', + \ pattern: '*.py', nested: v:false, once: v:false, + \ event: 'BufAdd'}, + \ #{cmd: 'echo "bufhidden"', group: 'TestAutoCmdFns', + \ pattern: '*.mnv', nested: v:false, + \ once: v:false, event: 'BufHidden'}] + + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'})) + call assert_equal([expected[0]], + \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.py'})) + call assert_equal([expected[1]], + \ autocmd_get(#{group: 'TestAutoCmdFns', pattern: '*.mnv'})) + endfunc + + autocmd User Xauget call CheckAutocmdGet() + doautocmd User Xauget + autocmd! User Xauget + + call assert_fails("call autocmd_get(#{group: 'abc', event: 'BufAdd'})", + \ 'E367:') + let cmd = "echo autocmd_get(#{group: 'TestAutoCmdFns', event: 'abc'})" + call assert_fails(cmd, 'E216:') + call assert_fails("call autocmd_get(#{group: 'abc'})", 'E367:') + call assert_fails("echo autocmd_get(#{event: 'abc'})", 'E216:') + + augroup TestAutoCmdFns + au! + augroup END + call assert_equal([], autocmd_get(#{group: 'TestAutoCmdFns'})) + + " Test for nested and once autocmds + augroup TestAutoCmdFns + au! + autocmd MNVSuspend * ++nested echo "suspend" + autocmd MNVResume * ++once echo "resume" + augroup END + + let expected = [ + \ {'cmd': 'echo "resume"', 'group': 'TestAutoCmdFns', 'pattern': '*', + \ 'nested': v:false, 'once': v:true, 'event': 'MNVResume'}, + \ {'cmd': 'echo "suspend"', 'group': 'TestAutoCmdFns', 'pattern': '*', + \ 'nested': v:true, 'once': v:false, 'event': 'MNVSuspend'}] + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'})) + + " Test for buffer-local autocmd + augroup TestAutoCmdFns + au! + autocmd TextYankPost echo "textyankpost" + augroup END + + let expected = [ + \ {'cmd': 'echo "textyankpost"', 'group': 'TestAutoCmdFns', + \ 'pattern': '', 'nested': v:false, + \ 'once': v:false, 'bufnr': bufnr(), 'event': 'TextYankPost'}] + call assert_equal(expected, autocmd_get(#{group: 'TestAutoCmdFns'})) + + augroup TestAutoCmdFns + au! + augroup END + augroup! TestAutoCmdFns + augroup TestAutoCmdFns2 + au! + augroup END + augroup! TestAutoCmdFns2 + + call assert_fails("echo autocmd_get(#{group: []})", 'E730:') + call assert_fails("echo autocmd_get(#{event: {}})", 'E731:') + call assert_fails("echo autocmd_get([])", 'E1206:') +endfunc + +" Test for the autocmd_add() function +func Test_autocmd_add() + " Define a single autocmd in a group + call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pattern: '*.sh', + \ cmd: 'echo "bufadd"', once: v:true, nested: v:true}]) + call assert_equal([#{cmd: 'echo "bufadd"', group: 'TestAcSet', + \ pattern: '*.sh', nested: v:true, once: v:true, + \ event: 'BufAdd'}], autocmd_get(#{group: 'TestAcSet'})) + + " Define two autocmds in the same group + call autocmd_delete([#{group: 'TestAcSet'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pattern: '*.sh', + \ cmd: 'echo "bufadd"'}, + \ #{group: 'TestAcSet', event: 'BufEnter', pattern: '*.sh', + \ cmd: 'echo "bufenter"'}]) + call assert_equal([ + \ #{cmd: 'echo "bufadd"', group: 'TestAcSet', pattern: '*.sh', + \ nested: v:false, once: v:false, event: 'BufAdd'}, + \ #{cmd: 'echo "bufenter"', group: 'TestAcSet', pattern: '*.sh', + \ nested: v:false, once: v:false, event: 'BufEnter'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " Define a buffer-local autocmd + call autocmd_delete([#{group: 'TestAcSet'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'CursorHold', + \ bufnr: bufnr(), cmd: 'echo "cursorhold"'}]) + call assert_equal([ + \ #{cmd: 'echo "cursorhold"', group: 'TestAcSet', + \ pattern: '', nested: v:false, + \ once: v:false, bufnr: bufnr(), event: 'CursorHold'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " Use an invalid buffer number + call autocmd_delete([#{group: 'TestAcSet'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufEnter', + \ bufnr: -1, cmd: 'echo "bufenter"'}]) + let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999, + \ cmd: 'echo "bufadd"'}] + call assert_fails("echo autocmd_add(l)", 'E680:') + let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999, + \ pattern: '*.py', cmd: 'echo "bufadd"'}] + call assert_fails("echo autocmd_add(l)", 'E680:') + let l = [#{group: 'TestAcSet', event: 'BufAdd', bufnr: 9999, + \ pattern: ['*.py', '*.c'], cmd: 'echo "bufadd"'}] + call assert_fails("echo autocmd_add(l)", 'E680:') + let l = [#{group: 'TestAcSet', event: 'BufRead', bufnr: [], + \ cmd: 'echo "bufread"'}] + call assert_fails("echo autocmd_add(l)", 'E745:') + call assert_equal([], autocmd_get(#{group: 'TestAcSet'})) + + " Add two commands to the same group, event and pattern + call autocmd_delete([#{group: 'TestAcSet'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufUnload', + \ pattern: 'abc', cmd: 'echo "cmd1"'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufUnload', + \ pattern: 'abc', cmd: 'echo "cmd2"'}]) + call assert_equal([ + \ #{cmd: 'echo "cmd1"', group: 'TestAcSet', pattern: 'abc', + \ nested: v:false, once: v:false, event: 'BufUnload'}, + \ #{cmd: 'echo "cmd2"', group: 'TestAcSet', pattern: 'abc', + \ nested: v:false, once: v:false, event: 'BufUnload'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " When adding a new autocmd, if the autocmd 'group' is not specified, then + " the current autocmd group should be used. + call autocmd_delete([#{group: 'TestAcSet'}]) + augroup TestAcSet + call autocmd_add([#{event: 'BufHidden', pattern: 'abc', cmd: 'echo "abc"'}]) + augroup END + call assert_equal([ + \ #{cmd: 'echo "abc"', group: 'TestAcSet', pattern: 'abc', + \ nested: v:false, once: v:false, event: 'BufHidden'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " Test for replacing a cmd for an event in a group + call autocmd_delete([#{group: 'TestAcSet'}]) + call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter', + \ pattern: '*.py', cmd: 'echo "bufenter"'}]) + call autocmd_add([#{replace: v:true, group: 'TestAcSet', event: 'BufEnter', + \ pattern: '*.py', cmd: 'echo "bufenter"'}]) + call assert_equal([ + \ #{cmd: 'echo "bufenter"', group: 'TestAcSet', pattern: '*.py', + \ nested: v:false, once: v:false, event: 'BufEnter'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " Test for adding a command for an unsupported autocmd event + let l = [#{group: 'TestAcSet', event: 'abc', pattern: '*.sh', + \ cmd: 'echo "bufadd"'}] + call assert_fails('call autocmd_add(l)', 'E216:') + + " Test for using a list of events and patterns + call autocmd_delete([#{group: 'TestAcSet'}]) + let l = [#{group: 'TestAcSet', event: ['BufEnter', 'BufLeave'], + \ pattern: ['*.py', '*.sh'], cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + call assert_equal([ + \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.py', + \ nested: v:false, once: v:false, event: 'BufEnter'}, + \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.sh', + \ nested: v:false, once: v:false, event: 'BufEnter'}, + \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.py', + \ nested: v:false, once: v:false, event: 'BufLeave'}, + \ #{cmd: 'echo "bufcmds"', group: 'TestAcSet', pattern: '*.sh', + \ nested: v:false, once: v:false, event: 'BufLeave'}], + \ autocmd_get(#{group: 'TestAcSet'})) + + " Test for invalid values for 'event' item + call autocmd_delete([#{group: 'TestAcSet'}]) + let l = [#{group: 'TestAcSet', event: test_null_string(), + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: test_null_list(), + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E714:') + let l = [#{group: 'TestAcSet', event: {}, + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E777:') + let l = [#{group: 'TestAcSet', event: [{}], + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: [test_null_string()], + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: 'BufEnter,BufLeave', + \ pattern: '*.py', cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E216:') + let l = [#{group: 'TestAcSet', event: [], + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + let l = [#{group: 'TestAcSet', event: [""], + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E216:') + let l = [#{group: 'TestAcSet', event: "", + \ pattern: "*.py", cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + call assert_equal([], autocmd_get(#{group: 'TestAcSet'})) + + " Test for invalid values for 'pattern' item + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: test_null_string(), cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: test_null_list(), cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E714:') + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: {}, cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E777:') + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: [{}], cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: [test_null_string()], cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E928:') + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: [], cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: [""], cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + let l = [#{group: 'TestAcSet', event: "BufEnter", + \ pattern: "", cmd: 'echo "bufcmds"'}] + call autocmd_add(l) + call assert_equal([], autocmd_get(#{group: 'TestAcSet'})) + + let l = [#{group: 'TestAcSet', event: 'BufEnter,abc,BufLeave', + \ pattern: '*.py', cmd: 'echo "bufcmds"'}] + call assert_fails('call autocmd_add(l)', 'E216:') + + call assert_fails("call autocmd_add({})", 'E1211:') + call assert_equal(v:false, autocmd_add(test_null_list())) + call assert_true(autocmd_add([[]])) + call assert_true(autocmd_add([test_null_dict()])) + + augroup TestAcSet + au! + augroup END + + call autocmd_add([#{group: 'TestAcSet'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd'}]) + call autocmd_add([#{group: 'TestAcSet', pat: '*.sh'}]) + call autocmd_add([#{group: 'TestAcSet', cmd: 'echo "a"'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', pat: '*.sh'}]) + call autocmd_add([#{group: 'TestAcSet', event: 'BufAdd', cmd: 'echo "a"'}]) + call autocmd_add([#{group: 'TestAcSet', pat: '*.sh', cmd: 'echo "a"'}]) + call assert_equal([], autocmd_get(#{group: 'TestAcSet'})) + + augroup! TestAcSet +endfunc + +" Test for deleting autocmd events and groups +func Test_autocmd_delete() + " Delete an event in an autocmd group + augroup TestAcSet + au! + au BufAdd *.sh echo "bufadd" + au BufEnter *.sh echo "bufenter" + augroup END + call autocmd_delete([#{group: 'TestAcSet', event: 'BufAdd'}]) + call assert_equal([#{cmd: 'echo "bufenter"', group: 'TestAcSet', + \ pattern: '*.sh', nested: v:false, once: v:false, + \ event: 'BufEnter'}], autocmd_get(#{group: 'TestAcSet'})) + + " Delete all the events in an autocmd group + augroup TestAcSet + au BufAdd *.sh echo "bufadd" + augroup END + call autocmd_delete([#{group: 'TestAcSet', event: '*'}]) + call assert_equal([], autocmd_get(#{group: 'TestAcSet'})) + + " Delete a non-existing autocmd group + call assert_fails("call autocmd_delete([#{group: 'abc'}])", 'E367:') + " Delete a non-existing autocmd event + let l = [#{group: 'TestAcSet', event: 'abc'}] + call assert_fails("call autocmd_delete(l)", 'E216:') + " Delete a non-existing autocmd pattern + let l = [#{group: 'TestAcSet', event: 'BufAdd', pat: 'abc'}] + call assert_true(autocmd_delete(l)) + " Delete an autocmd for a non-existing buffer + let l = [#{event: '*', bufnr: 9999, cmd: 'echo "x"'}] + call assert_fails('call autocmd_delete(l)', 'E680:') + + " Delete an autocmd group + augroup TestAcSet + au! + au BufAdd *.sh echo "bufadd" + au BufEnter *.sh echo "bufenter" + augroup END + call autocmd_delete([#{group: 'TestAcSet'}]) + call assert_fails("call autocmd_get(#{group: 'TestAcSet'})", 'E367:') + + call assert_true(autocmd_delete([[]])) + call assert_true(autocmd_delete([test_null_dict()])) +endfunc + +func Test_autocmd_split_dummy() + " Autocommand trying to split a window containing a dummy buffer. + auto BufReadPre * exe "sbuf " .. expand("") + " Avoid the "W11" prompt + au FileChangedShell * let v:fcs_choice = 'reload' + func Xautocmd_changelist() + cal writefile(['Xtestfile2:4:4'], 'Xerr') + edit Xerr + lex 'Xtestfile2:4:4' + endfunc + call Xautocmd_changelist() + " Should get E86, but it doesn't always happen (timing?) + silent! call Xautocmd_changelist() + + au! BufReadPre + au! FileChangedShell + delfunc Xautocmd_changelist + bwipe! Xerr + call delete('Xerr') +endfunc + +" This was crashing because there was only one window to execute autocommands +" in. +func Test_autocmd_nested_setbufvar() + CheckFeature python3 + + set hidden + edit Xaaa + edit Xbbb + call setline(1, 'bar') + enew + au BufWriteCmd Xbbb ++nested call setbufvar('Xaaa', '&ft', 'foo') | bw! Xaaa + au FileType foo call py3eval('mnv.current.buffer.options["cindent"]') + wall + + au! BufWriteCmd + au! FileType foo + set nohidden + call delete('Xaaa') + call delete('Xbbb') + %bwipe! +endfunc + +func SetupMNVTest_shm() + let g:bwe = [] + let g:brp = [] + set shortmess+=F + messages clear + + let dirname='XMNVTestSHM' + call mkdir(dirname, 'R') + call writefile(['test'], dirname .. '/1') + call writefile(['test'], dirname .. '/2') + call writefile(['test'], dirname .. '/3') + + augroup test + autocmd! + autocmd BufWinEnter * call add(g:bwe, $'BufWinEnter: {expand('')}') + autocmd BufReadPost * call add(g:brp, $'BufReadPost: {expand('')}') + augroup END + + call setqflist([ + \ {'filename': dirname .. '/1', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0}, + \ {'filename': dirname .. '/2', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0}, + \ {'filename': dirname .. '/3', 'lnum': 1, 'col': 1, 'text': 'test', 'vcol': 0} + \ ]) + cdo! substitute/test/TEST + + " clean up + noa enew! + set shortmess&mnv + augroup test + autocmd! + augroup END + augroup! test +endfunc + +func Test_autocmd_shortmess() + CheckNotMSWindows + + call SetupMNVTest_shm() + let output = execute(':mess')->split('\n') + + let info = copy(output)->filter({idx, val -> val =~# '\d of 3'} ) + let bytes = copy(output)->filter({idx, val -> val =~# 'bytes'} ) + + " We test the following here: + " BufReadPost should have been triggered 3 times, once per file + " BufWinEnter should have been triggered 3 times, once per file + " FileInfoMessage should have been shown 3 times, regardless of shm option + " "(x of 3)" message from :cnext has been shown 3 times + + call assert_equal(3, g:brp->len()) + call assert_equal(3, g:bwe->len()) + call assert_equal(3, info->len()) + call assert_equal(3, bytes->len()) + + delfunc SetupMNVTest_shm +endfunc + +func Test_autocmd_invalidates_undo_on_textchanged() + CheckRunMNVInTerminal + let script =<< trim END + set hidden + " create quickfix list (at least 2 lines to move line) + mnvgrep /u/j % + + " enter quickfix window + cwindow + + " set modifiable + setlocal modifiable + + " set autocmd to clear quickfix list + + autocmd! TextChanged call setqflist([]) + " move line + move+1 + END + call writefile(script, 'XTest_autocmd_invalidates_undo_on_textchanged', 'D') + let buf = RunMNVInTerminal('XTest_autocmd_invalidates_undo_on_textchanged', {'rows': 20}) + call term_sendkeys(buf, ":so %\") + call term_sendkeys(buf, "G") + call WaitForAssert({-> assert_match('^XTest_autocmd_invalidates_undo_on_textchanged\s*$', term_getline(buf, 20))}, 1000) + + call StopMNVInTerminal(buf) +endfunc + +func Test_autocmd_creates_new_window_on_bufleave() + e a.txt + e b.txt + setlocal bufhidden=wipe + autocmd BufLeave diffsplit c.txt + bn + " curbuf set for the new split opened for c.txt, due to BufLeave + call assert_equal(2, winnr('$')) + call assert_equal('a.txt', bufname('%')) + call assert_equal('b.txt', bufname('#')) + %bw! +endfunc + +" Ensure `expected` was just recently written as a MNV session +func s:assert_session_path(expected) + call assert_equal(a:expected, v:this_session) +endfunc + +" Check for `expected` after a session is written to-disk. +func s:watch_for_session_path(expected) + execute 'autocmd SessionWritePost * ++once execute "call s:assert_session_path(\"' + \ . a:expected + \ . '\")"' +endfunc + +" Ensure v:this_session gets the full session path, if explicitly stated +func Test_explicit_session_absolute_path() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let name = "some_file.mnv" + let expected = fnamemodify(name, ":p") + call s:watch_for_session_path(expected) + execute "mksession! " .. expected + + call delete(expected) +endfunc + +" Ensure v:this_session gets the full session path, if explicitly stated +func Test_explicit_session_relative_path() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let name = "some_file.mnv" + let expected = fnamemodify(name, ":p") + call s:watch_for_session_path(expected) + execute "mksession! " .. name + + call delete(expected) +endfunc + +" Ensure v:this_session gets the full session path, if not specified +func Test_implicit_session() + %bwipeout! + + let directory = getcwd() + + let v:this_session = "" + let expected = fnamemodify("Session.mnv", ":p") + call s:watch_for_session_path(expected) + mksession! + + call delete(expected) +endfunc + +" Test TextChangedI and TextChanged +func Test_Changed_ChangedI() + " Run this test in a terminal because it requires running the main loop. + " Don't use CheckRunMNVInTerminal as that will skip the test on Windows. + CheckFeature terminal + CheckNotGui + " Starting a terminal to run MNV is always considered flaky. + let g:test_is_flaky = 1 + + call writefile(['one', 'two', 'three'], 'XTextChangedI2', 'D') + let before =<< trim END + set ttimeout ttimeoutlen=10 + let [g:autocmd_n, g:autocmd_i] = ['',''] + + func TextChangedAutocmd(char) + let g:autocmd_{tolower(a:char)} = a:char .. b:changedtick + call writefile([$'{g:autocmd_n},{g:autocmd_i}'], 'XTextChangedI3') + endfunc + + au TextChanged :call TextChangedAutocmd('N') + au TextChangedI :call TextChangedAutocmd('I') + + nnoremap o + autocmd SafeState * ++once call writefile([''], 'XTextChangedI3') + END + + call writefile(before, 'Xinit', 'D') + let buf = term_start( + \ GetMNVCommandCleanTerm() .. '-n -S Xinit XTextChangedI2', + \ {'term_rows': 10}) + call assert_equal('running', term_getstatus(buf)) + call WaitForAssert({-> assert_true(filereadable('XTextChangedI3'))}) + defer delete('XTextChangedI3') + call WaitForAssert({-> assert_equal([''], readfile('XTextChangedI3'))}) + + " TextChanged should trigger if a mapping enters and leaves Insert mode. + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))}) + + call term_sendkeys(buf, "i") + call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_equal('N4,', readfile('XTextChangedI3')->join("\n"))}) + " TextChangedI should trigger if change is done in Insert mode. + call term_sendkeys(buf, "f") + call WaitForAssert({-> assert_equal('N4,I5', readfile('XTextChangedI3')->join("\n"))}) + call term_sendkeys(buf, "o") + call WaitForAssert({-> assert_equal('N4,I6', readfile('XTextChangedI3')->join("\n"))}) + call term_sendkeys(buf, "o") + call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))}) + " TextChanged shouldn't trigger when leaving Insert mode and TextChangedI + " has been triggered. + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_equal('N4,I7', readfile('XTextChangedI3')->join("\n"))}) + + " TextChanged should trigger if change is done in Normal mode. + call term_sendkeys(buf, "yyp") + call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))}) + + " TextChangedI shouldn't trigger if change isn't done in Insert mode. + call term_sendkeys(buf, "i") + call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))}) + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_equal('N8,I7', readfile('XTextChangedI3')->join("\n"))}) + + " TextChangedI should trigger if change is a mix of Normal and Insert modes. + func! s:validate_mixed_textchangedi(buf, keys) + let buf = a:buf + call term_sendkeys(buf, "ifoo") + call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))}) + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))}) + call term_sendkeys(buf, ":let [g:autocmd_n, g:autocmd_i] = ['', '']\") + call writefile([], 'XTextChangedI3') + call term_sendkeys(buf, a:keys) + call WaitForAssert({-> assert_match('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))}) + call term_sendkeys(buf, "\") + call WaitForAssert({-> assert_notmatch('^-- INSERT --', term_getline(buf, 10))}) + call WaitForAssert({-> assert_match('^,I\d\+', readfile('XTextChangedI3')->join("\n"))}) + endfunc + + call s:validate_mixed_textchangedi(buf, "o") + call s:validate_mixed_textchangedi(buf, "O") + call s:validate_mixed_textchangedi(buf, "ciw") + call s:validate_mixed_textchangedi(buf, "cc") + call s:validate_mixed_textchangedi(buf, "C") + call s:validate_mixed_textchangedi(buf, "s") + call s:validate_mixed_textchangedi(buf, "S") + + " clean up + bwipe! +endfunc + +" Test that filetype detection still works when SwapExists autocommand sets +" filetype in another buffer. +func Test_SwapExists_set_other_buf_filetype() + let lines =<< trim END + set nocompatible directory=. + filetype on + + let g:buf = bufnr() + new + + func SwapExists() + let v:swapchoice = 'o' + call setbufvar(g:buf, '&filetype', 'text') + endfunc + + func SafeState() + edit