Skip to content

Instantly share code, notes, and snippets.

@StanAngeloff
Created September 16, 2010 10:14
Show Gist options
  • Select an option

  • Save StanAngeloff/582204 to your computer and use it in GitHub Desktop.

Select an option

Save StanAngeloff/582204 to your computer and use it in GitHub Desktop.
Vi-mode patches
--- viKeyBinder.js.original 2010-09-16 13:14:16.198295100 +0300
+++ viKeyBinder.js 2010-09-16 13:12:20.045651500 +0300
@@ -744,6 +744,44 @@
'cmd_delete': 'cmd_vim_cutChar'
};
+// List of commands that the '.' can repeat. If a command is not mentioned in
+// here, executing it while in Insert mode resets the buffer
+var repeatableCommands = [
+ 'cmd_back', 'cmd_backSmart', 'cmd_beginningOfWord',
+ 'cmd_beginningOfWordExtend', 'cmd_braceMatch', 'cmd_callPart',
+ 'cmd_comment', 'cmd_completeWord', 'cmd_completeWordBack',
+ 'cmd_convertLowerCase', 'cmd_convertUpperCase', 'cmd_copy',
+ 'cmd_copyLine', 'cmd_copyRegion', 'cmd_cut', 'cmd_cutRegion',
+ 'cmd_dedent', 'cmd_delete', 'cmd_deleteBlankLines', 'cmd_deleteWordLeft',
+ 'cmd_deleteWordRight', 'cmd_documentEnd', 'cmd_documentHome',
+ 'cmd_editCenterVertically', 'cmd_editMoveCurrentLineToTop',
+ 'cmd_editReflow', 'cmd_editSelectAll', 'cmd_end', 'cmd_endOfWord',
+ 'cmd_endOfWordExtend', 'cmd_expandAbbrev', 'cmd_gotoLine',
+ 'cmd_historyBack', 'cmd_historyForward', 'cmd_home', 'cmd_homeAbsolute',
+ 'cmd_indent', 'cmd_join', 'cmd_jumpToMatchingBrace', 'cmd_killLine',
+ 'cmd_left', 'cmd_lineCut', 'cmd_lineDelete', 'cmd_lineDuplicate',
+ 'cmd_lineNext', 'cmd_lineOrSelectionDuplicate', 'cmd_linePrevious',
+ 'cmd_lineScrollDown', 'cmd_lineScrollUp', 'cmd_lineTranspose',
+ 'cmd_newline', 'cmd_newlineBare', 'cmd_newlineExtra',
+ 'cmd_newlinePrevious', 'cmd_newlineSame', 'cmd_openLine', 'cmd_pageDown',
+ 'cmd_pageUp', 'cmd_paraDown', 'cmd_paraUp', 'cmd_paste',
+ 'cmd_pasteAndSelect', 'cmd_prefix', 'cmd_redo', 'cmd_right',
+ 'cmd_selectAll', 'cmd_selectCharNext', 'cmd_selectCharPrevious',
+ 'cmd_selectDocumentEnd', 'cmd_selectDocumentHome', 'cmd_selectEnd',
+ 'cmd_selectHome', 'cmd_selectHomeAbsolute', 'cmd_selectLineNext',
+ 'cmd_selectLinePrevious', 'cmd_selectPageDown', 'cmd_selectPageUp',
+ 'cmd_selectRectCharNext', 'cmd_selectRectCharPrevious',
+ 'cmd_selectRectEnd', 'cmd_selectRectHome', 'cmd_selectRectLineNext',
+ 'cmd_selectRectLinePrevious', 'cmd_selectRectPageDown',
+ 'cmd_selectRectPageUp', 'cmd_selectToMatchingBrace', 'cmd_selectWordLeft',
+ 'cmd_selectWordRight', 'cmd_selectWordUnderCursor', 'cmd_splitLine',
+ 'cmd_tabstopClear', 'cmd_transpose', 'cmd_transposeWords',
+ 'cmd_triggerPrecedingCompletion', 'cmd_uncomment', 'cmd_undo',
+ 'cmd_wordLeft', 'cmd_wordLeftEnd', 'cmd_wordPartLeft',
+ 'cmd_wordPartLeftExtend', 'cmd_wordPartRight', 'cmd_wordPartRightExtend',
+ 'cmd_wordRight'
+];
+
// Vi handles command
VimController.prototype.handleCommand = function(event, commandname, keylabel, multikey) {
try {
@@ -775,10 +813,10 @@
}
} else if (this.mode == VimController.MODE_INSERT ||
this.mode == VimController.MODE_OVERTYPE) {
- if (commandname == 'cmd_backSmart') {
- // Remove the last character from recorded chars
- //dump("Removing last inserted key\n");
- this._lastInsertedKeycodes.pop();
+ if (repeatableCommands.indexOf(commandname) >= 0) {
+ // Record command for later execution, everything wrapped
+ // within < and > is treated as the command name
+ this._lastInsertedKeycodes.push('<' + commandname + '>');
} else if (commandname != 'cmd_cancel') {
// Any other characters (left, right, etc...) reset the buffer
//dump("Resetting keycodes back to empty\n");
@@ -895,7 +933,7 @@
if (charCode != 0) {
this._lastInsertedKeycodes.push(key_char);
} else if (keyCode == event.DOM_VK_TAB) {
- this._lastInsertedKeycodes.push("\t");
+ this._lastInsertedKeycodes.push('<cmd_indent>');
}
}
return false;
@@ -2818,32 +2856,8 @@
numRepeats = gVimController.repeatCount;
}
- // The idea here is convert the keys to one block of text and to
- // insert that text into scintilla directly. Special characters
- // like newline and tab will need to be handle through a command,
- // in order to repeat the same way.
- var textLines = [];
- var specialChars = [];
+ // Cache as vim_doCommand below resets the buffer when entering Insert mode
var keys = gVimController._lastInsertedKeycodes;
- if (keys) {
- var textPos = 0;
- var textArray;
- var text;
- var i;
- for (i=0; i < keys.length; i++) {
- if (keys[i] == "\n" || keys[i] == "\t") {
- textArray = keys.slice(textPos, i);
- text = textArray.join("");
- textLines.push(text);
- textPos = i + 1;
- // Remember the character type, we'll need it later
- specialChars.push(keys[i]);
- }
- }
- textArray = keys.slice(textPos, i);
- text = textArray.join("");
- textLines.push(text);
- }
// Make a copy of these, as they will get modified as we run
// commands, then restore them once were done. Bug 58627
@@ -2862,14 +2876,13 @@
gVimController.operationFlags = lastOperationFlags;
vim_doCommand(lastModifyCommand);
// Re-add the text if there is some
- for (j=0; j < textLines.length; j++) {
- scimoz.addText(ko.stringutils.bytelength(textLines[j]), textLines[j]);
- if (j < (textLines.length - 1)) {
- // Don't do this for the last block of text
- if (specialChars[i] == '\n') {
- ko.commands.doCommand('cmd_newline');
- } else if (specialChars[i] == '\t') {
- ko.commands.doCommand('cmd_indent');
+ if (keys) {
+ var commandname, isCommand = /^<(\w+)>$/;
+ for (j=0; j < keys.length; j++) {
+ if ((commandname = keys[j].match(isCommand))) {
+ ko.commands.doCommand(commandname[1]);
+ } else {
+ scimoz.replaceSel(keys[j]);
}
}
}
--- viKeyBinder.js.original 2010-09-16 13:48:38.619258800 +0300
+++ viKeyBinder.js 2010-09-16 13:45:26.682280600 +0300
@@ -2458,10 +2458,10 @@
VimController.WORKS_IN_VISUAL_MODE |
VimController.SPECIAL_REPEAT_HANDLING |
VimController.CANCELS_VISUAL_MODE ],
- "cmd_vim_indent_visual" : [ "cmd_indent", VimController.REPEATABLE_ACTION | VimController.MODIFY_ACTION |
+ "cmd_vim_indent_visual" : [ "cmd_vim_indent", VimController.REPEATABLE_ACTION | VimController.MODIFY_ACTION |
VimController.WORKS_IN_VISUAL_MODE |
VimController.CANCELS_VISUAL_MODE ],
- "cmd_vim_dedent_visual" : [ "cmd_dedent", VimController.REPEATABLE_ACTION | VimController.MODIFY_ACTION |
+ "cmd_vim_dedent_visual" : [ "cmd_vim_dedent", VimController.REPEATABLE_ACTION | VimController.MODIFY_ACTION |
VimController.WORKS_IN_VISUAL_MODE |
VimController.CANCELS_VISUAL_MODE ],
"cmd_vim_enterSearchForward" : [ VimController.SPECIAL_COMMAND,VimController.NO_REPEAT_ACTION |
@@ -3508,9 +3508,15 @@
}
function cmd_vim_dedent(scimoz, repeatCount) {
- var lineNo = scimoz.lineFromPosition(gVimController._currentPos);
- var endLineNo = Math.min(scimoz.lineCount, lineNo + repeatCount - 1);
+ var lineNo = scimoz.lineFromPosition(Math.min(gVimController._anchor, gVimController._currentPos));
+ var endLineNo;
var anchor = scimoz.positionFromLine(lineNo);
+ if (gVimController._anchor == gVimController._currentPos) {
+ endLineNo = Math.min(scimoz.lineCount, lineNo + repeatCount - 1);
+ } else {
+ endLineNo = scimoz.lineFromPosition(Math.max(gVimController._anchor, gVimController._currentPos));
+ gVimController._lastRepeatCount = endLineNo - lineNo + 1;
+ }
scimoz.setSel(anchor,
scimoz.getLineEndPosition(endLineNo));
ko.commands.doCommand('cmd_dedent');
@@ -3520,9 +3526,15 @@
}
function cmd_vim_indent(scimoz, repeatCount) {
- var lineNo = scimoz.lineFromPosition(gVimController._currentPos);
- var endLineNo = Math.min(scimoz.lineCount, lineNo + repeatCount - 1);
+ var lineNo = scimoz.lineFromPosition(Math.min(gVimController._anchor, gVimController._currentPos));
+ var endLineNo;
var anchor = scimoz.positionFromLine(lineNo);
+ if (gVimController._anchor == gVimController._currentPos) {
+ endLineNo = Math.min(scimoz.lineCount, lineNo + repeatCount - 1);
+ } else {
+ endLineNo = scimoz.lineFromPosition(Math.max(gVimController._anchor, gVimController._currentPos));
+ gVimController._lastRepeatCount = endLineNo - lineNo + 1;
+ }
scimoz.setSel(anchor,
scimoz.getLineEndPosition(endLineNo));
ko.commands.doCommand('cmd_indent');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment