Skip to content
Permalink
Browse files

readline: move escape codes into internal/readline

Moves escape codes into internal/readline for easier management.

PR-URL: #12755
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information...
jasnell authored and addaleax committed Apr 30, 2017
1 parent 4ac7a68 commit 4c070d489718b196d7950998ccfb54bcc50d9711
Showing with 43 additions and 15 deletions.
  1. +23 −4 lib/internal/readline.js
  2. +20 −11 lib/readline.js
@@ -7,9 +7,27 @@
const ansi =
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;

const kEscape = '\x1b';

var getStringWidth;
var isFullWidthCodePoint;

function CSI(strings, ...args) {
let ret = `${kEscape}[`;
for (var n = 0; n < strings.length; n++) {
ret += strings[n];
if (n < args.length)
ret += args[n];
}
return ret;
}

CSI.kEscape = kEscape;
CSI.kClearToBeginning = CSI`1K`;
CSI.kClearToEnd = CSI`0K`;
CSI.kClearLine = CSI`2K`;
CSI.kClearScreenDown = CSI`0J`;

if (process.binding('config').hasIntl) {
const icu = process.binding('icu');
getStringWidth = function getStringWidth(str, options) {
@@ -151,11 +169,11 @@ function* emitKeys(stream) {
shift: false
};

if (ch === '\x1b') {
if (ch === kEscape) {
escaped = true;
s += (ch = yield);

if (ch === '\x1b') {
if (ch === kEscape) {
s += (ch = yield);
}
}
@@ -370,7 +388,7 @@ function* emitKeys(stream) {
// backspace or ctrl+h
key.name = 'backspace';
key.meta = escaped;
} else if (ch === '\x1b') {
} else if (ch === kEscape) {
// escape key
key.name = 'escape';
key.meta = escaped;
@@ -409,5 +427,6 @@ module.exports = {
emitKeys,
getStringWidth,
isFullWidthCodePoint,
stripVTControlCharacters
stripVTControlCharacters,
CSI
};
@@ -31,12 +31,21 @@ const { debug, inherits } = require('util');
const Buffer = require('buffer').Buffer;
const EventEmitter = require('events');
const {
CSI,
emitKeys,
getStringWidth,
isFullWidthCodePoint,
stripVTControlCharacters
} = require('internal/readline');

const {
kEscape,
kClearToBeginning,
kClearToEnd,
kClearLine,
kClearScreenDown
} = CSI;

const kHistorySize = 30;
const kMincrlfDelay = 100;
const kMaxcrlfDelay = 2000;
@@ -995,7 +1004,7 @@ function emitKeypressEvents(stream, iface) {
try {
stream[ESCAPE_DECODER].next(r[i]);
// Escape letter at the tail position
if (r[i] === '\x1b' && i + 1 === r.length) {
if (r[i] === kEscape && i + 1 === r.length) {
timeoutId = setTimeout(escapeCodeTimeout, ESCAPE_CODE_TIMEOUT);
}
} catch (err) {
@@ -1047,9 +1056,9 @@ function cursorTo(stream, x, y) {
throw new Error('Can\'t set cursor row without also setting it\'s column');

if (typeof y !== 'number') {
stream.write('\x1b[' + (x + 1) + 'G');
stream.write(CSI`${x + 1}G`);
} else {
stream.write('\x1b[' + (y + 1) + ';' + (x + 1) + 'H');
stream.write(CSI`${y + 1};${x + 1}H`);
}
}

@@ -1062,15 +1071,15 @@ function moveCursor(stream, dx, dy) {
return;

if (dx < 0) {
stream.write('\x1b[' + (-dx) + 'D');
stream.write(CSI`${-dx}D`);
} else if (dx > 0) {
stream.write('\x1b[' + dx + 'C');
stream.write(CSI`${dx}C`);
}

if (dy < 0) {
stream.write('\x1b[' + (-dy) + 'A');
stream.write(CSI`${-dy}A`);
} else if (dy > 0) {
stream.write('\x1b[' + dy + 'B');
stream.write(CSI`${dy}B`);
}
}

@@ -1087,13 +1096,13 @@ function clearLine(stream, dir) {

if (dir < 0) {
// to the beginning
stream.write('\x1b[1K');
stream.write(kClearToBeginning);
} else if (dir > 0) {
// to the end
stream.write('\x1b[0K');
stream.write(kClearToEnd);
} else {
// entire line
stream.write('\x1b[2K');
stream.write(kClearLine);
}
}

@@ -1105,7 +1114,7 @@ function clearScreenDown(stream) {
if (stream === null || stream === undefined)
return;

stream.write('\x1b[0J');
stream.write(kClearScreenDown);
}

module.exports = {

0 comments on commit 4c070d4

Please sign in to comment.
You can’t perform that action at this time.