update vim.js

This commit is contained in:
nightwing 2014-12-13 00:43:30 +04:00
commit 5a03993f65
2 changed files with 264 additions and 136 deletions

View file

@ -167,7 +167,7 @@ define(function(require, exports, module) {
this.removeOverlay(); this.removeOverlay();
}; };
this.virtualSelectionMode = function() { this.virtualSelectionMode = function() {
return this.ace.inVirtualSelectionMode && this.ace.selection.index return this.ace.inVirtualSelectionMode && this.ace.selection.index;
}; };
this.onChange = function(delta) { this.onChange = function(delta) {
var oldDelta = delta.data; var oldDelta = delta.data;
@ -356,7 +356,7 @@ define(function(require, exports, module) {
point.row = start.row; point.row = start.row;
point.column = start.column; point.column = start.column;
if (cmp2 === 0) if (cmp2 === 0)
point.bias = 1 point.bias = 1;
} }
} }
}; };
@ -421,9 +421,6 @@ define(function(require, exports, module) {
throw "not implemented"; throw "not implemented";
} }
}; };
this.openDialog = function() {
debugger
};
this.getSearchCursor = function(query, pos, caseFold) { this.getSearchCursor = function(query, pos, caseFold) {
var caseSensitive = false; var caseSensitive = false;
var isRegexp = false; var isRegexp = false;
@ -566,12 +563,11 @@ define(function(require, exports, module) {
var row = delta.start.row; var row = delta.start.row;
if (row == delta.end.row) highlight.cache[row] = undefined; if (row == delta.end.row) highlight.cache[row] = undefined;
else highlight.cache.splice(row, highlight.cache.length); else highlight.cache.splice(row, highlight.cache.length);
} };
highlight.session.on("changeEditor", highlight.destroy); highlight.session.on("changeEditor", highlight.destroy);
highlight.session.on("change", highlight.updateOnChange); highlight.session.on("change", highlight.updateOnChange);
} }
var re = new RegExp(o.query.source, "gmi"); var re = new RegExp(o.query.source, "gmi");
console.log(re)
this.$searchHighlight = o.highlight = highlight; this.$searchHighlight = o.highlight = highlight;
this.$searchHighlight.setRegexp(re); this.$searchHighlight.setRegexp(re);
this.ace.renderer.updateBackMarkers(); this.ace.renderer.updateBackMarkers();
@ -866,11 +862,11 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: '<Up>', type: 'keyToKey', toKeys: 'k' }, { keys: '<Up>', type: 'keyToKey', toKeys: 'k' },
{ keys: '<Down>', type: 'keyToKey', toKeys: 'j' }, { keys: '<Down>', type: 'keyToKey', toKeys: 'j' },
{ keys: '<Space>', type: 'keyToKey', toKeys: 'l' }, { keys: '<Space>', type: 'keyToKey', toKeys: 'l' },
{ keys: '<BS>', type: 'keyToKey', toKeys: 'h' }, { keys: '<BS>', type: 'keyToKey', toKeys: 'h', context: 'normal'},
{ keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' }, { keys: '<C-Space>', type: 'keyToKey', toKeys: 'W' },
{ keys: '<C-BS>', type: 'keyToKey', toKeys: 'B' }, { keys: '<C-BS>', type: 'keyToKey', toKeys: 'B', context: 'normal' },
{ keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' }, { keys: '<S-Space>', type: 'keyToKey', toKeys: 'w' },
{ keys: '<S-BS>', type: 'keyToKey', toKeys: 'b' }, { keys: '<S-BS>', type: 'keyToKey', toKeys: 'b', context: 'normal' },
{ keys: '<C-n>', type: 'keyToKey', toKeys: 'j' }, { keys: '<C-n>', type: 'keyToKey', toKeys: 'j' },
{ keys: '<C-p>', type: 'keyToKey', toKeys: 'k' }, { keys: '<C-p>', type: 'keyToKey', toKeys: 'k' },
{ keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>' }, { keys: '<C-[>', type: 'keyToKey', toKeys: '<Esc>' },
@ -1018,55 +1014,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
var Pos = CodeMirror.Pos; var Pos = CodeMirror.Pos;
var modifierCodes = [16, 17, 18, 91];
var specialKey = {Enter:'CR',Backspace:'BS',Delete:'Del'};
var mac = /Mac/.test(navigator.platform);
var Vim = function() { return vimApi; } //{ var Vim = function() { return vimApi; } //{
function lookupKey(e) {
var keyCode = e.keyCode;
if (modifierCodes.indexOf(keyCode) != -1) { return; }
var hasModifier = e.ctrlKey || e.metaKey;
var key = CodeMirror.keyNames[keyCode];
key = specialKey[key] || key;
var name = '';
if (e.ctrlKey) { name += 'C-'; }
if (e.altKey) { name += 'A-'; }
if (mac && e.metaKey || (!hasModifier && e.shiftKey) && key.length < 2) {
// Shift key bindings can only specified for special characters.
return;
} else if (e.shiftKey && !/^[A-Za-z]$/.test(key)) {
name += 'S-';
}
if (key.length == 1) { key = key.toLowerCase(); }
name += key;
if (name.length > 1) { name = '<' + name + '>'; }
return name;
}
// Keys with modifiers are handled using keydown due to limitations of
// keypress event.
function handleKeyDown(cm, e) {
var name = lookupKey(e);
if (!name) { return; }
CodeMirror.signal(cm, 'vim-keypress', name);
if (CodeMirror.Vim.handleKey(cm, name, 'user')) {
CodeMirror.e_stop(e);
}
}
// Keys without modifiers are handled using keypress to work best with
// non-standard keyboard layouts.
function handleKeyPress(cm, e) {
var code = e.charCode || e.keyCode;
if (e.ctrlKey || e.metaKey || e.altKey ||
e.shiftKey && code < 32) { return; }
var name = String.fromCharCode(code);
CodeMirror.signal(cm, 'vim-keypress', name);
if (CodeMirror.Vim.handleKey(cm, name, 'user')) {
CodeMirror.e_stop(e);
}
}
function enterVimMode(cm) { function enterVimMode(cm) {
cm.setOption('disableInput', true); cm.setOption('disableInput', true);
cm.setOption('showCursorWhenSelecting', false); cm.setOption('showCursorWhenSelecting', false);
@ -1074,8 +1022,6 @@ dom.importCssString(".normal-mode .ace_cursor{\
cm.on('cursorActivity', onCursorActivity); cm.on('cursorActivity', onCursorActivity);
maybeInitVimState(cm); maybeInitVimState(cm);
CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm)); CodeMirror.on(cm.getInputField(), 'paste', getOnPasteFn(cm));
cm.on('keypress', handleKeyPress);
cm.on('keydown', handleKeyDown);
} }
function leaveVimMode(cm) { function leaveVimMode(cm) {
@ -1083,8 +1029,6 @@ dom.importCssString(".normal-mode .ace_cursor{\
cm.off('cursorActivity', onCursorActivity); cm.off('cursorActivity', onCursorActivity);
CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm));
cm.state.vim = null; cm.state.vim = null;
cm.off('keypress', handleKeyPress);
cm.off('keydown', handleKeyDown);
} }
function detachVimMap(cm, next) { function detachVimMap(cm, next) {
@ -1109,6 +1053,60 @@ dom.importCssString(".normal-mode .ace_cursor{\
else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap"))) else if (!val && prev != CodeMirror.Init && /^vim/.test(cm.getOption("keyMap")))
cm.setOption("keyMap", "default"); cm.setOption("keyMap", "default");
}); });
function cmKey(key, cm) {
if (!cm) { return undefined; }
var vimKey = cmKeyToVimKey(key);
if (!vimKey) {
return false;
}
var cmd = CodeMirror.Vim.findKey(cm, vimKey);
if (typeof cmd == 'function') {
CodeMirror.signal(cm, 'vim-keypress', vimKey);
}
return cmd;
}
var modifiers = {'Shift': 'S', 'Ctrl': 'C', 'Alt': 'A', 'Cmd': 'D', 'Mod': 'A'};
var specialKeys = {Enter:'CR',Backspace:'BS',Delete:'Del'};
function cmKeyToVimKey(key) {
if (key.charAt(0) == '\'') {
// Keypress character binding of format "'a'"
return key.charAt(1);
}
var pieces = key.split('-');
if (/-$/.test(key)) {
// If the - key was typed, split will result in 2 extra empty strings
// in the array. Replace them with 1 '-'.
pieces.splice(-2, 2, '-');
}
var lastPiece = pieces[pieces.length - 1];
if (pieces.length == 1 && pieces[0].length == 1) {
// No-modifier bindings use literal character bindings above. Skip.
return false;
} else if (pieces.length == 2 && pieces[0] == 'Shift' && lastPiece.length == 1) {
// Ignore Shift+char bindings as they should be handled by literal character.
return false;
}
var hasCharacter = false;
for (var i = 0; i < pieces.length; i++) {
var piece = pieces[i];
if (piece in modifiers) { pieces[i] = modifiers[piece]; }
else { hasCharacter = true; }
if (piece in specialKeys) { pieces[i] = specialKeys[piece]; }
}
if (!hasCharacter) {
// Vim does not support modifier only keys.
return false;
}
// TODO: Current bindings expect the character to be lower case, but
// it looks like vim key notation uses upper case.
if (isUpperCase(lastPiece)) {
pieces[pieces.length - 1] = lastPiece.toLowerCase();
}
return '<' + pieces.join('-') + '>';
}
function getOnPasteFn(cm) { function getOnPasteFn(cm) {
var vim = cm.state.vim; var vim = cm.state.vim;
if (!vim.onPasteFn) { if (!vim.onPasteFn) {
@ -1168,15 +1166,10 @@ dom.importCssString(".normal-mode .ace_cursor{\
function defineOption(name, defaultValue, type) { function defineOption(name, defaultValue, type) {
if (defaultValue === undefined) { throw Error('defaultValue is required'); } if (defaultValue === undefined) { throw Error('defaultValue is required'); }
if (!type) { type = 'string'; } if (!type) { type = 'string'; }
var opt = name; options[name] = {
if (typeof name == "string")
opt = {
type: type, type: type,
defaultValue: defaultValue defaultValue: defaultValue
}; };
else
name = opt.name;
options[name] = opt;
setOption(name, defaultValue); setOption(name, defaultValue);
} }
@ -1193,8 +1186,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
value = true; value = true;
} }
} }
option.value = value; option.value = option.type == 'boolean' ? !!value : value;
if (option.set) option.set(value, cm);
} }
function getOption(name) { function getOption(name) {
@ -1428,9 +1420,23 @@ dom.importCssString(".normal-mode .ace_cursor{\
exCommands[name]=func; exCommands[name]=func;
exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'}; exCommandDispatcher.commandMap_[prefix]={name:name, shortName:prefix, type:'api'};
}, },
// This is the outermost function called by CodeMirror, after keys have handleKey: function (cm, key, origin) {
// been mapped to their Vim equivalents. var command = this.findKey(cm, key, origin);
handleKey: function(cm, key, origin) { if (typeof command === 'function') {
return command();
}
},
/**
* This is the outermost function called by CodeMirror, after keys have
* been mapped to their Vim equivalents.
*
* Finds a command based on the key (and cached keys if there is a
* multi-key sequence). Returns `undefined` if no key is matched, a noop
* function if a partial match is found (multi-key), and a function to
* execute the bound command if a a key is matched. The function always
* returns true.
*/
findKey: function(cm, key, origin) {
var vim = maybeInitVimState(cm); var vim = maybeInitVimState(cm);
function handleMacroRecording() { function handleMacroRecording() {
var macroModeState = vimGlobalState.macroModeState; var macroModeState = vimGlobalState.macroModeState;
@ -1496,13 +1502,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input'); cm.replaceRange('', offsetCursor(here, 0, -(keys.length - 1)), here, '+input');
} }
clearInputState(cm); clearInputState(cm);
var command = match.command; return match.command;
if (command.type == 'keyToKey') {
doKeyToKey(command.toKeys);
} else {
commandDispatcher.processCommand(cm, vim, command);
}
return true;
} }
function handleKeyNonInsertMode() { function handleKeyNonInsertMode() {
@ -1520,31 +1520,44 @@ dom.importCssString(".normal-mode .ace_cursor{\
else if (match.type == 'partial') { return true; } else if (match.type == 'partial') { return true; }
vim.inputState.keyBuffer = ''; vim.inputState.keyBuffer = '';
var command = match.command;
var keysMatcher = /^(\d*)(.*)$/.exec(keys); var keysMatcher = /^(\d*)(.*)$/.exec(keys);
if (keysMatcher[1] && keysMatcher[1] != '0') { if (keysMatcher[1] && keysMatcher[1] != '0') {
vim.inputState.pushRepeatDigit(keysMatcher[1]); vim.inputState.pushRepeatDigit(keysMatcher[1]);
} }
return match.command;
}
var command;
if (vim.insertMode) { command = handleKeyInsertMode(); }
else { command = handleKeyNonInsertMode(); }
if (command === false) {
return undefined;
} else if (command === true) {
// TODO: Look into using CodeMirror's multi-key handling.
// Return no-op since we are caching the key. Counts as handled, but
// don't want act on it just yet.
return function() {};
} else {
return function() {
return cm.operation(function() {
cm.curOp.isVimOp = true;
try {
if (command.type == 'keyToKey') { if (command.type == 'keyToKey') {
doKeyToKey(command.toKeys); doKeyToKey(command.toKeys);
} else { } else {
commandDispatcher.processCommand(cm, vim, command); commandDispatcher.processCommand(cm, vim, command);
} }
return true;
}
return cm.operation(function() {
cm.curOp.isVimOp = true;
try {
if (vim.insertMode) { return handleKeyInsertMode(); }
else { return handleKeyNonInsertMode(); }
} catch (e) { } catch (e) {
// clear VIM state in case it's in a bad state. // clear VIM state in case it's in a bad state.
cm.state.vim = undefined; cm.state.vim = undefined;
maybeInitVimState(cm); maybeInitVimState(cm);
console['log'](e);
throw e; throw e;
} }
return true;
}); });
};
}
}, },
handleEx: function(cm, input) { handleEx: function(cm, input) {
exCommandDispatcher.processCommand(cm, input); exCommandDispatcher.processCommand(cm, input);
@ -2105,7 +2118,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
newHead = copyCursor(origHead); newHead = copyCursor(origHead);
} }
if (vim.visualMode) { if (vim.visualMode) {
newHead = clipCursorToContent(cm, newHead, true); newHead = clipCursorToContent(cm, newHead, vim.visualBlock);
if (newAnchor) { if (newAnchor) {
newAnchor = clipCursorToContent(cm, newAnchor, true); newAnchor = clipCursorToContent(cm, newAnchor, true);
} }
@ -2409,20 +2422,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page'); return cm.findPosV(curStart, (motionArgs.forward ? repeat : -repeat), 'page');
}, },
moveByParagraph: function(cm, head, motionArgs) { moveByParagraph: function(cm, head, motionArgs) {
var line = head.line; var dir = motionArgs.forward ? 1 : -1;
var repeat = motionArgs.repeat; return findParagraph(cm, head, motionArgs.repeat, dir);
var inc = motionArgs.forward ? 1 : -1;
for (var i = 0; i < repeat; i++) {
if ((!motionArgs.forward && line === cm.firstLine() ) ||
(motionArgs.forward && line == cm.lastLine())) {
break;
}
line += inc;
while (line !== cm.firstLine() && line != cm.lastLine() && cm.getLine(line)) {
line += inc;
}
}
return Pos(line, 0);
}, },
moveByScroll: function(cm, head, motionArgs, vim) { moveByScroll: function(cm, head, motionArgs, vim) {
var scrollbox = cm.getScrollInfo(); var scrollbox = cm.getScrollInfo();
@ -2522,7 +2523,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
return Pos(lineNum, return Pos(lineNum,
findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum))); findFirstNonWhiteSpaceCharacter(cm.getLine(lineNum)));
}, },
textObjectManipulation: function(cm, head, motionArgs) { textObjectManipulation: function(cm, head, motionArgs, vim) {
// TODO: lots of possible exceptions that can be thrown here. Try da( // TODO: lots of possible exceptions that can be thrown here. Try da(
// outside of a () block. // outside of a () block.
@ -2561,8 +2562,15 @@ dom.importCssString(".normal-mode .ace_cursor{\
tmp = expandWordUnderCursor(cm, inclusive, true /** forward */, tmp = expandWordUnderCursor(cm, inclusive, true /** forward */,
false /** bigWord */); false /** bigWord */);
} else if (character === 'p') { } else if (character === 'p') {
tmp = expandParagraphUnderCursor(cm, inclusive, true /** forward */, tmp = findParagraph(cm, head, motionArgs.repeat, 0, inclusive);
false /** bigWord */); motionArgs.linewise = true;
if (vim.visualMode) {
if (!vim.visualLine) { vim.visualLine = true; }
} else {
var operatorArgs = vim.inputState.operatorArgs;
if (operatorArgs) { operatorArgs.linewise = true; }
tmp.end.line--;
}
} else { } else {
// No text object defined for this, don't move. // No text object defined for this, don't move.
return null; return null;
@ -4070,6 +4078,54 @@ dom.importCssString(".normal-mode .ace_cursor{\
return idx; return idx;
} }
function findParagraph(cm, head, repeat, dir, inclusive) {
var line = head.line;
var min = cm.firstLine();
var max = cm.lastLine();
var start, end, i = line;
function isEmpty(i) { return !cm.getLine(i); }
function isBoundary(i, dir, any) {
if (any) { return isEmpty(i) != isEmpty(i + dir); }
return !isEmpty(i) && isEmpty(i + dir);
}
if (dir) {
while (min <= i && i <= max && repeat > 0) {
if (isBoundary(i, dir)) { repeat--; }
i += dir;
}
return new Pos(i, 0);
}
var vim = cm.state.vim;
if (vim.visualLine && isBoundary(line, 1, true)) {
var anchor = vim.sel.anchor;
if (isBoundary(anchor.line, -1, true)) {
if (!inclusive || anchor.line != line) {
line += 1;
}
}
}
var startState = isEmpty(line);
for (i = line; i <= max && repeat; i++) {
if (isBoundary(i, 1, true)) {
if (!inclusive || isEmpty(i) != startState) {
repeat--;
}
}
}
end = new Pos(i, 0);
// select boundary before paragraph for the last one
if (i > max && !startState) { startState = true; }
else { inclusive = false; }
for (i = line; i > min; i--) {
if (!inclusive || isEmpty(i) == startState || i == line) {
if (isBoundary(i, -1, true)) { break; }
}
}
start = new Pos(i, 0);
return { start: start, end: end };
}
// TODO: perhaps this finagling of start and end positions belonds // TODO: perhaps this finagling of start and end positions belonds
// in codmirror/replaceRange? // in codmirror/replaceRange?
function selectCompanionObject(cm, head, symb, inclusive) { function selectCompanionObject(cm, head, symb, inclusive) {
@ -5276,7 +5332,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
CodeMirror.keyMap.vim = { CodeMirror.keyMap.vim = {
attach: attachVimMap, attach: attachVimMap,
detach: detachVimMap detach: detachVimMap,
call: cmKey
}; };
function exitInsertMode(cm) { function exitInsertMode(cm) {
@ -5349,20 +5406,16 @@ dom.importCssString(".normal-mode .ace_cursor{\
}, },
fallthrough: ['default'], fallthrough: ['default'],
attach: attachVimMap, attach: attachVimMap,
detach: detachVimMap detach: detachVimMap,
}; call: cmKey
CodeMirror.keyMap['await-second'] = {
fallthrough: ['vim-insert'],
attach: attachVimMap,
detach: detachVimMap
}; };
CodeMirror.keyMap['vim-replace'] = { CodeMirror.keyMap['vim-replace'] = {
'Backspace': 'goCharLeft', 'Backspace': 'goCharLeft',
fallthrough: ['vim-insert'], fallthrough: ['vim-insert'],
attach: attachVimMap, attach: attachVimMap,
detach: detachVimMap detach: detachVimMap,
call: cmKey
}; };
function executeMacroRegister(cm, vim, macroModeState, registerName) { function executeMacroRegister(cm, vim, macroModeState, registerName) {
@ -5628,7 +5681,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
Vim = CodeMirror.Vim; Vim = CodeMirror.Vim;
specialKey = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc', var specialKey = {'return':'CR',backspace:'BS','delete':'Del',esc:'Esc',
left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space', left:'Left',right:'Right',up:'Up',down:'Down',space: 'Space',
home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR' home:'Home',end:'End',pageup:'PageUp',pagedown:'PageDown', enter: 'CR'
}; };
@ -5646,7 +5699,7 @@ dom.importCssString(".normal-mode .ace_cursor{\
if (name.length > 1) { name = '<' + name + '>'; } if (name.length > 1) { name = '<' + name + '>'; }
return name; return name;
} }
var handleKey = Vim.handleKey var handleKey = Vim.handleKey.bind(Vim);
Vim.handleKey = function(cm, key, origin) { Vim.handleKey = function(cm, key, origin) {
return cm.operation(function() { return cm.operation(function() {
return handleKey(cm, key, origin); return handleKey(cm, key, origin);
@ -5750,7 +5803,6 @@ dom.importCssString(".normal-mode .ace_cursor{\
}); });
return {command: "null", passEvent: true}; return {command: "null", passEvent: true};
} }
return {command: coreCommands.stop};
} else if (!vim.insertMode) { } else if (!vim.insertMode) {
if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) { if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) {
hashId = -1; hashId = -1;
@ -5925,10 +5977,10 @@ dom.importCssString(".normal-mode .ace_cursor{\
{ keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, { keys: 'zf', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },
{ keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } }, { keys: 'zd', type: 'action', action: 'fold', actionArgs: { open: true, all: true } },
{ keys: '<C-A-j>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } }, { keys: '<C-A-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAbove" } },
{ keys: '<C-A-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } }, { keys: '<C-A-j>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelow" } },
{ keys: '<C-A-S-j>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } }, { keys: '<C-A-S-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorAboveSkipCurrent" } },
{ keys: '<C-A-S-k>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelowSkipCurrent" } }, { keys: '<C-A-S-j>', type: 'action', action: 'aceCommand', actionArgs: { name: "addCursorBelowSkipCurrent" } },
{ keys: '<C-A-h>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreBefore" } }, { keys: '<C-A-h>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreBefore" } },
{ keys: '<C-A-l>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreAfter" } }, { keys: '<C-A-l>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectMoreAfter" } },
{ keys: '<C-A-S-h>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextBefore" } }, { keys: '<C-A-S-h>', type: 'action', action: 'aceCommand', actionArgs: { name: "selectNextBefore" } },
@ -5955,6 +6007,8 @@ dom.importCssString(".normal-mode .ace_cursor{\
}, },
exports.handler.defaultKeymap = defaultKeymap; exports.handler.defaultKeymap = defaultKeymap;
exports.handler.actions = actions;
exports.Vim = Vim;
Vim.map("Y", "yy"); Vim.map("Y", "yy");
}); });

View file

@ -592,6 +592,80 @@ testVim('{', function(cm, vim, helpers) {
helpers.doKeys('6', '{'); helpers.doKeys('6', '{');
helpers.assertCursorAt(0, 0); helpers.assertCursorAt(0, 0);
}, { value: 'a\n\nb\nc\n\nd' }); }, { value: 'a\n\nb\nc\n\nd' });
testVim('paragraph motions', function(cm, vim, helpers) {
cm.setCursor(10, 0);
helpers.doKeys('{');
helpers.assertCursorAt(4, 0);
helpers.doKeys('{');
helpers.assertCursorAt(0, 0);
helpers.doKeys('2', '}');
helpers.assertCursorAt(7, 0);
helpers.doKeys('2', '}');
helpers.assertCursorAt(16, 0);
cm.setCursor(9, 0);
helpers.doKeys('}');
helpers.assertCursorAt(14, 0);
cm.setCursor(6, 0);
helpers.doKeys('}');
helpers.assertCursorAt(7, 0);
// ip inside empty space
cm.setCursor(10, 0);
helpers.doKeys('v', 'i', 'p');
eqPos(Pos(7, 0), cm.getCursor('anchor'));
eqPos(Pos(12, 0), cm.getCursor('head'));
helpers.doKeys('i', 'p');
eqPos(Pos(7, 0), cm.getCursor('anchor'));
eqPos(Pos(13, 1), cm.getCursor('head'));
helpers.doKeys('2', 'i', 'p');
eqPos(Pos(7, 0), cm.getCursor('anchor'));
eqPos(Pos(16, 1), cm.getCursor('head'));
// should switch to visualLine mode
cm.setCursor(14, 0);
helpers.doKeys('<Esc>', 'v', 'i', 'p');
helpers.assertCursorAt(14, 0);
cm.setCursor(14, 0);
helpers.doKeys('<Esc>', 'V', 'i', 'p');
eqPos(Pos(16, 1), cm.getCursor('head'));
// ap inside empty space
cm.setCursor(10, 0);
helpers.doKeys('<Esc>', 'v', 'a', 'p');
eqPos(Pos(7, 0), cm.getCursor('anchor'));
eqPos(Pos(13, 1), cm.getCursor('head'));
helpers.doKeys('a', 'p');
eqPos(Pos(7, 0), cm.getCursor('anchor'));
eqPos(Pos(16, 1), cm.getCursor('head'));
cm.setCursor(13, 0);
helpers.doKeys('v', 'a', 'p');
eqPos(Pos(13, 0), cm.getCursor('anchor'));
eqPos(Pos(14, 0), cm.getCursor('head'));
cm.setCursor(16, 0);
helpers.doKeys('v', 'a', 'p');
eqPos(Pos(14, 0), cm.getCursor('anchor'));
eqPos(Pos(16, 1), cm.getCursor('head'));
cm.setCursor(0, 0);
helpers.doKeys('v', 'a', 'p');
eqPos(Pos(0, 0), cm.getCursor('anchor'));
eqPos(Pos(4, 0), cm.getCursor('head'));
cm.setCursor(0, 0);
helpers.doKeys('d', 'i', 'p');
var register = helpers.getRegisterController().getRegister();
eq('a\na\n', register.toString());
is(register.linewise);
helpers.doKeys('3', 'j', 'p');
helpers.doKeys('y', 'i', 'p');
is(register.linewise);
eq('b\na\na\nc\n', register.toString());
}, { value: 'a\na\n\n\n\nb\nc\n\n\n\n\n\n\nd\n\ne\nf' });
// Operator tests // Operator tests
testVim('dl', function(cm, vim, helpers) { testVim('dl', function(cm, vim, helpers) {