public/lib/CodeMirror/test/vim_test.js   F
last analyzed

Complexity

Total Complexity 433
Complexity/F 1.09

Size

Lines of Code 3953
Function Count 399

Duplication

Duplicated Lines 118
Ratio 2.99 %

Importance

Changes 0
Metric Value
cc 0
eloc 3537
nc 1
dl 118
loc 3953
rs 0.8
c 0
b 0
f 0
wmc 433
mnd 3
bc 446
fnc 399
bpm 1.1177
cpm 1.0852
noi 75

327 Functions

Rating   Name   Duplication   Size   Complexity  
A vim_test.js ➔ fillArray 0 7 2
A vim_test.js ➔ testVim(ꞌscrollMotionꞌ) 0 21 1
A vim_test.js ➔ testVim(ꞌ[(, ])ꞌ) 0 16 1
A vim_test.js ➔ testVim(ꞌ~ꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌdb_word_end_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌd_inclusiveꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌyank_visual_blockꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌg~w_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌcc_multiply_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌdw_empty_line_followed_by_wordꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_writeꞌ) 0 19 2
A vim_test.js ➔ testVim(ꞌgj_gkꞌ) 0 28 2
A vim_test.js ➔ testVim(ꞌdhꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌ%_skip_commentꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌex_map_key2keyꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌsearch_clearꞌ) 19 19 1
A vim_test.js ➔ testVim(ꞌ%_seek_skipꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌJꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_nomarkꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_initial_selectionꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_map_key2key_from_colonꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌdb_start_of_documentꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌ[{, ]}ꞌ) 0 17 1
A vim_test.js ➔ testVim(ꞌdw_spaceꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌex_sort_uniqueꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌp_registerꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌFd,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌty,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_sort_hexꞌ) 0 4 1
A lines.constructor 0 13 2
A vim_test.js ➔ testVim(ꞌmacro_search_2fꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌmouse_selectꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌyank_append_line_to_word_registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌddꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌzz<ztꞌ) 0 3 1
A vim_test.js ➔ testVim(ꞌsearch_register_escapeꞌ) 0 32 1
A vim_test.js ➔ testVim(ꞌ? and n/Nꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌi_repeatꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌtc,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌoꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ?_nongreedyꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌmacro_insert_repeatꞌ) 0 18 1
A vim_test.js ➔ testVim(ꞌchangeCase_visualꞌ) 0 19 1
A vim_test.js ➔ testVim(ꞌdk_start_of_documentꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌreselect_visual_blockꞌ) 0 19 1
A vim_test.js ➔ testVim(ꞌj_k_and_gj_gkꞌ) 0 26 1
A vim_test.js ➔ testVim(ꞌmacro_multislash_searchꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌ/_2_nopcreꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌvisualꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌyank_registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_sort_ignoreCaseꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌvisual_lineꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌdd_motion_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌex_sort_decimal_reverseꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌ#ꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌRꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_joinꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌiꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌ:_registerꞌ) 0 8 1
B vim_test.js ➔ testVim(ꞌsearch_historyꞌ) 42 42 1
A vim_test.js ➔ testVim(ꞌex_go_to_lineꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌmacro_slash_searchꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌzt==z<CR>ꞌ) 0 3 1
A testVim(ꞌ._visual_>ꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌ[#, ]#ꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prev_samelineꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌcc_should_not_append_to_documentꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌex_globalꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌd_/ꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌ<{motion}ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌTy,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_unmap_key2keyꞌ) 0 5 1
A testVim(ꞌ._delete_repeatꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌmacro_last_ex_command_registerꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌdw_repeatꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌHMLꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌD_visual_blockꞌ) 0 5 1
A testVim(ꞌzz==z.ꞌ) 0 3 1
A vim_test.js ➔ testVim(ꞌex_sort_decimal_negativeꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌex_map_key2exꞌ) 0 14 1
A testVim(ꞌ._deleteꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌblockwise_paste_long/short_lineꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌdelmark_allꞌ) 0 24 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prev_nomarkꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌex_imapꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌa_eolꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌfd,;ꞌ) 0 11 1
A vim_test.js ➔ testEdit 0 12 1
A vim_test.js ➔ testVim(ꞌex_set_callbackꞌ) 0 48 1
A vim_test.js ➔ testVim(ꞌdd_only_lineꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌyank_append_word_to_word_registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌvisual_exitꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌt,ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌex_set_filetypeꞌ) 0 18 1
A vim_test.js ➔ testVim(ꞌF,ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_block_move_to_eolꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌd_visual_blockꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌfy,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌvisual_wꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌctꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdw_only_wordꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdd_lastlineꞌ) 0 7 1
A testVim(ꞌ._swapCase_visualBlockꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌs_normalꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌctrl-xꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌ@@ꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌDꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌex_substitute_empty_argumentsꞌ) 0 7 1
A vim_test.js ➔ makeCursor 0 3 1
A vim_test.js ➔ testVim(ꞌblockwise_pasteꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌd_reverseꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌdge_start_of_documentꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌF;ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌpꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌTd,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌ/_greedy_0_or_moreꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌ]p_with_spaces_translated_to_tabsꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_line_actionꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌ]p_first_indent_is_smallerꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prev_onlynextꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ*_symbolꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_sort_decimal_mixed_reverseꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌvisual_blankꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌ[m, ]m, [M, ]Mꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌ*_seekꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌmoveTillCharacterꞌ) 0 35 1
A vim_test.js ➔ testVim(ꞌp_lineꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌdw_empty_line_followed_by_whitespaceꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌv_paste_from_registerꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌex_sort_patterns_not_supportedꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌdb_word_start_and_empty_linesꞌ) 0 5 1
A 0 8 1
A testVim(ꞌ._repeat_insertꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌ>>ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌcwꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌT;ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ}ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌ]p_first_indent_is_largerꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌde_whitespace_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌIꞌ) 0 6 1
A testVim(ꞌ._insert_cw_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌvisual_block_crossing_short_lineꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌex_substitute_same_lineꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌdkꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌyy_multiply_repeatꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌreselect_visual_lineꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌexCommand_clearꞌ) 19 19 1
A vim_test.js ➔ forEach 0 5 2
A vim_test.js ➔ testVim(ꞌTc,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdw_eol_with_multiple_newlinesꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌf;ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌexCommand_historyꞌ) 38 38 1
A vim_test.js ➔ testVim(ꞌvisual_block_different_line_lengthsꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌbeforeSelectionChangeꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌdw_whitespace_followed_by_empty_lineꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌzb<zzꞌ) 0 3 1
A vim_test.js ➔ testVim(ꞌex_sort_decimal_mixedꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌblockwise_paste_from_registerꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌex_sort_octalꞌ) 0 4 1
A testVim(ꞌ._delete_visualBlockꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌblockwise_paste_last_lineꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌaꞌ) 0 6 1
A testVim(ꞌ._insertꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌdge_whitespace_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_repeatꞌ) 0 14 1
A vim_test.js ➔ testVim(ꞌ/_greedyꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prev_repeatꞌ) 0 14 1
A vim_test.js ➔ testVim(ꞌzb==z-ꞌ) 0 3 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prevꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌex_substitute_full_fileꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌ<<ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌOꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_crossover_downꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdjꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌgu_and_gUꞌ) 0 26 1
A vim_test.js ➔ testVim(ꞌf,ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ<C-x>/<C-a> search forwardꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌmacro_parensꞌ) 0 13 1
A testVim(ꞌ._registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌ/_caseꞌ) 0 5 1
A testVim(ꞌ._insert_o_indentꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌCꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdelmark_multi_spaceꞌ) 0 24 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_samelineꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌS_normalꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_join_2ꞌ) 0 5 1
A vim_test.js ➔ offsetCursor 0 3 1
A vim_test.js ➔ testVim(ꞌp_wrong_registerꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌdd_prefix_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌjumpToMark_prev_linewise_overꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌ/ and n/Nꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌr_visual_blockꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌT,ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ*ꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdw_empty_line_followed_by_empty_lineꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌg~g~ꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌchangeCase_visual_blockꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌex_map_ex2key:ꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌ]p_with_tab_indentsꞌ) 0 5 1
A testVim(ꞌ._insert_cwꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌt;ꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌjumpToMark_nextꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌ[pꞌ) 0 5 1
A vim_test.js ➔ testSubstituteConfirm 0 44 1
A vim_test.js ➔ testVim(ꞌYꞌ) 0 10 1
A testVim(ꞌ.ꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌvisual_block_~ꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌ*_no_wordꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌgj_gk_clippingꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌset_booleanꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌex_sort_decimalꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌsearchForPipeꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌqq@qꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌmacro_f_searchꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌfc,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌi_repeat_deleteꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌyank_append_word_to_line_registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_substitute_input_rangeꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌPꞌ) 0 7 1
A vim_test.js ➔ copyCursor 0 3 1
A vim_test.js ➔ testVim(ꞌdw_wordꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌA_endOfSelectedAreaꞌ) 0 7 1
B vim_test.js ➔ testVim 0 111 3
A vim_test.js ➔ testVim(ꞌtd,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌvisual_block_mode_switchꞌ) 0 16 1
A vim_test.js ➔ testVim(ꞌvisual_yankꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌg*ꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌFy,;ꞌ) 0 11 1
B vim_test.js ➔ testVim(ꞌparagraph_motionsꞌ) 0 74 1
A vim_test.js ➔ testVim(ꞌvisual_crossover_leftꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌdw_end_of_documentꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_onlyprevꞌ) 0 7 1
A testVim(ꞌ._insert_repeatꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌc_visual_blockꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌrꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdd_multiply_repeatꞌ) 0 12 1
A vim_test.js ➔ testSubstitute 0 16 2
A vim_test.js ➔ testVim(ꞌyw_repeatꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌex_unmap_key2key_does_not_remove_defaultꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌex_api_testꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌg#ꞌ) 0 8 1
A testVim(ꞌ._insert_o_repeatꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌcw_repeatꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌde_end_of_documentꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_sort_onelineꞌ) 0 5 1
A vim_test.js ➔ testJumplist 0 11 1
A vim_test.js ➔ testVim(ꞌmacro_t_searchꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdlꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌex_substitute_javascriptꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌ[], ][ꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌvisual_block_truncate_on_short_lineꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌo_visual_blockꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌctrl-aꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌdl_eolꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdelmark_multiꞌ) 0 24 1
A vim_test.js ➔ testSelection 0 12 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_actionꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌdelmark_singleꞌ) 0 8 1
A testVim(ꞌ._repeatꞌ) 0 6 1
A vim_test.js ➔ testVim(ꞌdge_word_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_map_key2key_visual_apiꞌ) 0 19 1
A vim_test.js ➔ testVim(ꞌI_repeatꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌdw_word_whitespace_wordꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌvisual_crossover_upꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌmacro_registerꞌ) 0 17 1
A vim_test.js ➔ testVim(ꞌdelmark_rangeꞌ) 0 24 1
A vim_test.js ➔ testVim(ꞌmacro_overwriteꞌ) 0 16 1
A vim_test.js ➔ testVim(ꞌex_sortꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌjumpToMark_next_linewise_overꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌ%_skip_stringꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌblockwise_paste_cut_pasteꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌex_set_filetype_nullꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌo_repeatꞌ) 0 8 1
A vim_test.js ➔ testMotion 0 10 1
A vim_test.js ➔ testVim(ꞌ/_2_pcreꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌs_visualꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌAꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌdw_unicode_wordꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌvisual_block_curPos_on_exitꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌmacro_search_fꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌex_global_confirmꞌ) 0 27 1
A vim_test.js ➔ testVim(ꞌex_map_key2key_to_colonꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌ/_nongreedyꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌo_visualꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌde_word_start_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_sort_reverseꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌP_lineꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌset_stringꞌ) 0 18 1
A vim_test.js ➔ testVim(ꞌdw_eolꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌp_lastlineꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌvisual_pasteꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌvisual_block_cornersꞌ) 0 17 1
A vim_test.js ➔ testVim(ꞌChanging lines after Eol operationꞌ) 0 20 1
A vim_test.js ➔ testVim(ꞌ[[, ]]ꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌI_visual_blockꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌex_set_booleanꞌ) 0 13 1
A testVim(ꞌ._insert_oꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌex_sort_rangeꞌ) 0 4 1
A vim_test.js ➔ testVim(ꞌ[*, ]*, [/, ]/ꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdge_empty_linesꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdl_repeatꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌex_noh_clearSearchHighlightꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌFc,;ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_substitute_visual_rangeꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌS_visualꞌ) 0 7 1
A vim_test.js ➔ testVim(ꞌ?_greedy_0_or_moreꞌ) 0 15 1
A vim_test.js ➔ testVim(ꞌdw_whitespace_followed_by_whitespaceꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌ>{motion}ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌ{ꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌvisual_marksꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌdj_end_of_documentꞌ) 0 10 1
A vim_test.js ➔ testVim(ꞌmacro_spaceꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌmacro_insertꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌreselect_visualꞌ) 0 23 1
A vim_test.js ➔ testVim(ꞌ?_greedyꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdb_whitespace_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌmarkꞌ) 0 12 1
A vim_test.js ➔ testVim(ꞌA_visual_blockꞌ) 0 13 1
A vim_test.js ➔ testVim(ꞌex_map_ex2exꞌ) 0 14 1
A vim_test.js ➔ testVim(ꞌc_visual_block_replayꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌex_set_stringꞌ) 0 30 1
A vim_test.js ➔ testVim(ꞌde_word_end_and_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌyank_append_line_to_line_registerꞌ) 0 11 1
A vim_test.js ➔ testVim(ꞌdb_empty_linesꞌ) 0 5 1
A vim_test.js ➔ testVim(ꞌex_substitute_empty_queryꞌ) 0 8 1
A vim_test.js ➔ testVim(ꞌsearch_registerꞌ) 0 9 1
A vim_test.js ➔ testVim(ꞌJ_repeatꞌ) 0 7 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like public/lib/CodeMirror/test/vim_test.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
CodeMirror.Vim.suppressErrorLogging = true;
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
2
3
var code = '' +
4
' wOrd1 (#%\n' +
5
' word3] \n' +
6
'aopop pop 0 1 2 3 4\n' +
7
' (a) [b] {c} \n' +
8
'int getchar(void) {\n' +
9
'  static char buf[BUFSIZ];\n' +
10
'  static char *bufp = buf;\n' +
11
'  if (n == 0) {  /* buffer is empty */\n' +
12
'    n = read(0, buf, sizeof buf);\n' +
13
'    bufp = buf;\n' +
14
'  }\n' +
15
'\n' +
16
'  return (--n >= 0) ? (unsigned char) *bufp++ : EOF;\n' +
17
' \n' +
18
'}\n';
19
20
var lines = (function() {
21
  lineText = code.split('\n');
0 ignored issues
show
Bug introduced by
The variable lineText seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.lineText.
Loading history...
22
  var ret = [];
23
  for (var i = 0; i < lineText.length; i++) {
24
    ret[i] = {
25
      line: i,
26
      length: lineText[i].length,
27
      lineText: lineText[i],
28
      textStart: /^\s*/.exec(lineText[i])[0].length
29
    };
30
  }
31
  return ret;
32
})();
33
var endOfDocument = makeCursor(lines.length - 1,
34
    lines[lines.length - 1].length);
35
var wordLine = lines[0];
36
var bigWordLine = lines[1];
37
var charLine = lines[2];
38
var bracesLine = lines[3];
39
var seekBraceLine = lines[4];
40
41
var word1 = {
42
  start: { line: wordLine.line, ch: 1 },
43
  end: { line: wordLine.line, ch: 5 }
44
};
45
var word2 = {
46
  start: { line: wordLine.line, ch: word1.end.ch + 2 },
47
  end: { line: wordLine.line, ch: word1.end.ch + 4 }
48
};
49
var word3 = {
50
  start: { line: bigWordLine.line, ch: 1 },
51
  end: { line: bigWordLine.line, ch: 5 }
52
};
53
var bigWord1 = word1;
54
var bigWord2 = word2;
55
var bigWord3 = {
56
  start: { line: bigWordLine.line, ch: 1 },
57
  end: { line: bigWordLine.line, ch: 7 }
58
};
59
var bigWord4 = {
60
  start: { line: bigWordLine.line, ch: bigWord1.end.ch + 3 },
61
  end: { line: bigWordLine.line, ch: bigWord1.end.ch + 7 }
62
};
63
64
var oChars = [ { line: charLine.line, ch: 1 },
65
    { line: charLine.line, ch: 3 },
66
    { line: charLine.line, ch: 7 } ];
67
var pChars = [ { line: charLine.line, ch: 2 },
68
    { line: charLine.line, ch: 4 },
69
    { line: charLine.line, ch: 6 },
70
    { line: charLine.line, ch: 8 } ];
71
var numChars = [ { line: charLine.line, ch: 10 },
72
    { line: charLine.line, ch: 12 },
73
    { line: charLine.line, ch: 14 },
74
    { line: charLine.line, ch: 16 },
75
    { line: charLine.line, ch: 18 }];
76
var parens1 = {
77
  start: { line: bracesLine.line, ch: 1 },
78
  end: { line: bracesLine.line, ch: 3 }
79
};
80
var squares1 = {
81
  start: { line: bracesLine.line, ch: 5 },
82
  end: { line: bracesLine.line, ch: 7 }
83
};
84
var curlys1 = {
85
  start: { line: bracesLine.line, ch: 9 },
86
  end: { line: bracesLine.line, ch: 11 }
87
};
88
var seekOutside = {
89
  start: { line: seekBraceLine.line, ch: 1 },
90
  end: { line: seekBraceLine.line, ch: 16 }
91
};
92
var seekInside = {
93
  start: { line: seekBraceLine.line, ch: 14 },
94
  end: { line: seekBraceLine.line, ch: 11 }
95
};
96
97
function copyCursor(cur) {
98
  return { ch: cur.ch, line: cur.line };
99
}
100
101
function forEach(arr, func) {
102
  for (var i = 0; i < arr.length; i++) {
103
    func(arr[i], i, arr);
104
  }
105
}
106
107
function testVim(name, run, opts, expectedFail) {
108
  var vimOpts = {
109
    lineNumbers: true,
110
    vimMode: true,
111
    showCursorWhenSelecting: true,
112
    value: code
113
  };
114
  for (var prop in opts) {
115
    if (opts.hasOwnProperty(prop)) {
116
      vimOpts[prop] = opts[prop];
117
    }
118
  }
119
  return test('vim_' + name, function() {
120
    var place = document.getElementById("testground");
121
    var cm = CodeMirror(place, vimOpts);
122
    var vim = CodeMirror.Vim.maybeInitVimState_(cm);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
123
124
    function doKeysFn(cm) {
125
      return function(args) {
126
        if (args instanceof Array) {
127
          arguments = args;
128
        }
129
        for (var i = 0; i < arguments.length; i++) {
130
          CodeMirror.Vim.handleKey(cm, arguments[i]);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
131
        }
132
      }
133
    }
134
    function doInsertModeKeysFn(cm) {
135
      return function(args) {
136
        if (args instanceof Array) { arguments = args; }
137
        function executeHandler(handler) {
138
          if (typeof handler == 'string') {
139
            CodeMirror.commands[handler](cm);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
140
          } else {
141
            handler(cm);
142
          }
143
          return true;
144
        }
145
        for (var i = 0; i < arguments.length; i++) {
146
          var key = arguments[i];
147
          // Find key in keymap and handle.
148
          var handled = CodeMirror.lookupKey(key, 'vim-insert', executeHandler);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
149
          // Record for insert mode.
150
          if (handled == "handled" && cm.state.vim.insertMode && arguments[i] != 'Esc') {
151
            var lastChange = CodeMirror.Vim.getVimGlobalState_().macroModeState.lastInsertModeChanges;
152
            if (lastChange) {
153
              lastChange.changes.push(new CodeMirror.Vim.InsertModeKey(key));
154
            }
155
          }
156
        }
157
      }
158
    }
159
    function doExFn(cm) {
160
      return function(command) {
161
        cm.openDialog = helpers.fakeOpenDialog(command);
162
        helpers.doKeys(':');
163
      }
164
    }
165
    function assertCursorAtFn(cm) {
166
      return function(line, ch) {
167
        var pos;
168
        if (ch == null && typeof line.line == 'number') {
0 ignored issues
show
Best Practice introduced by
Comparing ch to null using the == operator is not safe. Consider using === instead.
Loading history...
169
          pos = line;
170
        } else {
171
          pos = makeCursor(line, ch);
172
        }
173
        eqPos(pos, cm.getCursor());
174
      }
175
    }
176
    function fakeOpenDialog(result) {
177
      return function(text, callback) {
178
        return callback(result);
179
      }
180
    }
181
    function fakeOpenNotification(matcher) {
182
      return function(text) {
183
        matcher(text);
184
      }
185
    }
186
    var helpers = {
187
      doKeys: doKeysFn(cm),
188
      // Warning: Only emulates keymap events, not character insertions. Use
189
      // replaceRange to simulate character insertions.
190
      // Keys are in CodeMirror format, NOT vim format.
191
      doInsertModeKeys: doInsertModeKeysFn(cm),
192
      doEx: doExFn(cm),
193
      assertCursorAt: assertCursorAtFn(cm),
194
      fakeOpenDialog: fakeOpenDialog,
195
      fakeOpenNotification: fakeOpenNotification,
196
      getRegisterController: function() {
197
        return CodeMirror.Vim.getRegisterController();
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
198
      }
199
    }
200
    CodeMirror.Vim.resetVimGlobalState_();
201
    var successful = false;
202
    var savedOpenNotification = cm.openNotification;
203
    var savedOpenDialog = cm.openDialog;
204
    try {
205
      run(cm, vim, helpers);
206
      successful = true;
207
    } finally {
208
      cm.openNotification = savedOpenNotification;
209
      cm.openDialog = savedOpenDialog;
210
      if (!successful || verbose) {
0 ignored issues
show
Best Practice introduced by
If you intend to check if the variable verbose is declared in the current environment, consider using typeof verbose === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
211
        place.style.visibility = "visible";
212
      } else {
213
        place.removeChild(cm.getWrapperElement());
214
      }
215
    }
216
  }, expectedFail);
217
};
218
testVim('qq@q', function(cm, vim, helpers) {
219
  cm.setCursor(0, 0);
220
  helpers.doKeys('q', 'q', 'l', 'l', 'q');
221
  helpers.assertCursorAt(0,2);
222
  helpers.doKeys('@', 'q');
223
  helpers.assertCursorAt(0,4);
224
}, { value: '            '});
225
testVim('@@', function(cm, vim, helpers) {
226
  cm.setCursor(0, 0);
227
  helpers.doKeys('q', 'q', 'l', 'l', 'q');
228
  helpers.assertCursorAt(0,2);
229
  helpers.doKeys('@', 'q');
230
  helpers.assertCursorAt(0,4);
231
  helpers.doKeys('@', '@');
232
  helpers.assertCursorAt(0,6);
233
}, { value: '            '});
234
var jumplistScene = ''+
235
  'word\n'+
236
  '(word)\n'+
237
  '{word\n'+
238
  'word.\n'+
239
  '\n'+
240
  'word search\n'+
241
  '}word\n'+
242
  'word\n'+
243
  'word\n';
244
function testJumplist(name, keys, endPos, startPos, dialog) {
245
  endPos = makeCursor(endPos[0], endPos[1]);
246
  startPos = makeCursor(startPos[0], startPos[1]);
247
  testVim(name, function(cm, vim, helpers) {
248
    CodeMirror.Vim.resetVimGlobalState_();
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
249
    if(dialog)cm.openDialog = helpers.fakeOpenDialog('word');
250
    cm.setCursor(startPos);
251
    helpers.doKeys.apply(null, keys);
252
    helpers.assertCursorAt(endPos);
253
  }, {value: jumplistScene});
254
};
255
testJumplist('jumplist_H', ['H', '<C-o>'], [5,2], [5,2]);
256
testJumplist('jumplist_M', ['M', '<C-o>'], [2,2], [2,2]);
257
testJumplist('jumplist_L', ['L', '<C-o>'], [2,2], [2,2]);
258
testJumplist('jumplist_[[', ['[', '[', '<C-o>'], [5,2], [5,2]);
259
testJumplist('jumplist_]]', [']', ']', '<C-o>'], [2,2], [2,2]);
260
testJumplist('jumplist_G', ['G', '<C-o>'], [5,2], [5,2]);
261
testJumplist('jumplist_gg', ['g', 'g', '<C-o>'], [5,2], [5,2]);
262
testJumplist('jumplist_%', ['%', '<C-o>'], [1,5], [1,5]);
263
testJumplist('jumplist_{', ['{', '<C-o>'], [1,5], [1,5]);
264
testJumplist('jumplist_}', ['}', '<C-o>'], [1,5], [1,5]);
265
testJumplist('jumplist_\'', ['m', 'a', 'h', '\'', 'a', 'h', '<C-i>'], [1,0], [1,5]);
266
testJumplist('jumplist_`', ['m', 'a', 'h', '`', 'a', 'h', '<C-i>'], [1,5], [1,5]);
267
testJumplist('jumplist_*_cachedCursor', ['*', '<C-o>'], [1,3], [1,3]);
268
testJumplist('jumplist_#_cachedCursor', ['#', '<C-o>'], [1,3], [1,3]);
269
testJumplist('jumplist_n', ['#', 'n', '<C-o>'], [1,1], [2,3]);
270
testJumplist('jumplist_N', ['#', 'N', '<C-o>'], [1,1], [2,3]);
271
testJumplist('jumplist_repeat_<c-o>', ['*', '*', '*', '3', '<C-o>'], [2,3], [2,3]);
272
testJumplist('jumplist_repeat_<c-i>', ['*', '*', '*', '3', '<C-o>', '2', '<C-i>'], [5,0], [2,3]);
273
testJumplist('jumplist_repeated_motion', ['3', '*', '<C-o>'], [2,3], [2,3]);
274
testJumplist('jumplist_/', ['/', '<C-o>'], [2,3], [2,3], 'dialog');
275
testJumplist('jumplist_?', ['?', '<C-o>'], [2,3], [2,3], 'dialog');
276
testJumplist('jumplist_skip_delted_mark<c-o>',
277
             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-o>', '<C-o>'],
278
             [0,2], [0,2]);
279
testJumplist('jumplist_skip_delted_mark<c-i>',
280
             ['*', 'n', 'n', 'k', 'd', 'k', '<C-o>', '<C-i>', '<C-i>'],
281
             [1,0], [0,2]);
282
283
/**
284
 * @param name Name of the test
285
 * @param keys An array of keys or a string with a single key to simulate.
286
 * @param endPos The expected end position of the cursor.
287
 * @param startPos The position the cursor should start at, defaults to 0, 0.
288
 */
289
function testMotion(name, keys, endPos, startPos) {
290
  testVim(name, function(cm, vim, helpers) {
291
    if (!startPos) {
292
      startPos = { line: 0, ch: 0 };
293
    }
294
    cm.setCursor(startPos);
295
    helpers.doKeys(keys);
296
    helpers.assertCursorAt(endPos);
297
  });
298
};
299
300
function makeCursor(line, ch) {
301
  return { line: line, ch: ch };
302
};
303
304
function offsetCursor(cur, offsetLine, offsetCh) {
305
  return { line: cur.line + offsetLine, ch: cur.ch + offsetCh };
306
};
307
308
// Motion tests
309
testMotion('|', '|', makeCursor(0, 0), makeCursor(0,4));
310
testMotion('|_repeat', ['3', '|'], makeCursor(0, 2), makeCursor(0,4));
311
testMotion('h', 'h', makeCursor(0, 0), word1.start);
312
testMotion('h_repeat', ['3', 'h'], offsetCursor(word1.end, 0, -3), word1.end);
313
testMotion('l', 'l', makeCursor(0, 1));
314
testMotion('l_repeat', ['2', 'l'], makeCursor(0, 2));
315
testMotion('j', 'j', offsetCursor(word1.end, 1, 0), word1.end);
316
testMotion('j_repeat', ['2', 'j'], offsetCursor(word1.end, 2, 0), word1.end);
317
testMotion('j_repeat_clip', ['1000', 'j'], endOfDocument);
318
testMotion('k', 'k', offsetCursor(word3.end, -1, 0), word3.end);
319
testMotion('k_repeat', ['2', 'k'], makeCursor(0, 4), makeCursor(2, 4));
320
testMotion('k_repeat_clip', ['1000', 'k'], makeCursor(0, 4), makeCursor(2, 4));
321
testMotion('w', 'w', word1.start);
322
testMotion('w_multiple_newlines_no_space', 'w', makeCursor(12, 2), makeCursor(11, 2));
323
testMotion('w_multiple_newlines_with_space', 'w', makeCursor(14, 0), makeCursor(12, 51));
324
testMotion('w_repeat', ['2', 'w'], word2.start);
325
testMotion('w_wrap', ['w'], word3.start, word2.start);
326
testMotion('w_endOfDocument', 'w', endOfDocument, endOfDocument);
327
testMotion('w_start_to_end', ['1000', 'w'], endOfDocument, makeCursor(0, 0));
328
testMotion('W', 'W', bigWord1.start);
329
testMotion('W_repeat', ['2', 'W'], bigWord3.start, bigWord1.start);
330
testMotion('e', 'e', word1.end);
331
testMotion('e_repeat', ['2', 'e'], word2.end);
332
testMotion('e_wrap', 'e', word3.end, word2.end);
333
testMotion('e_endOfDocument', 'e', endOfDocument, endOfDocument);
334
testMotion('e_start_to_end', ['1000', 'e'], endOfDocument, makeCursor(0, 0));
335
testMotion('b', 'b', word3.start, word3.end);
336
testMotion('b_repeat', ['2', 'b'], word2.start, word3.end);
337
testMotion('b_wrap', 'b', word2.start, word3.start);
338
testMotion('b_startOfDocument', 'b', makeCursor(0, 0), makeCursor(0, 0));
339
testMotion('b_end_to_start', ['1000', 'b'], makeCursor(0, 0), endOfDocument);
340
testMotion('ge', ['g', 'e'], word2.end, word3.end);
341
testMotion('ge_repeat', ['2', 'g', 'e'], word1.end, word3.start);
342
testMotion('ge_wrap', ['g', 'e'], word2.end, word3.start);
343
testMotion('ge_startOfDocument', ['g', 'e'], makeCursor(0, 0),
344
    makeCursor(0, 0));
345
testMotion('ge_end_to_start', ['1000', 'g', 'e'], makeCursor(0, 0), endOfDocument);
346
testMotion('gg', ['g', 'g'], makeCursor(lines[0].line, lines[0].textStart),
347
    makeCursor(3, 1));
348
testMotion('gg_repeat', ['3', 'g', 'g'],
349
    makeCursor(lines[2].line, lines[2].textStart));
350
testMotion('G', 'G',
351
    makeCursor(lines[lines.length - 1].line, lines[lines.length - 1].textStart),
352
    makeCursor(3, 1));
353
testMotion('G_repeat', ['3', 'G'], makeCursor(lines[2].line,
354
    lines[2].textStart));
355
// TODO: Make the test code long enough to test Ctrl-F and Ctrl-B.
356
testMotion('0', '0', makeCursor(0, 0), makeCursor(0, 8));
357
testMotion('^', '^', makeCursor(0, lines[0].textStart), makeCursor(0, 8));
358
testMotion('+', '+', makeCursor(1, lines[1].textStart), makeCursor(0, 8));
359
testMotion('-', '-', makeCursor(0, lines[0].textStart), makeCursor(1, 4));
360
testMotion('_', ['6','_'], makeCursor(5, lines[5].textStart), makeCursor(0, 8));
361
testMotion('$', '$', makeCursor(0, lines[0].length - 1), makeCursor(0, 1));
362
testMotion('$_repeat', ['2', '$'], makeCursor(1, lines[1].length - 1),
363
    makeCursor(0, 3));
364
testMotion('f', ['f', 'p'], pChars[0], makeCursor(charLine.line, 0));
365
testMotion('f_repeat', ['2', 'f', 'p'], pChars[2], pChars[0]);
366
testMotion('f_num', ['f', '2'], numChars[2], makeCursor(charLine.line, 0));
367
testMotion('t', ['t','p'], offsetCursor(pChars[0], 0, -1),
368
    makeCursor(charLine.line, 0));
369
testMotion('t_repeat', ['2', 't', 'p'], offsetCursor(pChars[2], 0, -1),
370
    pChars[0]);
371
testMotion('F', ['F', 'p'], pChars[0], pChars[1]);
372
testMotion('F_repeat', ['2', 'F', 'p'], pChars[0], pChars[2]);
373
testMotion('T', ['T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[1]);
374
testMotion('T_repeat', ['2', 'T', 'p'], offsetCursor(pChars[0], 0, 1), pChars[2]);
375
testMotion('%_parens', ['%'], parens1.end, parens1.start);
376
testMotion('%_squares', ['%'], squares1.end, squares1.start);
377
testMotion('%_braces', ['%'], curlys1.end, curlys1.start);
378
testMotion('%_seek_outside', ['%'], seekOutside.end, seekOutside.start);
379
testMotion('%_seek_inside', ['%'], seekInside.end, seekInside.start);
380
testVim('%_seek_skip', function(cm, vim, helpers) {
381
  cm.setCursor(0,0);
382
  helpers.doKeys(['%']);
383
  helpers.assertCursorAt(0,9);
384
}, {value:'01234"("()'});
385
testVim('%_skip_string', function(cm, vim, helpers) {
386
  cm.setCursor(0,0);
387
  helpers.doKeys(['%']);
388
  helpers.assertCursorAt(0,4);
389
  cm.setCursor(0,2);
390
  helpers.doKeys(['%']);
391
  helpers.assertCursorAt(0,0);
392
}, {value:'(")")'});
393
testVim('%_skip_comment', function(cm, vim, helpers) {
394
  cm.setCursor(0,0);
395
  helpers.doKeys(['%']);
396
  helpers.assertCursorAt(0,6);
397
  cm.setCursor(0,3);
398
  helpers.doKeys(['%']);
399
  helpers.assertCursorAt(0,0);
400
}, {value:'(/*)*/)'});
401
// Make sure that moving down after going to the end of a line always leaves you
402
// at the end of a line, but preserves the offset in other cases
403
testVim('Changing lines after Eol operation', function(cm, vim, helpers) {
404
  cm.setCursor(0,0);
405
  helpers.doKeys(['$']);
406
  helpers.doKeys(['j']);
407
  // After moving to Eol and then down, we should be at Eol of line 2
408
  helpers.assertCursorAt({ line: 1, ch: lines[1].length - 1 });
409
  helpers.doKeys(['j']);
410
  // After moving down, we should be at Eol of line 3
411
  helpers.assertCursorAt({ line: 2, ch: lines[2].length - 1 });
412
  helpers.doKeys(['h']);
413
  helpers.doKeys(['j']);
414
  // After moving back one space and then down, since line 4 is shorter than line 2, we should
415
  // be at Eol of line 2 - 1
416
  helpers.assertCursorAt({ line: 3, ch: lines[3].length - 1 });
417
  helpers.doKeys(['j']);
418
  helpers.doKeys(['j']);
419
  // After moving down again, since line 3 has enough characters, we should be back to the
420
  // same place we were at on line 1
421
  helpers.assertCursorAt({ line: 5, ch: lines[2].length - 2 });
422
});
423
//making sure gj and gk recover from clipping
424
testVim('gj_gk_clipping', function(cm,vim,helpers){
425
  cm.setCursor(0, 1);
426
  helpers.doKeys('g','j','g','j');
427
  helpers.assertCursorAt(2, 1);
428
  helpers.doKeys('g','k','g','k');
429
  helpers.assertCursorAt(0, 1);
430
},{value: 'line 1\n\nline 2'});
431
//testing a mix of j/k and gj/gk
432
testVim('j_k_and_gj_gk', function(cm,vim,helpers){
433
  cm.setSize(120);
434
  cm.setCursor(0, 0);
435
  //go to the last character on the first line
436
  helpers.doKeys('$');
437
  //move up/down on the column within the wrapped line
438
  //side-effect: cursor is not locked to eol anymore
439
  helpers.doKeys('g','k');
440
  var cur=cm.getCursor();
441
  eq(cur.line,0);
442
  is((cur.ch<176),'gk didn\'t move cursor back (1)');
443
  helpers.doKeys('g','j');
444
  helpers.assertCursorAt(0, 176);
445
  //should move to character 177 on line 2 (j/k preserve character index within line)
446
  helpers.doKeys('j');
447
  //due to different line wrapping, the cursor can be on a different screen-x now
448
  //gj and gk preserve screen-x on movement, much like moveV
449
  helpers.doKeys('3','g','k');
450
  cur=cm.getCursor();
451
  eq(cur.line,1);
452
  is((cur.ch<176),'gk didn\'t move cursor back (2)');
453
  helpers.doKeys('g','j','2','g','j');
454
  //should return to the same character-index
455
  helpers.doKeys('k');
456
  helpers.assertCursorAt(0, 176);
457
},{ lineWrapping:true, value: 'This line is intentially long to test movement of gj and gk over wrapped lines. I will start on the end of this line, then make a step up and back to set the origin for j and k.\nThis line is supposed to be even longer than the previous. I will jump here and make another wiggle with gj and gk, before I jump back to the line above. Both wiggles should not change my cursor\'s target character but both j/k and gj/gk change each other\'s reference position.'});
458
testVim('gj_gk', function(cm, vim, helpers) {
459
  if (phantom) return;
0 ignored issues
show
Best Practice introduced by
If you intend to check if the variable phantom is declared in the current environment, consider using typeof phantom === "undefined" instead. This is safe if the variable is not actually declared.
Loading history...
460
  cm.setSize(120);
461
  // Test top of document edge case.
462
  cm.setCursor(0, 4);
463
  helpers.doKeys('g', 'j');
464
  helpers.doKeys('10', 'g', 'k');
465
  helpers.assertCursorAt(0, 4);
466
467
  // Test moving down preserves column position.
468
  helpers.doKeys('g', 'j');
469
  var pos1 = cm.getCursor();
470
  var expectedPos2 = { line: 0, ch: (pos1.ch - 4) * 2 + 4};
471
  helpers.doKeys('g', 'j');
472
  helpers.assertCursorAt(expectedPos2);
473
474
  // Move to the last character
475
  cm.setCursor(0, 0);
476
  // Move left to reset HSPos
477
  helpers.doKeys('h');
478
  // Test bottom of document edge case.
479
  helpers.doKeys('100', 'g', 'j');
480
  var endingPos = cm.getCursor();
481
  is(endingPos != 0, 'gj should not be on wrapped line 0');
0 ignored issues
show
Best Practice introduced by
Comparing endingPos to 0 using the != operator is not safe. Consider using !== instead.
Loading history...
482
  var topLeftCharCoords = cm.charCoords(makeCursor(0, 0));
483
  var endingCharCoords = cm.charCoords(endingPos);
484
  is(topLeftCharCoords.left == endingCharCoords.left, 'gj should end up on column 0');
485
},{ lineNumbers: false, lineWrapping:true, value: 'Thislineisintentiallylongtotestmovementofgjandgkoverwrappedlines.' });
486
testVim('}', function(cm, vim, helpers) {
487
  cm.setCursor(0, 0);
488
  helpers.doKeys('}');
489
  helpers.assertCursorAt(1, 0);
490
  cm.setCursor(0, 0);
491
  helpers.doKeys('2', '}');
492
  helpers.assertCursorAt(4, 0);
493
  cm.setCursor(0, 0);
494
  helpers.doKeys('6', '}');
495
  helpers.assertCursorAt(5, 0);
496
}, { value: 'a\n\nb\nc\n\nd' });
497
testVim('{', function(cm, vim, helpers) {
498
  cm.setCursor(5, 0);
499
  helpers.doKeys('{');
500
  helpers.assertCursorAt(4, 0);
501
  cm.setCursor(5, 0);
502
  helpers.doKeys('2', '{');
503
  helpers.assertCursorAt(1, 0);
504
  cm.setCursor(5, 0);
505
  helpers.doKeys('6', '{');
506
  helpers.assertCursorAt(0, 0);
507
}, { value: 'a\n\nb\nc\n\nd' });
508
testVim('paragraph_motions', function(cm, vim, helpers) {
509
  cm.setCursor(10, 0);
510
  helpers.doKeys('{');
511
  helpers.assertCursorAt(4, 0);
512
  helpers.doKeys('{');
513
  helpers.assertCursorAt(0, 0);
514
  helpers.doKeys('2', '}');
515
  helpers.assertCursorAt(7, 0);
516
  helpers.doKeys('2', '}');
517
  helpers.assertCursorAt(16, 0);
518
519
  cm.setCursor(9, 0);
520
  helpers.doKeys('}');
521
  helpers.assertCursorAt(14, 0);
522
523
  cm.setCursor(6, 0);
524
  helpers.doKeys('}');
525
  helpers.assertCursorAt(7, 0);
526
527
  // ip inside empty space
528
  cm.setCursor(10, 0);
529
  helpers.doKeys('v', 'i', 'p');
530
  eqPos(Pos(7, 0), cm.getCursor('anchor'));
531
  eqPos(Pos(12, 0), cm.getCursor('head'));
532
  helpers.doKeys('i', 'p');
533
  eqPos(Pos(7, 0), cm.getCursor('anchor'));
534
  eqPos(Pos(13, 1), cm.getCursor('head'));
535
  helpers.doKeys('2', 'i', 'p');
536
  eqPos(Pos(7, 0), cm.getCursor('anchor'));
537
  eqPos(Pos(16, 1), cm.getCursor('head'));
538
539
  // should switch to visualLine mode
540
  cm.setCursor(14, 0);
541
  helpers.doKeys('<Esc>', 'v', 'i', 'p');
542
  helpers.assertCursorAt(14, 0);
543
544
  cm.setCursor(14, 0);
545
  helpers.doKeys('<Esc>', 'V', 'i', 'p');
546
  eqPos(Pos(16, 1), cm.getCursor('head'));
547
548
  // ap inside empty space
549
  cm.setCursor(10, 0);
550
  helpers.doKeys('<Esc>', 'v', 'a', 'p');
551
  eqPos(Pos(7, 0), cm.getCursor('anchor'));
552
  eqPos(Pos(13, 1), cm.getCursor('head'));
553
  helpers.doKeys('a', 'p');
554
  eqPos(Pos(7, 0), cm.getCursor('anchor'));
555
  eqPos(Pos(16, 1), cm.getCursor('head'));
556
557
  cm.setCursor(13, 0);
558
  helpers.doKeys('v', 'a', 'p');
559
  eqPos(Pos(13, 0), cm.getCursor('anchor'));
560
  eqPos(Pos(14, 0), cm.getCursor('head'));
561
562
  cm.setCursor(16, 0);
563
  helpers.doKeys('v', 'a', 'p');
564
  eqPos(Pos(14, 0), cm.getCursor('anchor'));
565
  eqPos(Pos(16, 1), cm.getCursor('head'));
566
567
  cm.setCursor(0, 0);
568
  helpers.doKeys('v', 'a', 'p');
569
  eqPos(Pos(0, 0), cm.getCursor('anchor'));
570
  eqPos(Pos(4, 0), cm.getCursor('head'));
571
572
  cm.setCursor(0, 0);
573
  helpers.doKeys('d', 'i', 'p');
574
  var register = helpers.getRegisterController().getRegister();
575
  eq('a\na\n', register.toString());
576
  is(register.linewise);
577
  helpers.doKeys('3', 'j', 'p');
578
  helpers.doKeys('y', 'i', 'p');
579
  is(register.linewise);
580
  eq('b\na\na\nc\n', register.toString());
581
}, { value: 'a\na\n\n\n\nb\nc\n\n\n\n\n\n\nd\n\ne\nf' });
582
583
// Operator tests
584
testVim('dl', function(cm, vim, helpers) {
585
  var curStart = makeCursor(0, 0);
586
  cm.setCursor(curStart);
587
  helpers.doKeys('d', 'l');
588
  eq('word1 ', cm.getValue());
589
  var register = helpers.getRegisterController().getRegister();
590
  eq(' ', register.toString());
591
  is(!register.linewise);
592
  eqPos(curStart, cm.getCursor());
593
}, { value: ' word1 ' });
594
testVim('dl_eol', function(cm, vim, helpers) {
595
  cm.setCursor(0, 6);
596
  helpers.doKeys('d', 'l');
597
  eq(' word1', cm.getValue());
598
  var register = helpers.getRegisterController().getRegister();
599
  eq(' ', register.toString());
600
  is(!register.linewise);
601
  helpers.assertCursorAt(0, 5);
602
}, { value: ' word1 ' });
603
testVim('dl_repeat', function(cm, vim, helpers) {
604
  var curStart = makeCursor(0, 0);
605
  cm.setCursor(curStart);
606
  helpers.doKeys('2', 'd', 'l');
607
  eq('ord1 ', cm.getValue());
608
  var register = helpers.getRegisterController().getRegister();
609
  eq(' w', register.toString());
610
  is(!register.linewise);
611
  eqPos(curStart, cm.getCursor());
612
}, { value: ' word1 ' });
613
testVim('dh', function(cm, vim, helpers) {
614
  var curStart = makeCursor(0, 3);
615
  cm.setCursor(curStart);
616
  helpers.doKeys('d', 'h');
617
  eq(' wrd1 ', cm.getValue());
618
  var register = helpers.getRegisterController().getRegister();
619
  eq('o', register.toString());
620
  is(!register.linewise);
621
  eqPos(offsetCursor(curStart, 0 , -1), cm.getCursor());
622
}, { value: ' word1 ' });
623
testVim('dj', function(cm, vim, helpers) {
624
  var curStart = makeCursor(0, 3);
625
  cm.setCursor(curStart);
626
  helpers.doKeys('d', 'j');
627
  eq(' word3', cm.getValue());
628
  var register = helpers.getRegisterController().getRegister();
629
  eq(' word1\nword2\n', register.toString());
630
  is(register.linewise);
631
  helpers.assertCursorAt(0, 1);
632
}, { value: ' word1\nword2\n word3' });
633
testVim('dj_end_of_document', function(cm, vim, helpers) {
634
  var curStart = makeCursor(0, 3);
635
  cm.setCursor(curStart);
636
  helpers.doKeys('d', 'j');
637
  eq(' word1 ', cm.getValue());
638
  var register = helpers.getRegisterController().getRegister();
639
  eq('', register.toString());
640
  is(!register.linewise);
641
  helpers.assertCursorAt(0, 3);
642
}, { value: ' word1 ' });
643
testVim('dk', function(cm, vim, helpers) {
644
  var curStart = makeCursor(1, 3);
645
  cm.setCursor(curStart);
646
  helpers.doKeys('d', 'k');
647
  eq(' word3', cm.getValue());
648
  var register = helpers.getRegisterController().getRegister();
649
  eq(' word1\nword2\n', register.toString());
650
  is(register.linewise);
651
  helpers.assertCursorAt(0, 1);
652
}, { value: ' word1\nword2\n word3' });
653
testVim('dk_start_of_document', function(cm, vim, helpers) {
654
  var curStart = makeCursor(0, 3);
655
  cm.setCursor(curStart);
656
  helpers.doKeys('d', 'k');
657
  eq(' word1 ', cm.getValue());
658
  var register = helpers.getRegisterController().getRegister();
659
  eq('', register.toString());
660
  is(!register.linewise);
661
  helpers.assertCursorAt(0, 3);
662
}, { value: ' word1 ' });
663
testVim('dw_space', function(cm, vim, helpers) {
664
  var curStart = makeCursor(0, 0);
665
  cm.setCursor(curStart);
666
  helpers.doKeys('d', 'w');
667
  eq('word1 ', cm.getValue());
668
  var register = helpers.getRegisterController().getRegister();
669
  eq(' ', register.toString());
670
  is(!register.linewise);
671
  eqPos(curStart, cm.getCursor());
672
}, { value: ' word1 ' });
673
testVim('dw_word', function(cm, vim, helpers) {
674
  var curStart = makeCursor(0, 1);
675
  cm.setCursor(curStart);
676
  helpers.doKeys('d', 'w');
677
  eq(' word2', cm.getValue());
678
  var register = helpers.getRegisterController().getRegister();
679
  eq('word1 ', register.toString());
680
  is(!register.linewise);
681
  eqPos(curStart, cm.getCursor());
682
}, { value: ' word1 word2' });
683
testVim('dw_unicode_word', function(cm, vim, helpers) {
684
  helpers.doKeys('d', 'w');
685
  eq(cm.getValue().length, 10);
686
  helpers.doKeys('d', 'w');
687
  eq(cm.getValue().length, 6);
688
  helpers.doKeys('d', 'w');
689
  eq(cm.getValue().length, 5);
690
  helpers.doKeys('d', 'e');
691
  eq(cm.getValue().length, 2);
692
}, { value: '  \u0562\u0561\u0580\u0587\xbbe\xb5g  ' });
693
testVim('dw_only_word', function(cm, vim, helpers) {
694
  // Test that if there is only 1 word left, dw deletes till the end of the
695
  // line.
696
  cm.setCursor(0, 1);
697
  helpers.doKeys('d', 'w');
698
  eq(' ', cm.getValue());
699
  var register = helpers.getRegisterController().getRegister();
700
  eq('word1 ', register.toString());
701
  is(!register.linewise);
702
  helpers.assertCursorAt(0, 0);
703
}, { value: ' word1 ' });
704
testVim('dw_eol', function(cm, vim, helpers) {
705
  // Assert that dw does not delete the newline if last word to delete is at end
706
  // of line.
707
  cm.setCursor(0, 1);
708
  helpers.doKeys('d', 'w');
709
  eq(' \nword2', cm.getValue());
710
  var register = helpers.getRegisterController().getRegister();
711
  eq('word1', register.toString());
712
  is(!register.linewise);
713
  helpers.assertCursorAt(0, 0);
714
}, { value: ' word1\nword2' });
715
testVim('dw_eol_with_multiple_newlines', function(cm, vim, helpers) {
716
  // Assert that dw does not delete the newline if last word to delete is at end
717
  // of line and it is followed by multiple newlines.
718
  cm.setCursor(0, 1);
719
  helpers.doKeys('d', 'w');
720
  eq(' \n\nword2', cm.getValue());
721
  var register = helpers.getRegisterController().getRegister();
722
  eq('word1', register.toString());
723
  is(!register.linewise);
724
  helpers.assertCursorAt(0, 0);
725
}, { value: ' word1\n\nword2' });
726
testVim('dw_empty_line_followed_by_whitespace', function(cm, vim, helpers) {
727
  cm.setCursor(0, 0);
728
  helpers.doKeys('d', 'w');
729
  eq('  \nword', cm.getValue());
730
}, { value: '\n  \nword' });
731
testVim('dw_empty_line_followed_by_word', function(cm, vim, helpers) {
732
  cm.setCursor(0, 0);
733
  helpers.doKeys('d', 'w');
734
  eq('word', cm.getValue());
735
}, { value: '\nword' });
736
testVim('dw_empty_line_followed_by_empty_line', function(cm, vim, helpers) {
737
  cm.setCursor(0, 0);
738
  helpers.doKeys('d', 'w');
739
  eq('\n', cm.getValue());
740
}, { value: '\n\n' });
741
testVim('dw_whitespace_followed_by_whitespace', function(cm, vim, helpers) {
742
  cm.setCursor(0, 0);
743
  helpers.doKeys('d', 'w');
744
  eq('\n   \n', cm.getValue());
745
}, { value: '  \n   \n' });
746
testVim('dw_whitespace_followed_by_empty_line', function(cm, vim, helpers) {
747
  cm.setCursor(0, 0);
748
  helpers.doKeys('d', 'w');
749
  eq('\n\n', cm.getValue());
750
}, { value: '  \n\n' });
751
testVim('dw_word_whitespace_word', function(cm, vim, helpers) {
752
  cm.setCursor(0, 0);
753
  helpers.doKeys('d', 'w');
754
  eq('\n   \nword2', cm.getValue());
755
}, { value: 'word1\n   \nword2'})
756
testVim('dw_end_of_document', function(cm, vim, helpers) {
757
  cm.setCursor(1, 2);
758
  helpers.doKeys('d', 'w');
759
  eq('\nab', cm.getValue());
760
}, { value: '\nabc' });
761
testVim('dw_repeat', function(cm, vim, helpers) {
762
  // Assert that dw does delete newline if it should go to the next line, and
763
  // that repeat works properly.
764
  cm.setCursor(0, 1);
765
  helpers.doKeys('d', '2', 'w');
766
  eq(' ', cm.getValue());
767
  var register = helpers.getRegisterController().getRegister();
768
  eq('word1\nword2', register.toString());
769
  is(!register.linewise);
770
  helpers.assertCursorAt(0, 0);
771
}, { value: ' word1\nword2' });
772
testVim('de_word_start_and_empty_lines', function(cm, vim, helpers) {
773
  cm.setCursor(0, 0);
774
  helpers.doKeys('d', 'e');
775
  eq('\n\n', cm.getValue());
776
}, { value: 'word\n\n' });
777
testVim('de_word_end_and_empty_lines', function(cm, vim, helpers) {
778
  cm.setCursor(0, 3);
779
  helpers.doKeys('d', 'e');
780
  eq('wor', cm.getValue());
781
}, { value: 'word\n\n\n' });
782
testVim('de_whitespace_and_empty_lines', function(cm, vim, helpers) {
783
  cm.setCursor(0, 0);
784
  helpers.doKeys('d', 'e');
785
  eq('', cm.getValue());
786
}, { value: '   \n\n\n' });
787
testVim('de_end_of_document', function(cm, vim, helpers) {
788
  cm.setCursor(1, 2);
789
  helpers.doKeys('d', 'e');
790
  eq('\nab', cm.getValue());
791
}, { value: '\nabc' });
792
testVim('db_empty_lines', function(cm, vim, helpers) {
793
  cm.setCursor(2, 0);
794
  helpers.doKeys('d', 'b');
795
  eq('\n\n', cm.getValue());
796
}, { value: '\n\n\n' });
797
testVim('db_word_start_and_empty_lines', function(cm, vim, helpers) {
798
  cm.setCursor(2, 0);
799
  helpers.doKeys('d', 'b');
800
  eq('\nword', cm.getValue());
801
}, { value: '\n\nword' });
802
testVim('db_word_end_and_empty_lines', function(cm, vim, helpers) {
803
  cm.setCursor(2, 3);
804
  helpers.doKeys('d', 'b');
805
  eq('\n\nd', cm.getValue());
806
}, { value: '\n\nword' });
807
testVim('db_whitespace_and_empty_lines', function(cm, vim, helpers) {
808
  cm.setCursor(2, 0);
809
  helpers.doKeys('d', 'b');
810
  eq('', cm.getValue());
811
}, { value: '\n   \n' });
812
testVim('db_start_of_document', function(cm, vim, helpers) {
813
  cm.setCursor(0, 0);
814
  helpers.doKeys('d', 'b');
815
  eq('abc\n', cm.getValue());
816
}, { value: 'abc\n' });
817
testVim('dge_empty_lines', function(cm, vim, helpers) {
818
  cm.setCursor(1, 0);
819
  helpers.doKeys('d', 'g', 'e');
820
  // Note: In real VIM the result should be '', but it's not quite consistent,
821
  // since 2 newlines are deleted. But in the similar case of word\n\n, only
822
  // 1 newline is deleted. We'll diverge from VIM's behavior since it's much
823
  // easier this way.
824
  eq('\n', cm.getValue());
825
}, { value: '\n\n' });
826
testVim('dge_word_and_empty_lines', function(cm, vim, helpers) {
827
  cm.setCursor(1, 0);
828
  helpers.doKeys('d', 'g', 'e');
829
  eq('wor\n', cm.getValue());
830
}, { value: 'word\n\n'});
831
testVim('dge_whitespace_and_empty_lines', function(cm, vim, helpers) {
832
  cm.setCursor(2, 0);
833
  helpers.doKeys('d', 'g', 'e');
834
  eq('', cm.getValue());
835
}, { value: '\n  \n' });
836
testVim('dge_start_of_document', function(cm, vim, helpers) {
837
  cm.setCursor(0, 0);
838
  helpers.doKeys('d', 'g', 'e');
839
  eq('bc\n', cm.getValue());
840
}, { value: 'abc\n' });
841
testVim('d_inclusive', function(cm, vim, helpers) {
842
  // Assert that when inclusive is set, the character the cursor is on gets
843
  // deleted too.
844
  var curStart = makeCursor(0, 1);
845
  cm.setCursor(curStart);
846
  helpers.doKeys('d', 'e');
847
  eq('  ', cm.getValue());
848
  var register = helpers.getRegisterController().getRegister();
849
  eq('word1', register.toString());
850
  is(!register.linewise);
851
  eqPos(curStart, cm.getCursor());
852
}, { value: ' word1 ' });
853
testVim('d_reverse', function(cm, vim, helpers) {
854
  // Test that deleting in reverse works.
855
  cm.setCursor(1, 0);
856
  helpers.doKeys('d', 'b');
857
  eq(' word2 ', cm.getValue());
858
  var register = helpers.getRegisterController().getRegister();
859
  eq('word1\n', register.toString());
860
  is(!register.linewise);
861
  helpers.assertCursorAt(0, 1);
862
}, { value: ' word1\nword2 ' });
863
testVim('dd', function(cm, vim, helpers) {
864
  cm.setCursor(0, 3);
865
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
866
    { line: 1, ch: 0 });
867
  var expectedLineCount = cm.lineCount() - 1;
868
  helpers.doKeys('d', 'd');
869
  eq(expectedLineCount, cm.lineCount());
870
  var register = helpers.getRegisterController().getRegister();
871
  eq(expectedBuffer, register.toString());
872
  is(register.linewise);
873
  helpers.assertCursorAt(0, lines[1].textStart);
874
});
875
testVim('dd_prefix_repeat', function(cm, vim, helpers) {
876
  cm.setCursor(0, 3);
877
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
878
    { line: 2, ch: 0 });
879
  var expectedLineCount = cm.lineCount() - 2;
880
  helpers.doKeys('2', 'd', 'd');
881
  eq(expectedLineCount, cm.lineCount());
882
  var register = helpers.getRegisterController().getRegister();
883
  eq(expectedBuffer, register.toString());
884
  is(register.linewise);
885
  helpers.assertCursorAt(0, lines[2].textStart);
886
});
887
testVim('dd_motion_repeat', function(cm, vim, helpers) {
888
  cm.setCursor(0, 3);
889
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
890
    { line: 2, ch: 0 });
891
  var expectedLineCount = cm.lineCount() - 2;
892
  helpers.doKeys('d', '2', 'd');
893
  eq(expectedLineCount, cm.lineCount());
894
  var register = helpers.getRegisterController().getRegister();
895
  eq(expectedBuffer, register.toString());
896
  is(register.linewise);
897
  helpers.assertCursorAt(0, lines[2].textStart);
898
});
899
testVim('dd_multiply_repeat', function(cm, vim, helpers) {
900
  cm.setCursor(0, 3);
901
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
902
    { line: 6, ch: 0 });
903
  var expectedLineCount = cm.lineCount() - 6;
904
  helpers.doKeys('2', 'd', '3', 'd');
905
  eq(expectedLineCount, cm.lineCount());
906
  var register = helpers.getRegisterController().getRegister();
907
  eq(expectedBuffer, register.toString());
908
  is(register.linewise);
909
  helpers.assertCursorAt(0, lines[6].textStart);
910
});
911
testVim('dd_lastline', function(cm, vim, helpers) {
912
  cm.setCursor(cm.lineCount(), 0);
913
  var expectedLineCount = cm.lineCount() - 1;
914
  helpers.doKeys('d', 'd');
915
  eq(expectedLineCount, cm.lineCount());
916
  helpers.assertCursorAt(cm.lineCount() - 1, 0);
917
});
918
testVim('dd_only_line', function(cm, vim, helpers) {
919
  cm.setCursor(0, 0);
920
  var expectedRegister = cm.getValue() + "\n";
921
  helpers.doKeys('d','d');
922
  eq(1, cm.lineCount());
923
  eq('', cm.getValue());
924
  var register = helpers.getRegisterController().getRegister();
925
  eq(expectedRegister, register.toString());
926
}, { value: "thisistheonlyline" });
927
// Yank commands should behave the exact same as d commands, expect that nothing
928
// gets deleted.
929
testVim('yw_repeat', function(cm, vim, helpers) {
930
  // Assert that yw does yank newline if it should go to the next line, and
931
  // that repeat works properly.
932
  var curStart = makeCursor(0, 1);
933
  cm.setCursor(curStart);
934
  helpers.doKeys('y', '2', 'w');
935
  eq(' word1\nword2', cm.getValue());
936
  var register = helpers.getRegisterController().getRegister();
937
  eq('word1\nword2', register.toString());
938
  is(!register.linewise);
939
  eqPos(curStart, cm.getCursor());
940
}, { value: ' word1\nword2' });
941
testVim('yy_multiply_repeat', function(cm, vim, helpers) {
942
  var curStart = makeCursor(0, 3);
943
  cm.setCursor(curStart);
944
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
945
    { line: 6, ch: 0 });
946
  var expectedLineCount = cm.lineCount();
947
  helpers.doKeys('2', 'y', '3', 'y');
948
  eq(expectedLineCount, cm.lineCount());
949
  var register = helpers.getRegisterController().getRegister();
950
  eq(expectedBuffer, register.toString());
951
  is(register.linewise);
952
  eqPos(curStart, cm.getCursor());
953
});
954
// Change commands behave like d commands except that it also enters insert
955
// mode. In addition, when the change is linewise, an additional newline is
956
// inserted so that insert mode starts on that line.
957
testVim('cw', function(cm, vim, helpers) {
958
  cm.setCursor(0, 0);
959
  helpers.doKeys('c', '2', 'w');
960
  eq(' word3', cm.getValue());
961
  helpers.assertCursorAt(0, 0);
962
}, { value: 'word1 word2 word3'});
963
testVim('cw_repeat', function(cm, vim, helpers) {
964
  // Assert that cw does delete newline if it should go to the next line, and
965
  // that repeat works properly.
966
  var curStart = makeCursor(0, 1);
967
  cm.setCursor(curStart);
968
  helpers.doKeys('c', '2', 'w');
969
  eq(' ', cm.getValue());
970
  var register = helpers.getRegisterController().getRegister();
971
  eq('word1\nword2', register.toString());
972
  is(!register.linewise);
973
  eqPos(curStart, cm.getCursor());
974
  eq('vim-insert', cm.getOption('keyMap'));
975
}, { value: ' word1\nword2' });
976
testVim('cc_multiply_repeat', function(cm, vim, helpers) {
977
  cm.setCursor(0, 3);
978
  var expectedBuffer = cm.getRange({ line: 0, ch: 0 },
979
    { line: 6, ch: 0 });
980
  var expectedLineCount = cm.lineCount() - 5;
981
  helpers.doKeys('2', 'c', '3', 'c');
982
  eq(expectedLineCount, cm.lineCount());
983
  var register = helpers.getRegisterController().getRegister();
984
  eq(expectedBuffer, register.toString());
985
  is(register.linewise);
986
  eq('vim-insert', cm.getOption('keyMap'));
987
});
988
testVim('ct', function(cm, vim, helpers) {
989
  cm.setCursor(0, 9);
990
  helpers.doKeys('c', 't', 'w');
991
  eq('  word1  word3', cm.getValue());
992
  helpers.doKeys('<Esc>', 'c', '|');
993
  eq(' word3', cm.getValue());
994
  helpers.assertCursorAt(0, 0);
995
  helpers.doKeys('<Esc>', '2', 'u', 'w', 'h');
996
  helpers.doKeys('c', '2', 'g', 'e');
997
  eq('  wordword3', cm.getValue());
998
}, { value: '  word1  word2  word3'});
999
testVim('cc_should_not_append_to_document', function(cm, vim, helpers) {
1000
  var expectedLineCount = cm.lineCount();
1001
  cm.setCursor(cm.lastLine(), 0);
1002
  helpers.doKeys('c', 'c');
1003
  eq(expectedLineCount, cm.lineCount());
1004
});
1005
function fillArray(val, times) {
1006
  var arr = [];
1007
  for (var i = 0; i < times; i++) {
1008
    arr.push(val);
1009
  }
1010
  return arr;
1011
}
1012
testVim('c_visual_block', function(cm, vim, helpers) {
1013
  cm.setCursor(0, 1);
1014
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 'c');
1015
  var replacement = fillArray('hello', 3);
1016
  cm.replaceSelections(replacement);
1017
  eq('1hello\n5hello\nahellofg', cm.getValue());
1018
  helpers.doKeys('<Esc>');
1019
  cm.setCursor(2, 3);
1020
  helpers.doKeys('<C-v>', '2', 'k', 'h', 'C');
1021
  replacement = fillArray('world', 3);
1022
  cm.replaceSelections(replacement);
1023
  eq('1hworld\n5hworld\nahworld', cm.getValue());
1024
}, {value: '1234\n5678\nabcdefg'});
1025
testVim('c_visual_block_replay', function(cm, vim, helpers) {
1026
  cm.setCursor(0, 1);
1027
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'c');
1028
  var replacement = fillArray('fo', 3);
1029
  cm.replaceSelections(replacement);
1030
  eq('1fo4\n5fo8\nafodefg', cm.getValue());
1031
  helpers.doKeys('<Esc>');
1032
  cm.setCursor(0, 0);
1033
  helpers.doKeys('.');
1034
  eq('foo4\nfoo8\nfoodefg', cm.getValue());
1035
}, {value: '1234\n5678\nabcdefg'});
1036
1037
testVim('d_visual_block', function(cm, vim, helpers) {
1038
  cm.setCursor(0, 1);
1039
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'l', 'd');
1040
  eq('1\n5\nafg', cm.getValue());
1041
}, {value: '1234\n5678\nabcdefg'});
1042
testVim('D_visual_block', function(cm, vim, helpers) {
1043
  cm.setCursor(0, 1);
1044
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'D');
1045
  eq('1\n5\na', cm.getValue());
1046
}, {value: '1234\n5678\nabcdefg'});
1047
1048
// Swapcase commands edit in place and do not modify registers.
1049
testVim('g~w_repeat', function(cm, vim, helpers) {
1050
  // Assert that dw does delete newline if it should go to the next line, and
1051
  // that repeat works properly.
1052
  var curStart = makeCursor(0, 1);
1053
  cm.setCursor(curStart);
1054
  helpers.doKeys('g', '~', '2', 'w');
1055
  eq(' WORD1\nWORD2', cm.getValue());
1056
  var register = helpers.getRegisterController().getRegister();
1057
  eq('', register.toString());
1058
  is(!register.linewise);
1059
  eqPos(curStart, cm.getCursor());
1060
}, { value: ' word1\nword2' });
1061
testVim('g~g~', function(cm, vim, helpers) {
1062
  var curStart = makeCursor(0, 3);
1063
  cm.setCursor(curStart);
1064
  var expectedLineCount = cm.lineCount();
0 ignored issues
show
Unused Code introduced by
The variable expectedLineCount seems to be never used. Consider removing it.
Loading history...
1065
  var expectedValue = cm.getValue().toUpperCase();
1066
  helpers.doKeys('2', 'g', '~', '3', 'g', '~');
1067
  eq(expectedValue, cm.getValue());
1068
  var register = helpers.getRegisterController().getRegister();
1069
  eq('', register.toString());
1070
  is(!register.linewise);
1071
  eqPos(curStart, cm.getCursor());
1072
}, { value: ' word1\nword2\nword3\nword4\nword5\nword6' });
1073
testVim('gu_and_gU', function(cm, vim, helpers) {
1074
  var curStart = makeCursor(0, 7);
1075
  var value = cm.getValue();
1076
  cm.setCursor(curStart);
1077
  helpers.doKeys('2', 'g', 'U', 'w');
1078
  eq(cm.getValue(), 'wa wb xX WC wd');
1079
  eqPos(curStart, cm.getCursor());
1080
  helpers.doKeys('2', 'g', 'u', 'w');
1081
  eq(cm.getValue(), value);
1082
1083
  helpers.doKeys('2', 'g', 'U', 'B');
1084
  eq(cm.getValue(), 'wa WB Xx wc wd');
1085
  eqPos(makeCursor(0, 3), cm.getCursor());
1086
1087
  cm.setCursor(makeCursor(0, 4));
1088
  helpers.doKeys('g', 'u', 'i', 'w');
1089
  eq(cm.getValue(), 'wa wb Xx wc wd');
1090
  eqPos(makeCursor(0, 3), cm.getCursor());
1091
1092
  // TODO: support gUgU guu
1093
  // eqPos(makeCursor(0, 0), cm.getCursor());
1094
1095
  var register = helpers.getRegisterController().getRegister();
1096
  eq('', register.toString());
1097
  is(!register.linewise);
1098
}, { value: 'wa wb xx wc wd' });
1099
testVim('visual_block_~', function(cm, vim, helpers) {
1100
  cm.setCursor(1, 1);
1101
  helpers.doKeys('<C-v>', 'l', 'l', 'j', '~');
1102
  helpers.assertCursorAt(1, 1);
1103
  eq('hello\nwoRLd\naBCDe', cm.getValue());
1104
  cm.setCursor(2, 0);
1105
  helpers.doKeys('v', 'l', 'l', '~');
1106
  helpers.assertCursorAt(2, 0);
1107
  eq('hello\nwoRLd\nAbcDe', cm.getValue());
1108
},{value: 'hello\nwOrld\nabcde' });
1109
testVim('._swapCase_visualBlock', function(cm, vim, helpers) {
1110
  helpers.doKeys('<C-v>', 'j', 'j', 'l', '~');
1111
  cm.setCursor(0, 3);
1112
  helpers.doKeys('.');
1113
  eq('HelLO\nWorLd\nAbcdE', cm.getValue());
1114
},{value: 'hEllo\nwOrlD\naBcDe' });
1115
testVim('._delete_visualBlock', function(cm, vim, helpers) {
1116
  helpers.doKeys('<C-v>', 'j', 'x');
1117
  eq('ive\ne\nsome\nsugar', cm.getValue());
1118
  helpers.doKeys('.');
1119
  eq('ve\n\nsome\nsugar', cm.getValue());
1120
  helpers.doKeys('j', 'j', '.');
1121
  eq('ve\n\nome\nugar', cm.getValue());
1122
  helpers.doKeys('u', '<C-r>', '.');
1123
  eq('ve\n\nme\ngar', cm.getValue());
1124
},{value: 'give\nme\nsome\nsugar' });
1125
testVim('>{motion}', function(cm, vim, helpers) {
1126
  cm.setCursor(1, 3);
1127
  var expectedLineCount = cm.lineCount();
0 ignored issues
show
Unused Code introduced by
The variable expectedLineCount seems to be never used. Consider removing it.
Loading history...
1128
  var expectedValue = '   word1\n  word2\nword3 ';
1129
  helpers.doKeys('>', 'k');
1130
  eq(expectedValue, cm.getValue());
1131
  var register = helpers.getRegisterController().getRegister();
1132
  eq('', register.toString());
1133
  is(!register.linewise);
1134
  helpers.assertCursorAt(0, 3);
1135
}, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
1136
testVim('>>', function(cm, vim, helpers) {
1137
  cm.setCursor(0, 3);
1138
  var expectedLineCount = cm.lineCount();
0 ignored issues
show
Unused Code introduced by
The variable expectedLineCount seems to be never used. Consider removing it.
Loading history...
1139
  var expectedValue = '   word1\n  word2\nword3 ';
1140
  helpers.doKeys('2', '>', '>');
1141
  eq(expectedValue, cm.getValue());
1142
  var register = helpers.getRegisterController().getRegister();
1143
  eq('', register.toString());
1144
  is(!register.linewise);
1145
  helpers.assertCursorAt(0, 3);
1146
}, { value: ' word1\nword2\nword3 ', indentUnit: 2 });
1147
testVim('<{motion}', function(cm, vim, helpers) {
1148
  cm.setCursor(1, 3);
1149
  var expectedLineCount = cm.lineCount();
0 ignored issues
show
Unused Code introduced by
The variable expectedLineCount seems to be never used. Consider removing it.
Loading history...
1150
  var expectedValue = ' word1\nword2\nword3 ';
1151
  helpers.doKeys('<', 'k');
1152
  eq(expectedValue, cm.getValue());
1153
  var register = helpers.getRegisterController().getRegister();
1154
  eq('', register.toString());
1155
  is(!register.linewise);
1156
  helpers.assertCursorAt(0, 1);
1157
}, { value: '   word1\n  word2\nword3 ', indentUnit: 2 });
1158
testVim('<<', function(cm, vim, helpers) {
1159
  cm.setCursor(0, 3);
1160
  var expectedLineCount = cm.lineCount();
0 ignored issues
show
Unused Code introduced by
The variable expectedLineCount seems to be never used. Consider removing it.
Loading history...
1161
  var expectedValue = ' word1\nword2\nword3 ';
1162
  helpers.doKeys('2', '<', '<');
1163
  eq(expectedValue, cm.getValue());
1164
  var register = helpers.getRegisterController().getRegister();
1165
  eq('', register.toString());
1166
  is(!register.linewise);
1167
  helpers.assertCursorAt(0, 1);
1168
}, { value: '   word1\n  word2\nword3 ', indentUnit: 2 });
1169
1170
// Edit tests
1171
function testEdit(name, before, pos, edit, after) {
1172
  return testVim(name, function(cm, vim, helpers) {
1173
             var ch = before.search(pos)
1174
             var line = before.substring(0, ch).split('\n').length - 1;
1175
             if (line) {
1176
               ch = before.substring(0, ch).split('\n').pop().length;
1177
             }
1178
             cm.setCursor(line, ch);
1179
             helpers.doKeys.apply(this, edit.split(''));
1180
             eq(after, cm.getValue());
1181
           }, {value: before});
1182
}
1183
1184
// These Delete tests effectively cover word-wise Change, Visual & Yank.
1185
// Tabs are used as differentiated whitespace to catch edge cases.
1186
// Normal word:
1187
testEdit('diw_mid_spc', 'foo \tbAr\t baz', /A/, 'diw', 'foo \t\t baz');
1188
testEdit('daw_mid_spc', 'foo \tbAr\t baz', /A/, 'daw', 'foo \tbaz');
1189
testEdit('diw_mid_punct', 'foo \tbAr.\t baz', /A/, 'diw', 'foo \t.\t baz');
1190
testEdit('daw_mid_punct', 'foo \tbAr.\t baz', /A/, 'daw', 'foo.\t baz');
1191
testEdit('diw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diw', 'foo \t,.\t baz');
1192
testEdit('daw_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daw', 'foo \t,.\t baz');
1193
testEdit('diw_start_spc', 'bAr \tbaz', /A/, 'diw', ' \tbaz');
1194
testEdit('daw_start_spc', 'bAr \tbaz', /A/, 'daw', 'baz');
1195
testEdit('diw_start_punct', 'bAr. \tbaz', /A/, 'diw', '. \tbaz');
1196
testEdit('daw_start_punct', 'bAr. \tbaz', /A/, 'daw', '. \tbaz');
1197
testEdit('diw_end_spc', 'foo \tbAr', /A/, 'diw', 'foo \t');
1198
testEdit('daw_end_spc', 'foo \tbAr', /A/, 'daw', 'foo');
1199
testEdit('diw_end_punct', 'foo \tbAr.', /A/, 'diw', 'foo \t.');
1200
testEdit('daw_end_punct', 'foo \tbAr.', /A/, 'daw', 'foo.');
1201
// Big word:
1202
testEdit('diW_mid_spc', 'foo \tbAr\t baz', /A/, 'diW', 'foo \t\t baz');
1203
testEdit('daW_mid_spc', 'foo \tbAr\t baz', /A/, 'daW', 'foo \tbaz');
1204
testEdit('diW_mid_punct', 'foo \tbAr.\t baz', /A/, 'diW', 'foo \t\t baz');
1205
testEdit('daW_mid_punct', 'foo \tbAr.\t baz', /A/, 'daW', 'foo \tbaz');
1206
testEdit('diW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'diW', 'foo \t\t baz');
1207
testEdit('daW_mid_punct2', 'foo \t,bAr.\t baz', /A/, 'daW', 'foo \tbaz');
1208
testEdit('diW_start_spc', 'bAr\t baz', /A/, 'diW', '\t baz');
1209
testEdit('daW_start_spc', 'bAr\t baz', /A/, 'daW', 'baz');
1210
testEdit('diW_start_punct', 'bAr.\t baz', /A/, 'diW', '\t baz');
1211
testEdit('daW_start_punct', 'bAr.\t baz', /A/, 'daW', 'baz');
1212
testEdit('diW_end_spc', 'foo \tbAr', /A/, 'diW', 'foo \t');
1213
testEdit('daW_end_spc', 'foo \tbAr', /A/, 'daW', 'foo');
1214
testEdit('diW_end_punct', 'foo \tbAr.', /A/, 'diW', 'foo \t');
1215
testEdit('daW_end_punct', 'foo \tbAr.', /A/, 'daW', 'foo');
1216
// Deleting text objects
1217
//    Open and close on same line
1218
testEdit('di(_open_spc', 'foo (bAr) baz', /\(/, 'di(', 'foo () baz');
1219
testEdit('di)_open_spc', 'foo (bAr) baz', /\(/, 'di)', 'foo () baz');
1220
testEdit('dib_open_spc', 'foo (bAr) baz', /\(/, 'dib', 'foo () baz');
1221
testEdit('da(_open_spc', 'foo (bAr) baz', /\(/, 'da(', 'foo  baz');
1222
testEdit('da)_open_spc', 'foo (bAr) baz', /\(/, 'da)', 'foo  baz');
1223
1224
testEdit('di(_middle_spc', 'foo (bAr) baz', /A/, 'di(', 'foo () baz');
1225
testEdit('di)_middle_spc', 'foo (bAr) baz', /A/, 'di)', 'foo () baz');
1226
testEdit('da(_middle_spc', 'foo (bAr) baz', /A/, 'da(', 'foo  baz');
1227
testEdit('da)_middle_spc', 'foo (bAr) baz', /A/, 'da)', 'foo  baz');
1228
1229
testEdit('di(_close_spc', 'foo (bAr) baz', /\)/, 'di(', 'foo () baz');
1230
testEdit('di)_close_spc', 'foo (bAr) baz', /\)/, 'di)', 'foo () baz');
1231
testEdit('da(_close_spc', 'foo (bAr) baz', /\)/, 'da(', 'foo  baz');
1232
testEdit('da)_close_spc', 'foo (bAr) baz', /\)/, 'da)', 'foo  baz');
1233
1234
//  delete around and inner b.
1235
testEdit('dab_on_(_should_delete_around_()block', 'o( in(abc) )', /\(a/, 'dab', 'o( in )');
1236
1237
//  delete around and inner B.
1238
testEdit('daB_on_{_should_delete_around_{}block', 'o{ in{abc} }', /{a/, 'daB', 'o{ in }');
1239
testEdit('diB_on_{_should_delete_inner_{}block', 'o{ in{abc} }', /{a/, 'diB', 'o{ in{} }');
1240
1241
testEdit('da{_on_{_should_delete_inner_block', 'o{ in{abc} }', /{a/, 'da{', 'o{ in }');
1242
testEdit('di[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'di[', 'foo (bAr) baz');
1243
testEdit('di[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'di[', 'foo (bAr) baz');
1244
testEdit('da[_on_(_should_not_delete', 'foo (bAr) baz', /\(/, 'da[', 'foo (bAr) baz');
1245
testEdit('da[_on_)_should_not_delete', 'foo (bAr) baz', /\)/, 'da[', 'foo (bAr) baz');
1246
testMotion('di(_outside_should_stay', ['d', 'i', '('], { line: 0, ch: 0}, { line: 0, ch: 0});
1247
1248
//  Open and close on different lines, equally indented
1249
testEdit('di{_middle_spc', 'a{\n\tbar\n}b', /r/, 'di{', 'a{}b');
1250
testEdit('di}_middle_spc', 'a{\n\tbar\n}b', /r/, 'di}', 'a{}b');
1251
testEdit('da{_middle_spc', 'a{\n\tbar\n}b', /r/, 'da{', 'ab');
1252
testEdit('da}_middle_spc', 'a{\n\tbar\n}b', /r/, 'da}', 'ab');
1253
testEdit('daB_middle_spc', 'a{\n\tbar\n}b', /r/, 'daB', 'ab');
1254
1255
// open and close on diff lines, open indented less than close
1256
testEdit('di{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di{', 'a{}b');
1257
testEdit('di}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'di}', 'a{}b');
1258
testEdit('da{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da{', 'ab');
1259
testEdit('da}_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'da}', 'ab');
1260
1261
// open and close on diff lines, open indented more than close
1262
testEdit('di[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di[', 'a\t[]b');
1263
testEdit('di]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'di]', 'a\t[]b');
1264
testEdit('da[_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da[', 'a\tb');
1265
testEdit('da]_middle_spc', 'a\t[\n\tbar\n]b', /r/, 'da]', 'a\tb');
1266
1267
function testSelection(name, before, pos, keys, sel) {
1268
  return testVim(name, function(cm, vim, helpers) {
1269
             var ch = before.search(pos)
1270
             var line = before.substring(0, ch).split('\n').length - 1;
1271
             if (line) {
1272
               ch = before.substring(0, ch).split('\n').pop().length;
1273
             }
1274
             cm.setCursor(line, ch);
1275
             helpers.doKeys.apply(this, keys.split(''));
1276
             eq(sel, cm.getSelection());
1277
           }, {value: before});
1278
}
1279
testSelection('viw_middle_spc', 'foo \tbAr\t baz', /A/, 'viw', 'bAr');
1280
testSelection('vaw_middle_spc', 'foo \tbAr\t baz', /A/, 'vaw', 'bAr\t ');
1281
testSelection('viw_middle_punct', 'foo \tbAr,\t baz', /A/, 'viw', 'bAr');
1282
testSelection('vaW_middle_punct', 'foo \tbAr,\t baz', /A/, 'vaW', 'bAr,\t ');
1283
testSelection('viw_start_spc', 'foo \tbAr\t baz', /b/, 'viw', 'bAr');
1284
testSelection('viw_end_spc', 'foo \tbAr\t baz', /r/, 'viw', 'bAr');
1285
testSelection('viw_eol', 'foo \tbAr', /r/, 'viw', 'bAr');
1286
testSelection('vi{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'vi{', '\n\tbar\n\t');
1287
testSelection('va{_middle_spc', 'a{\n\tbar\n\t}b', /r/, 'va{', '{\n\tbar\n\t}');
1288
1289
testVim('mouse_select', function(cm, vim, helpers) {
1290
  cm.setSelection(Pos(0, 2), Pos(0, 4), {origin: '*mouse'});
1291
  is(cm.state.vim.visualMode);
1292
  is(!cm.state.vim.visualLine);
1293
  is(!cm.state.vim.visualBlock);
1294
  helpers.doKeys('<Esc>');
1295
  is(!cm.somethingSelected());
1296
  helpers.doKeys('g', 'v');
1297
  eq('cd', cm.getSelection());
1298
}, {value: 'abcdef'});
1299
1300
// Operator-motion tests
1301
testVim('D', function(cm, vim, helpers) {
1302
  cm.setCursor(0, 3);
1303
  helpers.doKeys('D');
1304
  eq(' wo\nword2\n word3', cm.getValue());
1305
  var register = helpers.getRegisterController().getRegister();
1306
  eq('rd1', register.toString());
1307
  is(!register.linewise);
1308
  helpers.assertCursorAt(0, 2);
1309
}, { value: ' word1\nword2\n word3' });
1310
testVim('C', function(cm, vim, helpers) {
1311
  var curStart = makeCursor(0, 3);
1312
  cm.setCursor(curStart);
1313
  helpers.doKeys('C');
1314
  eq(' wo\nword2\n word3', cm.getValue());
1315
  var register = helpers.getRegisterController().getRegister();
1316
  eq('rd1', register.toString());
1317
  is(!register.linewise);
1318
  eqPos(curStart, cm.getCursor());
1319
  eq('vim-insert', cm.getOption('keyMap'));
1320
}, { value: ' word1\nword2\n word3' });
1321
testVim('Y', function(cm, vim, helpers) {
1322
  var curStart = makeCursor(0, 3);
1323
  cm.setCursor(curStart);
1324
  helpers.doKeys('Y');
1325
  eq(' word1\nword2\n word3', cm.getValue());
1326
  var register = helpers.getRegisterController().getRegister();
1327
  eq('rd1', register.toString());
1328
  is(!register.linewise);
1329
  helpers.assertCursorAt(0, 3);
1330
}, { value: ' word1\nword2\n word3' });
1331
testVim('~', function(cm, vim, helpers) {
1332
  helpers.doKeys('3', '~');
1333
  eq('ABCdefg', cm.getValue());
1334
  helpers.assertCursorAt(0, 3);
1335
}, { value: 'abcdefg' });
1336
1337
// Action tests
1338
testVim('ctrl-a', function(cm, vim, helpers) {
1339
  cm.setCursor(0, 0);
1340
  helpers.doKeys('<C-a>');
1341
  eq('-9', cm.getValue());
1342
  helpers.assertCursorAt(0, 1);
1343
  helpers.doKeys('2','<C-a>');
1344
  eq('-7', cm.getValue());
1345
}, {value: '-10'});
1346
testVim('ctrl-x', function(cm, vim, helpers) {
1347
  cm.setCursor(0, 0);
1348
  helpers.doKeys('<C-x>');
1349
  eq('-1', cm.getValue());
1350
  helpers.assertCursorAt(0, 1);
1351
  helpers.doKeys('2','<C-x>');
1352
  eq('-3', cm.getValue());
1353
}, {value: '0'});
1354
testVim('<C-x>/<C-a> search forward', function(cm, vim, helpers) {
1355
  forEach(['<C-x>', '<C-a>'], function(key) {
1356
    cm.setCursor(0, 0);
1357
    helpers.doKeys(key);
1358
    helpers.assertCursorAt(0, 5);
1359
    helpers.doKeys('l');
1360
    helpers.doKeys(key);
1361
    helpers.assertCursorAt(0, 10);
1362
    cm.setCursor(0, 11);
1363
    helpers.doKeys(key);
1364
    helpers.assertCursorAt(0, 11);
1365
  });
1366
}, {value: '__jmp1 jmp2 jmp'});
1367
testVim('a', function(cm, vim, helpers) {
1368
  cm.setCursor(0, 1);
1369
  helpers.doKeys('a');
1370
  helpers.assertCursorAt(0, 2);
1371
  eq('vim-insert', cm.getOption('keyMap'));
1372
});
1373
testVim('a_eol', function(cm, vim, helpers) {
1374
  cm.setCursor(0, lines[0].length - 1);
1375
  helpers.doKeys('a');
1376
  helpers.assertCursorAt(0, lines[0].length);
1377
  eq('vim-insert', cm.getOption('keyMap'));
1378
});
1379
testVim('A_endOfSelectedArea', function(cm, vim, helpers) {
1380
  cm.setCursor(0, 0);
1381
  helpers.doKeys('v', 'j', 'l');
1382
  helpers.doKeys('A');
1383
  helpers.assertCursorAt(1, 2);
1384
  eq('vim-insert', cm.getOption('keyMap'));
1385
}, {value: 'foo\nbar'});
1386
testVim('i', function(cm, vim, helpers) {
1387
  cm.setCursor(0, 1);
1388
  helpers.doKeys('i');
1389
  helpers.assertCursorAt(0, 1);
1390
  eq('vim-insert', cm.getOption('keyMap'));
1391
});
1392
testVim('i_repeat', function(cm, vim, helpers) {
1393
  helpers.doKeys('3', 'i');
1394
  cm.replaceRange('test', cm.getCursor());
1395
  helpers.doKeys('<Esc>');
1396
  eq('testtesttest', cm.getValue());
1397
  helpers.assertCursorAt(0, 11);
1398
}, { value: '' });
1399
testVim('i_repeat_delete', function(cm, vim, helpers) {
1400
  cm.setCursor(0, 4);
1401
  helpers.doKeys('2', 'i');
1402
  cm.replaceRange('z', cm.getCursor());
1403
  helpers.doInsertModeKeys('Backspace', 'Backspace');
1404
  helpers.doKeys('<Esc>');
1405
  eq('abe', cm.getValue());
1406
  helpers.assertCursorAt(0, 1);
1407
}, { value: 'abcde' });
1408
testVim('A', function(cm, vim, helpers) {
1409
  helpers.doKeys('A');
1410
  helpers.assertCursorAt(0, lines[0].length);
1411
  eq('vim-insert', cm.getOption('keyMap'));
1412
});
1413
testVim('A_visual_block', function(cm, vim, helpers) {
1414
  cm.setCursor(0, 1);
1415
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'A');
1416
  var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' ');
1417
  replacement.pop();
1418
  cm.replaceSelections(replacement);
1419
  eq('testhello\nmehello\npleahellose', cm.getValue());
1420
  helpers.doKeys('<Esc>');
1421
  cm.setCursor(0, 0);
1422
  helpers.doKeys('.');
1423
  // TODO this doesn't work yet
1424
  // eq('teshellothello\nme hello hello\nplehelloahellose', cm.getValue());
1425
}, {value: 'test\nme\nplease'});
1426
testVim('I', function(cm, vim, helpers) {
1427
  cm.setCursor(0, 4);
1428
  helpers.doKeys('I');
1429
  helpers.assertCursorAt(0, lines[0].textStart);
1430
  eq('vim-insert', cm.getOption('keyMap'));
1431
});
1432
testVim('I_repeat', function(cm, vim, helpers) {
1433
  cm.setCursor(0, 1);
1434
  helpers.doKeys('3', 'I');
1435
  cm.replaceRange('test', cm.getCursor());
1436
  helpers.doKeys('<Esc>');
1437
  eq('testtesttestblah', cm.getValue());
1438
  helpers.assertCursorAt(0, 11);
1439
}, { value: 'blah' });
1440
testVim('I_visual_block', function(cm, vim, helpers) {
1441
  cm.setCursor(0, 0);
1442
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'l', 'I');
1443
  var replacement = new Array(cm.listSelections().length+1).join('hello ').split(' ');
1444
  replacement.pop();
1445
  cm.replaceSelections(replacement);
1446
  eq('hellotest\nhellome\nhelloplease', cm.getValue());
1447
}, {value: 'test\nme\nplease'});
1448
testVim('o', function(cm, vim, helpers) {
1449
  cm.setCursor(0, 4);
1450
  helpers.doKeys('o');
1451
  eq('word1\n\nword2', cm.getValue());
1452
  helpers.assertCursorAt(1, 0);
1453
  eq('vim-insert', cm.getOption('keyMap'));
1454
}, { value: 'word1\nword2' });
1455
testVim('o_repeat', function(cm, vim, helpers) {
1456
  cm.setCursor(0, 0);
1457
  helpers.doKeys('3', 'o');
1458
  cm.replaceRange('test', cm.getCursor());
1459
  helpers.doKeys('<Esc>');
1460
  eq('\ntest\ntest\ntest', cm.getValue());
1461
  helpers.assertCursorAt(3, 3);
1462
}, { value: '' });
1463
testVim('O', function(cm, vim, helpers) {
1464
  cm.setCursor(0, 4);
1465
  helpers.doKeys('O');
1466
  eq('\nword1\nword2', cm.getValue());
1467
  helpers.assertCursorAt(0, 0);
1468
  eq('vim-insert', cm.getOption('keyMap'));
1469
}, { value: 'word1\nword2' });
1470
testVim('J', function(cm, vim, helpers) {
1471
  cm.setCursor(0, 4);
1472
  helpers.doKeys('J');
1473
  var expectedValue = 'word1  word2\nword3\n word4';
1474
  eq(expectedValue, cm.getValue());
1475
  helpers.assertCursorAt(0, expectedValue.indexOf('word2') - 1);
1476
}, { value: 'word1 \n    word2\nword3\n word4' });
1477
testVim('J_repeat', function(cm, vim, helpers) {
1478
  cm.setCursor(0, 4);
1479
  helpers.doKeys('3', 'J');
1480
  var expectedValue = 'word1  word2 word3\n word4';
1481
  eq(expectedValue, cm.getValue());
1482
  helpers.assertCursorAt(0, expectedValue.indexOf('word3') - 1);
1483
}, { value: 'word1 \n    word2\nword3\n word4' });
1484
testVim('p', function(cm, vim, helpers) {
1485
  cm.setCursor(0, 1);
1486
  helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
1487
  helpers.doKeys('p');
1488
  eq('__abc\ndef_', cm.getValue());
1489
  helpers.assertCursorAt(1, 2);
1490
}, { value: '___' });
1491
testVim('p_register', function(cm, vim, helpers) {
1492
  cm.setCursor(0, 1);
1493
  helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
1494
  helpers.doKeys('"', 'a', 'p');
1495
  eq('__abc\ndef_', cm.getValue());
1496
  helpers.assertCursorAt(1, 2);
1497
}, { value: '___' });
1498
testVim('p_wrong_register', function(cm, vim, helpers) {
1499
  cm.setCursor(0, 1);
1500
  helpers.getRegisterController().getRegister('a').setText('abc\ndef', false);
1501
  helpers.doKeys('p');
1502
  eq('___', cm.getValue());
1503
  helpers.assertCursorAt(0, 1);
1504
}, { value: '___' });
1505
testVim('p_line', function(cm, vim, helpers) {
1506
  cm.setCursor(0, 1);
1507
  helpers.getRegisterController().pushText('"', 'yank', '  a\nd\n', true);
1508
  helpers.doKeys('2', 'p');
1509
  eq('___\n  a\nd\n  a\nd', cm.getValue());
1510
  helpers.assertCursorAt(1, 2);
1511
}, { value: '___' });
1512
testVim('p_lastline', function(cm, vim, helpers) {
1513
  cm.setCursor(0, 1);
1514
  helpers.getRegisterController().pushText('"', 'yank', '  a\nd', true);
1515
  helpers.doKeys('2', 'p');
1516
  eq('___\n  a\nd\n  a\nd', cm.getValue());
1517
  helpers.assertCursorAt(1, 2);
1518
}, { value: '___' });
1519
testVim(']p_first_indent_is_smaller', function(cm, vim, helpers) {
1520
  helpers.getRegisterController().pushText('"', 'yank', '  abc\n    def\n', true);
1521
  helpers.doKeys(']', 'p');
1522
  eq('  ___\n  abc\n    def', cm.getValue());
1523
}, { value: '  ___' });
1524
testVim(']p_first_indent_is_larger', function(cm, vim, helpers) {
1525
  helpers.getRegisterController().pushText('"', 'yank', '    abc\n  def\n', true);
1526
  helpers.doKeys(']', 'p');
1527
  eq('  ___\n  abc\ndef', cm.getValue());
1528
}, { value: '  ___' });
1529
testVim(']p_with_tab_indents', function(cm, vim, helpers) {
1530
  helpers.getRegisterController().pushText('"', 'yank', '\t\tabc\n\t\t\tdef\n', true);
1531
  helpers.doKeys(']', 'p');
1532
  eq('\t___\n\tabc\n\t\tdef', cm.getValue());
1533
}, { value: '\t___', indentWithTabs: true});
1534
testVim(']p_with_spaces_translated_to_tabs', function(cm, vim, helpers) {
1535
  helpers.getRegisterController().pushText('"', 'yank', '  abc\n    def\n', true);
1536
  helpers.doKeys(']', 'p');
1537
  eq('\t___\n\tabc\n\t\tdef', cm.getValue());
1538
}, { value: '\t___', indentWithTabs: true, tabSize: 2 });
1539
testVim('[p', function(cm, vim, helpers) {
1540
  helpers.getRegisterController().pushText('"', 'yank', '  abc\n    def\n', true);
1541
  helpers.doKeys('[', 'p');
1542
  eq('  abc\n    def\n  ___', cm.getValue());
1543
}, { value: '  ___' });
1544
testVim('P', function(cm, vim, helpers) {
1545
  cm.setCursor(0, 1);
1546
  helpers.getRegisterController().pushText('"', 'yank', 'abc\ndef', false);
1547
  helpers.doKeys('P');
1548
  eq('_abc\ndef__', cm.getValue());
1549
  helpers.assertCursorAt(1, 3);
1550
}, { value: '___' });
1551
testVim('P_line', function(cm, vim, helpers) {
1552
  cm.setCursor(0, 1);
1553
  helpers.getRegisterController().pushText('"', 'yank', '  a\nd\n', true);
1554
  helpers.doKeys('2', 'P');
1555
  eq('  a\nd\n  a\nd\n___', cm.getValue());
1556
  helpers.assertCursorAt(0, 2);
1557
}, { value: '___' });
1558
testVim('r', function(cm, vim, helpers) {
1559
  cm.setCursor(0, 1);
1560
  helpers.doKeys('3', 'r', 'u');
1561
  eq('wuuuet\nanother', cm.getValue(),'3r failed');
1562
  helpers.assertCursorAt(0, 3);
1563
  cm.setCursor(0, 4);
1564
  helpers.doKeys('v', 'j', 'h', 'r', '<Space>');
1565
  eq('wuuu  \n    her', cm.getValue(),'Replacing selection by space-characters failed');
1566
}, { value: 'wordet\nanother' });
1567
testVim('r_visual_block', function(cm, vim, helpers) {
1568
  cm.setCursor(2, 3);
1569
  helpers.doKeys('<C-v>', 'k', 'k', 'h', 'h', 'r', 'l');
1570
  eq('1lll\n5lll\nalllefg', cm.getValue());
1571
  helpers.doKeys('<C-v>', 'l', 'j', 'r', '<Space>');
1572
  eq('1  l\n5  l\nalllefg', cm.getValue());
1573
  cm.setCursor(2, 0);
1574
  helpers.doKeys('o');
1575
  helpers.doKeys('<Esc>');
1576
  cm.replaceRange('\t\t', cm.getCursor());
1577
  helpers.doKeys('<C-v>', 'h', 'h', 'r', 'r');
1578
  eq('1  l\n5  l\nalllefg\nrrrrrrrr', cm.getValue());
1579
}, {value: '1234\n5678\nabcdefg'});
1580
testVim('R', function(cm, vim, helpers) {
1581
  cm.setCursor(0, 1);
1582
  helpers.doKeys('R');
1583
  helpers.assertCursorAt(0, 1);
1584
  eq('vim-replace', cm.getOption('keyMap'));
1585
  is(cm.state.overwrite, 'Setting overwrite state failed');
1586
});
1587
testVim('mark', function(cm, vim, helpers) {
1588
  cm.setCursor(2, 2);
1589
  helpers.doKeys('m', 't');
1590
  cm.setCursor(0, 0);
1591
  helpers.doKeys('`', 't');
1592
  helpers.assertCursorAt(2, 2);
1593
  cm.setCursor(2, 0);
1594
  cm.replaceRange('   h', cm.getCursor());
1595
  cm.setCursor(0, 0);
1596
  helpers.doKeys('\'', 't');
1597
  helpers.assertCursorAt(2, 3);
1598
});
1599
testVim('jumpToMark_next', function(cm, vim, helpers) {
1600
  cm.setCursor(2, 2);
1601
  helpers.doKeys('m', 't');
1602
  cm.setCursor(0, 0);
1603
  helpers.doKeys(']', '`');
1604
  helpers.assertCursorAt(2, 2);
1605
  cm.setCursor(0, 0);
1606
  helpers.doKeys(']', '\'');
1607
  helpers.assertCursorAt(2, 0);
1608
});
1609
testVim('jumpToMark_next_repeat', function(cm, vim, helpers) {
1610
  cm.setCursor(2, 2);
1611
  helpers.doKeys('m', 'a');
1612
  cm.setCursor(3, 2);
1613
  helpers.doKeys('m', 'b');
1614
  cm.setCursor(4, 2);
1615
  helpers.doKeys('m', 'c');
1616
  cm.setCursor(0, 0);
1617
  helpers.doKeys('2', ']', '`');
1618
  helpers.assertCursorAt(3, 2);
1619
  cm.setCursor(0, 0);
1620
  helpers.doKeys('2', ']', '\'');
1621
  helpers.assertCursorAt(3, 1);
1622
});
1623
testVim('jumpToMark_next_sameline', function(cm, vim, helpers) {
1624
  cm.setCursor(2, 0);
1625
  helpers.doKeys('m', 'a');
1626
  cm.setCursor(2, 4);
1627
  helpers.doKeys('m', 'b');
1628
  cm.setCursor(2, 2);
1629
  helpers.doKeys(']', '`');
1630
  helpers.assertCursorAt(2, 4);
1631
});
1632
testVim('jumpToMark_next_onlyprev', function(cm, vim, helpers) {
1633
  cm.setCursor(2, 0);
1634
  helpers.doKeys('m', 'a');
1635
  cm.setCursor(4, 0);
1636
  helpers.doKeys(']', '`');
1637
  helpers.assertCursorAt(4, 0);
1638
});
1639
testVim('jumpToMark_next_nomark', function(cm, vim, helpers) {
1640
  cm.setCursor(2, 2);
1641
  helpers.doKeys(']', '`');
1642
  helpers.assertCursorAt(2, 2);
1643
  helpers.doKeys(']', '\'');
1644
  helpers.assertCursorAt(2, 0);
1645
});
1646
testVim('jumpToMark_next_linewise_over', function(cm, vim, helpers) {
1647
  cm.setCursor(2, 2);
1648
  helpers.doKeys('m', 'a');
1649
  cm.setCursor(3, 4);
1650
  helpers.doKeys('m', 'b');
1651
  cm.setCursor(2, 1);
1652
  helpers.doKeys(']', '\'');
1653
  helpers.assertCursorAt(3, 1);
1654
});
1655
testVim('jumpToMark_next_action', function(cm, vim, helpers) {
1656
  cm.setCursor(2, 2);
1657
  helpers.doKeys('m', 't');
1658
  cm.setCursor(0, 0);
1659
  helpers.doKeys('d', ']', '`');
1660
  helpers.assertCursorAt(0, 0);
1661
  var actual = cm.getLine(0);
1662
  var expected = 'pop pop 0 1 2 3 4';
1663
  eq(actual, expected, "Deleting while jumping to the next mark failed.");
1664
});
1665
testVim('jumpToMark_next_line_action', function(cm, vim, helpers) {
1666
  cm.setCursor(2, 2);
1667
  helpers.doKeys('m', 't');
1668
  cm.setCursor(0, 0);
1669
  helpers.doKeys('d', ']', '\'');
1670
  helpers.assertCursorAt(0, 1);
1671
  var actual = cm.getLine(0);
1672
  var expected = ' (a) [b] {c} '
1673
  eq(actual, expected, "Deleting while jumping to the next mark line failed.");
1674
});
1675
testVim('jumpToMark_prev', function(cm, vim, helpers) {
1676
  cm.setCursor(2, 2);
1677
  helpers.doKeys('m', 't');
1678
  cm.setCursor(4, 0);
1679
  helpers.doKeys('[', '`');
1680
  helpers.assertCursorAt(2, 2);
1681
  cm.setCursor(4, 0);
1682
  helpers.doKeys('[', '\'');
1683
  helpers.assertCursorAt(2, 0);
1684
});
1685
testVim('jumpToMark_prev_repeat', function(cm, vim, helpers) {
1686
  cm.setCursor(2, 2);
1687
  helpers.doKeys('m', 'a');
1688
  cm.setCursor(3, 2);
1689
  helpers.doKeys('m', 'b');
1690
  cm.setCursor(4, 2);
1691
  helpers.doKeys('m', 'c');
1692
  cm.setCursor(5, 0);
1693
  helpers.doKeys('2', '[', '`');
1694
  helpers.assertCursorAt(3, 2);
1695
  cm.setCursor(5, 0);
1696
  helpers.doKeys('2', '[', '\'');
1697
  helpers.assertCursorAt(3, 1);
1698
});
1699
testVim('jumpToMark_prev_sameline', function(cm, vim, helpers) {
1700
  cm.setCursor(2, 0);
1701
  helpers.doKeys('m', 'a');
1702
  cm.setCursor(2, 4);
1703
  helpers.doKeys('m', 'b');
1704
  cm.setCursor(2, 2);
1705
  helpers.doKeys('[', '`');
1706
  helpers.assertCursorAt(2, 0);
1707
});
1708
testVim('jumpToMark_prev_onlynext', function(cm, vim, helpers) {
1709
  cm.setCursor(4, 4);
1710
  helpers.doKeys('m', 'a');
1711
  cm.setCursor(2, 0);
1712
  helpers.doKeys('[', '`');
1713
  helpers.assertCursorAt(2, 0);
1714
});
1715
testVim('jumpToMark_prev_nomark', function(cm, vim, helpers) {
1716
  cm.setCursor(2, 2);
1717
  helpers.doKeys('[', '`');
1718
  helpers.assertCursorAt(2, 2);
1719
  helpers.doKeys('[', '\'');
1720
  helpers.assertCursorAt(2, 0);
1721
});
1722
testVim('jumpToMark_prev_linewise_over', function(cm, vim, helpers) {
1723
  cm.setCursor(2, 2);
1724
  helpers.doKeys('m', 'a');
1725
  cm.setCursor(3, 4);
1726
  helpers.doKeys('m', 'b');
1727
  cm.setCursor(3, 6);
1728
  helpers.doKeys('[', '\'');
1729
  helpers.assertCursorAt(2, 0);
1730
});
1731
testVim('delmark_single', function(cm, vim, helpers) {
1732
  cm.setCursor(1, 2);
1733
  helpers.doKeys('m', 't');
1734
  helpers.doEx('delmarks t');
1735
  cm.setCursor(0, 0);
1736
  helpers.doKeys('`', 't');
1737
  helpers.assertCursorAt(0, 0);
1738
});
1739
testVim('delmark_range', function(cm, vim, helpers) {
1740
  cm.setCursor(1, 2);
1741
  helpers.doKeys('m', 'a');
1742
  cm.setCursor(2, 2);
1743
  helpers.doKeys('m', 'b');
1744
  cm.setCursor(3, 2);
1745
  helpers.doKeys('m', 'c');
1746
  cm.setCursor(4, 2);
1747
  helpers.doKeys('m', 'd');
1748
  cm.setCursor(5, 2);
1749
  helpers.doKeys('m', 'e');
1750
  helpers.doEx('delmarks b-d');
1751
  cm.setCursor(0, 0);
1752
  helpers.doKeys('`', 'a');
1753
  helpers.assertCursorAt(1, 2);
1754
  helpers.doKeys('`', 'b');
1755
  helpers.assertCursorAt(1, 2);
1756
  helpers.doKeys('`', 'c');
1757
  helpers.assertCursorAt(1, 2);
1758
  helpers.doKeys('`', 'd');
1759
  helpers.assertCursorAt(1, 2);
1760
  helpers.doKeys('`', 'e');
1761
  helpers.assertCursorAt(5, 2);
1762
});
1763
testVim('delmark_multi', function(cm, vim, helpers) {
1764
  cm.setCursor(1, 2);
1765
  helpers.doKeys('m', 'a');
1766
  cm.setCursor(2, 2);
1767
  helpers.doKeys('m', 'b');
1768
  cm.setCursor(3, 2);
1769
  helpers.doKeys('m', 'c');
1770
  cm.setCursor(4, 2);
1771
  helpers.doKeys('m', 'd');
1772
  cm.setCursor(5, 2);
1773
  helpers.doKeys('m', 'e');
1774
  helpers.doEx('delmarks bcd');
1775
  cm.setCursor(0, 0);
1776
  helpers.doKeys('`', 'a');
1777
  helpers.assertCursorAt(1, 2);
1778
  helpers.doKeys('`', 'b');
1779
  helpers.assertCursorAt(1, 2);
1780
  helpers.doKeys('`', 'c');
1781
  helpers.assertCursorAt(1, 2);
1782
  helpers.doKeys('`', 'd');
1783
  helpers.assertCursorAt(1, 2);
1784
  helpers.doKeys('`', 'e');
1785
  helpers.assertCursorAt(5, 2);
1786
});
1787
testVim('delmark_multi_space', function(cm, vim, helpers) {
1788
  cm.setCursor(1, 2);
1789
  helpers.doKeys('m', 'a');
1790
  cm.setCursor(2, 2);
1791
  helpers.doKeys('m', 'b');
1792
  cm.setCursor(3, 2);
1793
  helpers.doKeys('m', 'c');
1794
  cm.setCursor(4, 2);
1795
  helpers.doKeys('m', 'd');
1796
  cm.setCursor(5, 2);
1797
  helpers.doKeys('m', 'e');
1798
  helpers.doEx('delmarks b c d');
1799
  cm.setCursor(0, 0);
1800
  helpers.doKeys('`', 'a');
1801
  helpers.assertCursorAt(1, 2);
1802
  helpers.doKeys('`', 'b');
1803
  helpers.assertCursorAt(1, 2);
1804
  helpers.doKeys('`', 'c');
1805
  helpers.assertCursorAt(1, 2);
1806
  helpers.doKeys('`', 'd');
1807
  helpers.assertCursorAt(1, 2);
1808
  helpers.doKeys('`', 'e');
1809
  helpers.assertCursorAt(5, 2);
1810
});
1811
testVim('delmark_all', function(cm, vim, helpers) {
1812
  cm.setCursor(1, 2);
1813
  helpers.doKeys('m', 'a');
1814
  cm.setCursor(2, 2);
1815
  helpers.doKeys('m', 'b');
1816
  cm.setCursor(3, 2);
1817
  helpers.doKeys('m', 'c');
1818
  cm.setCursor(4, 2);
1819
  helpers.doKeys('m', 'd');
1820
  cm.setCursor(5, 2);
1821
  helpers.doKeys('m', 'e');
1822
  helpers.doEx('delmarks a b-de');
1823
  cm.setCursor(0, 0);
1824
  helpers.doKeys('`', 'a');
1825
  helpers.assertCursorAt(0, 0);
1826
  helpers.doKeys('`', 'b');
1827
  helpers.assertCursorAt(0, 0);
1828
  helpers.doKeys('`', 'c');
1829
  helpers.assertCursorAt(0, 0);
1830
  helpers.doKeys('`', 'd');
1831
  helpers.assertCursorAt(0, 0);
1832
  helpers.doKeys('`', 'e');
1833
  helpers.assertCursorAt(0, 0);
1834
});
1835
testVim('visual', function(cm, vim, helpers) {
1836
  helpers.doKeys('l', 'v', 'l', 'l');
1837
  helpers.assertCursorAt(0, 4);
1838
  eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
1839
  helpers.doKeys('d');
1840
  eq('15', cm.getValue());
1841
}, { value: '12345' });
1842
testVim('visual_yank', function(cm, vim, helpers) {
1843
  helpers.doKeys('v', '3', 'l', 'y');
1844
  helpers.assertCursorAt(0, 0);
1845
  helpers.doKeys('p');
1846
  eq('aa te test for yank', cm.getValue());
1847
}, { value: 'a test for yank' })
1848
testVim('visual_w', function(cm, vim, helpers) {
1849
  helpers.doKeys('v', 'w');
1850
  eq(cm.getSelection(), 'motion t');
1851
}, { value: 'motion test'});
1852
testVim('visual_initial_selection', function(cm, vim, helpers) {
1853
  cm.setCursor(0, 1);
1854
  helpers.doKeys('v');
1855
  cm.getSelection('n');
1856
}, { value: 'init'});
1857
testVim('visual_crossover_left', function(cm, vim, helpers) {
1858
  cm.setCursor(0, 2);
1859
  helpers.doKeys('v', 'l', 'h', 'h');
1860
  cm.getSelection('ro');
1861
}, { value: 'cross'});
1862
testVim('visual_crossover_left', function(cm, vim, helpers) {
1863
  cm.setCursor(0, 2);
1864
  helpers.doKeys('v', 'h', 'l', 'l');
1865
  cm.getSelection('os');
1866
}, { value: 'cross'});
1867
testVim('visual_crossover_up', function(cm, vim, helpers) {
1868
  cm.setCursor(3, 2);
1869
  helpers.doKeys('v', 'j', 'k', 'k');
1870
  eqPos(Pos(2, 2), cm.getCursor('head'));
1871
  eqPos(Pos(3, 3), cm.getCursor('anchor'));
1872
  helpers.doKeys('k');
1873
  eqPos(Pos(1, 2), cm.getCursor('head'));
1874
  eqPos(Pos(3, 3), cm.getCursor('anchor'));
1875
}, { value: 'cross\ncross\ncross\ncross\ncross\n'});
1876
testVim('visual_crossover_down', function(cm, vim, helpers) {
1877
  cm.setCursor(1, 2);
1878
  helpers.doKeys('v', 'k', 'j', 'j');
1879
  eqPos(Pos(2, 3), cm.getCursor('head'));
1880
  eqPos(Pos(1, 2), cm.getCursor('anchor'));
1881
  helpers.doKeys('j');
1882
  eqPos(Pos(3, 3), cm.getCursor('head'));
1883
  eqPos(Pos(1, 2), cm.getCursor('anchor'));
1884
}, { value: 'cross\ncross\ncross\ncross\ncross\n'});
1885
testVim('visual_exit', function(cm, vim, helpers) {
1886
  helpers.doKeys('<C-v>', 'l', 'j', 'j', '<Esc>');
1887
  eqPos(cm.getCursor('anchor'), cm.getCursor('head'));
1888
  eq(vim.visualMode, false);
1889
}, { value: 'hello\nworld\nfoo' });
1890
testVim('visual_line', function(cm, vim, helpers) {
1891
  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'd');
1892
  eq(' 4\n 5', cm.getValue());
1893
}, { value: ' 1\n 2\n 3\n 4\n 5' });
1894
testVim('visual_block_move_to_eol', function(cm, vim, helpers) {
1895
  // moveToEol should move all block cursors to end of line
1896
  cm.setCursor(0, 0);
1897
  helpers.doKeys('<C-v>', 'G', '$');
1898
  var selections = cm.getSelections().join();
1899
  eq('123,45,6', selections);
1900
  // Checks that with cursor at Infinity, finding words backwards still works.
1901
  helpers.doKeys('2', 'k', 'b');
1902
  selections = cm.getSelections().join();
1903
  eq('1', selections);
1904
}, {value: '123\n45\n6'});
1905
testVim('visual_block_different_line_lengths', function(cm, vim, helpers) {
1906
  // test the block selection with lines of different length
1907
  // i.e. extending the selection
1908
  // till the end of the longest line.
1909
  helpers.doKeys('<C-v>', 'l', 'j', 'j', '6', 'l', 'd');
1910
  helpers.doKeys('d', 'd', 'd', 'd');
1911
  eq('', cm.getValue());
1912
}, {value: '1234\n5678\nabcdefg'});
1913
testVim('visual_block_truncate_on_short_line', function(cm, vim, helpers) {
1914
  // check for left side selection in case
1915
  // of moving up to a shorter line.
1916
  cm.replaceRange('', cm.getCursor());
1917
  cm.setCursor(3, 4);
1918
  helpers.doKeys('<C-v>', 'l', 'k', 'k', 'd');
1919
  eq('hello world\n{\ntis\nsa!', cm.getValue());
1920
}, {value: 'hello world\n{\nthis is\nsparta!'});
1921
testVim('visual_block_corners', function(cm, vim, helpers) {
1922
  cm.setCursor(1, 2);
1923
  helpers.doKeys('<C-v>', '2', 'l', 'k');
1924
  // circle around the anchor
1925
  // and check the selections
1926
  var selections = cm.getSelections();
1927
  eq('345891', selections.join(''));
1928
  helpers.doKeys('4', 'h');
1929
  selections = cm.getSelections();
1930
  eq('123678', selections.join(''));
1931
  helpers.doKeys('j', 'j');
1932
  selections = cm.getSelections();
1933
  eq('678abc', selections.join(''));
1934
  helpers.doKeys('4', 'l');
1935
  selections = cm.getSelections();
1936
  eq('891cde', selections.join(''));
1937
}, {value: '12345\n67891\nabcde'});
1938
testVim('visual_block_mode_switch', function(cm, vim, helpers) {
1939
  // switch between visual modes
1940
  cm.setCursor(1, 1);
1941
  // blockwise to characterwise visual
1942
  helpers.doKeys('<C-v>', 'j', 'l', 'v');
1943
  selections = cm.getSelections();
0 ignored issues
show
Bug introduced by
The variable selections seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.selections.
Loading history...
1944
  eq('7891\nabc', selections.join(''));
1945
  // characterwise to blockwise
1946
  helpers.doKeys('<C-v>');
1947
  selections = cm.getSelections();
1948
  eq('78bc', selections.join(''));
1949
  // blockwise to linewise visual
1950
  helpers.doKeys('V');
1951
  selections = cm.getSelections();
1952
  eq('67891\nabcde', selections.join(''));
1953
}, {value: '12345\n67891\nabcde'});
1954
testVim('visual_block_crossing_short_line', function(cm, vim, helpers) {
1955
  // visual block with long and short lines
1956
  cm.setCursor(0, 3);
1957
  helpers.doKeys('<C-v>', 'j', 'j', 'j');
1958
  var selections = cm.getSelections().join();
1959
  eq('4,,d,b', selections);
1960
  helpers.doKeys('3', 'k');
1961
  selections = cm.getSelections().join();
1962
  eq('4', selections);
1963
  helpers.doKeys('5', 'j', 'k');
1964
  selections = cm.getSelections().join("");
1965
  eq(10, selections.length);
1966
}, {value: '123456\n78\nabcdefg\nfoobar\n}\n'});
1967
testVim('visual_block_curPos_on_exit', function(cm, vim, helpers) {
1968
  cm.setCursor(0, 0);
1969
  helpers.doKeys('<C-v>', '3' , 'l', '<Esc>');
1970
  eqPos(makeCursor(0, 3), cm.getCursor());
1971
  helpers.doKeys('h', '<C-v>', '2' , 'j' ,'3' , 'l');
1972
  eq(cm.getSelections().join(), "3456,,cdef");
1973
  helpers.doKeys('4' , 'h');
1974
  eq(cm.getSelections().join(), "23,8,bc");
1975
  helpers.doKeys('2' , 'l');
1976
  eq(cm.getSelections().join(), "34,,cd");
1977
}, {value: '123456\n78\nabcdefg\nfoobar'});
1978
1979
testVim('visual_marks', function(cm, vim, helpers) {
1980
  helpers.doKeys('l', 'v', 'l', 'l', 'j', 'j', 'v');
1981
  // Test visual mode marks
1982
  cm.setCursor(2, 1);
1983
  helpers.doKeys('\'', '<');
1984
  helpers.assertCursorAt(0, 1);
1985
  helpers.doKeys('\'', '>');
1986
  helpers.assertCursorAt(2, 0);
1987
});
1988
testVim('visual_join', function(cm, vim, helpers) {
1989
  helpers.doKeys('l', 'V', 'l', 'j', 'j', 'J');
1990
  eq(' 1 2 3\n 4\n 5', cm.getValue());
1991
  is(!vim.visualMode);
1992
}, { value: ' 1\n 2\n 3\n 4\n 5' });
1993
testVim('visual_join_2', function(cm, vim, helpers) {
1994
  helpers.doKeys('G', 'V', 'g', 'g', 'J');
1995
  eq('1 2 3 4 5 6 ', cm.getValue());
1996
  is(!vim.visualMode);
1997
}, { value: '1\n2\n3\n4\n5\n6\n'});
1998
testVim('visual_blank', function(cm, vim, helpers) {
1999
  helpers.doKeys('v', 'k');
2000
  eq(vim.visualMode, true);
2001
}, { value: '\n' });
2002
testVim('reselect_visual', function(cm, vim, helpers) {
2003
  helpers.doKeys('l', 'v', 'l', 'l', 'l', 'y', 'g', 'v');
2004
  helpers.assertCursorAt(0, 5);
2005
  eqPos(makeCursor(0, 1), cm.getCursor('anchor'));
2006
  helpers.doKeys('v');
2007
  cm.setCursor(1, 0);
2008
  helpers.doKeys('v', 'l', 'l', 'p');
2009
  eq('123456\n2345\nbar', cm.getValue());
2010
  cm.setCursor(0, 0);
2011
  helpers.doKeys('g', 'v');
2012
  // here the fake cursor is at (1, 3)
2013
  helpers.assertCursorAt(1, 4);
2014
  eqPos(makeCursor(1, 0), cm.getCursor('anchor'));
2015
  helpers.doKeys('v');
2016
  cm.setCursor(2, 0);
2017
  helpers.doKeys('v', 'l', 'l', 'g', 'v');
2018
  helpers.assertCursorAt(1, 4);
2019
  eqPos(makeCursor(1, 0), cm.getCursor('anchor'));
2020
  helpers.doKeys('g', 'v');
2021
  helpers.assertCursorAt(2, 3);
2022
  eqPos(makeCursor(2, 0), cm.getCursor('anchor'));
2023
  eq('123456\n2345\nbar', cm.getValue());
2024
}, { value: '123456\nfoo\nbar' });
2025
testVim('reselect_visual_line', function(cm, vim, helpers) {
2026
  helpers.doKeys('l', 'V', 'j', 'j', 'V', 'g', 'v', 'd');
2027
  eq('foo\nand\nbar', cm.getValue());
2028
  cm.setCursor(1, 0);
2029
  helpers.doKeys('V', 'y', 'j');
2030
  helpers.doKeys('V', 'p' , 'g', 'v', 'd');
2031
  eq('foo\nand', cm.getValue());
2032
}, { value: 'hello\nthis\nis\nfoo\nand\nbar' });
2033
testVim('reselect_visual_block', function(cm, vim, helpers) {
2034
  cm.setCursor(1, 2);
2035
  helpers.doKeys('<C-v>', 'k', 'h', '<C-v>');
2036
  cm.setCursor(2, 1);
2037
  helpers.doKeys('v', 'l', 'g', 'v');
2038
  eqPos(Pos(1, 2), vim.sel.anchor);
2039
  eqPos(Pos(0, 1), vim.sel.head);
2040
  // Ensure selection is done with visual block mode rather than one
2041
  // continuous range.
2042
  eq(cm.getSelections().join(''), '23oo')
2043
  helpers.doKeys('g', 'v');
2044
  eqPos(Pos(2, 1), vim.sel.anchor);
2045
  eqPos(Pos(2, 2), vim.sel.head);
2046
  helpers.doKeys('<Esc>');
2047
  // Ensure selection of deleted range
2048
  cm.setCursor(1, 1);
2049
  helpers.doKeys('v', '<C-v>', 'j', 'd', 'g', 'v');
2050
  eq(cm.getSelections().join(''), 'or');
2051
}, { value: '123456\nfoo\nbar' });
2052
testVim('s_normal', function(cm, vim, helpers) {
2053
  cm.setCursor(0, 1);
2054
  helpers.doKeys('s');
2055
  helpers.doKeys('<Esc>');
2056
  eq('ac', cm.getValue());
2057
}, { value: 'abc'});
2058
testVim('s_visual', function(cm, vim, helpers) {
2059
  cm.setCursor(0, 1);
2060
  helpers.doKeys('v', 's');
2061
  helpers.doKeys('<Esc>');
2062
  helpers.assertCursorAt(0, 0);
2063
  eq('ac', cm.getValue());
2064
}, { value: 'abc'});
2065
testVim('o_visual', function(cm, vim, helpers) {
2066
  cm.setCursor(0,0);
2067
  helpers.doKeys('v','l','l','l','o');
2068
  helpers.assertCursorAt(0,0);
2069
  helpers.doKeys('v','v','j','j','j','o');
2070
  helpers.assertCursorAt(0,0);
2071
  helpers.doKeys('O');
2072
  helpers.doKeys('l','l')
2073
  helpers.assertCursorAt(3, 3);
2074
  helpers.doKeys('d');
2075
  eq('p',cm.getValue());
2076
}, { value: 'abcd\nefgh\nijkl\nmnop'});
2077
testVim('o_visual_block', function(cm, vim, helpers) {
2078
  cm.setCursor(0, 1);
2079
  helpers.doKeys('<C-v>','3','j','l','l', 'o');
2080
  eqPos(Pos(3, 3), vim.sel.anchor);
2081
  eqPos(Pos(0, 1), vim.sel.head);
2082
  helpers.doKeys('O');
2083
  eqPos(Pos(3, 1), vim.sel.anchor);
2084
  eqPos(Pos(0, 3), vim.sel.head);
2085
  helpers.doKeys('o');
2086
  eqPos(Pos(0, 3), vim.sel.anchor);
2087
  eqPos(Pos(3, 1), vim.sel.head);
2088
}, { value: 'abcd\nefgh\nijkl\nmnop'});
2089
testVim('changeCase_visual', function(cm, vim, helpers) {
2090
  cm.setCursor(0, 0);
2091
  helpers.doKeys('v', 'l', 'l');
2092
  helpers.doKeys('U');
2093
  helpers.assertCursorAt(0, 0);
2094
  helpers.doKeys('v', 'l', 'l');
2095
  helpers.doKeys('u');
2096
  helpers.assertCursorAt(0, 0);
2097
  helpers.doKeys('l', 'l', 'l', '.');
2098
  helpers.assertCursorAt(0, 3);
2099
  cm.setCursor(0, 0);
2100
  helpers.doKeys('q', 'a', 'v', 'j', 'U', 'q');
2101
  helpers.assertCursorAt(0, 0);
2102
  helpers.doKeys('j', '@', 'a');
2103
  helpers.assertCursorAt(1, 0);
2104
  cm.setCursor(3, 0);
2105
  helpers.doKeys('V', 'U', 'j', '.');
2106
  eq('ABCDEF\nGHIJKL\nMnopq\nSHORT LINE\nLONG LINE OF TEXT', cm.getValue());
2107
}, { value: 'abcdef\nghijkl\nmnopq\nshort line\nlong line of text'});
2108
testVim('changeCase_visual_block', function(cm, vim, helpers) {
2109
  cm.setCursor(2, 1);
2110
  helpers.doKeys('<C-v>', 'k', 'k', 'h', 'U');
2111
  eq('ABcdef\nGHijkl\nMNopq\nfoo', cm.getValue());
2112
  cm.setCursor(0, 2);
2113
  helpers.doKeys('.');
2114
  eq('ABCDef\nGHIJkl\nMNOPq\nfoo', cm.getValue());
2115
  // check when last line is shorter.
2116
  cm.setCursor(2, 2);
2117
  helpers.doKeys('.');
2118
  eq('ABCDef\nGHIJkl\nMNOPq\nfoO', cm.getValue());
2119
}, { value: 'abcdef\nghijkl\nmnopq\nfoo'});
2120
testVim('visual_paste', function(cm, vim, helpers) {
2121
  cm.setCursor(0, 0);
2122
  helpers.doKeys('v', 'l', 'l', 'y');
2123
  helpers.assertCursorAt(0, 0);
2124
  helpers.doKeys('3', 'l', 'j', 'v', 'l', 'p');
2125
  helpers.assertCursorAt(1, 5);
2126
  eq('this is a\nunithitest for visual paste', cm.getValue());
2127
  cm.setCursor(0, 0);
2128
  // in case of pasting whole line
2129
  helpers.doKeys('y', 'y');
2130
  cm.setCursor(1, 6);
2131
  helpers.doKeys('v', 'l', 'l', 'l', 'p');
2132
  helpers.assertCursorAt(2, 0);
2133
  eq('this is a\nunithi\nthis is a\n for visual paste', cm.getValue());
2134
}, { value: 'this is a\nunit test for visual paste'});
2135
2136
// This checks the contents of the register used to paste the text
2137
testVim('v_paste_from_register', function(cm, vim, helpers) {
2138
  cm.setCursor(0, 0);
2139
  helpers.doKeys('"', 'a', 'y', 'w');
2140
  cm.setCursor(1, 0);
2141
  helpers.doKeys('v', 'p');
2142
  cm.openDialog = helpers.fakeOpenDialog('registers');
2143
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2144
    is(/a\s+register/.test(text));
2145
  });
2146
}, { value: 'register contents\nare not erased'});
2147
testVim('S_normal', function(cm, vim, helpers) {
2148
  cm.setCursor(0, 1);
2149
  helpers.doKeys('j', 'S');
2150
  helpers.doKeys('<Esc>');
2151
  helpers.assertCursorAt(1, 0);
2152
  eq('aa\n\ncc', cm.getValue());
2153
}, { value: 'aa\nbb\ncc'});
2154
testVim('blockwise_paste', function(cm, vim, helpers) {
2155
  cm.setCursor(0, 0);
2156
  helpers.doKeys('<C-v>', '3', 'j', 'l', 'y');
2157
  cm.setCursor(0, 2);
2158
  // paste one char after the current cursor position
2159
  helpers.doKeys('p');
2160
  eq('helhelo\nworwold\nfoofo\nbarba', cm.getValue());
2161
  cm.setCursor(0, 0);
2162
  helpers.doKeys('v', '4', 'l', 'y');
2163
  cm.setCursor(0, 0);
2164
  helpers.doKeys('<C-v>', '3', 'j', 'p');
2165
  eq('helheelhelo\norwold\noofo\narba', cm.getValue());
2166
}, { value: 'hello\nworld\nfoo\nbar'});
2167
testVim('blockwise_paste_long/short_line', function(cm, vim, helpers) {
2168
  // extend short lines in case of different line lengths.
2169
  cm.setCursor(0, 0);
2170
  helpers.doKeys('<C-v>', 'j', 'j', 'y');
2171
  cm.setCursor(0, 3);
2172
  helpers.doKeys('p');
2173
  eq('hellho\nfoo f\nbar b', cm.getValue());
2174
}, { value: 'hello\nfoo\nbar'});
2175
testVim('blockwise_paste_cut_paste', function(cm, vim, helpers) {
2176
  cm.setCursor(0, 0);
2177
  helpers.doKeys('<C-v>', '2', 'j', 'x');
2178
  cm.setCursor(0, 0);
2179
  helpers.doKeys('P');
2180
  eq('cut\nand\npaste\nme', cm.getValue());
2181
}, { value: 'cut\nand\npaste\nme'});
2182
testVim('blockwise_paste_from_register', function(cm, vim, helpers) {
2183
  cm.setCursor(0, 0);
2184
  helpers.doKeys('<C-v>', '2', 'j', '"', 'a', 'y');
2185
  cm.setCursor(0, 3);
2186
  helpers.doKeys('"', 'a', 'p');
2187
  eq('foobfar\nhellho\nworlwd', cm.getValue());
2188
}, { value: 'foobar\nhello\nworld'});
2189
testVim('blockwise_paste_last_line', function(cm, vim, helpers) {
2190
  cm.setCursor(0, 0);
2191
  helpers.doKeys('<C-v>', '2', 'j', 'l', 'y');
2192
  cm.setCursor(3, 0);
2193
  helpers.doKeys('p');
2194
  eq('cut\nand\npaste\nmcue\n an\n pa', cm.getValue());
2195
}, { value: 'cut\nand\npaste\nme'});
2196
2197
testVim('S_visual', function(cm, vim, helpers) {
2198
  cm.setCursor(0, 1);
2199
  helpers.doKeys('v', 'j', 'S');
2200
  helpers.doKeys('<Esc>');
2201
  helpers.assertCursorAt(0, 0);
2202
  eq('\ncc', cm.getValue());
2203
}, { value: 'aa\nbb\ncc'});
2204
2205
testVim('d_/', function(cm, vim, helpers) {
2206
  cm.openDialog = helpers.fakeOpenDialog('match');
2207
  helpers.doKeys('2', 'd', '/');
2208
  helpers.assertCursorAt(0, 0);
2209
  eq('match \n next', cm.getValue());
2210
  cm.openDialog = helpers.fakeOpenDialog('2');
2211
  helpers.doKeys('d', ':');
2212
  // TODO eq(' next', cm.getValue());
2213
}, { value: 'text match match \n next' });
2214
testVim('/ and n/N', function(cm, vim, helpers) {
2215
  cm.openDialog = helpers.fakeOpenDialog('match');
2216
  helpers.doKeys('/');
2217
  helpers.assertCursorAt(0, 11);
2218
  helpers.doKeys('n');
2219
  helpers.assertCursorAt(1, 6);
2220
  helpers.doKeys('N');
2221
  helpers.assertCursorAt(0, 11);
2222
2223
  cm.setCursor(0, 0);
2224
  helpers.doKeys('2', '/');
2225
  helpers.assertCursorAt(1, 6);
2226
}, { value: 'match nope match \n nope Match' });
2227
testVim('/_case', function(cm, vim, helpers) {
2228
  cm.openDialog = helpers.fakeOpenDialog('Match');
2229
  helpers.doKeys('/');
2230
  helpers.assertCursorAt(1, 6);
2231
}, { value: 'match nope match \n nope Match' });
2232
testVim('/_2_pcre', function(cm, vim, helpers) {
2233
  CodeMirror.Vim.setOption('pcre', true);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
2234
  cm.openDialog = helpers.fakeOpenDialog('(word){2}');
2235
  helpers.doKeys('/');
2236
  helpers.assertCursorAt(1, 9);
2237
  helpers.doKeys('n');
2238
  helpers.assertCursorAt(2, 1);
2239
}, { value: 'word\n another wordword\n wordwordword\n' });
2240
testVim('/_2_nopcre', function(cm, vim, helpers) {
2241
  CodeMirror.Vim.setOption('pcre', false);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
2242
  cm.openDialog = helpers.fakeOpenDialog('\\(word\\)\\{2}');
2243
  helpers.doKeys('/');
2244
  helpers.assertCursorAt(1, 9);
2245
  helpers.doKeys('n');
2246
  helpers.assertCursorAt(2, 1);
2247
}, { value: 'word\n another wordword\n wordwordword\n' });
2248
testVim('/_nongreedy', function(cm, vim, helpers) {
2249
  cm.openDialog = helpers.fakeOpenDialog('aa');
2250
  helpers.doKeys('/');
2251
  helpers.assertCursorAt(0, 4);
2252
  helpers.doKeys('n');
2253
  helpers.assertCursorAt(1, 3);
2254
  helpers.doKeys('n');
2255
  helpers.assertCursorAt(0, 0);
2256
}, { value: 'aaa aa \n a aa'});
2257
testVim('?_nongreedy', function(cm, vim, helpers) {
2258
  cm.openDialog = helpers.fakeOpenDialog('aa');
2259
  helpers.doKeys('?');
2260
  helpers.assertCursorAt(1, 3);
2261
  helpers.doKeys('n');
2262
  helpers.assertCursorAt(0, 4);
2263
  helpers.doKeys('n');
2264
  helpers.assertCursorAt(0, 0);
2265
}, { value: 'aaa aa \n a aa'});
2266
testVim('/_greedy', function(cm, vim, helpers) {
2267
  cm.openDialog = helpers.fakeOpenDialog('a+');
2268
  helpers.doKeys('/');
2269
  helpers.assertCursorAt(0, 4);
2270
  helpers.doKeys('n');
2271
  helpers.assertCursorAt(1, 1);
2272
  helpers.doKeys('n');
2273
  helpers.assertCursorAt(1, 3);
2274
  helpers.doKeys('n');
2275
  helpers.assertCursorAt(0, 0);
2276
}, { value: 'aaa aa \n a aa'});
2277
testVim('?_greedy', function(cm, vim, helpers) {
2278
  cm.openDialog = helpers.fakeOpenDialog('a+');
2279
  helpers.doKeys('?');
2280
  helpers.assertCursorAt(1, 3);
2281
  helpers.doKeys('n');
2282
  helpers.assertCursorAt(1, 1);
2283
  helpers.doKeys('n');
2284
  helpers.assertCursorAt(0, 4);
2285
  helpers.doKeys('n');
2286
  helpers.assertCursorAt(0, 0);
2287
}, { value: 'aaa aa \n a aa'});
2288
testVim('/_greedy_0_or_more', function(cm, vim, helpers) {
2289
  cm.openDialog = helpers.fakeOpenDialog('a*');
2290
  helpers.doKeys('/');
2291
  helpers.assertCursorAt(0, 3);
2292
  helpers.doKeys('n');
2293
  helpers.assertCursorAt(0, 4);
2294
  helpers.doKeys('n');
2295
  helpers.assertCursorAt(0, 5);
2296
  helpers.doKeys('n');
2297
  helpers.assertCursorAt(1, 0);
2298
  helpers.doKeys('n');
2299
  helpers.assertCursorAt(1, 1);
2300
  helpers.doKeys('n');
2301
  helpers.assertCursorAt(0, 0);
2302
}, { value: 'aaa  aa\n aa'});
2303
testVim('?_greedy_0_or_more', function(cm, vim, helpers) {
2304
  cm.openDialog = helpers.fakeOpenDialog('a*');
2305
  helpers.doKeys('?');
2306
  helpers.assertCursorAt(1, 1);
2307
  helpers.doKeys('n');
2308
  helpers.assertCursorAt(1, 0);
2309
  helpers.doKeys('n');
2310
  helpers.assertCursorAt(0, 5);
2311
  helpers.doKeys('n');
2312
  helpers.assertCursorAt(0, 4);
2313
  helpers.doKeys('n');
2314
  helpers.assertCursorAt(0, 3);
2315
  helpers.doKeys('n');
2316
  helpers.assertCursorAt(0, 0);
2317
}, { value: 'aaa  aa\n aa'});
2318
testVim('? and n/N', function(cm, vim, helpers) {
2319
  cm.openDialog = helpers.fakeOpenDialog('match');
2320
  helpers.doKeys('?');
2321
  helpers.assertCursorAt(1, 6);
2322
  helpers.doKeys('n');
2323
  helpers.assertCursorAt(0, 11);
2324
  helpers.doKeys('N');
2325
  helpers.assertCursorAt(1, 6);
2326
2327
  cm.setCursor(0, 0);
2328
  helpers.doKeys('2', '?');
2329
  helpers.assertCursorAt(0, 11);
2330
}, { value: 'match nope match \n nope Match' });
2331
testVim('*', function(cm, vim, helpers) {
2332
  cm.setCursor(0, 9);
2333
  helpers.doKeys('*');
2334
  helpers.assertCursorAt(0, 22);
2335
2336
  cm.setCursor(0, 9);
2337
  helpers.doKeys('2', '*');
2338
  helpers.assertCursorAt(1, 8);
2339
}, { value: 'nomatch match nomatch match \nnomatch Match' });
2340
testVim('*_no_word', function(cm, vim, helpers) {
2341
  cm.setCursor(0, 0);
2342
  helpers.doKeys('*');
2343
  helpers.assertCursorAt(0, 0);
2344
}, { value: ' \n match \n' });
2345
testVim('*_symbol', function(cm, vim, helpers) {
2346
  cm.setCursor(0, 0);
2347
  helpers.doKeys('*');
2348
  helpers.assertCursorAt(1, 0);
2349
}, { value: ' /}\n/} match \n' });
2350
testVim('#', function(cm, vim, helpers) {
2351
  cm.setCursor(0, 9);
2352
  helpers.doKeys('#');
2353
  helpers.assertCursorAt(1, 8);
2354
2355
  cm.setCursor(0, 9);
2356
  helpers.doKeys('2', '#');
2357
  helpers.assertCursorAt(0, 22);
2358
}, { value: 'nomatch match nomatch match \nnomatch Match' });
2359
testVim('*_seek', function(cm, vim, helpers) {
2360
  // Should skip over space and symbols.
2361
  cm.setCursor(0, 3);
2362
  helpers.doKeys('*');
2363
  helpers.assertCursorAt(0, 22);
2364
}, { value: '    :=  match nomatch match \nnomatch Match' });
2365
testVim('#', function(cm, vim, helpers) {
2366
  // Should skip over space and symbols.
2367
  cm.setCursor(0, 3);
2368
  helpers.doKeys('#');
2369
  helpers.assertCursorAt(1, 8);
2370
}, { value: '    :=  match nomatch match \nnomatch Match' });
2371
testVim('g*', function(cm, vim, helpers) {
2372
  cm.setCursor(0, 8);
2373
  helpers.doKeys('g', '*');
2374
  helpers.assertCursorAt(0, 18);
2375
  cm.setCursor(0, 8);
2376
  helpers.doKeys('3', 'g', '*');
2377
  helpers.assertCursorAt(1, 8);
2378
}, { value: 'matches match alsoMatch\nmatchme matching' });
2379
testVim('g#', function(cm, vim, helpers) {
2380
  cm.setCursor(0, 8);
2381
  helpers.doKeys('g', '#');
2382
  helpers.assertCursorAt(0, 0);
2383
  cm.setCursor(0, 8);
2384
  helpers.doKeys('3', 'g', '#');
2385
  helpers.assertCursorAt(1, 0);
2386
}, { value: 'matches match alsoMatch\nmatchme matching' });
2387
testVim('macro_insert', function(cm, vim, helpers) {
2388
  cm.setCursor(0, 0);
2389
  helpers.doKeys('q', 'a', '0', 'i');
2390
  cm.replaceRange('foo', cm.getCursor());
2391
  helpers.doKeys('<Esc>');
2392
  helpers.doKeys('q', '@', 'a');
2393
  eq('foofoo', cm.getValue());
2394
}, { value: ''});
2395
testVim('macro_insert_repeat', function(cm, vim, helpers) {
2396
  cm.setCursor(0, 0);
2397
  helpers.doKeys('q', 'a', '$', 'a');
2398
  cm.replaceRange('larry.', cm.getCursor());
2399
  helpers.doKeys('<Esc>');
2400
  helpers.doKeys('a');
2401
  cm.replaceRange('curly.', cm.getCursor());
2402
  helpers.doKeys('<Esc>');
2403
  helpers.doKeys('q');
2404
  helpers.doKeys('a');
2405
  cm.replaceRange('moe.', cm.getCursor());
2406
  helpers.doKeys('<Esc>');
2407
  helpers.doKeys('@', 'a');
2408
  // At this point, the most recent edit should be the 2nd insert change
2409
  // inside the macro, i.e. "curly.".
2410
  helpers.doKeys('.');
2411
  eq('larry.curly.moe.larry.curly.curly.', cm.getValue());
2412
}, { value: ''});
2413
testVim('macro_space', function(cm, vim, helpers) {
2414
  cm.setCursor(0, 0);
2415
  helpers.doKeys('<Space>', '<Space>');
2416
  helpers.assertCursorAt(0, 2);
2417
  helpers.doKeys('q', 'a', '<Space>', '<Space>', 'q');
2418
  helpers.assertCursorAt(0, 4);
2419
  helpers.doKeys('@', 'a');
2420
  helpers.assertCursorAt(0, 6);
2421
  helpers.doKeys('@', 'a');
2422
  helpers.assertCursorAt(0, 8);
2423
}, { value: 'one line of text.'});
2424
testVim('macro_t_search', function(cm, vim, helpers) {
2425
  cm.setCursor(0, 0);
2426
  helpers.doKeys('q', 'a', 't', 'e', 'q');
2427
  helpers.assertCursorAt(0, 1);
2428
  helpers.doKeys('l', '@', 'a');
2429
  helpers.assertCursorAt(0, 6);
2430
  helpers.doKeys('l', ';');
2431
  helpers.assertCursorAt(0, 12);
2432
}, { value: 'one line of text.'});
2433
testVim('macro_f_search', function(cm, vim, helpers) {
2434
  cm.setCursor(0, 0);
2435
  helpers.doKeys('q', 'b', 'f', 'e', 'q');
2436
  helpers.assertCursorAt(0, 2);
2437
  helpers.doKeys('@', 'b');
2438
  helpers.assertCursorAt(0, 7);
2439
  helpers.doKeys(';');
2440
  helpers.assertCursorAt(0, 13);
2441
}, { value: 'one line of text.'});
2442
testVim('macro_slash_search', function(cm, vim, helpers) {
2443
  cm.setCursor(0, 0);
2444
  helpers.doKeys('q', 'c');
2445
  cm.openDialog = helpers.fakeOpenDialog('e');
2446
  helpers.doKeys('/', 'q');
2447
  helpers.assertCursorAt(0, 2);
2448
  helpers.doKeys('@', 'c');
2449
  helpers.assertCursorAt(0, 7);
2450
  helpers.doKeys('n');
2451
  helpers.assertCursorAt(0, 13);
2452
}, { value: 'one line of text.'});
2453
testVim('macro_multislash_search', function(cm, vim, helpers) {
2454
  cm.setCursor(0, 0);
2455
  helpers.doKeys('q', 'd');
2456
  cm.openDialog = helpers.fakeOpenDialog('e');
2457
  helpers.doKeys('/');
2458
  cm.openDialog = helpers.fakeOpenDialog('t');
2459
  helpers.doKeys('/', 'q');
2460
  helpers.assertCursorAt(0, 12);
2461
  helpers.doKeys('@', 'd');
2462
  helpers.assertCursorAt(0, 15);
2463
}, { value: 'one line of text to rule them all.'});
2464
testVim('macro_last_ex_command_register', function (cm, vim, helpers) {
2465
  cm.setCursor(0, 0);
2466
  helpers.doEx('s/a/b');
2467
  helpers.doKeys('2', '@', ':');
2468
  eq('bbbaa', cm.getValue());
2469
  helpers.assertCursorAt(0, 2);
2470
}, { value: 'aaaaa'});
2471
testVim('macro_parens', function(cm, vim, helpers) {
2472
  cm.setCursor(0, 0);
2473
  helpers.doKeys('q', 'z', 'i');
2474
  cm.replaceRange('(', cm.getCursor());
2475
  helpers.doKeys('<Esc>');
2476
  helpers.doKeys('e', 'a');
2477
  cm.replaceRange(')', cm.getCursor());
2478
  helpers.doKeys('<Esc>');
2479
  helpers.doKeys('q');
2480
  helpers.doKeys('w', '@', 'z');
2481
  helpers.doKeys('w', '@', 'z');
2482
  eq('(see) (spot) (run)', cm.getValue());
2483
}, { value: 'see spot run'});
2484
testVim('macro_overwrite', function(cm, vim, helpers) {
2485
  cm.setCursor(0, 0);
2486
  helpers.doKeys('q', 'z', '0', 'i');
2487
  cm.replaceRange('I ', cm.getCursor());
2488
  helpers.doKeys('<Esc>');
2489
  helpers.doKeys('q');
2490
  helpers.doKeys('e');
2491
  // Now replace the macro with something else.
2492
  helpers.doKeys('q', 'z', 'a');
2493
  cm.replaceRange('.', cm.getCursor());
2494
  helpers.doKeys('<Esc>');
2495
  helpers.doKeys('q');
2496
  helpers.doKeys('e', '@', 'z');
2497
  helpers.doKeys('e', '@', 'z');
2498
  eq('I see. spot. run.', cm.getValue());
2499
}, { value: 'see spot run'});
2500
testVim('macro_search_f', function(cm, vim, helpers) {
2501
  cm.setCursor(0, 0);
2502
  helpers.doKeys('q', 'a', 'f', ' ');
2503
  helpers.assertCursorAt(0,3);
2504
  helpers.doKeys('q', '0');
2505
  helpers.assertCursorAt(0,0);
2506
  helpers.doKeys('@', 'a');
2507
  helpers.assertCursorAt(0,3);
2508
}, { value: 'The quick brown fox jumped over the lazy dog.'});
2509
testVim('macro_search_2f', function(cm, vim, helpers) {
2510
  cm.setCursor(0, 0);
2511
  helpers.doKeys('q', 'a', '2', 'f', ' ');
2512
  helpers.assertCursorAt(0,9);
2513
  helpers.doKeys('q', '0');
2514
  helpers.assertCursorAt(0,0);
2515
  helpers.doKeys('@', 'a');
2516
  helpers.assertCursorAt(0,9);
2517
}, { value: 'The quick brown fox jumped over the lazy dog.'});
2518
testVim('yank_register', function(cm, vim, helpers) {
2519
  cm.setCursor(0, 0);
2520
  helpers.doKeys('"', 'a', 'y', 'y');
2521
  helpers.doKeys('j', '"', 'b', 'y', 'y');
2522
  cm.openDialog = helpers.fakeOpenDialog('registers');
2523
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2524
    is(/a\s+foo/.test(text));
2525
    is(/b\s+bar/.test(text));
2526
  });
2527
  helpers.doKeys(':');
2528
}, { value: 'foo\nbar'});
2529
testVim('yank_visual_block', function(cm, vim, helpers) {
2530
  cm.setCursor(0, 1);
2531
  helpers.doKeys('<C-v>', 'l', 'j', '"', 'a', 'y');
2532
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2533
    is(/a\s+oo\nar/.test(text));
2534
  });
2535
  helpers.doKeys(':');
2536
}, { value: 'foo\nbar'});
2537
testVim('yank_append_line_to_line_register', function(cm, vim, helpers) {
2538
  cm.setCursor(0, 0);
2539
  helpers.doKeys('"', 'a', 'y', 'y');
2540
  helpers.doKeys('j', '"', 'A', 'y', 'y');
2541
  cm.openDialog = helpers.fakeOpenDialog('registers');
2542
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2543
    is(/a\s+foo\nbar/.test(text));
2544
    is(/"\s+foo\nbar/.test(text));
2545
  });
2546
  helpers.doKeys(':');
2547
}, { value: 'foo\nbar'});
2548
testVim('yank_append_word_to_word_register', function(cm, vim, helpers) {
2549
  cm.setCursor(0, 0);
2550
  helpers.doKeys('"', 'a', 'y', 'w');
2551
  helpers.doKeys('j', '"', 'A', 'y', 'w');
2552
  cm.openDialog = helpers.fakeOpenDialog('registers');
2553
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2554
    is(/a\s+foobar/.test(text));
2555
    is(/"\s+foobar/.test(text));
2556
  });
2557
  helpers.doKeys(':');
2558
}, { value: 'foo\nbar'});
2559
testVim('yank_append_line_to_word_register', function(cm, vim, helpers) {
2560
  cm.setCursor(0, 0);
2561
  helpers.doKeys('"', 'a', 'y', 'w');
2562
  helpers.doKeys('j', '"', 'A', 'y', 'y');
2563
  cm.openDialog = helpers.fakeOpenDialog('registers');
2564
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2565
    is(/a\s+foo\nbar/.test(text));
2566
    is(/"\s+foo\nbar/.test(text));
2567
  });
2568
  helpers.doKeys(':');
2569
}, { value: 'foo\nbar'});
2570
testVim('yank_append_word_to_line_register', function(cm, vim, helpers) {
2571
  cm.setCursor(0, 0);
2572
  helpers.doKeys('"', 'a', 'y', 'y');
2573
  helpers.doKeys('j', '"', 'A', 'y', 'w');
2574
  cm.openDialog = helpers.fakeOpenDialog('registers');
2575
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2576
    is(/a\s+foo\nbar/.test(text));
2577
    is(/"\s+foo\nbar/.test(text));
2578
  });
2579
  helpers.doKeys(':');
2580
}, { value: 'foo\nbar'});
2581
testVim('macro_register', function(cm, vim, helpers) {
2582
  cm.setCursor(0, 0);
2583
  helpers.doKeys('q', 'a', 'i');
2584
  cm.replaceRange('gangnam', cm.getCursor());
2585
  helpers.doKeys('<Esc>');
2586
  helpers.doKeys('q');
2587
  helpers.doKeys('q', 'b', 'o');
2588
  cm.replaceRange('style', cm.getCursor());
2589
  helpers.doKeys('<Esc>');
2590
  helpers.doKeys('q');
2591
  cm.openDialog = helpers.fakeOpenDialog('registers');
2592
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2593
    is(/a\s+i/.test(text));
2594
    is(/b\s+o/.test(text));
2595
  });
