Use strings instead of buffers in readline
For eventual large character support.
This commit is contained in:
parent
a6942b345d
commit
0377b12964
106
lib/readline.js
106
lib/readline.js
@ -25,8 +25,7 @@ function Interface (output, isTTY) {
|
|||||||
this.setPrompt("node> ");
|
this.setPrompt("node> ");
|
||||||
|
|
||||||
// Current line
|
// Current line
|
||||||
this.buf = new Buffer(kBufSize);
|
this.line = ""
|
||||||
this.buf.used = 0;
|
|
||||||
|
|
||||||
if (!isTTY) {
|
if (!isTTY) {
|
||||||
this._tty = false;
|
this._tty = false;
|
||||||
@ -57,7 +56,6 @@ Interface.prototype.setPrompt = function (prompt, length) {
|
|||||||
|
|
||||||
Interface.prototype.prompt = function () {
|
Interface.prototype.prompt = function () {
|
||||||
if (this._tty) {
|
if (this._tty) {
|
||||||
this.buf.used = 0;
|
|
||||||
this.cursor = 0;
|
this.cursor = 0;
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
} else {
|
} else {
|
||||||
@ -67,13 +65,10 @@ Interface.prototype.prompt = function () {
|
|||||||
|
|
||||||
|
|
||||||
Interface.prototype._addHistory = function () {
|
Interface.prototype._addHistory = function () {
|
||||||
if (this.buf.used === 0) return "";
|
if (this.line.length === 0) return "";
|
||||||
|
|
||||||
var b = new Buffer(this.buf.used);
|
this.history.unshift(this.line);
|
||||||
this.buf.copy(b, 0, 0, this.buf.used);
|
this.line = "";
|
||||||
this.buf.used = 0;
|
|
||||||
|
|
||||||
this.history.unshift(b);
|
|
||||||
this.historyIndex = -1;
|
this.historyIndex = -1;
|
||||||
|
|
||||||
this.cursor = 0;
|
this.cursor = 0;
|
||||||
@ -81,7 +76,7 @@ Interface.prototype._addHistory = function () {
|
|||||||
// Only store so many
|
// Only store so many
|
||||||
if (this.history.length > kHistorySize) this.history.pop();
|
if (this.history.length > kHistorySize) this.history.pop();
|
||||||
|
|
||||||
return b.toString('utf8');
|
return this.history[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -95,9 +90,7 @@ Interface.prototype._refreshLine = function () {
|
|||||||
|
|
||||||
// Write the prompt and the current buffer content.
|
// Write the prompt and the current buffer content.
|
||||||
this.output.write(this._prompt);
|
this.output.write(this._prompt);
|
||||||
if (this.buf.used > 0) {
|
this.output.write(this.line);
|
||||||
this.output.write(this.buf.slice(0, this.buf.used));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase to right.
|
// Erase to right.
|
||||||
this.output.write('\x1b[0K');
|
this.output.write('\x1b[0K');
|
||||||
@ -123,31 +116,22 @@ Interface.prototype.write = function (d) {
|
|||||||
|
|
||||||
|
|
||||||
Interface.prototype._normalWrite = function (b) {
|
Interface.prototype._normalWrite = function (b) {
|
||||||
for (var i = 0; i < b.length; i++) {
|
// Very simple implementation right now. Should try to break on
|
||||||
var code = b instanceof Buffer ? b[i] : b.charCodeAt(i);
|
// new lines.
|
||||||
if (code === '\n'.charCodeAt(0) || code === '\r'.charCodeAt(0)) {
|
this.emit('line', b.toString());
|
||||||
var s = this.buf.toString('utf8', 0, this.buf.used);
|
|
||||||
this.emit('line', s);
|
|
||||||
this.buf.used = 0;
|
|
||||||
} else {
|
|
||||||
this.buf[this.buf.used++] = code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Interface.prototype._historyNext = function () {
|
Interface.prototype._historyNext = function () {
|
||||||
if (this.historyIndex > 0) {
|
if (this.historyIndex > 0) {
|
||||||
this.historyIndex--;
|
this.historyIndex--;
|
||||||
this.history[this.historyIndex].copy(this.buf, 0);
|
this.line = this.history[this.historyIndex];
|
||||||
this.buf.used = this.history[this.historyIndex].length;
|
this.cursor = this.line.length; // set cursor to end of line.
|
||||||
// set cursor to end of line.
|
|
||||||
this.cursor = this.buf.used;
|
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
|
|
||||||
} else if (this.historyIndex === 0) {
|
} else if (this.historyIndex === 0) {
|
||||||
this.historyIndex = -1;
|
this.historyIndex = -1;
|
||||||
this.cursor = 0;
|
this.cursor = 0;
|
||||||
this.buf.used = 0;
|
this.line = '';
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -155,10 +139,8 @@ Interface.prototype._historyNext = function () {
|
|||||||
Interface.prototype._historyPrev = function () {
|
Interface.prototype._historyPrev = function () {
|
||||||
if (this.historyIndex + 1 < this.history.length) {
|
if (this.historyIndex + 1 < this.history.length) {
|
||||||
this.historyIndex++;
|
this.historyIndex++;
|
||||||
this.history[this.historyIndex].copy(this.buf, 0);
|
this.line = this.history[this.historyIndex];
|
||||||
this.buf.used = this.history[this.historyIndex].length;
|
this.cursor = this.line.length; // set cursor to end of line.
|
||||||
// set cursor to end of line.
|
|
||||||
this.cursor = this.buf.used;
|
|
||||||
|
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
}
|
}
|
||||||
@ -174,13 +156,12 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // control-d, delete right or EOF
|
case 4: // control-d, delete right or EOF
|
||||||
if (this.cursor === 0 && this.buf.used === 0) {
|
if (this.cursor === 0 && this.line.length === 0) {
|
||||||
this.close();
|
this.close();
|
||||||
} else if (this.cursor < this.buf.used) {
|
} else if (this.cursor < this.line.length) {
|
||||||
for (var i = this.cursor; i < this.buf.used; i++) {
|
this.line = this.line.slice(0, this.cursor)
|
||||||
this.buf[i] = this.buf[i+1];
|
+ this.line.slice(this.cursor+1, this.line.length)
|
||||||
}
|
;
|
||||||
this.buf.used--;
|
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -194,23 +175,23 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
|
|
||||||
case 127: /* backspace */
|
case 127: /* backspace */
|
||||||
case 8: /* ctrl+h */
|
case 8: /* ctrl+h */
|
||||||
if (this.cursor > 0 && this.buf.used > 0) {
|
if (this.cursor > 0 && this.line.length > 0) {
|
||||||
for (var i = this.cursor; i < this.buf.used; i++) {
|
this.line = this.line.slice(0, this.cursor-1)
|
||||||
this.buf[i-1] = this.buf[i];
|
+ this.line.slice(this.cursor, this.line.length)
|
||||||
}
|
;
|
||||||
this.cursor--;
|
this.cursor--;
|
||||||
this.buf.used--;
|
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 21: /* Ctrl+u, delete the whole line. */
|
case 21: /* Ctrl+u, delete the whole line. */
|
||||||
this.cursor = this.buf.used = 0;
|
this.cursor = 0;
|
||||||
|
this.line = '';
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 11: /* Ctrl+k, delete from current to end of line. */
|
case 11: /* Ctrl+k, delete from current to end of line. */
|
||||||
this.buf.used = this.cursor;
|
this.line = this.line.slice(0, this.cursor);
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -220,7 +201,7 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: /* ctrl+e, go to the end of the line */
|
case 5: /* ctrl+e, go to the end of the line */
|
||||||
this.cursor = this.buf.used;
|
this.cursor = this.line.length;
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -232,7 +213,7 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 6: // control-f, forward one character
|
case 6: // control-f, forward one character
|
||||||
if (this.cursor != this.buf.used) {
|
if (this.cursor != this.line.length) {
|
||||||
this.cursor++;
|
this.cursor++;
|
||||||
this._refreshLine();
|
this._refreshLine();
|
||||||
}
|
}
|
||||||
@ -249,17 +230,17 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
case 27: /* escape sequence */
|
case 27: /* escape sequence */
|
||||||
if (b[1] === 98 && this.cursor > 0) { // meta-b - backward word
|
if (b[1] === 98 && this.cursor > 0) { // meta-b - backward word
|
||||||
|
|
||||||
} else if (b[1] === 102 && this.cursor < this.buf.used) { // meta-f - forward word
|
} else if (b[1] === 102 && this.cursor < this.line.length) { // meta-f - forward word
|
||||||
|
|
||||||
} 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--;
|
||||||
this._refreshLine();
|
this.output.write('\x1b[0D');
|
||||||
}
|
}
|
||||||
} else if (b[1] === 91 && b[2] === 67) { // right arrow
|
} else if (b[1] === 91 && b[2] === 67) { // right arrow
|
||||||
if (this.cursor != this.buf.used) {
|
if (this.cursor != this.line.length) {
|
||||||
this.cursor++;
|
this.cursor++;
|
||||||
this._refreshLine();
|
this.output.write('\x1b[0C');
|
||||||
}
|
}
|
||||||
} else if (b[1] === 91 && b[2] === 65) { // up arrow
|
} else if (b[1] === 91 && b[2] === 65) { // up arrow
|
||||||
this._historyPrev();
|
this._historyPrev();
|
||||||
@ -269,18 +250,17 @@ Interface.prototype._ttyWrite = function (b) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (this.buf.used < kBufSize) {
|
var c = b.toString('utf8');
|
||||||
for (var i = this.buf.used + 1; this.cursor < i; i--) {
|
if (this.cursor < this.line.length) {
|
||||||
this.buf[i] = this.buf[i-1];
|
var beg = this.line.slice(0, this.cursor);
|
||||||
}
|
var end = this.line.slice(this.cursor, this.line.length);
|
||||||
this.buf[this.cursor++] = b[0];
|
this.line = beg + c + end;
|
||||||
this.buf.used++;
|
this.cursor += c.length;
|
||||||
|
this._refreshLine();
|
||||||
if (this.buf.used == this.cursor) {
|
} else {
|
||||||
this.output.write(b);
|
this.line += c;
|
||||||
} else {
|
this.cursor += c.length;
|
||||||
this._refreshLine();
|
this.output.write(c);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user