Merge pull request #884 from ajaxorg/vim

Vim
This commit is contained in:
Mostafa Eweda 2012-08-24 02:45:42 -07:00
commit f9d580d106
10 changed files with 132 additions and 43 deletions

View file

@ -47,6 +47,8 @@ var env = {};
var dom = require("ace/lib/dom");
var net = require("ace/lib/net");
var lang = require("ace/lib/lang");
var useragent = require("ace/lib/useragent");
var event = require("ace/lib/event");
var theme = require("ace/theme/textmate");
@ -739,10 +741,41 @@ function singleLineEditor(el) {
editor.setHighlightActiveLine(false);
editor.setShowPrintMargin(false);
editor.renderer.setShowGutter(false);
// editor.renderer.setHighlightGutterLine(false);
editor.renderer.setHighlightGutterLine(false);
return editor;
};
/** simple statusbar **/
var editor = env.editor;
var statusBarEl = dom.createElement("div");
statusBarEl.style.cssText = "color:gray;position:absolute;right:0;border-left:1px solid";
cmdLine.container.appendChild(statusBarEl);
var statusUpdate = lang.deferredCall(function() {
var status = [];
function add(s, sep) {s && status.push(s, sep || "|")}
if (editor.$vimModeHandler)
add(editor.$vimModeHandler.getStatusText());
else if (editor.commands.recording)
add("REC");
var c = editor.selection.lead;
add(c.row + ":" + c.column, " ");
if (!editor.selection.isEmpty()) {
var r = editor.getSelectionRange()
add("(" + (r.end.row - r.start.row) + ":" +(r.end.column - r.start.column) + ")");
}
status.pop();
statusBarEl.textContent = status.join("");
});
env.editor.on("changeStatus", function() {
statusUpdate.schedule(50);
});
env.editor.on("changeSelection", function() {
statusUpdate.schedule(50);
});
});

View file