2596
  helpers.doKeys(':');
2597
}, { value: ''});
2598
testVim('._register', function(cm,vim,helpers) {
2599
  cm.setCursor(0,0);
2600
  helpers.doKeys('i');
2601
  cm.replaceRange('foo',cm.getCursor());
2602
  helpers.doKeys('<Esc>');
2603
  cm.openDialog = helpers.fakeOpenDialog('registers');
2604
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2605
    is(/\.\s+foo/.test(text));
2606
  });
2607
  helpers.doKeys(':');
2608
}, {value: ''});
2609
testVim(':_register', function(cm,vim,helpers) {
2610
  helpers.doEx('bar');
2611
  cm.openDialog = helpers.fakeOpenDialog('registers');
2612
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2613
    is(/:\s+bar/.test(text));
2614
  });
2615
  helpers.doKeys(':');
2616
}, {value: ''});
2617
testVim('search_register_escape', function(cm, vim, helpers) {
2618
  // Check that the register is restored if the user escapes rather than confirms.
2619
  cm.openDialog = helpers.fakeOpenDialog('waldo');
2620
  helpers.doKeys('/');
2621
  var onKeyDown;
2622
  var onKeyUp;
2623
  var KEYCODES = {
2624
    f: 70,
2625
    o: 79,
2626
    Esc: 27
2627
  };
2628
  cm.openDialog = function(template, callback, options) {
2629
    onKeyDown = options.onKeyDown;
2630
    onKeyUp = options.onKeyUp;
2631
  };
2632
  var close = function() {};
2633
  helpers.doKeys('/');
2634
  // Fake some keyboard events coming in.
2635
  onKeyDown({keyCode: KEYCODES.f}, '', close);
2636
  onKeyUp({keyCode: KEYCODES.f}, '', close);
2637
  onKeyDown({keyCode: KEYCODES.o}, 'f', close);
2638
  onKeyUp({keyCode: KEYCODES.o}, 'f', close);
2639
  onKeyDown({keyCode: KEYCODES.o}, 'fo', close);
2640
  onKeyUp({keyCode: KEYCODES.o}, 'fo', close);
2641
  onKeyDown({keyCode: KEYCODES.Esc}, 'foo', close);
2642
  cm.openDialog = helpers.fakeOpenDialog('registers');
2643
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2644
    is(/waldo/.test(text));
2645
    is(!/foo/.test(text));
2646
  });
