Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
repl: activate previews for lines exceeding the terminal columns
This improves the completion previews by activating them for lines
that exceed the current terminal columns.
As a drive-by fix it also simplifies some statements.

PR-URL: #31112
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
BridgeAR authored and targos committed Apr 28, 2020
1 parent 4e9e440 commit a4ca378
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 29 deletions.
67 changes: 38 additions & 29 deletions lib/internal/repl/utils.js
Expand Up @@ -136,14 +136,16 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {

function getPreviewPos() {
const displayPos = repl._getDisplayPos(`${repl._prompt}${repl.line}`);
const cursorPos = repl.getCursorPos();
const rows = 1 + displayPos.rows - cursorPos.rows;
return { rows, cols: cursorPos.cols };
const cursorPos = repl.line.length !== repl.cursor ?
repl.getCursorPos() :
displayPos;
return { displayPos, cursorPos };
}

const clearPreview = () => {
if (inputPreview !== null) {
const { rows } = getPreviewPos();
const { displayPos, cursorPos } = getPreviewPos();
const rows = displayPos.rows - cursorPos.rows + 1;
moveCursor(repl.output, 0, rows);
clearLine(repl.output);
moveCursor(repl.output, 0, -rows);
Expand All @@ -153,12 +155,25 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
if (completionPreview !== null) {
// Prevent cursor moves if not necessary!
const move = repl.line.length !== repl.cursor;
let pos, rows;
if (move) {
cursorTo(repl.output, repl._prompt.length + repl.line.length);
pos = getPreviewPos();
cursorTo(repl.output, pos.displayPos.cols);
rows = pos.displayPos.rows - pos.cursorPos.rows;
moveCursor(repl.output, 0, rows);
}
const totalLine = `${repl._prompt}${repl.line}${completionPreview}`;
const newPos = repl._getDisplayPos(totalLine);
// Minimize work for the terminal. It is enough to clear the right part of
// the current line in case the preview is visible on a single line.
if (newPos.rows === 0 || (pos && pos.displayPos.rows === newPos.rows)) {
clearLine(repl.output, 1);
} else {
clearScreenDown(repl.output);
}
clearLine(repl.output, 1);
if (move) {
cursorTo(repl.output, repl._prompt.length + repl.cursor);
cursorTo(repl.output, pos.cursorPos.cols);
moveCursor(repl.output, 0, -rows);
}
completionPreview = null;
}
Expand Down Expand Up @@ -198,17 +213,6 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {

const suffix = prefix.slice(completeOn.length);

const totalLength = repl.line.length +
repl._prompt.length +
suffix.length +
(repl.useColors ? 0 : 4);

// TODO(BridgeAR): Fix me. This should not be necessary. See similar
// comment in `showPreview()`.
if (totalLength > repl.columns) {
return;
}

if (insertPreview) {
repl._insertString(suffix);
return;
Expand All @@ -220,11 +224,17 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
`\u001b[90m${suffix}\u001b[39m` :
` // ${suffix}`;

const { cursorPos, displayPos } = getPreviewPos();
if (repl.line.length !== repl.cursor) {
cursorTo(repl.output, repl._prompt.length + repl.line.length);
cursorTo(repl.output, displayPos.cols);
moveCursor(repl.output, 0, displayPos.rows - cursorPos.rows);
}
repl.output.write(result);
cursorTo(repl.output, repl._prompt.length + repl.cursor);
cursorTo(repl.output, cursorPos.cols);
const totalLine = `${repl._prompt}${repl.line}${suffix}`;
const newPos = repl._getDisplayPos(totalLine);
const rows = newPos.rows - cursorPos.rows - (newPos.cols === 0 ? 1 : 0);
moveCursor(repl.output, 0, -rows);
});
}

Expand Down Expand Up @@ -288,6 +298,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
}, () => callback(new ERR_INSPECTOR_NOT_AVAILABLE()));
}

// TODO(BridgeAR): Prevent previews while pasting code.
const showPreview = () => {
// Prevent duplicated previews after a refresh.
if (inputPreview !== null) {
Expand Down Expand Up @@ -373,12 +384,12 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
`\u001b[90m${inspected}\u001b[39m` :
`// ${inspected}`;

const { rows: previewRows, cols: cursorCols } = getPreviewPos();
if (previewRows !== 1)
moveCursor(repl.output, 0, previewRows - 1);
const { cursorPos, displayPos } = getPreviewPos();
const rows = displayPos.rows - cursorPos.rows;
moveCursor(repl.output, 0, rows);
const { cols: resultCols } = repl._getDisplayPos(result);
repl.output.write(`\n${result}`);
moveCursor(repl.output, cursorCols - resultCols, -previewRows);
moveCursor(repl.output, cursorPos.cols - resultCols, -rows - 1);
});
};

Expand Down Expand Up @@ -452,8 +463,8 @@ function setupReverseSearch(repl) {
// Reset the already matched set in case the direction is changed. That
// way it's possible to find those entries again.
alreadyMatched.clear();
dir = keyName;
}
dir = keyName;
return true;
}

Expand Down Expand Up @@ -598,16 +609,14 @@ function setupReverseSearch(repl) {

// Clear screen and write the current repl.line before exiting.
cursorTo(repl.output, promptPos.cols);
if (promptPos.rows !== 0)
moveCursor(repl.output, 0, promptPos.rows);
moveCursor(repl.output, 0, promptPos.rows);
clearScreenDown(repl.output);
if (repl.line !== '') {
repl.output.write(repl.line);
if (repl.line.length !== repl.cursor) {
const { cols, rows } = repl.getCursorPos();
cursorTo(repl.output, cols);
if (rows !== 0)
moveCursor(repl.output, 0, rows);
moveCursor(repl.output, 0, rows);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-repl-history-navigation.js
Expand Up @@ -201,6 +201,9 @@ const tests = [
// 236 + 2 + 4 + 8
'\x1B[1G', '\x1B[0J',
`${prompt}${' '.repeat(236)} fun`, '\x1B[243G',
' // ction', '\x1B[243G',
' // ction', '\x1B[243G',
'\x1B[0K',
// 2. UP
'\x1B[1G', '\x1B[0J',
`${prompt}${' '.repeat(235)} fun`, '\x1B[242G',
Expand Down

0 comments on commit a4ca378

Please sign in to comment.