@ -60,9 +60,11 @@ oop.inherits(CommandManager, HashHandler);
return retvalue === false ? false : true;
};
this.toggleRecording = function() {
this.toggleRecording = function(editor) {
if (this.$inReplay)
return;
editor && editor._emit("changeStatus");
if (this.recording) {
this.macro.pop();
this.removeEventListener("exec", this.$addCommandToMacro);
@ -74,8 +76,8 @@ oop.inherits(CommandManager, HashHandler);
}
if (!this.$addCommandToMacro) {
this.$addCommandToMacro = function(e) {
this.macro.push([e.command, e.args]);
}.bind(this);
this.macro.push([e.command, e.args]);
}.bind(this);
}
this.oldMacro = this.macro;
@ -89,7 +91,7 @@ oop.inherits(CommandManager, HashHandler);
return;
if (this.recording)
return this.toggleRecording();
return this.toggleRecording(editor);
try {
this.$inReplay = true;

View file

@ -128,7 +128,7 @@ module.exports = {
var called = "";
this.cm.addCommands({
togglerecording: function(editor) {
editor.cm.toggleRecording();
editor.cm.toggleRecording(editor);
},
replay: function(editor) {
editor.cm.replay();
@ -140,9 +140,14 @@ module.exports = {
called += "2";
}
});
var statusUpdateEmitted = false;
this._emit = function() {statusUpdateEmitted = true};
this.cm.exec("togglerecording", this);
assert.ok(this.cm.recording);
assert.ok(statusUpdateEmitted);
this.cm.exec("cm1", this, "-");
this.cm.exec("cm2");

View file

@ -288,7 +288,7 @@ exports.commands = [{
}, {
name: "togglerecording",
bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
exec: function(editor) { editor.commands.toggleRecording(); },
exec: function(editor) { editor.commands.toggleRecording(editor); },
readOnly: true
}, {
name: "replaymacro",

View file

@ -475,6 +475,7 @@ var Editor = function(renderer, session) {
this.$highlightBrackets();
this.$updateHighlightActiveLine();
this._emit("changeSelection");
};
/** internal, hide
@ -531,6 +532,8 @@ var Editor = function(renderer, session) {
var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
this.session.highlight(re);
this._emit("changeSelection");
};
this.$getSelectionHighLightRegexp = function() {

View file

@ -39,10 +39,10 @@
define(function(require, exports, module) {
"use strict";
var keyUtil = require("../lib/keys");
var cmds = require("./vim/commands");
var coreCommands = cmds.coreCommands;
var util = require("./vim/maps/util");
var useragent = require("../lib/useragent");
var startCommands = {
"i": {
@ -66,6 +66,28 @@ var startCommands = {
};
exports.handler = {
// workaround for j not repeating with `defaults write -g ApplePressAndHoldEnabled -bool true`
handleMacRepeat: function(data, hashId, key) {
if (hashId == -1) {
// record key
data.inputChar = key;
data.lastEvent = "input";
} else if (data.inputChar && data.$lastHash == hashId && data.$lastKey == key) {
// check for repeated keypress
if (data.lastEvent == "input") {
data.lastEvent = "input1";
} else if (data.lastEvent == "input1") {
// simulate textinput
return true;
}
} else {
// reset
data.$lastHash = hashId;
data.$lastKey = key;
data.lastEvent = "keypress";
}
},
handleKeyboard: function(data, hashId, key, keyCode, e) {
// ignore command keys (shift, ctrl etc.)
if (hashId != 0 && (key == "" || key == "\x00"))
@ -73,19 +95,25 @@ exports.handler = {
if (hashId == 1)
key = "ctrl-" + key;
if (data.state == "start") {
if (useragent.isMac && this.handleMacRepeat(data, hashId, key)) {
hashId = -1;
key = data.inputChar;
}
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: {
exec: function(editor) {cmds.inputBuffer.push(editor, key);}
}
};
} // if no modifier || shift: wait for input.
else if (key.length == 1 && (hashId == 0 || hashId == 4)) {
return {command: "null", passEvent: true};
} else if (key == "esc") {
} else if (key == "esc" && hashId == 0) {
return {command: coreCommands.stop};
}
} else {
@ -102,6 +130,7 @@ exports.handler = {
editor.on("click", exports.onCursorMove);
if (util.currentMode !== "insert")
cmds.coreCommands.stop.exec(editor);
editor.$vimModeHandler = this;
},
detach: function(editor) {
@ -110,7 +139,14 @@ exports.handler = {
util.currentMode = "normal";
},
actions: cmds.actions
actions: cmds.actions,
getStatusText: function() {
if (util.currentMode == "insert")
return "INSERT";
if (util.onVisualMode)
return (util.onVisualLineMode ? "VISUAL LINE " : "VISUAL ") + cmds.inputBuffer.status;
return cmds.inputBuffer.status;
}
};

View file

@ -304,6 +304,7 @@ var inputBuffer = exports.inputBuffer = {
currentCmd: null,
//currentMode: 0,
currentCount: "",
status: "",
// Types
operator: null,
@ -378,6 +379,17 @@ var inputBuffer = exports.inputBuffer = {
else {
this.reset();
}
if (this.waitingForParam || this.motion || this.operator) {
this.status += char;
} else if (this.currentCount) {
this.status = this.currentCount;
} else if (this.status) {
this.status = "";
} else {
return;
}
editor._emit("changeStatus");
},
waitForParam: function(cmd) {
@ -462,6 +474,7 @@ var inputBuffer = exports.inputBuffer = {
this.operator = null;
this.motion = null;
this.currentCount = "";
this.status = "";
this.accepting = [NUMBER, OPERATOR, MOTION, ACTION];
this.idle = true;
this.waitingForParam = null;

View file

@ -390,10 +390,9 @@ module.exports = {
param: true,
handlesCount: true,
nav: function(editor, range, count, param) {
count = parseInt(count, 10) || 1;
var ed = editor;
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") {
ed.selection.clearSelection(); // Why does it select in the first place?
@ -473,16 +472,9 @@ module.exports = {
editor.selection.selectLineEnd();
}
},
"0": {
nav: function(editor) {
var ed = editor;
ed.navigateTo(ed.selection.selectionLead.row, 0);
},
sel: function(editor) {
var ed = editor;
ed.selectTo(ed.selection.selectionLead.row, 0);
}
},
"0": new Motion(function(ed) {
return {row: ed.selection.lead.row, column: 0};
}),
"G": {
nav: function(editor, range, count, param) {
if (!count && count !== 0) { // Stupid JS

View file

@ -22,7 +22,7 @@ module.exports = {
editor.unsetStyle('insert-mode');
editor.unsetStyle('normal-mode');
if (editor.commands.recording)
editor.commands.toggleRecording();
editor.commands.toggleRecording(editor);
editor.setOverwrite(false);
},
insertMode: function(editor) {
@ -43,10 +43,10 @@ module.exports = {
this.onInsertReplaySequence = null;
this.normalMode(editor);
} else {
editor._emit("vimMode", "insert");
editor._emit("changeStatus");
// Record any movements, insertions in insert mode
if(!editor.commands.recording)
editor.commands.toggleRecording();
editor.commands.toggleRecording(editor);
}
},
normalMode: function(editor) {
@ -69,10 +69,10 @@ module.exports = {
editor.keyBinding.$data.state = "start";
this.onVisualMode = false;
this.onVisualLineMode = false;
editor._emit("changeVimMode", "normal");
editor._emit("changeStatus");
// Save recorded keystrokes
if (editor.commands.recording) {
editor.commands.toggleRecording();
editor.commands.toggleRecording(editor);
return editor.commands.macro;
}
else {
@ -91,7 +91,7 @@ module.exports = {
editor.setStyle('insert-mode');
editor.unsetStyle('normal-mode');
editor._emit("changeVimMode", "visual");
editor._emit("changeStatus");
if (lineMode) {
this.onVisualLineMode = true;
} else {

View file

@ -525,8 +525,8 @@ var Selection = function(session) {
// Determ the line
var beforeCursor = this.session.getDisplayLine(
row, null,
firstColumnPosition.row, firstColumnPosition.column
row, null, firstColumnPosition.row,
firstColumnPosition.column
);
var leadingSpace = beforeCursor.match(/^\s*/);
@ -550,12 +550,17 @@ var Selection = function(session) {
**/
this.moveCursorLineEnd = function() {
var lead = this.lead;
var lastRowColumnPosition =
this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
this.moveCursorTo(
lastRowColumnPosition.row,
lastRowColumnPosition.column
);
var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
if (this.lead.column == lineEnd.column) {
var line = this.session.getLine(lineEnd.row);
if (lineEnd.column == line.length) {
var textEnd = line.search(/\s+$/);
if (textEnd > 0)
lineEnd.column = textEnd;
}
}
this.moveCursorTo(lineEnd.row, lineEnd.column);
};
/**