2647
  helpers.doKeys(':');
2648
}, {value: ''});
2649
testVim('search_register', function(cm, vim, helpers) {
2650
  cm.openDialog = helpers.fakeOpenDialog('foo');
2651
  helpers.doKeys('/');
2652
  cm.openDialog = helpers.fakeOpenDialog('registers');
2653
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
2654
    is(/\/\s+foo/.test(text));
2655
  });
2656
  helpers.doKeys(':');
2657
}, {value: ''});
2658 View Code Duplication
testVim('search_history', function(cm, vim, helpers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2659
  cm.openDialog = helpers.fakeOpenDialog('this');
2660
  helpers.doKeys('/');
2661
  cm.openDialog = helpers.fakeOpenDialog('checks');
2662
  helpers.doKeys('/');
2663
  cm.openDialog = helpers.fakeOpenDialog('search');
2664
  helpers.doKeys('/');
2665
  cm.openDialog = helpers.fakeOpenDialog('history');
2666
  helpers.doKeys('/');
2667
  cm.openDialog = helpers.fakeOpenDialog('checks');
2668
  helpers.doKeys('/');
2669
  var onKeyDown;
2670
  var onKeyUp;
2671
  var query = '';
2672
  var keyCodes = {
2673
    Up: 38,
2674
    Down: 40
2675
  };
2676
  cm.openDialog = function(template, callback, options) {
2677
    onKeyUp = options.onKeyUp;
2678
    onKeyDown = options.onKeyDown;
2679
  };
2680
  var close = function(newVal) {
2681
    if (typeof newVal == 'string') query = newVal;
2682
  }
2683
  helpers.doKeys('/');
2684
  onKeyDown({keyCode: keyCodes.Up}, query, close);
2685
  onKeyUp({keyCode: keyCodes.Up}, query, close);
2686
  eq(query, 'checks');
2687
  onKeyDown({keyCode: keyCodes.Up}, query, close);
2688
  onKeyUp({keyCode: keyCodes.Up}, query, close);
2689
  eq(query, 'history');
2690
  onKeyDown({keyCode: keyCodes.Up}, query, close);
2691
  onKeyUp({keyCode: keyCodes.Up}, query, close);
2692
  eq(query, 'search');
2693
  onKeyDown({keyCode: keyCodes.Up}, query, close);
2694
  onKeyUp({keyCode: keyCodes.Up}, query, close);
2695
  eq(query, 'this');
2696
  onKeyDown({keyCode: keyCodes.Down}, query, close);
2697
  onKeyUp({keyCode: keyCodes.Down}, query, close);
2698
  eq(query, 'search');
2699
}, {value: ''});
2700 View Code Duplication
testVim('exCommand_history', function(cm, vim, helpers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2701
  cm.openDialog = helpers.fakeOpenDialog('registers');
2702
  helpers.doKeys(':');
2703
  cm.openDialog = helpers.fakeOpenDialog('sort');
2704
  helpers.doKeys(':');
2705
  cm.openDialog = helpers.fakeOpenDialog('map');
2706
  helpers.doKeys(':');
2707
  cm.openDialog = helpers.fakeOpenDialog('invalid');
2708
  helpers.doKeys(':');
2709
  var onKeyDown;
2710
  var onKeyUp;
2711
  var input = '';
2712
  var keyCodes = {
2713
    Up: 38,
2714
    Down: 40,
2715
    s: 115
2716
  };
2717
  cm.openDialog = function(template, callback, options) {
2718
    onKeyUp = options.onKeyUp;
2719
    onKeyDown = options.onKeyDown;
2720
  };
2721
  var close = function(newVal) {
2722
    if (typeof newVal == 'string') input = newVal;
2723
  }
2724
  helpers.doKeys(':');
2725
  onKeyDown({keyCode: keyCodes.Up}, input, close);
2726
  eq(input, 'invalid');
2727
  onKeyDown({keyCode: keyCodes.Up}, input, close);
2728
  eq(input, 'map');
2729
  onKeyDown({keyCode: keyCodes.Up}, input, close);
2730
  eq(input, 'sort');
2731
  onKeyDown({keyCode: keyCodes.Up}, input, close);
2732
  eq(input, 'registers');
2733
  onKeyDown({keyCode: keyCodes.s}, '', close);
2734
  input = 's';
2735
  onKeyDown({keyCode: keyCodes.Up}, input, close);
2736
  eq(input, 'sort');
2737
}, {value: ''});
2738 View Code Duplication
testVim('search_clear', function(cm, vim, helpers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2739
  var onKeyDown;
2740
  var input = '';
2741
  var keyCodes = {
2742
    Ctrl: 17,
2743
    u: 85
2744
  };
2745
  cm.openDialog = function(template, callback, options) {
2746
    onKeyDown = options.onKeyDown;
2747
  };
2748
  var close = function(newVal) {
2749
    if (typeof newVal == 'string') input = newVal;
2750
  }
2751
  helpers.doKeys('/');
2752
  input = 'foo';
2753
  onKeyDown({keyCode: keyCodes.Ctrl}, input, close);
2754
  onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close);
2755
  eq(input, '');
2756
});
2757 View Code Duplication
testVim('exCommand_clear', function(cm, vim, helpers) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2758
  var onKeyDown;
2759
  var input = '';
2760
  var keyCodes = {
2761
    Ctrl: 17,
2762
    u: 85
2763
  };
2764
  cm.openDialog = function(template, callback, options) {
2765
    onKeyDown = options.onKeyDown;
2766
  };
2767
  var close = function(newVal) {
2768
    if (typeof newVal == 'string') input = newVal;
2769
  }
2770
  helpers.doKeys(':');
2771
  input = 'foo';
2772
  onKeyDown({keyCode: keyCodes.Ctrl}, input, close);
2773
  onKeyDown({keyCode: keyCodes.u, ctrlKey: true}, input, close);
2774
  eq(input, '');
2775
});
2776
testVim('.', function(cm, vim, helpers) {
2777
  cm.setCursor(0, 0);
2778
  helpers.doKeys('2', 'd', 'w');
2779
  helpers.doKeys('.');
2780
  eq('5 6', cm.getValue());
2781
}, { value: '1 2 3 4 5 6'});
2782
testVim('._repeat', function(cm, vim, helpers) {
2783
  cm.setCursor(0, 0);
2784
  helpers.doKeys('2', 'd', 'w');
2785
  helpers.doKeys('3', '.');
2786
  eq('6', cm.getValue());
2787
}, { value: '1 2 3 4 5 6'});
2788
testVim('._insert', function(cm, vim, helpers) {
2789
  helpers.doKeys('i');
2790
  cm.replaceRange('test', cm.getCursor());
2791
  helpers.doKeys('<Esc>');
2792
  helpers.doKeys('.');
2793
  eq('testestt', cm.getValue());
2794
  helpers.assertCursorAt(0, 6);
2795
}, { value: ''});
2796
testVim('._insert_repeat', function(cm, vim, helpers) {
2797
  helpers.doKeys('i');
2798
  cm.replaceRange('test', cm.getCursor());
2799
  cm.setCursor(0, 4);
2800
  helpers.doKeys('<Esc>');
2801
  helpers.doKeys('2', '.');
2802
  eq('testesttestt', cm.getValue());
2803
  helpers.assertCursorAt(0, 10);
2804
}, { value: ''});
2805
testVim('._repeat_insert', function(cm, vim, helpers) {
2806
  helpers.doKeys('3', 'i');
2807
  cm.replaceRange('te', cm.getCursor());
2808
  cm.setCursor(0, 2);
2809
  helpers.doKeys('<Esc>');
2810
  helpers.doKeys('.');
2811
  eq('tetettetetee', cm.getValue());
2812
  helpers.assertCursorAt(0, 10);
2813
}, { value: ''});
2814
testVim('._insert_o', function(cm, vim, helpers) {
2815
  helpers.doKeys('o');
2816
  cm.replaceRange('z', cm.getCursor());
2817
  cm.setCursor(1, 1);
2818
  helpers.doKeys('<Esc>');
2819
  helpers.doKeys('.');
2820
  eq('\nz\nz', cm.getValue());
2821
  helpers.assertCursorAt(2, 0);
2822
}, { value: ''});
2823
testVim('._insert_o_repeat', function(cm, vim, helpers) {
2824
  helpers.doKeys('o');
2825
  cm.replaceRange('z', cm.getCursor());
2826
  helpers.doKeys('<Esc>');
2827
  cm.setCursor(1, 0);
2828
  helpers.doKeys('2', '.');
2829
  eq('\nz\nz\nz', cm.getValue());
2830
  helpers.assertCursorAt(3, 0);
2831
}, { value: ''});
2832
testVim('._insert_o_indent', function(cm, vim, helpers) {
2833
  helpers.doKeys('o');
2834
  cm.replaceRange('z', cm.getCursor());
2835
  helpers.doKeys('<Esc>');
2836
  cm.setCursor(1, 2);
2837
  helpers.doKeys('.');
2838
  eq('{\n  z\n  z', cm.getValue());
2839
  helpers.assertCursorAt(2, 2);
2840
}, { value: '{'});
2841
testVim('._insert_cw', function(cm, vim, helpers) {
2842
  helpers.doKeys('c', 'w');
2843
  cm.replaceRange('test', cm.getCursor());
2844
  helpers.doKeys('<Esc>');
2845
  cm.setCursor(0, 3);
2846
  helpers.doKeys('2', 'l');
2847
  helpers.doKeys('.');
2848
  eq('test test word3', cm.getValue());
2849
  helpers.assertCursorAt(0, 8);
2850
}, { value: 'word1 word2 word3' });
2851
testVim('._insert_cw_repeat', function(cm, vim, helpers) {
2852
  // For some reason, repeat cw in desktop VIM will does not repeat insert mode
2853
  // changes. Will conform to that behavior.
2854
  helpers.doKeys('c', 'w');
2855
  cm.replaceRange('test', cm.getCursor());
2856
  helpers.doKeys('<Esc>');
2857
  cm.setCursor(0, 4);
2858
  helpers.doKeys('l');
2859
  helpers.doKeys('2', '.');
2860
  eq('test test', cm.getValue());
2861
  helpers.assertCursorAt(0, 8);
2862
}, { value: 'word1 word2 word3' });
2863
testVim('._delete', function(cm, vim, helpers) {
2864
  cm.setCursor(0, 5);
2865
  helpers.doKeys('i');
2866
  helpers.doInsertModeKeys('Backspace');
2867
  helpers.doKeys('<Esc>');
2868
  helpers.doKeys('.');
2869
  eq('zace', cm.getValue());
2870
  helpers.assertCursorAt(0, 1);
2871
}, { value: 'zabcde'});
2872
testVim('._delete_repeat', function(cm, vim, helpers) {
2873
  cm.setCursor(0, 6);
2874
  helpers.doKeys('i');
2875
  helpers.doInsertModeKeys('Backspace');
2876
  helpers.doKeys('<Esc>');
2877
  helpers.doKeys('2', '.');
2878
  eq('zzce', cm.getValue());
2879
  helpers.assertCursorAt(0, 1);
2880
}, { value: 'zzabcde'});
2881
testVim('._visual_>', function(cm, vim, helpers) {
2882
  cm.setCursor(0, 0);
2883
  helpers.doKeys('V', 'j', '>');
2884
  cm.setCursor(2, 0)
2885
  helpers.doKeys('.');
2886
  eq('  1\n  2\n  3\n  4', cm.getValue());
2887
  helpers.assertCursorAt(2, 2);
2888
}, { value: '1\n2\n3\n4'});
2889
testVim('f;', function(cm, vim, helpers) {
2890
  cm.setCursor(0, 0);
2891
  helpers.doKeys('f', 'x');
2892
  helpers.doKeys(';');
2893
  helpers.doKeys('2', ';');
2894
  eq(9, cm.getCursor().ch);
2895
}, { value: '01x3xx678x'});
2896
testVim('F;', function(cm, vim, helpers) {
2897
  cm.setCursor(0, 8);
2898
  helpers.doKeys('F', 'x');
2899
  helpers.doKeys(';');
2900
  helpers.doKeys('2', ';');
2901
  eq(2, cm.getCursor().ch);
2902
}, { value: '01x3xx6x8x'});
2903
testVim('t;', function(cm, vim, helpers) {
2904
  cm.setCursor(0, 0);
2905
  helpers.doKeys('t', 'x');
2906
  helpers.doKeys(';');
2907
  helpers.doKeys('2', ';');
2908
  eq(8, cm.getCursor().ch);
2909
}, { value: '01x3xx678x'});
2910
testVim('T;', function(cm, vim, helpers) {
2911
  cm.setCursor(0, 9);
2912
  helpers.doKeys('T', 'x');
2913
  helpers.doKeys(';');
2914
  helpers.doKeys('2', ';');
2915
  eq(2, cm.getCursor().ch);
2916
}, { value: '0xx3xx678x'});
2917
testVim('f,', function(cm, vim, helpers) {
2918
  cm.setCursor(0, 6);
2919
  helpers.doKeys('f', 'x');
2920
  helpers.doKeys(',');
2921
  helpers.doKeys('2', ',');
2922
  eq(2, cm.getCursor().ch);
2923
}, { value: '01x3xx678x'});
2924
testVim('F,', function(cm, vim, helpers) {
2925
  cm.setCursor(0, 3);
2926
  helpers.doKeys('F', 'x');
2927
  helpers.doKeys(',');
2928
  helpers.doKeys('2', ',');
2929
  eq(9, cm.getCursor().ch);
2930
}, { value: '01x3xx678x'});
2931
testVim('t,', function(cm, vim, helpers) {
2932
  cm.setCursor(0, 6);
2933
  helpers.doKeys('t', 'x');
2934
  helpers.doKeys(',');
2935
  helpers.doKeys('2', ',');
2936
  eq(3, cm.getCursor().ch);
2937
}, { value: '01x3xx678x'});
2938
testVim('T,', function(cm, vim, helpers) {
2939
  cm.setCursor(0, 4);
2940
  helpers.doKeys('T', 'x');
2941
  helpers.doKeys(',');
2942
  helpers.doKeys('2', ',');
2943
  eq(8, cm.getCursor().ch);
2944
}, { value: '01x3xx67xx'});
2945
testVim('fd,;', function(cm, vim, helpers) {
2946
  cm.setCursor(0, 0);
2947
  helpers.doKeys('f', '4');
2948
  cm.setCursor(0, 0);
2949
  helpers.doKeys('d', ';');
2950
  eq('56789', cm.getValue());
2951
  helpers.doKeys('u');
2952
  cm.setCursor(0, 9);
2953
  helpers.doKeys('d', ',');
2954
  eq('01239', cm.getValue());
2955
}, { value: '0123456789'});
2956
testVim('Fd,;', function(cm, vim, helpers) {
2957
  cm.setCursor(0, 9);
2958
  helpers.doKeys('F', '4');
2959
  cm.setCursor(0, 9);
2960
  helpers.doKeys('d', ';');
2961
  eq('01239', cm.getValue());
2962
  helpers.doKeys('u');
2963
  cm.setCursor(0, 0);
2964
  helpers.doKeys('d', ',');
2965
  eq('56789', cm.getValue());
2966
}, { value: '0123456789'});
2967
testVim('td,;', function(cm, vim, helpers) {
2968
  cm.setCursor(0, 0);
2969
  helpers.doKeys('t', '4');
2970
  cm.setCursor(0, 0);
2971
  helpers.doKeys('d', ';');
2972
  eq('456789', cm.getValue());
2973
  helpers.doKeys('u');
2974
  cm.setCursor(0, 9);
2975
  helpers.doKeys('d', ',');
2976
  eq('012349', cm.getValue());
2977
}, { value: '0123456789'});
2978
testVim('Td,;', function(cm, vim, helpers) {
2979
  cm.setCursor(0, 9);
2980
  helpers.doKeys('T', '4');
2981
  cm.setCursor(0, 9);
2982
  helpers.doKeys('d', ';');
2983
  eq('012349', cm.getValue());
2984
  helpers.doKeys('u');
2985
  cm.setCursor(0, 0);
2986
  helpers.doKeys('d', ',');
2987
  eq('456789', cm.getValue());
2988
}, { value: '0123456789'});
2989
testVim('fc,;', function(cm, vim, helpers) {
2990
  cm.setCursor(0, 0);
2991
  helpers.doKeys('f', '4');
2992
  cm.setCursor(0, 0);
2993
  helpers.doKeys('c', ';', '<Esc>');
2994
  eq('56789', cm.getValue());
2995
  helpers.doKeys('u');
2996
  cm.setCursor(0, 9);
2997
  helpers.doKeys('c', ',');
2998
  eq('01239', cm.getValue());
2999
}, { value: '0123456789'});
3000
testVim('Fc,;', function(cm, vim, helpers) {
3001
  cm.setCursor(0, 9);
3002
  helpers.doKeys('F', '4');
3003
  cm.setCursor(0, 9);
3004
  helpers.doKeys('c', ';', '<Esc>');
3005
  eq('01239', cm.getValue());
3006
  helpers.doKeys('u');
3007
  cm.setCursor(0, 0);
3008
  helpers.doKeys('c', ',');
3009
  eq('56789', cm.getValue());
3010
}, { value: '0123456789'});
3011
testVim('tc,;', function(cm, vim, helpers) {
3012
  cm.setCursor(0, 0);
3013
  helpers.doKeys('t', '4');
3014
  cm.setCursor(0, 0);
3015
  helpers.doKeys('c', ';', '<Esc>');
3016
  eq('456789', cm.getValue());
3017
  helpers.doKeys('u');
3018
  cm.setCursor(0, 9);
3019
  helpers.doKeys('c', ',');
3020
  eq('012349', cm.getValue());
3021
}, { value: '0123456789'});
3022
testVim('Tc,;', function(cm, vim, helpers) {
3023
  cm.setCursor(0, 9);
3024
  helpers.doKeys('T', '4');
3025
  cm.setCursor(0, 9);
3026
  helpers.doKeys('c', ';', '<Esc>');
3027
  eq('012349', cm.getValue());
3028
  helpers.doKeys('u');
3029
  cm.setCursor(0, 0);
3030
  helpers.doKeys('c', ',');
3031
  eq('456789', cm.getValue());
3032
}, { value: '0123456789'});
3033
testVim('fy,;', function(cm, vim, helpers) {
3034
  cm.setCursor(0, 0);
3035
  helpers.doKeys('f', '4');
3036
  cm.setCursor(0, 0);
3037
  helpers.doKeys('y', ';', 'P');
3038
  eq('012340123456789', cm.getValue());
3039
  helpers.doKeys('u');
3040
  cm.setCursor(0, 9);
3041
  helpers.doKeys('y', ',', 'P');
3042
  eq('012345678456789', cm.getValue());
3043
}, { value: '0123456789'});
3044
testVim('Fy,;', function(cm, vim, helpers) {
3045
  cm.setCursor(0, 9);
3046
  helpers.doKeys('F', '4');
3047
  cm.setCursor(0, 9);
3048
  helpers.doKeys('y', ';', 'p');
3049
  eq('012345678945678', cm.getValue());
3050
  helpers.doKeys('u');
3051
  cm.setCursor(0, 0);
3052
  helpers.doKeys('y', ',', 'P');
3053
  eq('012340123456789', cm.getValue());
3054
}, { value: '0123456789'});
3055
testVim('ty,;', function(cm, vim, helpers) {
3056
  cm.setCursor(0, 0);
3057
  helpers.doKeys('t', '4');
3058
  cm.setCursor(0, 0);
3059
  helpers.doKeys('y', ';', 'P');
3060
  eq('01230123456789', cm.getValue());
3061
  helpers.doKeys('u');
3062
  cm.setCursor(0, 9);
3063
  helpers.doKeys('y', ',', 'p');
3064
  eq('01234567895678', cm.getValue());
3065
}, { value: '0123456789'});
3066
testVim('Ty,;', function(cm, vim, helpers) {
3067
  cm.setCursor(0, 9);
3068
  helpers.doKeys('T', '4');
3069
  cm.setCursor(0, 9);
3070
  helpers.doKeys('y', ';', 'p');
3071
  eq('01234567895678', cm.getValue());
3072
  helpers.doKeys('u');
3073
  cm.setCursor(0, 0);
3074
  helpers.doKeys('y', ',', 'P');
3075
  eq('01230123456789', cm.getValue());
3076
}, { value: '0123456789'});
3077
testVim('HML', function(cm, vim, helpers) {
3078
  var lines = 35;
3079
  var textHeight = cm.defaultTextHeight();
3080
  cm.setSize(600, lines*textHeight);
3081
  cm.setCursor(120, 0);
3082
  helpers.doKeys('H');
3083
  helpers.assertCursorAt(86, 2);
3084
  helpers.doKeys('L');
3085
  helpers.assertCursorAt(120, 4);
3086
  helpers.doKeys('M');
3087
  helpers.assertCursorAt(103,4);
3088
}, { value: (function(){
3089
  var lines = new Array(100);
3090
  var upper = '  xx\n';
3091
  var lower = '    xx\n';
3092
  upper = lines.join(upper);
3093
  lower = lines.join(lower);
3094
  return upper + lower;
3095
})()});
3096
3097
var zVals = [];
3098
forEach(['zb','zz','zt','z-','z.','z<CR>'], function(e, idx){
3099
  var lineNum = 250;
3100
  var lines = 35;
3101
  testVim(e, function(cm, vim, helpers) {
3102
    var k1 = e[0];
3103
    var k2 = e.substring(1);
3104
    var textHeight = cm.defaultTextHeight();
3105
    cm.setSize(600, lines*textHeight);
3106
    cm.setCursor(lineNum, 0);
3107
    helpers.doKeys(k1, k2);
3108
    zVals[idx] = cm.getScrollInfo().top;
3109
  }, { value: (function(){
3110
    return new Array(500).join('\n');
3111
  })()});
3112
});
3113
testVim('zb<zz', function(cm, vim, helpers){
0 ignored issues
show
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3114
  eq(zVals[0]<zVals[1], true);
3115
});
3116
testVim('zz<zt', function(cm, vim, helpers){
0 ignored issues
show
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3117
  eq(zVals[1]<zVals[2], true);
3118
});
3119
testVim('zb==z-', function(cm, vim, helpers){
0 ignored issues
show
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3120
  eq(zVals[0], zVals[3]);
3121
});
3122
testVim('zz==z.', function(cm, vim, helpers){
0 ignored issues
show
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3123
  eq(zVals[1], zVals[4]);
3124
});
3125
testVim('zt==z<CR>', function(cm, vim, helpers){
0 ignored issues
show
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3126
  eq(zVals[2], zVals[5]);
3127
});
3128
3129
var moveTillCharacterSandbox =
3130
  'The quick brown fox \n';
