From 47b25652e8ebaef608b3a7f73c72d4a8aa7b7a66 Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Thu, 3 Apr 2025 13:59:59 +0100 Subject: [PATCH 1/3] Filter command history based on current prompt --- src/commandwindow/CommandWindow.ts | 64 ++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/src/commandwindow/CommandWindow.ts b/src/commandwindow/CommandWindow.ts index 9e63b89..6d837de 100644 --- a/src/commandwindow/CommandWindow.ts +++ b/src/commandwindow/CommandWindow.ts @@ -94,6 +94,9 @@ export default class CommandWindow implements vscode.Pseudoterminal { private readonly _commandHistory: string[] = []; private _historyIndex: number = 0; private _lastKnownCurrentLine: string = ''; + private _filteredCommandHistory: string[] = []; + private _filteredHistoryIndex: number = 0; + private _commandHistoryFilter: string = ''; private _terminalDimensions: vscode.TerminalDimensions; private _lastSentTerminalDimensions: vscode.TerminalDimensions | null = null; @@ -347,26 +350,63 @@ export default class CommandWindow implements vscode.Pseudoterminal { private _handleNavigateHistory (direction: HistoryDirection): boolean { const isCurrentlyAtEndOfHistory = this._historyIndex === this._commandHistory.length; - const isCurrentlyAtBeginningOfHistory = this._historyIndex === 0; - if (direction === HistoryDirection.BACKWARDS && isCurrentlyAtBeginningOfHistory) { - return false; - } + if (isCurrentlyAtEndOfHistory && this._stripCurrentPrompt(this._currentPromptLine) !== '') { + // Only update the filtered history if the current line changes + if (this._filteredCommandHistory.length === 0) { + this._commandHistoryFilter = this._stripCurrentPrompt(this._currentPromptLine); + + this._filteredCommandHistory = this._commandHistory.filter(cmd => + cmd.toLowerCase().startsWith(this._commandHistoryFilter.toLowerCase())); + this._filteredHistoryIndex = this._filteredCommandHistory.length; + } - if (direction === HistoryDirection.FORWARDS && isCurrentlyAtEndOfHistory) { + // Filter history based on the current prompt text + return this._navigateHistory( + direction, + this._filteredHistoryIndex, + this._filteredCommandHistory, + (newIndex) => { this._filteredHistoryIndex = newIndex } + ); + } + + return this._navigateHistory( + direction, + this._historyIndex, + this._commandHistory, + (newIndex) => { this._historyIndex = newIndex } + ); + } + + private _navigateHistory ( + direction: HistoryDirection, + currentIndex: number, + history: string[], + updateIndex: (newIndex: number) => void + ): boolean { + const isAtEnd = currentIndex === history.length; + const isAtBeginning = currentIndex === 0; + + if ((direction === HistoryDirection.BACKWARDS && isAtBeginning) || + (direction === HistoryDirection.FORWARDS && isAtEnd)) { return false; } - if (isCurrentlyAtEndOfHistory) { + if (isAtEnd) { this._lastKnownCurrentLine = this._stripCurrentPrompt(this._currentPromptLine); } - this._historyIndex += direction === HistoryDirection.BACKWARDS ? -1 : 1; - return this._replaceCurrentLineWithNewLine(this._currentPrompt + this._getHistoryItem(this._historyIndex)); + currentIndex += direction === HistoryDirection.BACKWARDS ? -1 : 1; + updateIndex(currentIndex); + const line = (currentIndex < history.length) + ? history[currentIndex] + : this._lastKnownCurrentLine; + return this._replaceCurrentLineWithNewLine(this._currentPrompt + line); } private _markCurrentLineChanged (): void { this._historyIndex = this._commandHistory.length; + this._filteredCommandHistory = []; this._lastKnownCurrentLine = ''; } @@ -589,14 +629,6 @@ export default class CommandWindow implements vscode.Pseudoterminal { this._historyIndex = this._commandHistory.length; } - private _getHistoryItem (n: number): string { - if (this._historyIndex < this._commandHistory.length) { - return this._commandHistory[n]; - } else { - return this._lastKnownCurrentLine; - } - } - private _moveCursorToCurrent (lineOfInputCursorIsCurrentlyOn?: number): void { const lineNumberCursorShouldBeOn = Math.max(1, Math.ceil(this._getAbsoluteIndexOnLine(this._cursorIndex) / this._terminalDimensions.columns)); if (lineOfInputCursorIsCurrentlyOn === undefined) { From 5632f900f9bafea4b607ae7a615970dd5d703b6f Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Sun, 20 Apr 2025 21:21:35 +0100 Subject: [PATCH 2/3] Rename _commandHistory -> _rawCommandHistory --- src/commandwindow/CommandWindow.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/commandwindow/CommandWindow.ts b/src/commandwindow/CommandWindow.ts index 6d837de..98a26f6 100644 --- a/src/commandwindow/CommandWindow.ts +++ b/src/commandwindow/CommandWindow.ts @@ -91,7 +91,7 @@ export default class CommandWindow implements vscode.Pseudoterminal { private _lastOutputLine: string = ''; - private readonly _commandHistory: string[] = []; + private readonly _rawCommandHistory: string[] = []; private _historyIndex: number = 0; private _lastKnownCurrentLine: string = ''; private _filteredCommandHistory: string[] = []; @@ -349,14 +349,14 @@ export default class CommandWindow implements vscode.Pseudoterminal { } private _handleNavigateHistory (direction: HistoryDirection): boolean { - const isCurrentlyAtEndOfHistory = this._historyIndex === this._commandHistory.length; + const isCurrentlyAtEndOfHistory = this._historyIndex === this._rawCommandHistory.length; if (isCurrentlyAtEndOfHistory && this._stripCurrentPrompt(this._currentPromptLine) !== '') { // Only update the filtered history if the current line changes if (this._filteredCommandHistory.length === 0) { this._commandHistoryFilter = this._stripCurrentPrompt(this._currentPromptLine); - this._filteredCommandHistory = this._commandHistory.filter(cmd => + this._filteredCommandHistory = this._rawCommandHistory.filter(cmd => cmd.toLowerCase().startsWith(this._commandHistoryFilter.toLowerCase())); this._filteredHistoryIndex = this._filteredCommandHistory.length; } @@ -373,7 +373,7 @@ export default class CommandWindow implements vscode.Pseudoterminal { return this._navigateHistory( direction, this._historyIndex, - this._commandHistory, + this._rawCommandHistory, (newIndex) => { this._historyIndex = newIndex } ); } @@ -405,7 +405,7 @@ export default class CommandWindow implements vscode.Pseudoterminal { } private _markCurrentLineChanged (): void { - this._historyIndex = this._commandHistory.length; + this._historyIndex = this._rawCommandHistory.length; this._filteredCommandHistory = []; this._lastKnownCurrentLine = ''; } @@ -622,11 +622,11 @@ export default class CommandWindow implements vscode.Pseudoterminal { private _addToHistory (command: string): void { const isEmpty = command === ''; - const isLastInHistory = this._commandHistory.length !== 0 && command === this._commandHistory[this._commandHistory.length - 1]; + const isLastInHistory = this._rawCommandHistory.length !== 0 && command === this._rawCommandHistory[this._rawCommandHistory.length - 1]; if (!isEmpty && !isLastInHistory) { - this._commandHistory.push(command); + this._rawCommandHistory.push(command); } - this._historyIndex = this._commandHistory.length; + this._historyIndex = this._rawCommandHistory.length; } private _moveCursorToCurrent (lineOfInputCursorIsCurrentlyOn?: number): void { From ec0f23e5ab234f972ee4b8344cc6ba7cdc32fe4f Mon Sep 17 00:00:00 2001 From: robertoffmoura Date: Sun, 20 Apr 2025 23:51:42 +0100 Subject: [PATCH 3/3] Always act on filtered history instead of forking logic --- src/commandwindow/CommandWindow.ts | 70 ++++++++++-------------------- 1 file changed, 23 insertions(+), 47 deletions(-) diff --git a/src/commandwindow/CommandWindow.ts b/src/commandwindow/CommandWindow.ts index 98a26f6..0188ada 100644 --- a/src/commandwindow/CommandWindow.ts +++ b/src/commandwindow/CommandWindow.ts @@ -95,8 +95,6 @@ export default class CommandWindow implements vscode.Pseudoterminal { private _historyIndex: number = 0; private _lastKnownCurrentLine: string = ''; private _filteredCommandHistory: string[] = []; - private _filteredHistoryIndex: number = 0; - private _commandHistoryFilter: string = ''; private _terminalDimensions: vscode.TerminalDimensions; private _lastSentTerminalDimensions: vscode.TerminalDimensions | null = null; @@ -349,43 +347,8 @@ export default class CommandWindow implements vscode.Pseudoterminal { } private _handleNavigateHistory (direction: HistoryDirection): boolean { - const isCurrentlyAtEndOfHistory = this._historyIndex === this._rawCommandHistory.length; - - if (isCurrentlyAtEndOfHistory && this._stripCurrentPrompt(this._currentPromptLine) !== '') { - // Only update the filtered history if the current line changes - if (this._filteredCommandHistory.length === 0) { - this._commandHistoryFilter = this._stripCurrentPrompt(this._currentPromptLine); - - this._filteredCommandHistory = this._rawCommandHistory.filter(cmd => - cmd.toLowerCase().startsWith(this._commandHistoryFilter.toLowerCase())); - this._filteredHistoryIndex = this._filteredCommandHistory.length; - } - - // Filter history based on the current prompt text - return this._navigateHistory( - direction, - this._filteredHistoryIndex, - this._filteredCommandHistory, - (newIndex) => { this._filteredHistoryIndex = newIndex } - ); - } - - return this._navigateHistory( - direction, - this._historyIndex, - this._rawCommandHistory, - (newIndex) => { this._historyIndex = newIndex } - ); - } - - private _navigateHistory ( - direction: HistoryDirection, - currentIndex: number, - history: string[], - updateIndex: (newIndex: number) => void - ): boolean { - const isAtEnd = currentIndex === history.length; - const isAtBeginning = currentIndex === 0; + const isAtEnd = this._historyIndex === this._filteredCommandHistory.length; + const isAtBeginning = this._historyIndex === 0; if ((direction === HistoryDirection.BACKWARDS && isAtBeginning) || (direction === HistoryDirection.FORWARDS && isAtEnd)) { @@ -396,17 +359,21 @@ export default class CommandWindow implements vscode.Pseudoterminal { this._lastKnownCurrentLine = this._stripCurrentPrompt(this._currentPromptLine); } - currentIndex += direction === HistoryDirection.BACKWARDS ? -1 : 1; - updateIndex(currentIndex); - const line = (currentIndex < history.length) - ? history[currentIndex] - : this._lastKnownCurrentLine; + this._historyIndex += direction === HistoryDirection.BACKWARDS ? -1 : 1; + const line = this._getHistoryItem(this._historyIndex); return this._replaceCurrentLineWithNewLine(this._currentPrompt + line); } private _markCurrentLineChanged (): void { - this._historyIndex = this._rawCommandHistory.length; - this._filteredCommandHistory = []; + const commandHistoryFilter = this._stripCurrentPrompt(this._currentPromptLine); + if (commandHistoryFilter !== '') { + this._filteredCommandHistory = this._rawCommandHistory.filter(cmd => + cmd.toLowerCase().startsWith(commandHistoryFilter.toLowerCase())); + } else { + this._filteredCommandHistory = this._rawCommandHistory + } + + this._historyIndex = this._filteredCommandHistory.length; this._lastKnownCurrentLine = ''; } @@ -622,11 +589,20 @@ export default class CommandWindow implements vscode.Pseudoterminal { private _addToHistory (command: string): void { const isEmpty = command === ''; - const isLastInHistory = this._rawCommandHistory.length !== 0 && command === this._rawCommandHistory[this._rawCommandHistory.length - 1]; + const isLastInHistory = + this._rawCommandHistory.length !== 0 && + command === this._rawCommandHistory[this._rawCommandHistory.length - 1]; if (!isEmpty && !isLastInHistory) { this._rawCommandHistory.push(command); } this._historyIndex = this._rawCommandHistory.length; + this._filteredCommandHistory = this._rawCommandHistory + } + + private _getHistoryItem (n: number): string { + return (this._historyIndex < this._filteredCommandHistory.length) + ? this._filteredCommandHistory[n] + : this._lastKnownCurrentLine; } private _moveCursorToCurrent (lineOfInputCursorIsCurrentlyOn?: number): void {