Skip to content

Commit ac10064

Browse files
Fix cursor position when cycling through multi line command history. Allow cursor to move between lines of a single multi line command
1 parent e8108c2 commit ac10064

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/commandwindow/CommandWindow.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,17 @@ export default class CommandWindow implements vscode.Pseudoterminal {
462462
// Don't actually move the cursor, but do move the index we think the cursor is at.
463463
this._justTypedLastInColumn = false;
464464
} else {
465-
if (this._getAbsoluteIndexOnLine(this._cursorIndex) % this._terminalDimensions.columns === 0) {
465+
// Check if the character before cursor is a newline (explicit line break)
466+
const charBeforeCursor = this._currentPromptLine.charAt(this._getAbsoluteIndexOnLine(this._cursorIndex) - 1);
467+
if (charBeforeCursor === '\n') {
468+
// Moving left across an explicit newline - need to go up and find position on previous line
469+
const textBeforeNewline = this._currentPromptLine.substring(0, this._getAbsoluteIndexOnLine(this._cursorIndex) - 1);
470+
const previousNewlineIndex = textBeforeNewline.lastIndexOf('\n');
471+
const positionOnPreviousLine = previousNewlineIndex === -1
472+
? textBeforeNewline.length
473+
: textBeforeNewline.length - previousNewlineIndex - 1;
474+
this._writeEmitter.fire(ACTION_KEYS.UP + ACTION_KEYS.MOVE_TO_POSITION_IN_LINE((positionOnPreviousLine % this._terminalDimensions.columns) + 1));
475+
} else if (this._getAbsoluteIndexOnLine(this._cursorIndex) % this._terminalDimensions.columns === 0) {
466476
this._writeEmitter.fire(ACTION_KEYS.UP + ACTION_KEYS.MOVE_TO_POSITION_IN_LINE(this._terminalDimensions.columns));
467477
} else {
468478
this._writeEmitter.fire(ACTION_KEYS.LEFT);
@@ -477,7 +487,12 @@ export default class CommandWindow implements vscode.Pseudoterminal {
477487
if (this._justTypedLastInColumn) {
478488
// Not possible
479489
} else {
480-
if (this._getAbsoluteIndexOnLine(this._cursorIndex) % this._terminalDimensions.columns === (this._terminalDimensions.columns - 1)) {
490+
// Check if the character at cursor is a newline (explicit line break)
491+
const charAtCursor = this._currentPromptLine.charAt(this._getAbsoluteIndexOnLine(this._cursorIndex));
492+
if (charAtCursor === '\n') {
493+
// Moving right across an explicit newline - go down to start of next line
494+
this._writeEmitter.fire(ACTION_KEYS.DOWN + ACTION_KEYS.MOVE_TO_POSITION_IN_LINE(1));
495+
} else if (this._getAbsoluteIndexOnLine(this._cursorIndex) % this._terminalDimensions.columns === (this._terminalDimensions.columns - 1)) {
481496
this._writeEmitter.fire(ACTION_KEYS.DOWN + ACTION_KEYS.MOVE_TO_POSITION_IN_LINE(0));
482497
} else {
483498
this._writeEmitter.fire(ACTION_KEYS.RIGHT);
@@ -669,7 +684,13 @@ export default class CommandWindow implements vscode.Pseudoterminal {
669684
} else if (lineNumberCursorShouldBeOn < lineOfInputCursorIsCurrentlyOn) {
670685
this._writeEmitter.fire(ACTION_KEYS.UP.repeat(lineOfInputCursorIsCurrentlyOn - lineNumberCursorShouldBeOn));
671686
}
672-
this._writeEmitter.fire(ACTION_KEYS.MOVE_TO_POSITION_IN_LINE((this._getAbsoluteIndexOnLine(this._cursorIndex) % this._terminalDimensions.columns) + 1));
687+
// Calculate column position accounting for explicit newlines
688+
const textUpToCursor = this._currentPromptLine.substring(0, this._getAbsoluteIndexOnLine(this._cursorIndex));
689+
const lastNewlineIndex = textUpToCursor.lastIndexOf('\n');
690+
const positionOnCurrentLine = lastNewlineIndex === -1
691+
? this._getAbsoluteIndexOnLine(this._cursorIndex)
692+
: textUpToCursor.length - lastNewlineIndex - 1;
693+
this._writeEmitter.fire(ACTION_KEYS.MOVE_TO_POSITION_IN_LINE((positionOnCurrentLine % this._terminalDimensions.columns) + 1));
673694
}
674695

675696
setDimensions (dimensions: vscode.TerminalDimensions): void {

0 commit comments

Comments
 (0)