3131
testVim('moveTillCharacter', function(cm, vim, helpers){
3132
  cm.setCursor(0, 0);
3133
  // Search for the 'q'.
3134
  cm.openDialog = helpers.fakeOpenDialog('q');
3135
  helpers.doKeys('/');
3136
  eq(4, cm.getCursor().ch);
3137
  // Jump to just before the first o in the list.
3138
  helpers.doKeys('t');
3139
  helpers.doKeys('o');
3140
  eq('The quick brown fox \n', cm.getValue());
3141
  // Delete that one character.
3142
  helpers.doKeys('d');
3143
  helpers.doKeys('t');
3144
  helpers.doKeys('o');
3145
  eq('The quick bown fox \n', cm.getValue());
3146
  // Delete everything until the next 'o'.
3147
  helpers.doKeys('.');
3148
  eq('The quick box \n', cm.getValue());
3149
  // An unmatched character should have no effect.
3150
  helpers.doKeys('d');
3151
  helpers.doKeys('t');
3152
  helpers.doKeys('q');
3153
  eq('The quick box \n', cm.getValue());
3154
  // Matches should only be possible on single lines.
3155
  helpers.doKeys('d');
3156
  helpers.doKeys('t');
3157
  helpers.doKeys('z');
3158
  eq('The quick box \n', cm.getValue());
3159
  // After all that, the search for 'q' should still be active, so the 'N' command
3160
  // can run it again in reverse. Use that to delete everything back to the 'q'.
3161
  helpers.doKeys('d');
3162
  helpers.doKeys('N');
3163
  eq('The ox \n', cm.getValue());
3164
  eq(4, cm.getCursor().ch);
3165
}, { value: moveTillCharacterSandbox});
3166
testVim('searchForPipe', function(cm, vim, helpers){
3167
  CodeMirror.Vim.setOption('pcre', false);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3168
  cm.setCursor(0, 0);
3169
  // Search for the '|'.
3170
  cm.openDialog = helpers.fakeOpenDialog('|');
3171
  helpers.doKeys('/');
3172
  eq(4, cm.getCursor().ch);
3173
}, { value: 'this|that'});
3174
3175
3176
var scrollMotionSandbox =
3177
  '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n';
