manual merge of ace++ branch
This commit is contained in:
parent
0c7b310ecc
commit
a2a3043907
11 changed files with 599 additions and 326 deletions
|
|
@ -116,7 +116,7 @@ var KeyBinding = function(editor) {
|
||||||
if (toExecute.command != "null")
|
if (toExecute.command != "null")
|
||||||
success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
|
success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
|
||||||
else
|
else
|
||||||
success = true;
|
success = toExecute.stopEvent == true;
|
||||||
|
|
||||||
if (success && e)
|
if (success && e)
|
||||||
event.stopEvent(e);
|
event.stopEvent(e);
|
||||||
|
|
@ -130,9 +130,7 @@ var KeyBinding = function(editor) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onTextInput = function(text) {
|
this.onTextInput = function(text) {
|
||||||
var success = false;
|
var success = this.$callKeyboardHandlers(-1, text);
|
||||||
if (text.length == 1)
|
|
||||||
success = this.$callKeyboardHandlers(0, text);
|
|
||||||
if (!success)
|
if (!success)
|
||||||
this.$editor.commands.exec("insertstring", this.$editor, text);
|
this.$editor.commands.exec("insertstring", this.$editor, text);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,8 @@ StateHandler.prototype = {
|
||||||
* This function is called by keyBinding.
|
* This function is called by keyBinding.
|
||||||
*/
|
*/
|
||||||
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
||||||
|
if (hashId == -1)
|
||||||
|
hashId = 0
|
||||||
// If we pressed any command key but no other key, then ignore the input.
|
// If we pressed any command key but no other key, then ignore the input.
|
||||||
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
||||||
// which results in "shift-shift-g" which doesn't make sense.
|
// which results in "shift-shift-g" which doesn't make sense.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
|
||||||
|
|
||||||
"never use strict";
|
"never use strict";
|
||||||
|
|
||||||
|
|
@ -9,7 +8,7 @@ var util = require("./vim/maps/util");
|
||||||
exports.handler = require("./vim/keyboard").handler;
|
exports.handler = require("./vim/keyboard").handler;
|
||||||
|
|
||||||
exports.onCursorMove = function(e) {
|
exports.onCursorMove = function(e) {
|
||||||
commands.onCursorMove(e.editor);
|
commands.onCursorMove(e.editor, e);
|
||||||
exports.onCursorMove.scheduled = false;
|
exports.onCursorMove.scheduled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -21,7 +20,7 @@ exports.handler.attach = function(editor) {
|
||||||
|
|
||||||
exports.handler.detach = function(editor) {
|
exports.handler.detach = function(editor) {
|
||||||
editor.removeListener("click", exports.onCursorMove);
|
editor.removeListener("click", exports.onCursorMove);
|
||||||
commands.coreCommands.start.exec(editor);
|
util.noMode(editor);
|
||||||
util.currentMode = "normal";
|
util.currentMode = "normal";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ exports.searchStore = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var repeat = function repeat(fn, count, args) {
|
var repeat = function repeat(fn, count, args) {
|
||||||
count = parseInt(count, 10);
|
|
||||||
while (0 < count--)
|
while (0 < count--)
|
||||||
fn.apply(this, args);
|
fn.apply(this, args);
|
||||||
};
|
};
|
||||||
|
|
@ -48,19 +47,22 @@ var toggleCase = function toggleCase(ch) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var ensureScrollMargin = function(editor) {
|
var ensureScrollMargin = function(editor) {
|
||||||
setTimeout(function() {
|
var renderer = editor.renderer
|
||||||
var curPos = editor.getCursorPosition().row;
|
var pos = renderer.$cursorLayer.getPixelPosition();
|
||||||
var topRow = editor.renderer.layerConfig.firstRow;
|
|
||||||
var linesToBottom = editor.renderer.layerConfig.lastRow - curPos;
|
|
||||||
var linesToTop = curPos - topRow;
|
|
||||||
|
|
||||||
if (linesToBottom >= 0 && linesToBottom < HMARGIN) {
|
var top = pos.top;
|
||||||
editor.scrollToRow(topRow + (HMARGIN - linesToBottom));
|
|
||||||
}
|
var margin = HMARGIN * renderer.layerConfig.lineHeight;
|
||||||
else if (linesToTop >= 0 && linesToTop < HMARGIN) {
|
if (2 * margin > renderer.$size.scrollerHeight)
|
||||||
editor.scrollToRow(topRow - (HMARGIN - linesToTop));
|
margin = renderer.$size.scrollerHeight / 2
|
||||||
}
|
|
||||||
}, 20); // Delay introduced to ensure scroll after async find operation.
|
if (renderer.scrollTop > top - margin) {
|
||||||
|
renderer.session.setScrollTop(top - margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renderer.scrollTop + renderer.$size.scrollerHeight < top + margin + renderer.lineHeight) {
|
||||||
|
renderer.session.setScrollTop(top + margin + renderer.lineHeight - renderer.$size.scrollerHeight);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var actions = {
|
var actions = {
|
||||||
|
|
@ -69,10 +71,13 @@ var actions = {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "z":
|
case "z":
|
||||||
editor.centerSelection();
|
editor.alignCursor(null, 0.5);
|
||||||
break;
|
break;
|
||||||
case "t":
|
case "t":
|
||||||
editor.scrollToRow(editor.getCursorPosition().row);
|
editor.alignCursor(null, 0);
|
||||||
|
break;
|
||||||
|
case "b":
|
||||||
|
editor.alignCursor(null, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,21 +85,30 @@ var actions = {
|
||||||
"r": {
|
"r": {
|
||||||
param: true,
|
param: true,
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
param = util.toRealChar(param);
|
|
||||||
if (param && param.length) {
|
if (param && param.length) {
|
||||||
repeat(function() { editor.insert(param); }, count || 1);
|
repeat(function() { editor.insert(param); }, count || 1);
|
||||||
editor.navigateLeft();
|
editor.navigateLeft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// "~" HACK
|
"R": {
|
||||||
"shift-`": {
|
fn: function(editor, range, count, param) {
|
||||||
|
util.insertMode(editor);
|
||||||
|
editor.setOverwrite(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"~": {
|
||||||
fn: function(editor, range, count) {
|
fn: function(editor, range, count) {
|
||||||
repeat(function() {
|
repeat(function() {
|
||||||
var pos = editor.getCursorPosition();
|
var range = editor.selection.getRange();
|
||||||
var line = editor.session.getLine(pos.row);
|
if (range.isEmpty())
|
||||||
var ch = line[pos.column];
|
range.end.column++
|
||||||
editor.insert(toggleCase(ch));
|
var text = editor.session.getTextRange(range)
|
||||||
|
var toggled = text.toUpperCase()
|
||||||
|
if (toggled == text)
|
||||||
|
editor.navigateRight()
|
||||||
|
else
|
||||||
|
editor.session.replace(range, toggled);
|
||||||
}, count || 1);
|
}, count || 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -103,9 +117,8 @@ var actions = {
|
||||||
editor.selection.selectWord();
|
editor.selection.selectWord();
|
||||||
editor.findNext();
|
editor.findNext();
|
||||||
ensureScrollMargin(editor);
|
ensureScrollMargin(editor);
|
||||||
var cursor = editor.selection.getCursor();
|
var r = editor.selection.getRange();
|
||||||
range = editor.session.getWordRange(cursor.row, cursor.column);
|
editor.selection.setSelectionRange(r, true);
|
||||||
editor.selection.setSelectionRange(range, true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"#": {
|
"#": {
|
||||||
|
|
@ -113,9 +126,8 @@ var actions = {
|
||||||
editor.selection.selectWord();
|
editor.selection.selectWord();
|
||||||
editor.findPrevious();
|
editor.findPrevious();
|
||||||
ensureScrollMargin(editor);
|
ensureScrollMargin(editor);
|
||||||
var cursor = editor.selection.getCursor();
|
var r = editor.selection.getRange();
|
||||||
range = editor.session.getWordRange(cursor.row, cursor.column);
|
editor.selection.setSelectionRange(r, true);
|
||||||
editor.selection.setSelectionRange(range, true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"n": {
|
"n": {
|
||||||
|
|
@ -123,35 +135,39 @@ var actions = {
|
||||||
var options = editor.getLastSearchOptions();
|
var options = editor.getLastSearchOptions();
|
||||||
options.backwards = false;
|
options.backwards = false;
|
||||||
|
|
||||||
|
editor.selection.moveCursorRight();
|
||||||
|
editor.selection.clearSelection();
|
||||||
editor.findNext(options);
|
editor.findNext(options);
|
||||||
|
|
||||||
ensureScrollMargin(editor);
|
ensureScrollMargin(editor);
|
||||||
editor.selection.clearSelection();
|
var r = editor.selection.getRange();
|
||||||
|
r.end.row = r.start.row;
|
||||||
|
r.end.column = r.start.column
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-n": {
|
"N": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
var options = editor.getLastSearchOptions();
|
var options = editor.getLastSearchOptions();
|
||||||
options.backwards = true;
|
options.backwards = true;
|
||||||
|
|
||||||
editor.navigateWordLeft();
|
|
||||||
editor.findPrevious(options);
|
editor.findPrevious(options);
|
||||||
ensureScrollMargin(editor);
|
ensureScrollMargin(editor);
|
||||||
editor.selection.clearSelection();
|
var r = editor.selection.getRange();
|
||||||
|
r.end.row = r.start.row;
|
||||||
|
r.end.column = r.start.column
|
||||||
|
editor.selection.setSelectionRange(r, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"v": {
|
"v": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
editor.selection.selectRight();
|
editor.selection.selectRight();
|
||||||
util.onVisualMode = true;
|
util.visualMode(editor, false);
|
||||||
util.onVisualLineMode = false;
|
},
|
||||||
var cursor = document.getElementsByClassName("ace_cursor")[0];
|
acceptsMotion: true
|
||||||
cursor.style.display = "none";
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"shift-v": {
|
"V": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
util.onVisualLineMode = true;
|
|
||||||
//editor.selection.selectLine();
|
//editor.selection.selectLine();
|
||||||
//editor.selection.selectLeft();
|
//editor.selection.selectLeft();
|
||||||
var row = editor.getCursorPosition().row;
|
var row = editor.getCursorPosition().row;
|
||||||
|
|
@ -159,9 +175,12 @@ var actions = {
|
||||||
editor.selection.moveCursorTo(row, 0);
|
editor.selection.moveCursorTo(row, 0);
|
||||||
editor.selection.selectLineEnd();
|
editor.selection.selectLineEnd();
|
||||||
editor.selection.visualLineStart = row;
|
editor.selection.visualLineStart = row;
|
||||||
}
|
|
||||||
|
util.visualMode(editor, true);
|
||||||
|
},
|
||||||
|
acceptsMotion: true
|
||||||
},
|
},
|
||||||
"shift-y": {
|
"Y": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
util.copyLine(editor);
|
util.copyLine(editor);
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +205,7 @@ var actions = {
|
||||||
editor.selection.clearSelection();
|
editor.selection.clearSelection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-p": {
|
"P": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
var defaultReg = registers._default;
|
var defaultReg = registers._default;
|
||||||
editor.setOverwrite(false);
|
editor.setOverwrite(false);
|
||||||
|
|
@ -204,26 +223,26 @@ var actions = {
|
||||||
editor.selection.clearSelection();
|
editor.selection.clearSelection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-j": {
|
"J": {
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
var pos = editor.getCursorPosition();
|
var session = editor.session
|
||||||
|
range = editor.getSelectionRange();
|
||||||
|
var pos = {row: range.start.row, column: range.start.column};
|
||||||
|
count = count || range.end.row - range.start.row;
|
||||||
|
var maxRow = Math.min(pos.row + (count || 1), session.getLength() - 1);
|
||||||
|
|
||||||
if (editor.session.getLength() === pos.row + 1)
|
range.start.column = session.getLine(pos.row).length;
|
||||||
return;
|
range.end.column = session.getLine(maxRow).length;
|
||||||
|
range.end.row = maxRow;
|
||||||
|
|
||||||
var nextLine = editor.session.getLine(pos.row + 1);
|
var text = ""
|
||||||
var cleanLine = /^\s*(.*)$/.exec(nextLine)[1];
|
for (var i = pos.row; i < maxRow; i++) {
|
||||||
|
var nextLine = session.getLine(i + 1);
|
||||||
|
text += " " + /^\s*(.*)$/.exec(nextLine)[1] || "";
|
||||||
|
}
|
||||||
|
|
||||||
editor.navigateDown();
|
session.replace(range, text);
|
||||||
editor.removeLines();
|
|
||||||
|
|
||||||
if (editor.session.getLength() > editor.getCursorPosition().row + 1)
|
|
||||||
editor.navigateUp();
|
|
||||||
|
|
||||||
editor.navigateLineEnd();
|
|
||||||
editor.insert(" " + (cleanLine || ""));
|
|
||||||
editor.moveCursorTo(pos.row, pos.column);
|
editor.moveCursorTo(pos.row, pos.column);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"u": {
|
"u": {
|
||||||
|
|
@ -281,11 +300,6 @@ var inputBuffer = exports.inputBuffer = {
|
||||||
lastInsertCommands: [],
|
lastInsertCommands: [],
|
||||||
|
|
||||||
push: function(editor, char, keyId) {
|
push: function(editor, char, keyId) {
|
||||||
if (char && char.length > 1) { // There is a modifier key
|
|
||||||
if (!char[char.length - 1].match(/[A-za-z]/) && keyId) // It is a letter
|
|
||||||
char = keyId;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.idle = false;
|
this.idle = false;
|
||||||
var wObj = this.waitingForParam;
|
var wObj = this.waitingForParam;
|
||||||
if (wObj) {
|
if (wObj) {
|
||||||
|
|
@ -342,6 +356,9 @@ var inputBuffer = exports.inputBuffer = {
|
||||||
else {
|
else {
|
||||||
this.exec(editor, actionObj);
|
this.exec(editor, actionObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actions[char].acceptsMotion)
|
||||||
|
this.idle = false;
|
||||||
}
|
}
|
||||||
else if (this.operator) {
|
else if (this.operator) {
|
||||||
this.exec(editor, { operator: this.operator }, char);
|
this.exec(editor, { operator: this.operator }, char);
|
||||||
|
|
@ -358,7 +375,7 @@ var inputBuffer = exports.inputBuffer = {
|
||||||
getCount: function() {
|
getCount: function() {
|
||||||
var count = this.currentCount;
|
var count = this.currentCount;
|
||||||
this.currentCount = "";
|
this.currentCount = "";
|
||||||
return count;
|
return count && parseInt(count, 10);
|
||||||
},
|
},
|
||||||
|
|
||||||
exec: function(editor, action, param) {
|
exec: function(editor, action, param) {
|
||||||
|
|
@ -366,6 +383,9 @@ var inputBuffer = exports.inputBuffer = {
|
||||||
var o = action.operator;
|
var o = action.operator;
|
||||||
var a = action.action;
|
var a = action.action;
|
||||||
|
|
||||||
|
if (!param)
|
||||||
|
param = action.param;
|
||||||
|
|
||||||
if (o) {
|
if (o) {
|
||||||
this.previous = {
|
this.previous = {
|
||||||
action: action,
|
action: action,
|
||||||
|
|
@ -391,7 +411,7 @@ var inputBuffer = exports.inputBuffer = {
|
||||||
else if (m) {
|
else if (m) {
|
||||||
var run = function(fn) {
|
var run = function(fn) {
|
||||||
if (fn && typeof fn === "function") { // There should always be a motion
|
if (fn && typeof fn === "function") { // There should always be a motion
|
||||||
if (m.count)
|
if (m.count && !motionObj.handlesCount)
|
||||||
repeat(fn, m.count, [editor, null, m.count, param]);
|
repeat(fn, m.count, [editor, null, m.count, param]);
|
||||||
else
|
else
|
||||||
fn(editor, null, m.count, param);
|
fn(editor, null, m.count, param);
|
||||||
|
|
@ -480,18 +500,15 @@ exports.coreCommands = {
|
||||||
util.insertMode(editor);
|
util.insertMode(editor);
|
||||||
setPreviousCommand(appendEnd);
|
setPreviousCommand(appendEnd);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
builder: {
|
|
||||||
exec: function builder(editor) {}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var handleCursorMove = exports.onCursorMove = function(editor) {
|
var handleCursorMove = exports.onCursorMove = function(editor, e) {
|
||||||
if(util.currentMode === 'insert' || handleCursorMove.running)
|
if (util.currentMode === 'insert' || handleCursorMove.running)
|
||||||
return;
|
return;
|
||||||
else if(!editor.selection.isEmpty()) {
|
else if(!editor.selection.isEmpty()) {
|
||||||
handleCursorMove.running = true;
|
handleCursorMove.running = true;
|
||||||
if(util.onVisualLineMode) {
|
if (util.onVisualLineMode) {
|
||||||
var originRow = editor.selection.visualLineStart;
|
var originRow = editor.selection.visualLineStart;
|
||||||
var cursorRow = editor.getCursorPosition().row;
|
var cursorRow = editor.getCursorPosition().row;
|
||||||
if(originRow <= cursorRow) {
|
if(originRow <= cursorRow) {
|
||||||
|
|
@ -510,6 +527,11 @@ var handleCursorMove = exports.onCursorMove = function(editor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (e && (util.onVisualLineMode || util.onVisualMode)) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
util.normalMode(editor)
|
||||||
|
}
|
||||||
|
|
||||||
handleCursorMove.running = true;
|
handleCursorMove.running = true;
|
||||||
var pos = editor.getCursorPosition();
|
var pos = editor.getCursorPosition();
|
||||||
var lineLen = editor.session.getLine(pos.row).length;
|
var lineLen = editor.session.getLine(pos.row).length;
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,61 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
"never use strict";
|
|
||||||
|
|
||||||
var StateHandler = require("ace/keyboard/state_handler").StateHandler;
|
var keyUtil = require("../../lib/keys");
|
||||||
var cmds = require("./commands");
|
var cmds = require("./commands");
|
||||||
var coreCommands = cmds.coreCommands;
|
var coreCommands = cmds.coreCommands;
|
||||||
|
|
||||||
var matchChar = function(buffer, hashId, key, symbolicName, keyId) {
|
|
||||||
// If no command keys are pressed, then catch the input.
|
|
||||||
// If only the shift key is pressed and a character key, then
|
|
||||||
// catch that input as well.
|
|
||||||
// Otherwise, we let the input got through.
|
|
||||||
var matched = ((hashId === 0) || (((hashId === 1) || (hashId === 4)) && key.length === 1));
|
|
||||||
//console.log("INFO", arguments)
|
|
||||||
|
|
||||||
if (matched) {
|
var startCommands = {
|
||||||
if (keyId) {
|
'i': {
|
||||||
keyId = String.fromCharCode(parseInt(keyId.replace("U+", "0x"), 10));
|
command: coreCommands.start
|
||||||
}
|
},
|
||||||
|
'I': {
|
||||||
|
command: coreCommands.startBeginning,
|
||||||
|
},
|
||||||
|
'a': {
|
||||||
|
command: coreCommands.append
|
||||||
|
},
|
||||||
|
'A': {
|
||||||
|
command: coreCommands.appendEnd
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
coreCommands.builder.exec = function(editor) {
|
exports.handler = {
|
||||||
cmds.inputBuffer.push.call(cmds.inputBuffer, editor, symbolicName, keyId);
|
handleKeyboard: function(data, hashId, key, keyCode, e) {
|
||||||
|
// ignore command keys (shift, ctrl etc.)
|
||||||
|
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
|
||||||
|
// which results in "shift-shift-g" which doesn't make sense.
|
||||||
|
if (hashId != 0 && (key == "" || key == "\x00"))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (hashId == 1)
|
||||||
|
key = 'ctrl-' + key;
|
||||||
|
|
||||||
|
if (data.state == 'start') {
|
||||||
|
if (hashId == -1 || hashId == 1) {
|
||||||
|
if (cmds.inputBuffer.idle && startCommands[key])
|
||||||
|
return startCommands[key];
|
||||||
|
|
||||||
|
return { command: {
|
||||||
|
exec: function(editor) {cmds.inputBuffer.push(editor, key);}
|
||||||
|
} };
|
||||||
|
} // wait for input
|
||||||
|
else if (key.length === 1 && (hashId == 0 || hashId === 4)) { //no modifier || shift
|
||||||
|
return {command: "null", stopEvent: false}
|
||||||
|
} else if (key == 'esc') {
|
||||||
|
return {command: coreCommands.stop};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (key == 'esc' || key == 'ctrl-[') {
|
||||||
|
data.state = 'start'
|
||||||
|
return {command: coreCommands.stop}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return matched;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
var inIdleState = function() {
|
|
||||||
if (cmds.inputBuffer.idle) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
var states = exports.states = {
|
|
||||||
start: [ // normal mode
|
|
||||||
{
|
|
||||||
key: "esc",
|
|
||||||
exec: coreCommands.stop,
|
|
||||||
then: "start"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: "^i$",
|
|
||||||
match: inIdleState,
|
|
||||||
exec: coreCommands.start,
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: "^shift-i$",
|
|
||||||
match: inIdleState,
|
|
||||||
exec: coreCommands.startBeginning,
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: "^a$",
|
|
||||||
match: inIdleState,
|
|
||||||
exec: coreCommands.append,
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
regex: "^shift-a$",
|
|
||||||
match: inIdleState,
|
|
||||||
exec: coreCommands.appendEnd,
|
|
||||||
then: "insertMode"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// The rest of input will be processed here
|
|
||||||
match: matchChar,
|
|
||||||
exec: coreCommands.builder
|
|
||||||
}
|
|
||||||
],
|
|
||||||
insertMode: [
|
|
||||||
{
|
|
||||||
key: "esc",
|
|
||||||
exec: coreCommands.stop,
|
|
||||||
then: "start"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: "backspace",
|
|
||||||
exec: "backspace"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.handler = new StateHandler(states);
|
});
|
||||||
});
|
|
||||||
|
|
@ -12,7 +12,7 @@ module.exports = {
|
||||||
count: 1
|
count: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-x": {
|
"X": {
|
||||||
operator: {
|
operator: {
|
||||||
char: "d",
|
char: "d",
|
||||||
count: 1
|
count: 1
|
||||||
|
|
@ -22,7 +22,7 @@ module.exports = {
|
||||||
count: 1
|
count: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-d": {
|
"D": {
|
||||||
operator: {
|
operator: {
|
||||||
char: "d",
|
char: "d",
|
||||||
count: 1
|
count: 1
|
||||||
|
|
@ -32,7 +32,7 @@ module.exports = {
|
||||||
count: 1
|
count: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-c": {
|
"C": {
|
||||||
operator: {
|
operator: {
|
||||||
char: "c",
|
char: "c",
|
||||||
count: 1
|
count: 1
|
||||||
|
|
@ -52,15 +52,12 @@ module.exports = {
|
||||||
count: 1
|
count: 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-s": {
|
"S": {
|
||||||
operator: {
|
operator: {
|
||||||
char: "c",
|
char: "c",
|
||||||
count: 1
|
count: 1
|
||||||
},
|
},
|
||||||
motion: {
|
param: "c"
|
||||||
char: "l",
|
|
||||||
count: 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
"use strict"
|
"never use strict"
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
|
|
||||||
|
|
@ -12,23 +12,199 @@ var keepScrollPosition = function(editor, fn) {
|
||||||
editor.renderer.scrollToRow(editor.getCursorPosition().row - diff);
|
editor.renderer.scrollToRow(editor.getCursorPosition().row - diff);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function Motion(getRange, type){
|
||||||
|
if (type == 'extend')
|
||||||
|
var extend = true
|
||||||
|
else
|
||||||
|
var reverse = type
|
||||||
|
|
||||||
|
this.nav = function(editor) {
|
||||||
|
var r = getRange(editor);
|
||||||
|
if (!r)
|
||||||
|
return
|
||||||
|
if (!r.end)
|
||||||
|
var a = r
|
||||||
|
else if (reverse)
|
||||||
|
var a = r.start
|
||||||
|
else
|
||||||
|
var a = r.end
|
||||||
|
|
||||||
|
editor.clearSelection()
|
||||||
|
editor.moveCursorTo(a.row, a.column);
|
||||||
|
}
|
||||||
|
this.sel = function(editor){
|
||||||
|
var r = getRange(editor);
|
||||||
|
if (!r)
|
||||||
|
return
|
||||||
|
if (extend)
|
||||||
|
return editor.selection.setSelectionRange(r);
|
||||||
|
|
||||||
|
if (!r.end)
|
||||||
|
var a = r
|
||||||
|
else if (reverse)
|
||||||
|
var a = r.start
|
||||||
|
else
|
||||||
|
var a = r.end
|
||||||
|
|
||||||
|
editor.selection.selectTo(a.row, a.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var nonWordRe = /[\s.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
|
||||||
|
var wordSeparatorRe = /[.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/;
|
||||||
|
var whiteRe = /\s/;
|
||||||
|
var StringStream = function(editor, cursor) {
|
||||||
|
var sel = editor.selection
|
||||||
|
this.range = sel.getRange()
|
||||||
|
cursor = cursor || sel.selectionLead
|
||||||
|
this.row = cursor.row;
|
||||||
|
this.col = cursor.column;
|
||||||
|
var line = editor.session.getLine(this.row);
|
||||||
|
var maxRow = editor.session.getLength()
|
||||||
|
this.ch = line[this.col] || '\n'
|
||||||
|
this.skippedLines = 0
|
||||||
|
|
||||||
|
this.next = function() {
|
||||||
|
this.ch = line[++this.col] || this.handleNewLine(1)
|
||||||
|
//this.debug()
|
||||||
|
return this.ch
|
||||||
|
}
|
||||||
|
this.prev = function() {
|
||||||
|
this.ch = line[--this.col] || this.handleNewLine(-1)
|
||||||
|
//this.debug()
|
||||||
|
return this.ch
|
||||||
|
}
|
||||||
|
this.peek = function(dir) {
|
||||||
|
var ch = line[this.col + dir]
|
||||||
|
if (ch)
|
||||||
|
return ch
|
||||||
|
if (dir == -1)
|
||||||
|
return '\n'
|
||||||
|
if (this.col == line.length - 1)
|
||||||
|
return '\n'
|
||||||
|
return editor.session.getLine(this.row + 1)[0] || '\n'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handleNewLine = function(dir) {
|
||||||
|
if (dir == 1){
|
||||||
|
if (this.col == line.length)
|
||||||
|
return '\n'
|
||||||
|
if (this.row == maxRow - 1)
|
||||||
|
return ''
|
||||||
|
this.col = 0
|
||||||
|
this.row ++
|
||||||
|
line = editor.session.getLine(this.row)
|
||||||
|
this.skippedLines++
|
||||||
|
return line[0] || '\n'
|
||||||
|
}
|
||||||
|
if (dir == -1) {
|
||||||
|
if (this.row == 0)
|
||||||
|
return ''
|
||||||
|
this.row --
|
||||||
|
line = editor.session.getLine(this.row)
|
||||||
|
this.col = line.length;
|
||||||
|
this.skippedLines--
|
||||||
|
return '\n'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.debug = function() {
|
||||||
|
console.log(line.substring(0, this.col)+'|'+this.ch+'\''+this.col+'\''+line.substr(this.col+1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Search = require("ace/search").Search;
|
||||||
|
var search = new Search();
|
||||||
|
|
||||||
|
function find(editor, needle, dir) {
|
||||||
|
search.$options.needle = needle
|
||||||
|
search.$options.backwards = dir == -1
|
||||||
|
return search.find(editor.session)
|
||||||
|
}
|
||||||
|
var lang = require("ace/lib/lang");
|
||||||
|
var Range = require("ace/range").Range;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"w": {
|
"w": new Motion(function(editor) {
|
||||||
nav: function(editor) {
|
var str = new StringStream(editor)
|
||||||
editor.navigateWordRight();
|
|
||||||
},
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
sel: function(editor) {
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
editor.selection.selectWordRight();
|
str.next()
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.next()
|
||||||
}
|
}
|
||||||
},
|
while (str.ch && whiteRe.test(str.ch) && str.skippedLines < 2)
|
||||||
"b": {
|
str.next()
|
||||||
nav: function(editor) {
|
|
||||||
editor.navigateWordLeft();
|
str.skippedLines == 2 && str.prev()
|
||||||
},
|
return {column: str.col, row: str.row}
|
||||||
sel: function(editor) {
|
}),
|
||||||
editor.selection.selectWordLeft();
|
"W": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
while(str.ch && !(whiteRe.test(str.ch) && !whiteRe.test(str.peek(1))) && str.skippedLines < 2)
|
||||||
|
str.next()
|
||||||
|
if (str.skippedLines == 2)
|
||||||
|
str.prev()
|
||||||
|
else
|
||||||
|
str.next()
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}),
|
||||||
|
"b": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
|
||||||
|
str.prev()
|
||||||
|
while (str.ch && whiteRe.test(str.ch) && str.skippedLines > -2)
|
||||||
|
str.prev()
|
||||||
|
|
||||||
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
|
str.prev()
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.prev()
|
||||||
}
|
}
|
||||||
},
|
str.ch && str.next();
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}),
|
||||||
|
"B": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
str.prev()
|
||||||
|
while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(-1))) && str.skippedLines > -2)
|
||||||
|
str.prev()
|
||||||
|
|
||||||
|
if (str.skippedLines == -2)
|
||||||
|
str.next()
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}, true),
|
||||||
|
"e": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
|
||||||
|
str.next()
|
||||||
|
while (str.ch && whiteRe.test(str.ch))
|
||||||
|
str.next()
|
||||||
|
|
||||||
|
if (str.ch && wordSeparatorRe.test(str.ch)) {
|
||||||
|
while (str.ch && wordSeparatorRe.test(str.ch))
|
||||||
|
str.next()
|
||||||
|
} else {
|
||||||
|
while (str.ch && !nonWordRe.test(str.ch))
|
||||||
|
str.next()
|
||||||
|
}
|
||||||
|
str.ch && str.prev()
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}),
|
||||||
|
"E": new Motion(function(editor) {
|
||||||
|
var str = new StringStream(editor)
|
||||||
|
str.next()
|
||||||
|
while(str.ch && !(!whiteRe.test(str.ch) && whiteRe.test(str.peek(1))))
|
||||||
|
str.next()
|
||||||
|
|
||||||
|
return {column: str.col, row: str.row}
|
||||||
|
}),
|
||||||
|
|
||||||
"l": {
|
"l": {
|
||||||
nav: function(editor) {
|
nav: function(editor) {
|
||||||
editor.navigateRight();
|
editor.navigateRight();
|
||||||
|
|
@ -72,12 +248,41 @@ module.exports = {
|
||||||
editor.selection.selectDown();
|
editor.selection.selectDown();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"i": {
|
"i": {
|
||||||
param: true,
|
param: true,
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "w":
|
case "w":
|
||||||
editor.selection.selectWord();
|
editor.selection.selectWord();
|
||||||
|
break;
|
||||||
|
case "W":
|
||||||
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "(":
|
||||||
|
case "{":
|
||||||
|
case "[":
|
||||||
|
var cursor = editor.getCursorPosition()
|
||||||
|
var end = editor.session.$findClosingBracket(param, cursor, /paren/)
|
||||||
|
if (!end)
|
||||||
|
return
|
||||||
|
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/)
|
||||||
|
if (!start)
|
||||||
|
return
|
||||||
|
start.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start, end))
|
||||||
|
break
|
||||||
|
case "'":
|
||||||
|
case "\"":
|
||||||
|
case "/":
|
||||||
|
var end = find(editor, param, 1)
|
||||||
|
if (!end)
|
||||||
|
return
|
||||||
|
var start = find(editor, param, -1)
|
||||||
|
if (!start)
|
||||||
|
return
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start.end, end.start))
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -87,16 +292,46 @@ module.exports = {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "w":
|
case "w":
|
||||||
editor.selection.selectAWord();
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "W":
|
||||||
|
editor.selection.selectAWord();
|
||||||
|
break;
|
||||||
|
case "(":
|
||||||
|
case "{":
|
||||||
|
case "[":
|
||||||
|
var cursor = editor.getCursorPosition()
|
||||||
|
var end = editor.session.$findClosingBracket(param, cursor, /paren/)
|
||||||
|
if (!end)
|
||||||
|
return
|
||||||
|
var start = editor.session.$findOpeningBracket(editor.session.$brackets[param], cursor, /paren/)
|
||||||
|
if (!start)
|
||||||
|
return
|
||||||
|
end.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start, end))
|
||||||
|
break
|
||||||
|
case "'":
|
||||||
|
case "\"":
|
||||||
|
case "/":
|
||||||
|
var end = find(editor, param, 1)
|
||||||
|
if (!end)
|
||||||
|
return
|
||||||
|
var start = find(editor, param, -1)
|
||||||
|
if (!start)
|
||||||
|
return
|
||||||
|
end.column ++;
|
||||||
|
editor.selection.setSelectionRange(Range.fromPoints(start.start, end.end))
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"f": {
|
"f": {
|
||||||
param: true,
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
var cursor = ed.getCursorPosition();
|
var cursor = ed.getCursorPosition();
|
||||||
var column = util.getRightNthChar(editor, cursor, param, count);
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.selection.clearSelection(); // Why does it select in the first place?
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
|
@ -104,18 +339,18 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
var cursor = ed.getCursorPosition();
|
var cursor = ed.getCursorPosition();
|
||||||
var column = util.getRightNthChar(editor, cursor, param, count);
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.moveCursorTo(cursor.row, column + cursor.column + 1);
|
ed.moveCursorTo(cursor.row, column + cursor.column + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-f": {
|
"F": {
|
||||||
param: true,
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
count = parseInt(count, 10) || 1;
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
|
|
@ -124,27 +359,26 @@ module.exports = {
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.selection.clearSelection(); // Why does it select in the first place?
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
ed.moveCursorTo(cursor.row, cursor.column - column + 1);
|
ed.moveCursorTo(cursor.row, cursor.column - column - 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
var cursor = ed.getCursorPosition();
|
var cursor = ed.getCursorPosition();
|
||||||
var column = util.getLeftNthChar(editor, cursor, param, count);
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.moveCursorTo(cursor.row, cursor.column - column + 1);
|
ed.moveCursorTo(cursor.row, cursor.column - column - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"t": {
|
"t": {
|
||||||
param: true,
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
var cursor = ed.getCursorPosition();
|
var cursor = ed.getCursorPosition();
|
||||||
var column = util.getRightNthChar(editor, cursor, param, count);
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.selection.clearSelection(); // Why does it select in the first place?
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
|
@ -152,16 +386,39 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10) || 1;
|
|
||||||
var ed = editor;
|
var ed = editor;
|
||||||
var cursor = ed.getCursorPosition();
|
var cursor = ed.getCursorPosition();
|
||||||
var column = util.getRightNthChar(editor, cursor, param, count);
|
var column = util.getRightNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
if (typeof column === "number") {
|
if (typeof column === "number") {
|
||||||
ed.moveCursorTo(cursor.row, column + cursor.column);
|
ed.moveCursorTo(cursor.row, column + cursor.column);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"T": {
|
||||||
|
param: true,
|
||||||
|
handlesCount: true,
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.selection.clearSelection(); // Why does it select in the first place?
|
||||||
|
ed.moveCursorTo(cursor.row, -column + cursor.column);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
var ed = editor;
|
||||||
|
var cursor = ed.getCursorPosition();
|
||||||
|
var column = util.getLeftNthChar(editor, cursor, param, count || 1);
|
||||||
|
|
||||||
|
if (typeof column === "number") {
|
||||||
|
ed.moveCursorTo(cursor.row, -column + cursor.column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"^": {
|
"^": {
|
||||||
nav: function(editor) {
|
nav: function(editor) {
|
||||||
editor.navigateLineStart();
|
editor.navigateLineStart();
|
||||||
|
|
@ -188,41 +445,20 @@ module.exports = {
|
||||||
ed.selectTo(ed.selection.selectionLead.row, 0);
|
ed.selectTo(ed.selection.selectionLead.row, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-g": {
|
"G": {
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10);
|
|
||||||
if (!count && count !== 0) { // Stupid JS
|
if (!count && count !== 0) { // Stupid JS
|
||||||
count = editor.session.getLength();
|
count = editor.session.getLength();
|
||||||
}
|
}
|
||||||
editor.gotoLine(count);
|
editor.gotoLine(count);
|
||||||
},
|
},
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
count = parseInt(count, 10);
|
|
||||||
if (!count && count !== 0) { // Stupid JS
|
if (!count && count !== 0) { // Stupid JS
|
||||||
count = editor.session.getLength();
|
count = editor.session.getLength();
|
||||||
}
|
}
|
||||||
editor.selection.selectTo(count, 0);
|
editor.selection.selectTo(count, 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ctrl-d": {
|
|
||||||
nav: function(editor, range, count, param) {
|
|
||||||
editor.selection.clearSelection();
|
|
||||||
keepScrollPosition(editor, editor.gotoPageDown);
|
|
||||||
},
|
|
||||||
sel: function(editor, range, count, param) {
|
|
||||||
keepScrollPosition(editor, editor.selectPageDown);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ctrl-u": {
|
|
||||||
nav: function(editor, range, count, param) {
|
|
||||||
editor.selection.clearSelection();
|
|
||||||
keepScrollPosition(editor, editor.gotoPageUp);
|
|
||||||
|
|
||||||
},
|
|
||||||
sel: function(editor, range, count, param) {
|
|
||||||
keepScrollPosition(editor, editor.selectPageUp);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"g": {
|
"g": {
|
||||||
param: true,
|
param: true,
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
|
|
@ -235,6 +471,10 @@ module.exports = {
|
||||||
break;
|
break;
|
||||||
case "g":
|
case "g":
|
||||||
editor.gotoLine(count || 0);
|
editor.gotoLine(count || 0);
|
||||||
|
case "u":
|
||||||
|
editor.gotoLine(count || 0);
|
||||||
|
case "U":
|
||||||
|
editor.gotoLine(count || 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
sel: function(editor, range, count, param) {
|
sel: function(editor, range, count, param) {
|
||||||
|
|
@ -264,7 +504,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shift-o": {
|
"O": {
|
||||||
nav: function(editor, range, count, param) {
|
nav: function(editor, range, count, param) {
|
||||||
var row = editor.getCursorPosition().row;
|
var row = editor.getCursorPosition().row;
|
||||||
count = count || 1;
|
count = count || 1;
|
||||||
|
|
@ -285,18 +525,42 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"%": {
|
"%": new Motion(function(editor){
|
||||||
nav: function(editor, range, count, param) {
|
var brRe = /[\[\]{}()]/g;
|
||||||
var cursor = editor.getCursorPosition();
|
var cursor = editor.getCursorPosition();
|
||||||
var match = editor.session.findMatchingBracket({
|
var ch = editor.session.getLine(cursor.row)[cursor.column]
|
||||||
row: cursor.row,
|
if (!brRe.test(ch)){
|
||||||
column: cursor.column + 1
|
var range = find(editor, brRe)
|
||||||
});
|
if (!range)
|
||||||
|
return
|
||||||
if (match)
|
cursor = range.start
|
||||||
editor.moveCursorTo(match.row, match.column);
|
|
||||||
}
|
}
|
||||||
}
|
var match = editor.session.findMatchingBracket({
|
||||||
|
row: cursor.row,
|
||||||
|
column: cursor.column + 1
|
||||||
|
});
|
||||||
|
|
||||||
|
return match
|
||||||
|
}),
|
||||||
|
"ctrl-d": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
keepScrollPosition(editor, editor.gotoPageDown);
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
keepScrollPosition(editor, editor.selectPageDown);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ctrl-u": {
|
||||||
|
nav: function(editor, range, count, param) {
|
||||||
|
editor.selection.clearSelection();
|
||||||
|
keepScrollPosition(editor, editor.gotoPageUp);
|
||||||
|
|
||||||
|
},
|
||||||
|
sel: function(editor, range, count, param) {
|
||||||
|
keepScrollPosition(editor, editor.selectPageUp);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.backspace = module.exports.left = module.exports.h;
|
module.exports.backspace = module.exports.left = module.exports.h;
|
||||||
|
|
|
||||||
|
|
@ -7,63 +7,65 @@ var registers = require("../registers");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"d": {
|
"d": {
|
||||||
selFn: function(editor, range, count, param) {
|
selFn: function(editor, range, count, param) {
|
||||||
registers._default.text = editor.getCopyText();
|
registers._default.text = editor.getCopyText();
|
||||||
registers._default.isLine = util.onVisualLineMode;
|
registers._default.isLine = util.onVisualLineMode;
|
||||||
if(util.onVisualLineMode)
|
if(util.onVisualLineMode)
|
||||||
editor.removeLines();
|
editor.removeLines();
|
||||||
else
|
else
|
||||||
editor.session.remove(range);
|
editor.session.remove(range);
|
||||||
util.normalMode(editor);
|
util.normalMode(editor);
|
||||||
},
|
},
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "d":
|
case "d":
|
||||||
registers._default.text = "";
|
registers._default.text = "";
|
||||||
registers._default.isLine = true;
|
registers._default.isLine = true;
|
||||||
for (var i=0; i<count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
editor.selection.selectLine();
|
editor.selection.selectLine();
|
||||||
registers._default.text += editor.getCopyText();
|
registers._default.text += editor.getCopyText();
|
||||||
var selRange = editor.getSelectionRange();
|
var selRange = editor.getSelectionRange();
|
||||||
editor.session.remove(selRange);
|
editor.session.remove(selRange);
|
||||||
editor.selection.clearSelection();
|
editor.selection.clearSelection();
|
||||||
}
|
}
|
||||||
registers._default.text = registers._default.text.replace(/\n$/, "");
|
registers._default.text = registers._default.text.replace(/\n$/, "");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (range) {
|
if (range) {
|
||||||
editor.selection.setSelectionRange(range);
|
editor.selection.setSelectionRange(range);
|
||||||
registers._default.text = editor.getCopyText();
|
registers._default.text = editor.getCopyText();
|
||||||
registers._default.isLine = false;
|
registers._default.isLine = false;
|
||||||
editor.session.remove(range);
|
editor.session.remove(range);
|
||||||
editor.selection.clearSelection();
|
editor.selection.clearSelection();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"c": {
|
"c": {
|
||||||
selFn: function(editor, range, count, param) {
|
selFn: function(editor, range, count, param) {
|
||||||
editor.session.remove(range);
|
editor.session.remove(range);
|
||||||
util.insertMode(editor);
|
util.insertMode(editor);
|
||||||
},
|
},
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "c":
|
case "c":
|
||||||
for (var i=0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
editor.removeLines();
|
editor.removeLines();
|
||||||
util.insertMode(editor);
|
util.insertMode(editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (range) {
|
if (range) {
|
||||||
editor.session.remove(range);
|
|
||||||
util.insertMode(editor);
|
// range.end.column ++;
|
||||||
}
|
editor.session.remove(range);
|
||||||
}
|
util.insertMode(editor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"y": {
|
"y": {
|
||||||
selFn: function(editor, range, count, param) {
|
selFn: function(editor, range, count, param) {
|
||||||
|
|
@ -73,7 +75,7 @@ module.exports = {
|
||||||
util.normalMode(editor);
|
util.normalMode(editor);
|
||||||
},
|
},
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "y":
|
case "y":
|
||||||
var pos = editor.getCursorPosition();
|
var pos = editor.getCursorPosition();
|
||||||
|
|
@ -100,7 +102,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
">": {
|
">": {
|
||||||
selFn: function(editor, range, count, param) {
|
selFn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
editor.indent();
|
editor.indent();
|
||||||
}
|
}
|
||||||
|
|
@ -126,14 +128,14 @@ module.exports = {
|
||||||
},
|
},
|
||||||
"<": {
|
"<": {
|
||||||
selFn: function(editor, range, count, param) {
|
selFn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
for (var i = 0; i < count; i++) {
|
for (var i = 0; i < count; i++) {
|
||||||
editor.blockOutdent();
|
editor.blockOutdent();
|
||||||
}
|
}
|
||||||
util.normalMode(editor);
|
util.normalMode(editor);
|
||||||
},
|
},
|
||||||
fn: function(editor, range, count, param) {
|
fn: function(editor, range, count, param) {
|
||||||
count = parseInt(count || 1, 10);
|
count = count || 1;
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case "<":
|
case "<":
|
||||||
var pos = editor.getCursorPosition();
|
var pos = editor.getCursorPosition();
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,75 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
var registers = require("../registers");
|
var registers = require("../registers");
|
||||||
|
|
||||||
|
var dom = require("ace/lib/dom");
|
||||||
|
dom.importCssString('.insert-mode. ace_cursor{\
|
||||||
|
border-left: 2px solid #333333;\
|
||||||
|
}\
|
||||||
|
.ace_dark.insert-mode .ace_cursor{\
|
||||||
|
border-left: 2px solid #eeeeee;\
|
||||||
|
}\
|
||||||
|
.normal-mode .ace_cursor{\
|
||||||
|
border: 0!important;\
|
||||||
|
background-color: red;\
|
||||||
|
opacity: 0.5;\
|
||||||
|
}', 'vimMode');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
onVisualMode: false,
|
onVisualMode: false,
|
||||||
onVisualLineMode: false,
|
onVisualLineMode: false,
|
||||||
currentMode: 'normal',
|
currentMode: 'normal',
|
||||||
|
noMode: function(editor) {
|
||||||
|
editor.unsetStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
if (editor.commands.recording)
|
||||||
|
editor.commands.toggleRecording();
|
||||||
|
},
|
||||||
insertMode: function(editor) {
|
insertMode: function(editor) {
|
||||||
var _self = this;
|
this.currentMode = 'insert';
|
||||||
var theme = editor && editor.getTheme() || "ace/theme/textmate";
|
// Switch editor to insert mode
|
||||||
|
editor.setStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
|
||||||
require(["require", theme], function (require) {
|
|
||||||
var isDarkTheme = require(theme).isDark;
|
|
||||||
|
|
||||||
_self.currentMode = 'insert';
|
editor.setOverwrite(false);
|
||||||
// Switch editor to insert mode
|
editor.keyBinding.$data.buffer = "";
|
||||||
editor.unsetStyle('insert-mode');
|
editor.keyBinding.$data.state = "insertMode";
|
||||||
|
this.onVisualMode = false;
|
||||||
var cursor = document.getElementsByClassName("ace_cursor")[0];
|
this.onVisualLineMode = false;
|
||||||
if (cursor) {
|
if(this.onInsertReplaySequence) {
|
||||||
cursor.style.display = null;
|
// Ok, we're apparently replaying ("."), so let's do it
|
||||||
cursor.style.backgroundColor = null;
|
editor.commands.macro = this.onInsertReplaySequence;
|
||||||
cursor.style.opacity = null;
|
editor.commands.replay(editor);
|
||||||
cursor.style.border = null;
|
this.onInsertReplaySequence = null;
|
||||||
cursor.style.borderLeftColor = isDarkTheme? "#eeeeee" : "#333333";
|
this.normalMode(editor);
|
||||||
cursor.style.borderLeftStyle = "solid";
|
} else {
|
||||||
cursor.style.borderLeftWidth = "2px";
|
// Record any movements, insertions in insert mode
|
||||||
}
|
if(!editor.commands.recording)
|
||||||
|
editor.commands.toggleRecording();
|
||||||
editor.setOverwrite(false);
|
}
|
||||||
editor.keyBinding.$data.buffer = "";
|
|
||||||
editor.keyBinding.$data.state = "insertMode";
|
|
||||||
_self.onVisualMode = false;
|
|
||||||
_self.onVisualLineMode = false;
|
|
||||||
if(_self.onInsertReplaySequence) {
|
|
||||||
// Ok, we're apparently replaying ("."), so let's do it
|
|
||||||
editor.commands.macro = _self.onInsertReplaySequence;
|
|
||||||
editor.commands.replay(editor);
|
|
||||||
_self.onInsertReplaySequence = null;
|
|
||||||
_self.normalMode(editor);
|
|
||||||
} else {
|
|
||||||
// Record any movements, insertions in insert mode
|
|
||||||
if(!editor.commands.recording)
|
|
||||||
editor.commands.toggleRecording();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
normalMode: function(editor) {
|
normalMode: function(editor) {
|
||||||
// Switch editor to normal mode
|
// Switch editor to normal mode
|
||||||
this.currentMode = 'normal';
|
this.currentMode = 'normal';
|
||||||
|
|
||||||
|
editor.unsetStyle('insert-mode');
|
||||||
editor.setStyle('normal-mode');
|
editor.setStyle('normal-mode');
|
||||||
editor.clearSelection();
|
editor.clearSelection();
|
||||||
|
|
||||||
var cursor = document.getElementsByClassName("ace_cursor")[0];
|
|
||||||
if (cursor) {
|
|
||||||
cursor.style.display = null;
|
|
||||||
cursor.style.backgroundColor = "red";
|
|
||||||
cursor.style.opacity = ".5";
|
|
||||||
cursor.style.border = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
var pos;
|
var pos;
|
||||||
if (!editor.getOverwrite()) {
|
if (!editor.getOverwrite()) {
|
||||||
pos = editor.getCursorPosition();
|
pos = editor.getCursorPosition();
|
||||||
if (pos.column > 0)
|
if (pos.column > 0)
|
||||||
editor.navigateLeft();
|
editor.navigateLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.setOverwrite(true);
|
editor.setOverwrite(true);
|
||||||
editor.keyBinding.$data.buffer = "";
|
editor.keyBinding.$data.buffer = "";
|
||||||
editor.keyBinding.$data.state = "start";
|
editor.keyBinding.$data.state = "start";
|
||||||
this.onVisualMode = false;
|
this.onVisualMode = false;
|
||||||
this.onVisualLineMode = false;
|
this.onVisualLineMode = false;
|
||||||
// Save recorded keystrokes
|
// Save recorded keystrokes
|
||||||
if(editor.commands.recording) {
|
if (editor.commands.recording) {
|
||||||
editor.commands.toggleRecording();
|
editor.commands.toggleRecording();
|
||||||
return editor.commands.macro;
|
return editor.commands.macro;
|
||||||
}
|
}
|
||||||
|
|
@ -80,17 +77,36 @@ module.exports = {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
visualMode: function(editor, lineMode) {
|
||||||
|
if (
|
||||||
|
(this.onVisualLineMode && lineMode)
|
||||||
|
|| (this.onVisualMode && !lineMode)
|
||||||
|
) {
|
||||||
|
this.normalMode(editor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.setStyle('insert-mode');
|
||||||
|
editor.unsetStyle('normal-mode');
|
||||||
|
|
||||||
|
if (lineMode) {
|
||||||
|
this.onVisualLineMode = true;
|
||||||
|
} else {
|
||||||
|
this.onVisualMode = true;
|
||||||
|
this.onVisualLineMode = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
getRightNthChar: function(editor, cursor, char, n) {
|
getRightNthChar: function(editor, cursor, char, n) {
|
||||||
var line = editor.getSession().getLine(cursor.row);
|
var line = editor.getSession().getLine(cursor.row);
|
||||||
var matches = line.substr(cursor.column + 1).split(char);
|
var matches = line.substr(cursor.column + 1).split(char);
|
||||||
|
|
||||||
return n < matches.length ? matches.slice(0, n).join(char).length : 0;
|
return n < matches.length ? matches.slice(0, n).join(char).length : null;
|
||||||
},
|
},
|
||||||
getLeftNthChar: function(editor, cursor, char, n) {
|
getLeftNthChar: function(editor, cursor, char, n) {
|
||||||
var line = editor.getSession().getLine(cursor.row);
|
var line = editor.getSession().getLine(cursor.row);
|
||||||
var matches = line.substr(0, cursor.column).split(char);
|
var matches = line.substr(0, cursor.column).split(char);
|
||||||
|
|
||||||
return n < matches.length ? matches.slice(-1 * n).join(char).length + 2 : 0;
|
return n < matches.length ? matches.slice(-1 * n).join(char).length : null;
|
||||||
},
|
},
|
||||||
toRealChar: function(char) {
|
toRealChar: function(char) {
|
||||||
if (char.length === 1)
|
if (char.length === 1)
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ var Keys = (function() {
|
||||||
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
|
80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v',
|
||||||
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
|
87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.',
|
||||||
188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
|
188: ',', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',
|
||||||
221: ']', 222: '\"'
|
221: ']', 222: '\''
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var oop = require("../../lib/oop");
|
var oop = require("../../lib/oop");
|
||||||
var Behaviour = require('../behaviour').Behaviour;
|
var Behaviour = require("../behaviour").Behaviour;
|
||||||
|
|
||||||
var CstyleBehaviour = function () {
|
var CstyleBehaviour = function () {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue