(cm)
| 14047 | }; |
| 14048 | |
| 14049 | function exitInsertMode(cm) { |
| 14050 | var vim = cm.state.vim; |
| 14051 | var macroModeState = vimGlobalState.macroModeState; |
| 14052 | var insertModeChangeRegister = vimGlobalState.registerController.getRegister('.'); |
| 14053 | var isPlaying = macroModeState.isPlaying; |
| 14054 | var lastChange = macroModeState.lastInsertModeChanges; |
| 14055 | // In case of visual block, the insertModeChanges are not saved as a |
| 14056 | // single word, so we convert them to a single word |
| 14057 | // so as to update the ". register as expected in real vim. |
| 14058 | var text = []; |
| 14059 | if (!isPlaying) { |
| 14060 | var selLength = lastChange.inVisualBlock ? vim.lastSelection.visualBlock.height : 1; |
| 14061 | var changes = lastChange.changes; |
| 14062 | var text = []; |
| 14063 | var i = 0; |
| 14064 | // In case of multiple selections in blockwise visual, |
| 14065 | // the inserted text, for example: 'f<Backspace>oo', is stored as |
| 14066 | // 'f', 'f', InsertModeKey 'o', 'o', 'o', 'o'. (if you have a block with 2 lines). |
| 14067 | // We push the contents of the changes array as per the following: |
| 14068 | // 1. In case of InsertModeKey, just increment by 1. |
| 14069 | // 2. In case of a character, jump by selLength (2 in the example). |
| 14070 | while (i < changes.length) { |
| 14071 | // This loop will convert 'ff<bs>oooo' to 'f<bs>oo'. |
| 14072 | text.push(changes[i]); |
| 14073 | if (changes[i] instanceof InsertModeKey) { |
| 14074 | i++; |
| 14075 | } else { |
| 14076 | i+= selLength; |
| 14077 | } |
| 14078 | } |
| 14079 | lastChange.changes = text; |
| 14080 | cm.off('change', onChange); |
| 14081 | CodeMirror.off(cm.getInputField(), 'keydown', onKeyEventTargetKeyDown); |
| 14082 | } |
| 14083 | if (!isPlaying && vim.insertModeRepeat > 1) { |
| 14084 | // Perform insert mode repeat for commands like 3,a and 3,o. |
| 14085 | repeatLastEdit(cm, vim, vim.insertModeRepeat - 1, |
| 14086 | true /** repeatForInsert */); |
| 14087 | vim.lastEditInputState.repeatOverride = vim.insertModeRepeat; |
| 14088 | } |
| 14089 | delete vim.insertModeRepeat; |
| 14090 | vim.insertMode = false; |
| 14091 | cm.setCursor(cm.getCursor().line, cm.getCursor().ch-1); |
| 14092 | cm.setOption('keyMap', 'vim'); |
| 14093 | cm.setOption('disableInput', true); |
| 14094 | cm.toggleOverwrite(false); // exit replace mode if we were in it. |
| 14095 | // update the ". register before exiting insert mode |
| 14096 | insertModeChangeRegister.setText(lastChange.changes.join('')); |
| 14097 | CodeMirror.signal(cm, "vim-mode-change", {mode: "normal"}); |
| 14098 | if (macroModeState.isRecording) { |
| 14099 | logInsertModeChange(macroModeState); |
| 14100 | } |
| 14101 | } |
| 14102 | |
| 14103 | function _mapCommand(command) { |
| 14104 | defaultKeymap.unshift(command); |
no test coverage detected