3178
testVim('scrollMotion', function(cm, vim, helpers){
3179
  var prevCursor, prevScrollInfo;
3180
  cm.setCursor(0, 0);
3181
  // ctrl-y at the top of the file should have no effect.
3182
  helpers.doKeys('<C-y>');
3183
  eq(0, cm.getCursor().line);
3184
  prevScrollInfo = cm.getScrollInfo();
3185
  helpers.doKeys('<C-e>');
3186
  eq(1, cm.getCursor().line);
3187
  is(prevScrollInfo.top < cm.getScrollInfo().top);
3188
  // Jump to the end of the sandbox.
3189
  cm.setCursor(1000, 0);
3190
  prevCursor = cm.getCursor();
3191
  // ctrl-e at the bottom of the file should have no effect.
3192
  helpers.doKeys('<C-e>');
3193
  eq(prevCursor.line, cm.getCursor().line);
3194
  prevScrollInfo = cm.getScrollInfo();
3195
  helpers.doKeys('<C-y>');
3196
  eq(prevCursor.line - 1, cm.getCursor().line, "Y");
3197
  is(prevScrollInfo.top > cm.getScrollInfo().top);
3198
}, { value: scrollMotionSandbox});
3199
3200
var squareBracketMotionSandbox = ''+
3201
  '({\n'+//0
