add readline support for meta-f and meta-b

This commit is contained in:
Johan Euphrosine 2010-08-22 07:50:40 +02:00 committed by Ryan Dahl
parent fd3e84499e
commit 748469c71c
2 changed files with 77 additions and 11 deletions

View File

@ -15,7 +15,6 @@ var EventEmitter = require('events').EventEmitter;
var stdio = process.binding('stdio'); var stdio = process.binding('stdio');
exports.createInterface = function (output, completer) { exports.createInterface = function (output, completer) {
return new Interface(output, completer); return new Interface(output, completer);
}; };
@ -347,10 +346,37 @@ Interface.prototype._ttyWrite = function (b) {
return; return;
case 27: /* escape sequence */ case 27: /* escape sequence */
var next_word, next_non_word, previous_word, previous_non_word;
if (b[1] === 98 && this.cursor > 0) { // meta-b - backward word if (b[1] === 98 && this.cursor > 0) { // meta-b - backward word
previous_word = this.line.slice(0, this.cursor)
.split('').reverse().join('')
.search(/\w/);
if (previous_word !== -1) {
previous_non_word = this.line.slice(0, this.cursor - previous_word)
.split('').reverse().join('')
.search(/\W/);
if (previous_non_word !== -1) {
this.cursor -= previous_word + previous_non_word;
this._refreshLine();
break;
}
}
this.cursor = 0;
this._refreshLine();
} else if (b[1] === 102 && this.cursor < this.line.length) { // meta-f - forward word } else if (b[1] === 102 && this.cursor < this.line.length) { // meta-f - forward word
next_word = this.line.slice(this.cursor, this.line.length)
.search(/\w/);
if (next_word !== -1) {
next_non_word = this.line.slice(this.cursor + next_word, this.line.length)
.search(/\W/);
if (next_non_word !== -1) {
this.cursor += next_word + next_non_word;
this._refreshLine();
break;
}
}
this.cursor = this.line.length;
this._refreshLine();
} else if (b[1] === 91 && b[2] === 68) { // left arrow } else if (b[1] === 91 && b[2] === 68) { // left arrow
if (this.cursor > 0) { if (this.cursor > 0) {
this.cursor--; this.cursor--;

View File

@ -5,7 +5,9 @@ var readline = require("readline");
var key = { var key = {
xterm: { xterm: {
home: [27, 91, 72], home: [27, 91, 72],
end: [27, 91, 70] end: [27, 91, 70],
metab: [27, 98],
metaf: [27, 102]
}, },
gnome: { gnome: {
home: [27, 79, 72], home: [27, 79, 72],
@ -17,15 +19,21 @@ var key = {
} }
}; };
var fakestream = { var readlineFakeStream = function() {
fd: 1, var written_bytes = [];
write: function(bytes) { var rl = readline.createInterface({
} fd: 1,
write: function(b) {
written_bytes.push(b);
}}, function (text) {
return [[], ""];
});
rl.written_bytes = written_bytes;
return rl;
}; };
var rl = readline.createInterface(fakestream, function (text) { var rl = readlineFakeStream();
return [[], ""]; var written_bytes_length, refreshed;
});
rl.write('foo'); rl.write('foo');
assert.equal(3, rl.cursor); assert.equal(3, rl.cursor);
@ -41,3 +49,35 @@ rl.write(key.gnome.home);
assert.equal(0, rl.cursor); assert.equal(0, rl.cursor);
rl.write(key.gnome.end); rl.write(key.gnome.end);
assert.equal(3, rl.cursor); assert.equal(3, rl.cursor);
rl = readlineFakeStream();
rl.write('foo bar.hop/zoo');
rl.write(key.xterm.home);
written_bytes_length = rl.written_bytes.length;
rl.write(key.xterm.metaf);
assert.equal(3, rl.cursor);
refreshed = written_bytes_length !== rl.written_bytes.length;
assert.equal(true, refreshed);
rl.write(key.xterm.metaf);
assert.equal(7, rl.cursor);
rl.write(key.xterm.metaf);
assert.equal(11, rl.cursor);
written_bytes_length = rl.written_bytes.length;
rl.write(key.xterm.metaf);
assert.equal(15, rl.cursor);
refreshed = written_bytes_length !== rl.written_bytes.length;
assert.equal(true, refreshed);
written_bytes_length = rl.written_bytes.length;
rl.write(key.xterm.metab);
assert.equal(12, rl.cursor);
refreshed = written_bytes_length !== rl.written_bytes.length;
assert.equal(true, refreshed);
rl.write(key.xterm.metab);
assert.equal(8, rl.cursor);
rl.write(key.xterm.metab);
assert.equal(4, rl.cursor);
written_bytes_length = rl.written_bytes.length;
rl.write(key.xterm.metab);
assert.equal(0, rl.cursor);
refreshed = written_bytes_length !== rl.written_bytes.length;
assert.equal(true, refreshed);