Readline: fixes, more key bindings

- Made backward/forward more convenient
- More key bindings that windows users are used to
- Fix delete-word-right
- Duplicate code cleanup
This commit is contained in:
Bert Belder 2011-01-25 03:54:26 +01:00 committed by Ryan Dahl
parent 430a7f1bed
commit 07f3274ac4

View File

@ -307,6 +307,26 @@ function commonPrefix(strings) {
} }
Interface.prototype._wordLeft = function() {
if (this.cursor > 0) {
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/([^\w\s]+|\w+|)\s*$/);
this.cursor -= match[0].length;
this._refreshLine();
}
}
Interface.prototype._wordRight = function() {
if (this.cursor < this.line.length) {
var trailing = this.line.slice(this.cursor);
var match = trailing.match(/^(\s+|\W+|\w+)\s*/);
this.cursor += match[0].length;
this._refreshLine();
}
}
Interface.prototype._deleteLeft = function() { Interface.prototype._deleteLeft = function() {
if (this.cursor > 0 && this.line.length > 0) { if (this.cursor > 0 && this.line.length > 0) {
this.line = this.line.slice(0, this.cursor - 1) + this.line = this.line.slice(0, this.cursor - 1) +
@ -325,6 +345,42 @@ Interface.prototype._deleteRight = function() {
}; };
Interface.prototype._deleteWordLeft = function() {
if (this.cursor > 0) {
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/([^\w\s]+|\w+|)\s*$/);
leading = leading.slice(0, leading.length - match[0].length);
this.line = leading + this.line.slice(this.cursor, this.line.length);
this.cursor = leading.length;
this._refreshLine();
}
}
Interface.prototype._deleteWordRight = function() {
if (this.cursor < this.line.length) {
var trailing = this.line.slice(this.cursor);
var match = trailing.match(/^(\s+|\W+|\w+)\s*/);
this.line = this.line.slice(0, this.cursor) +
trailing.slice(match[0].length);
this._refreshLine();
}
}
Interface.prototype._deleteLineLeft = function() {
this.line = this.line.slice(this.cursor);
this.cursor = 0;
this._refreshLine();
}
Interface.prototype._deleteLineRight = function() {
this.line = this.line.slice(0, this.cursor);
this._refreshLine();
}
Interface.prototype._line = function() { Interface.prototype._line = function() {
var line = this._addHistory(); var line = this._addHistory();
this.output.write('\r\n'); this.output.write('\r\n');
@ -374,7 +430,19 @@ Interface.prototype._ttyWrite = function(s, key) {
var next_word, next_non_word, previous_word, previous_non_word; var next_word, next_non_word, previous_word, previous_non_word;
key = key || {}; key = key || {};
if (key.ctrl) { if (key.ctrl && key.shift) {
/* Control and shift pressed */
switch (key.name) {
case "backspace":
this._deleteLineLeft();
break;
case "delete":
this._deleteLineRight();
break;
}
} else if (key.ctrl) {
/* Control key pressed */ /* Control key pressed */
switch (key.name) { switch (key.name) {
@ -406,8 +474,7 @@ Interface.prototype._ttyWrite = function(s, key) {
break; break;
case 'k': // delete from current to end of line case 'k': // delete from current to end of line
this.line = this.line.slice(0, this.cursor); this._deleteLineRight();
this._refreshLine();
break; break;
case 'a': // go to the start of the line case 'a': // go to the start of the line
@ -438,17 +505,6 @@ Interface.prototype._ttyWrite = function(s, key) {
this._historyNext(); this._historyNext();
break; break;
case 'w': // delete backwards to a word boundary
if (this.cursor !== 0) {
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/\s?((\W+|\w+)\s*)$/);
leading = leading.slice(0, leading.length - match[1].length);
this.line = leading + this.line.slice(this.cursor, this.line.length);
this.cursor = leading.length;
this._refreshLine();
}
break;
case 'p': // previous history item case 'p': // previous history item
this._historyPrev(); this._historyPrev();
break; break;
@ -456,6 +512,26 @@ Interface.prototype._ttyWrite = function(s, key) {
case 'z': case 'z':
process.kill(process.pid, 'SIGTSTP'); process.kill(process.pid, 'SIGTSTP');
return; return;
case 'w': // delete backwards to a word boundary
case 'backspace':
this._deleteWordLeft();
break;
case 'delete': // delete forward to a word boundary
this._deleteWordRight();
break;
case 'backspace':
this._deleteWordLeft();
break;
case 'left':
this._wordLeft();
break;
case 'right':
this._wordRight();
} }
} else if (key.meta) { } else if (key.meta) {
@ -463,81 +539,21 @@ Interface.prototype._ttyWrite = function(s, key) {
switch (key.name) { switch (key.name) {
case 'b': // backward word case 'b': // backward word
if (this.cursor > 0) { this._wordLeft();
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();
}
break; break;
case 'f': // forward word case 'f': // forward word
if (this.cursor < this.line.length) { this._wordRight();
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();
}
break; break;
case 'd': // delete forward word case 'd': // delete forward word
case 'delete': case 'delete':
if (this.cursor < this.line.length) { this._deleteWordRight();
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.line = this.line.slice(this.cursor +
next_word +
next_non_word);
this.cursor = 0;
this._refreshLine();
break;
}
}
this.line = '';
this.cursor = 0;
this._refreshLine();
}
break; break;
case 'backspace': // delete backwards to a word boundary case 'backspace': // delete backwards to a word boundary
if (this.cursor !== 0) { this._deleteWordLeft();
var leading = this.line.slice(0, this.cursor);
var match = leading.match(/\s?((\W+|\w+)\s*)$/);
leading = leading.slice(0, leading.length - match[1].length);
this.line = leading + this.line.slice(this.cursor, this.line.length);
this.cursor = leading.length;
this._refreshLine();
}
break; break;
} }
} else { } else {