3202
  '  ({\n'+//11
3203
  '  /*comment {\n'+//2
3204
  '            */(\n'+//3
3205
  '#else                \n'+//4
3206
  '  /*       )\n'+//5
3207
  '#if        }\n'+//6
3208
  '  )}*/\n'+//7
3209
  ')}\n'+//8
3210
  '{}\n'+//9
3211
  '#else {{\n'+//10
3212
  '{}\n'+//11
3213
  '}\n'+//12
3214
  '{\n'+//13
3215
  '#endif\n'+//14
3216
  '}\n'+//15
3217
  '}\n'+//16
3218
  '#else';//17
3219
testVim('[[, ]]', function(cm, vim, helpers) {
3220
  cm.setCursor(0, 0);
3221
  helpers.doKeys(']', ']');
3222
  helpers.assertCursorAt(9,0);
3223
  helpers.doKeys('2', ']', ']');
3224
  helpers.assertCursorAt(13,0);
3225
  helpers.doKeys(']', ']');
3226
  helpers.assertCursorAt(17,0);
3227
  helpers.doKeys('[', '[');
3228
  helpers.assertCursorAt(13,0);
3229
  helpers.doKeys('2', '[', '[');
3230
  helpers.assertCursorAt(9,0);
3231
  helpers.doKeys('[', '[');
3232
  helpers.assertCursorAt(0,0);
3233
}, { value: squareBracketMotionSandbox});
3234
testVim('[], ][', function(cm, vim, helpers) {
3235
  cm.setCursor(0, 0);
3236
  helpers.doKeys(']', '[');
3237
  helpers.assertCursorAt(12,0);
3238
  helpers.doKeys('2', ']', '[');
3239
  helpers.assertCursorAt(16,0);
3240
  helpers.doKeys(']', '[');
3241
  helpers.assertCursorAt(17,0);
3242
  helpers.doKeys('[', ']');
3243
  helpers.assertCursorAt(16,0);
3244
  helpers.doKeys('2', '[', ']');
3245
  helpers.assertCursorAt(12,0);
3246
  helpers.doKeys('[', ']');
3247
  helpers.assertCursorAt(0,0);
3248
}, { value: squareBracketMotionSandbox});
3249
testVim('[{, ]}', function(cm, vim, helpers) {
3250
  cm.setCursor(4, 10);
3251
  helpers.doKeys('[', '{');
3252
  helpers.assertCursorAt(2,12);
3253
  helpers.doKeys('2', '[', '{');
3254
  helpers.assertCursorAt(0,1);
3255
  cm.setCursor(4, 10);
3256
  helpers.doKeys(']', '}');
3257
  helpers.assertCursorAt(6,11);
3258
  helpers.doKeys('2', ']', '}');
3259
  helpers.assertCursorAt(8,1);
3260
  cm.setCursor(0,1);
3261
  helpers.doKeys(']', '}');
3262
  helpers.assertCursorAt(8,1);
3263
  helpers.doKeys('[', '{');
3264
  helpers.assertCursorAt(0,1);
3265
}, { value: squareBracketMotionSandbox});
3266
testVim('[(, ])', function(cm, vim, helpers) {
3267
  cm.setCursor(4, 10);
3268
  helpers.doKeys('[', '(');
3269
  helpers.assertCursorAt(3,14);
3270
  helpers.doKeys('2', '[', '(');
3271
  helpers.assertCursorAt(0,0);
3272
  cm.setCursor(4, 10);
3273
  helpers.doKeys(']', ')');
3274
  helpers.assertCursorAt(5,11);
3275
  helpers.doKeys('2', ']', ')');
3276
  helpers.assertCursorAt(8,0);
3277
  helpers.doKeys('[', '(');
3278
  helpers.assertCursorAt(0,0);
3279
  helpers.doKeys(']', ')');
3280
  helpers.assertCursorAt(8,0);
3281
}, { value: squareBracketMotionSandbox});
3282
testVim('[*, ]*, [/, ]/', function(cm, vim, helpers) {
3283
  forEach(['*', '/'], function(key){
3284
    cm.setCursor(7, 0);
3285
    helpers.doKeys('2', '[', key);
3286
    helpers.assertCursorAt(2,2);
3287
    helpers.doKeys('2', ']', key);
3288
    helpers.assertCursorAt(7,5);
3289
  });
3290
}, { value: squareBracketMotionSandbox});
3291
testVim('[#, ]#', function(cm, vim, helpers) {
3292
  cm.setCursor(10, 3);
3293
  helpers.doKeys('2', '[', '#');
3294
  helpers.assertCursorAt(4,0);
3295
  helpers.doKeys('5', ']', '#');
3296
  helpers.assertCursorAt(17,0);
3297
  cm.setCursor(10, 3);
3298
  helpers.doKeys(']', '#');
3299
  helpers.assertCursorAt(14,0);
3300
}, { value: squareBracketMotionSandbox});
3301
testVim('[m, ]m, [M, ]M', function(cm, vim, helpers) {
3302
  cm.setCursor(11, 0);
3303
  helpers.doKeys('[', 'm');
3304
  helpers.assertCursorAt(10,7);
3305
  helpers.doKeys('4', '[', 'm');
3306
  helpers.assertCursorAt(1,3);
3307
  helpers.doKeys('5', ']', 'm');
3308
  helpers.assertCursorAt(11,0);
3309
  helpers.doKeys('[', 'M');
3310
  helpers.assertCursorAt(9,1);
3311
  helpers.doKeys('3', ']', 'M');
3312
  helpers.assertCursorAt(15,0);
3313
  helpers.doKeys('5', '[', 'M');
3314
  helpers.assertCursorAt(7,3);
3315
}, { value: squareBracketMotionSandbox});
3316
3317
// Ex mode tests
3318
testVim('ex_go_to_line', function(cm, vim, helpers) {
3319
  cm.setCursor(0, 0);
3320
  helpers.doEx('4');
3321
  helpers.assertCursorAt(3, 0);
3322
}, { value: 'a\nb\nc\nd\ne\n'});
3323
testVim('ex_write', function(cm, vim, helpers) {
3324
  var tmp = CodeMirror.commands.save;
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3325
  var written;
3326
  var actualCm;
3327
  CodeMirror.commands.save = function(cm) {
3328
    written = true;
3329
    actualCm = cm;
3330
  };
3331
  // Test that w, wr, wri ... write all trigger :write.
3332
  var command = 'write';
3333
  for (var i = 1; i < command.length; i++) {
3334
    written = false;
3335
    actualCm = null;
3336
    helpers.doEx(command.substring(0, i));
3337
    eq(written, true);
3338
    eq(actualCm, cm);
3339
  }
3340
  CodeMirror.commands.save = tmp;
3341
});
3342
testVim('ex_sort', function(cm, vim, helpers) {
3343
  helpers.doEx('sort');
3344
  eq('Z\na\nb\nc\nd', cm.getValue());
3345
}, { value: 'b\nZ\nd\nc\na'});
3346
testVim('ex_sort_reverse', function(cm, vim, helpers) {
3347
  helpers.doEx('sort!');
3348
  eq('d\nc\nb\na', cm.getValue());
3349
}, { value: 'b\nd\nc\na'});
3350
testVim('ex_sort_range', function(cm, vim, helpers) {
3351
  helpers.doEx('2,3sort');
3352
  eq('b\nc\nd\na', cm.getValue());
3353
}, { value: 'b\nd\nc\na'});
3354
testVim('ex_sort_oneline', function(cm, vim, helpers) {
3355
  helpers.doEx('2sort');
3356
  // Expect no change.
3357
  eq('b\nd\nc\na', cm.getValue());
3358
}, { value: 'b\nd\nc\na'});
3359
testVim('ex_sort_ignoreCase', function(cm, vim, helpers) {
3360
  helpers.doEx('sort i');
3361
  eq('a\nb\nc\nd\nZ', cm.getValue());
3362
}, { value: 'b\nZ\nd\nc\na'});
3363
testVim('ex_sort_unique', function(cm, vim, helpers) {
3364
  helpers.doEx('sort u');
3365
  eq('Z\na\nb\nc\nd', cm.getValue());
3366
}, { value: 'b\nZ\na\na\nd\na\nc\na'});
3367
testVim('ex_sort_decimal', function(cm, vim, helpers) {
3368
  helpers.doEx('sort d');
3369
  eq('d3\n s5\n6\n.9', cm.getValue());
3370
}, { value: '6\nd3\n s5\n.9'});
3371
testVim('ex_sort_decimal_negative', function(cm, vim, helpers) {
3372
  helpers.doEx('sort d');
3373
  eq('z-9\nd3\n s5\n6\n.9', cm.getValue());
3374
}, { value: '6\nd3\n s5\n.9\nz-9'});
3375
testVim('ex_sort_decimal_reverse', function(cm, vim, helpers) {
3376
  helpers.doEx('sort! d');
3377
  eq('.9\n6\n s5\nd3', cm.getValue());
3378
}, { value: '6\nd3\n s5\n.9'});
3379
testVim('ex_sort_hex', function(cm, vim, helpers) {
3380
  helpers.doEx('sort x');
3381
  eq(' s5\n6\n.9\n&0xB\nd3', cm.getValue());
3382
}, { value: '6\nd3\n s5\n&0xB\n.9'});
3383
testVim('ex_sort_octal', function(cm, vim, helpers) {
3384
  helpers.doEx('sort o');
3385
  eq('.8\n.9\nd3\n s5\n6', cm.getValue());
3386
}, { value: '6\nd3\n s5\n.9\n.8'});
3387
testVim('ex_sort_decimal_mixed', function(cm, vim, helpers) {
3388
  helpers.doEx('sort d');
3389
  eq('y\nz\nc1\nb2\na3', cm.getValue());
3390
}, { value: 'a3\nz\nc1\ny\nb2'});
3391
testVim('ex_sort_decimal_mixed_reverse', function(cm, vim, helpers) {
3392
  helpers.doEx('sort! d');
3393
  eq('a3\nb2\nc1\nz\ny', cm.getValue());
3394
}, { value: 'a3\nz\nc1\ny\nb2'});
3395
testVim('ex_sort_patterns_not_supported', function(cm, vim, helpers) {
3396
  var notified = false;
3397
  cm.openNotification = helpers.fakeOpenNotification(function(text) {
3398
    notified = /patterns not supported/.test(text);
3399
  });
3400
  helpers.doEx('sort /abc/');
3401
  is(notified, 'No notification.');
3402
});
3403
// test for :global command
3404
testVim('ex_global', function(cm, vim, helpers) {
3405
  cm.setCursor(0, 0);
3406
  helpers.doEx('g/one/s//two');
3407
  eq('two two\n two two\n two two', cm.getValue());
3408
  helpers.doEx('1,2g/two/s//one');
3409
  eq('one one\n one one\n two two', cm.getValue());
3410
}, {value: 'one one\n one one\n one one'});
3411
testVim('ex_global_confirm', function(cm, vim, helpers) {
3412
  cm.setCursor(0, 0);
3413
  var onKeyDown;
3414
  var openDialogSave = cm.openDialog;
0 ignored issues
show
Unused Code introduced by
The variable openDialogSave seems to be never used. Consider removing it.
Loading history...
3415
  var KEYCODES = {
3416
    a: 65,
3417
    n: 78,
3418
    q: 81,
3419
    y: 89
3420
  };
3421
  // Intercept the ex command, 'global'
3422
  cm.openDialog = function(template, callback, options) {
3423
    // Intercept the prompt for the embedded ex command, 'substitute'
3424
    cm.openDialog = function(template, callback, options) {
3425
      onKeyDown = options.onKeyDown;
3426
    };
3427
    callback('g/one/s//two/gc');
3428
  };
3429
  helpers.doKeys(':');
3430
  var close = function() {};
3431
  onKeyDown({keyCode: KEYCODES.n}, '', close);
3432
  onKeyDown({keyCode: KEYCODES.y}, '', close);
3433
  onKeyDown({keyCode: KEYCODES.a}, '', close);
3434
  onKeyDown({keyCode: KEYCODES.q}, '', close);
3435
  onKeyDown({keyCode: KEYCODES.y}, '', close);
3436
  eq('one two\n two two\n one one\n two one\n one one', cm.getValue());
3437
}, {value: 'one one\n one one\n one one\n one one\n one one'});
3438
// Basic substitute tests.
3439
testVim('ex_substitute_same_line', function(cm, vim, helpers) {
3440
  cm.setCursor(1, 0);
3441
  helpers.doEx('s/one/two/g');
3442
  eq('one one\n two two', cm.getValue());
3443
}, { value: 'one one\n one one'});
3444
testVim('ex_substitute_full_file', function(cm, vim, helpers) {
3445
  cm.setCursor(1, 0);
3446
  helpers.doEx('%s/one/two/g');
3447
  eq('two two\n two two', cm.getValue());
3448
}, { value: 'one one\n one one'});
3449
testVim('ex_substitute_input_range', function(cm, vim, helpers) {
3450
  cm.setCursor(1, 0);
3451
  helpers.doEx('1,3s/\\d/0/g');
3452
  eq('0\n0\n0\n4', cm.getValue());
3453
}, { value: '1\n2\n3\n4' });
3454
testVim('ex_substitute_visual_range', function(cm, vim, helpers) {
3455
  cm.setCursor(1, 0);
3456
  // Set last visual mode selection marks '< and '> at lines 2 and 4
3457
  helpers.doKeys('V', '2', 'j', 'v');
3458
  helpers.doEx('\'<,\'>s/\\d/0/g');
3459
  eq('1\n0\n0\n0\n5', cm.getValue());
3460
}, { value: '1\n2\n3\n4\n5' });
3461
testVim('ex_substitute_empty_query', function(cm, vim, helpers) {
3462
  // If the query is empty, use last query.
3463
  cm.setCursor(1, 0);
3464
  cm.openDialog = helpers.fakeOpenDialog('1');
3465
  helpers.doKeys('/');
3466
  helpers.doEx('s//b/g');
3467
  eq('abb ab2 ab3', cm.getValue());
3468
}, { value: 'a11 a12 a13' });
3469
testVim('ex_substitute_javascript', function(cm, vim, helpers) {
3470
  CodeMirror.Vim.setOption('pcre', false);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3471
  cm.setCursor(1, 0);
3472
  // Throw all the things that javascript likes to treat as special values
3473
  // into the replace part. All should be literal (this is VIM).
3474
  helpers.doEx('s/\\(\\d+\\)/$$ $\' $` $& \\1/g')
3475
  eq('a $$ $\' $` $& 0 b', cm.getValue());
3476
}, { value: 'a 0 b' });
3477
testVim('ex_substitute_empty_arguments', function(cm,vim,helpers) {
3478
  cm.setCursor(0, 0);
3479
  helpers.doEx('s/a/b/g');
3480
  cm.setCursor(1, 0);
3481
  helpers.doEx('s');
3482
  eq('b b\nb a', cm.getValue());
3483
}, {value: 'a a\na a'});
3484
3485
// More complex substitute tests that test both pcre and nopcre options.
3486
function testSubstitute(name, options) {
3487
  testVim(name + '_pcre', function(cm, vim, helpers) {
3488
    cm.setCursor(1, 0);
3489
    CodeMirror.Vim.setOption('pcre', true);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3490
    helpers.doEx(options.expr);
3491
    eq(options.expectedValue, cm.getValue());
3492
  }, options);
3493
  // If no noPcreExpr is defined, assume that it's the same as the expr.
3494
  var noPcreExpr = options.noPcreExpr ? options.noPcreExpr : options.expr;
3495
  testVim(name + '_nopcre', function(cm, vim, helpers) {
3496
    cm.setCursor(1, 0);
3497
    CodeMirror.Vim.setOption('pcre', false);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3498
    helpers.doEx(noPcreExpr);
3499
    eq(options.expectedValue, cm.getValue());
3500
  }, options);
3501
}
3502
testSubstitute('ex_substitute_capture', {
3503
  value: 'a11 a12 a13',
3504
  expectedValue: 'a1111 a1212 a1313',
3505
  // $n is a backreference
3506
  expr: 's/(\\d+)/$1$1/g',
3507
  // \n is a backreference.
3508
  noPcreExpr: 's/\\(\\d+\\)/\\1\\1/g'});
3509
testSubstitute('ex_substitute_capture2', {
3510
  value: 'a 0 b',
3511
  expectedValue: 'a $00 b',
3512
  expr: 's/(\\d+)/$$$1$1/g',
3513
  noPcreExpr: 's/\\(\\d+\\)/$\\1\\1/g'});
3514
testSubstitute('ex_substitute_nocapture', {
3515
  value: 'a11 a12 a13',
3516
  expectedValue: 'a$1$1 a$1$1 a$1$1',
3517
  expr: 's/(\\d+)/$$1$$1/g',
3518
  noPcreExpr: 's/\\(\\d+\\)/$1$1/g'});
3519
testSubstitute('ex_substitute_nocapture2', {
3520
  value: 'a 0 b',
3521
  expectedValue: 'a $10 b',
3522
  expr: 's/(\\d+)/$$1$1/g',
3523
  noPcreExpr: 's/\\(\\d+\\)/\\$1\\1/g'});
3524
testSubstitute('ex_substitute_nocapture', {
3525
  value: 'a b c',
3526
  expectedValue: 'a $ c',
3527
  expr: 's/b/$$/',
3528
  noPcreExpr: 's/b/$/'});
3529
testSubstitute('ex_substitute_slash_regex', {
3530
  value: 'one/two \n three/four',
3531
  expectedValue: 'one|two \n three|four',
3532
  expr: '%s/\\//|'});
3533
testSubstitute('ex_substitute_pipe_regex', {
3534
  value: 'one|two \n three|four',
3535
  expectedValue: 'one,two \n three,four',
3536
  expr: '%s/\\|/,/',
3537
  noPcreExpr: '%s/|/,/'});
3538
testSubstitute('ex_substitute_or_regex', {
3539
  value: 'one|two \n three|four',
3540
  expectedValue: 'ana|twa \n thraa|faar',
3541
  expr: '%s/o|e|u/a/g',
3542
  noPcreExpr: '%s/o\\|e\\|u/a/g'});
3543
testSubstitute('ex_substitute_or_word_regex', {
3544
  value: 'one|two \n three|four',
3545
  expectedValue: 'five|five \n three|four',
3546
  expr: '%s/(one|two)/five/g',
3547
  noPcreExpr: '%s/\\(one\\|two\\)/five/g'});
3548
testSubstitute('ex_substitute_backslashslash_regex', {
3549
  value: 'one\\two \n three\\four',
3550
  expectedValue: 'one,two \n three,four',
3551
  expr: '%s/\\\\/,'});
3552
testSubstitute('ex_substitute_slash_replacement', {
3553
  value: 'one,two \n three,four',
3554
  expectedValue: 'one/two \n three/four',
3555
  expr: '%s/,/\\/'});
3556
testSubstitute('ex_substitute_backslash_replacement', {
3557
  value: 'one,two \n three,four',
3558
  expectedValue: 'one\\two \n three\\four',
3559
  expr: '%s/,/\\\\/g'});
3560
testSubstitute('ex_substitute_multibackslash_replacement', {
3561
  value: 'one,two \n three,four',
3562
  expectedValue: 'one\\\\\\\\two \n three\\\\\\\\four', // 2*8 backslashes.
3563
  expr: '%s/,/\\\\\\\\\\\\\\\\/g'}); // 16 backslashes.
3564
testSubstitute('ex_substitute_newline_replacement', {
3565
  value: 'one,two \n three,four',
3566
  expectedValue: 'one\ntwo \n three\nfour',
3567
  expr: '%s/,/\\n/g'});
3568
testSubstitute('ex_substitute_braces_word', {
3569
  value: 'ababab abb ab{2}',
3570
  expectedValue: 'ab abb ab{2}',
3571
  expr: '%s/(ab){2}//g',
3572
  noPcreExpr: '%s/\\(ab\\)\\{2\\}//g'});
3573
testSubstitute('ex_substitute_braces_range', {
3574
  value: 'a aa aaa aaaa',
3575
  expectedValue: 'a   a',
3576
  expr: '%s/a{2,3}//g',
3577
  noPcreExpr: '%s/a\\{2,3\\}//g'});
3578
testSubstitute('ex_substitute_braces_literal', {
3579
  value: 'ababab abb ab{2}',
3580
  expectedValue: 'ababab abb ',
3581
  expr: '%s/ab\\{2\\}//g',
3582
  noPcreExpr: '%s/ab{2}//g'});
3583
testSubstitute('ex_substitute_braces_char', {
3584
  value: 'ababab abb ab{2}',
3585
  expectedValue: 'ababab  ab{2}',
3586
  expr: '%s/ab{2}//g',
3587
  noPcreExpr: '%s/ab\\{2\\}//g'});
3588
testSubstitute('ex_substitute_braces_no_escape', {
3589
  value: 'ababab abb ab{2}',
3590
  expectedValue: 'ababab  ab{2}',
3591
  expr: '%s/ab{2}//g',
3592
  noPcreExpr: '%s/ab\\{2}//g'});
3593
testSubstitute('ex_substitute_count', {
3594
  value: '1\n2\n3\n4',
3595
  expectedValue: '1\n0\n0\n4',
3596
  expr: 's/\\d/0/i 2'});
3597
testSubstitute('ex_substitute_count_with_range', {
3598
  value: '1\n2\n3\n4',
3599
  expectedValue: '1\n2\n0\n0',
3600
  expr: '1,3s/\\d/0/ 3'});
3601
testSubstitute('ex_substitute_not_global', {
3602
  value: 'aaa\nbaa\ncaa',
3603
  expectedValue: 'xaa\nbxa\ncxa',
3604
  expr: '%s/a/x/'});
3605
function testSubstituteConfirm(name, command, initialValue, expectedValue, keys, finalPos) {
3606
  testVim(name, function(cm, vim, helpers) {
3607
    var savedOpenDialog = cm.openDialog;
3608
    var savedKeyName = CodeMirror.keyName;
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3609
    var onKeyDown;
3610
    var recordedCallback;
3611
    var closed = true; // Start out closed, set false on second openDialog.
3612
    function close() {
3613
      closed = true;
3614
    }
3615
    // First openDialog should save callback.
3616
    cm.openDialog = function(template, callback, options) {
0 ignored issues
show
Unused Code introduced by
The parameter options is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3617
      recordedCallback = callback;
3618
    }
3619
    // Do first openDialog.
3620
    helpers.doKeys(':');
3621
    // Second openDialog should save keyDown handler.
3622
    cm.openDialog = function(template, callback, options) {
3623
      onKeyDown = options.onKeyDown;
3624
      closed = false;
3625
    };
3626
    // Return the command to Vim and trigger second openDialog.
3627
    recordedCallback(command);
3628
    // The event should really use keyCode, but here just mock it out and use
3629
    // key and replace keyName to just return key.
3630
    CodeMirror.keyName = function (e) { return e.key; }
3631
    keys = keys.toUpperCase();
3632
    for (var i = 0; i < keys.length; i++) {
3633
      is(!closed);
3634
      onKeyDown({ key: keys.charAt(i) }, '', close);
3635
    }
3636
    try {
3637
      eq(expectedValue, cm.getValue());
3638
      helpers.assertCursorAt(finalPos);
3639
      is(closed);
3640
    } catch(e) {
3641
      throw e
3642
    } finally {
3643
      // Restore overriden functions.
3644
      CodeMirror.keyName = savedKeyName;
3645
      cm.openDialog = savedOpenDialog;
3646
    }
3647
  }, { value: initialValue });
3648
};
3649
testSubstituteConfirm('ex_substitute_confirm_emptydoc',
3650
    '%s/x/b/c', '', '', '', makeCursor(0, 0));
3651
testSubstituteConfirm('ex_substitute_confirm_nomatch',
3652
    '%s/x/b/c', 'ba a\nbab', 'ba a\nbab', '', makeCursor(0, 0));
3653
testSubstituteConfirm('ex_substitute_confirm_accept',
3654
    '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'yyy', makeCursor(1, 1));
3655
testSubstituteConfirm('ex_substitute_confirm_random_keys',
3656
    '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ysdkywerty', makeCursor(1, 1));
3657
testSubstituteConfirm('ex_substitute_confirm_some',
3658
    '%s/a/b/cg', 'ba a\nbab', 'bb a\nbbb', 'yny', makeCursor(1, 1));
3659
testSubstituteConfirm('ex_substitute_confirm_all',
3660
    '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'a', makeCursor(1, 1));
3661
testSubstituteConfirm('ex_substitute_confirm_accept_then_all',
3662
    '%s/a/b/cg', 'ba a\nbab', 'bb b\nbbb', 'ya', makeCursor(1, 1));
3663
testSubstituteConfirm('ex_substitute_confirm_quit',
3664
    '%s/a/b/cg', 'ba a\nbab', 'bb a\nbab', 'yq', makeCursor(0, 3));
3665
testSubstituteConfirm('ex_substitute_confirm_last',
3666
    '%s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
3667
testSubstituteConfirm('ex_substitute_confirm_oneline',
3668
    '1s/a/b/cg', 'ba a\nbab', 'bb b\nbab', 'yl', makeCursor(0, 3));
3669
testSubstituteConfirm('ex_substitute_confirm_range_accept',
3670
    '1,2s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyy', makeCursor(1, 0));
3671
testSubstituteConfirm('ex_substitute_confirm_range_some',
3672
    '1,3s/a/b/cg', 'aa\na \na\na', 'ba\nb \nb\na', 'ynyy', makeCursor(2, 0));
3673
testSubstituteConfirm('ex_substitute_confirm_range_all',
3674
    '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \nb\na', 'a', makeCursor(2, 0));
3675
testSubstituteConfirm('ex_substitute_confirm_range_last',
3676
    '1,3s/a/b/cg', 'aa\na \na\na', 'bb\nb \na\na', 'yyl', makeCursor(1, 0));
3677
//:noh should clear highlighting of search-results but allow to resume search through n
3678
testVim('ex_noh_clearSearchHighlight', function(cm, vim, helpers) {
3679
  cm.openDialog = helpers.fakeOpenDialog('match');
3680
  helpers.doKeys('?');
3681
  helpers.doEx('noh');
3682
  eq(vim.searchState_.getOverlay(),null,'match-highlighting wasn\'t cleared');
3683
  helpers.doKeys('n');
3684
  helpers.assertCursorAt(0, 11,'can\'t resume search after clearing highlighting');
3685
}, { value: 'match nope match \n nope Match' });
3686
testVim('set_boolean', function(cm, vim, helpers) {
0 ignored issues
show
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3687
  CodeMirror.Vim.defineOption('testoption', true, 'boolean');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3688
  // Test default value is set.
3689
  is(CodeMirror.Vim.getOption('testoption'));
3690
  try {
3691
    // Test fail to set to non-boolean
3692
    CodeMirror.Vim.setOption('testoption', '5');
3693
    fail();
3694
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3695
  // Test setOption
3696
  CodeMirror.Vim.setOption('testoption', false);
3697
  is(!CodeMirror.Vim.getOption('testoption'));
3698
});
3699
testVim('ex_set_boolean', function(cm, vim, helpers) {
3700
  CodeMirror.Vim.defineOption('testoption', true, 'boolean');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3701
  // Test default value is set.
3702
  is(CodeMirror.Vim.getOption('testoption'));
3703
  try {
3704
    // Test fail to set to non-boolean
3705
    helpers.doEx('set testoption=22');
3706
    fail();
3707
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3708
  // Test setOption
3709
  helpers.doEx('set notestoption');
3710
  is(!CodeMirror.Vim.getOption('testoption'));
3711
});
3712
testVim('set_string', function(cm, vim, helpers) {
0 ignored issues
show
Unused Code introduced by
The parameter cm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3713
  CodeMirror.Vim.defineOption('testoption', 'a', 'string');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3714
  // Test default value is set.
3715
  eq('a', CodeMirror.Vim.getOption('testoption'));
3716
  try {
3717
    // Test fail to set non-string.
3718
    CodeMirror.Vim.setOption('testoption', true);
3719
    fail();
3720
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3721
  try {
3722
    // Test fail to set 'notestoption'
3723
    CodeMirror.Vim.setOption('notestoption', 'b');
3724
    fail();
3725
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3726
  // Test setOption
3727
  CodeMirror.Vim.setOption('testoption', 'c');
3728
  eq('c', CodeMirror.Vim.getOption('testoption'));
3729
});
3730
testVim('ex_set_string', function(cm, vim, helpers) {
3731
  CodeMirror.Vim.defineOption('testopt', 'a', 'string');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3732
  // Test default value is set.
3733
  eq('a', CodeMirror.Vim.getOption('testopt'));
3734
  try {
3735
    // Test fail to set 'notestopt'
3736
    helpers.doEx('set notestopt=b');
3737
    fail();
3738
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3739
  // Test setOption
3740
  helpers.doEx('set testopt=c')
3741
  eq('c', CodeMirror.Vim.getOption('testopt'));
3742
  helpers.doEx('set testopt=c')
3743
  eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global
3744
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local
3745
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global
3746
  eq('c', CodeMirror.Vim.getOption('testopt')); // global
3747
  // Test setOption global
3748
  helpers.doEx('setg testopt=d')
3749
  eq('c', CodeMirror.Vim.getOption('testopt', cm));
3750
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));
3751
  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));
3752
  eq('d', CodeMirror.Vim.getOption('testopt'));
3753
  // Test setOption local
3754
  helpers.doEx('setl testopt=e')
3755
  eq('e', CodeMirror.Vim.getOption('testopt', cm));
3756
  eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));
3757
  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));
3758
  eq('d', CodeMirror.Vim.getOption('testopt'));
3759
});
3760
testVim('ex_set_callback', function(cm, vim, helpers) {
3761
  var global;
3762
3763
  function cb(val, cm, cfg) {
0 ignored issues
show
Unused Code introduced by
The parameter cfg is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3764
    if (val === undefined) {
3765
      // Getter
3766
      if (cm) {
3767
        return cm._local;
3768
      } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3769
        return global;
3770
      }
3771
    } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3772
      // Setter
3773
      if (cm) {
3774
        cm._local = val;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3775
      } else {
3776
        global = val;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3777
      }
3778
    }
3779
  }
3780
3781
  CodeMirror.Vim.defineOption('testopt', 'a', 'string', cb);
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3782
  // Test default value is set.
3783
  eq('a', CodeMirror.Vim.getOption('testopt'));
3784
  try {
3785
    // Test fail to set 'notestopt'
3786
    helpers.doEx('set notestopt=b');
3787
    fail();
3788
  } catch (expected) {};
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3789
  // Test setOption (Identical to the string tests, but via callback instead)
3790
  helpers.doEx('set testopt=c')
3791
  eq('c', CodeMirror.Vim.getOption('testopt', cm)); //local || global
3792
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'})); // local
3793
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'})); // global
3794
  eq('c', CodeMirror.Vim.getOption('testopt')); // global
3795
  // Test setOption global
3796
  helpers.doEx('setg testopt=d')
3797
  eq('c', CodeMirror.Vim.getOption('testopt', cm));
3798
  eq('c', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));
3799
  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));
3800
  eq('d', CodeMirror.Vim.getOption('testopt'));
3801
  // Test setOption local
3802
  helpers.doEx('setl testopt=e')
3803
  eq('e', CodeMirror.Vim.getOption('testopt', cm));
3804
  eq('e', CodeMirror.Vim.getOption('testopt', cm, {scope: 'local'}));
3805
  eq('d', CodeMirror.Vim.getOption('testopt', cm, {scope: 'global'}));
3806
  eq('d', CodeMirror.Vim.getOption('testopt'));
3807
})
3808
testVim('ex_set_filetype', function(cm, vim, helpers) {
3809
  CodeMirror.defineMode('test_mode', function() {
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3810
    return {token: function(stream) {
3811
      stream.match(/^\s+|^\S+/);
3812
    }};
3813
  });
3814
  CodeMirror.defineMode('test_mode_2', function() {
3815
    return {token: function(stream) {
3816
      stream.match(/^\s+|^\S+/);
3817
    }};
3818
  });
3819
  // Test mode is set.
3820
  helpers.doEx('set filetype=test_mode');
3821
  eq('test_mode', cm.getMode().name);
3822
  // Test 'ft' alias also sets mode.
3823
  helpers.doEx('set ft=test_mode_2');
3824
  eq('test_mode_2', cm.getMode().name);
3825
});
3826
testVim('ex_set_filetype_null', function(cm, vim, helpers) {
3827
  CodeMirror.defineMode('test_mode', function() {
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3828
    return {token: function(stream) {
3829
      stream.match(/^\s+|^\S+/);
3830
    }};
3831
  });
3832
  cm.setOption('mode', 'test_mode');
3833
  // Test mode is set to null.
3834
  helpers.doEx('set filetype=');
3835
  eq('null', cm.getMode().name);
3836
});
3837
// TODO: Reset key maps after each test.
3838
testVim('ex_map_key2key', function(cm, vim, helpers) {
3839
  helpers.doEx('map a x');
3840
  helpers.doKeys('a');
3841
  helpers.assertCursorAt(0, 0);
3842
  eq('bc', cm.getValue());
3843
}, { value: 'abc' });
3844
testVim('ex_unmap_key2key', function(cm, vim, helpers) {
3845
  helpers.doEx('unmap a');
3846
  helpers.doKeys('a');
3847
  eq('vim-insert', cm.getOption('keyMap'));
3848
}, { value: 'abc' });
3849
testVim('ex_unmap_key2key_does_not_remove_default', function(cm, vim, helpers) {
3850
  try {
3851
    helpers.doEx('unmap a');
3852
    fail();
3853
  } catch (expected) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
3854
  helpers.doKeys('a');
3855
  eq('vim-insert', cm.getOption('keyMap'));
3856
}, { value: 'abc' });
3857
testVim('ex_map_key2key_to_colon', function(cm, vim, helpers) {
3858
  helpers.doEx('map ; :');
3859
  var dialogOpened = false;
3860
  cm.openDialog = function() {
3861
    dialogOpened = true;
3862
  }
3863
  helpers.doKeys(';');
3864
  eq(dialogOpened, true);
3865
});
3866
testVim('ex_map_ex2key:', function(cm, vim, helpers) {
3867
  helpers.doEx('map :del x');
3868
  helpers.doEx('del');
3869
  helpers.assertCursorAt(0, 0);
3870
  eq('bc', cm.getValue());
3871
}, { value: 'abc' });
3872
testVim('ex_map_ex2ex', function(cm, vim, helpers) {
3873
  helpers.doEx('map :del :w');
3874
  var tmp = CodeMirror.commands.save;
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3875
  var written = false;
3876
  var actualCm;
3877
  CodeMirror.commands.save = function(cm) {
3878
    written = true;
3879
    actualCm = cm;
3880
  };
3881
  helpers.doEx('del');
3882
  CodeMirror.commands.save = tmp;
3883
  eq(written, true);
3884
  eq(actualCm, cm);
3885
});
3886
testVim('ex_map_key2ex', function(cm, vim, helpers) {
3887
  helpers.doEx('map a :w');
3888
  var tmp = CodeMirror.commands.save;
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3889
  var written = false;
3890
  var actualCm;
3891
  CodeMirror.commands.save = function(cm) {
3892
    written = true;
3893
    actualCm = cm;
3894
  };
3895
  helpers.doKeys('a');
3896
  CodeMirror.commands.save = tmp;
3897
  eq(written, true);
3898
  eq(actualCm, cm);
3899
});
3900
testVim('ex_map_key2key_visual_api', function(cm, vim, helpers) {
3901
  CodeMirror.Vim.map('b', ':w', 'visual');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3902
  var tmp = CodeMirror.commands.save;
3903
  var written = false;
3904
  var actualCm;
3905
  CodeMirror.commands.save = function(cm) {
3906
    written = true;
3907
    actualCm = cm;
3908
  };
3909
  // Mapping should not work in normal mode.
3910
  helpers.doKeys('b');
3911
  eq(written, false);
3912
  // Mapping should work in visual mode.
3913
  helpers.doKeys('v', 'b');
3914
  eq(written, true);
3915
  eq(actualCm, cm);
3916
3917
  CodeMirror.commands.save = tmp;
3918
});
3919
testVim('ex_imap', function(cm, vim, helpers) {
3920
  CodeMirror.Vim.map('jk', '<Esc>', 'insert');
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3921
  helpers.doKeys('i');
3922
  is(vim.insertMode);
3923
  helpers.doKeys('j', 'k');
3924
  is(!vim.insertMode);
3925
})
3926
3927
// Testing registration of functions as ex-commands and mapping to <Key>-keys
3928
testVim('ex_api_test', function(cm, vim, helpers) {
3929
  var res=false;
3930
  var val='from';
3931
  CodeMirror.Vim.defineEx('extest','ext',function(cm,params){
0 ignored issues
show
Bug introduced by
The variable CodeMirror seems to be never declared. If this is a global, consider adding a /** global: CodeMirror */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3932
    if(params.args)val=params.args[0];
3933
    else res=true;
3934
  });
3935
  helpers.doEx(':ext to');
3936
  eq(val,'to','Defining ex-command failed');
3937
  CodeMirror.Vim.map('<C-CR><Space>',':ext');
3938
  helpers.doKeys('<C-CR>','<Space>');
3939
  is(res,'Mapping to key failed');
3940
});
3941
// For now, this test needs to be last because it messes up : for future tests.
3942
testVim('ex_map_key2key_from_colon', function(cm, vim, helpers) {
3943
  helpers.doEx('map : x');
3944
  helpers.doKeys(':');
3945
  helpers.assertCursorAt(0, 0);
3946
  eq('bc', cm.getValue());
3947
}, { value: 'abc' });
3948
3949
// Test event handlers
3950
testVim('beforeSelectionChange', function(cm, vim, helpers) {
0 ignored issues
show
Unused Code introduced by
The parameter vim is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter helpers is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
3951
  cm.setCursor(0, 100);
3952
  eqPos(cm.getCursor('head'), cm.getCursor('anchor'));
3953
}, { value: 'abc' });
3954
3955
3956