From 68a3986487a9675b457374e4c76869da566c5f36 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:06:37 -0700 Subject: [PATCH 01/13] Change method of fetching pwsh completions --- .../browser/media/shellIntegration.ps1 | 74 ++++++++++++--- .../suggest/browser/terminalSuggestAddon.ts | 90 +++++++++++++++---- 2 files changed, 135 insertions(+), 29 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index c22f7d64224..41d146b6606 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -174,12 +174,12 @@ function Set-MappedKeyHandlers { } # Suggest trigger characters - Set-PSReadLineKeyHandler -Chord "-" -ScriptBlock { - [Microsoft.PowerShell.PSConsoleReadLine]::Insert("-") - if (!$Global:__VSCodeHaltCompletions) { - Send-Completions - } - } + # Set-PSReadLineKeyHandler -Chord "-" -ScriptBlock { + # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("-") + # if (!$Global:__VSCodeHaltCompletions) { + # Send-Completions + # } + # } Set-PSReadLineKeyHandler -Chord 'F12,y' -ScriptBlock { $Global:__VSCodeHaltCompletions = $true @@ -188,6 +188,13 @@ function Set-MappedKeyHandlers { Set-PSReadLineKeyHandler -Chord 'F12,z' -ScriptBlock { $Global:__VSCodeHaltCompletions = $false } + + # TODO: When does this invalidate? Installing a new module could add new commands + # Commands are expensive to complete and send over, do this ones for the empty string so we + # don't need to do it each time the user requests. + $result = "$([char]0x1b)]633;CompletionsPwshCommands;commands;" + $result += [System.Management.Automation.CompletionCompleters]::CompleteCommand('') | ConvertTo-Json -Compress + Write-Host -NoNewLine $result } } @@ -200,16 +207,59 @@ function Send-Completions { [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$commandLine, [ref]$cursorIndex) $completionPrefix = $commandLine - # Get completions + # Start completions sequence $result = "$([char]0x1b)]633;Completions" + + # Get completions if ($completionPrefix.Length -gt 0) { - # Get and send completions - $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex - if ($null -ne $completions.CompletionMatches) { - $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" - $result += $completions.CompletionMatches | ConvertTo-Json -Compress + # If there is a space in the input, defer to TabExpansion2 as it's more complicated to + # determine valid completions + if ($completionPrefix.Contains(' ')) { + $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex + if ($null -ne $completions.CompletionMatches) { + $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + $result += $completions.CompletionMatches | ConvertTo-Json -Compress + } + } + # If there is no space, get completions using CompletionCompleters as it gives us more + # control and works on the empty string + else { + # $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex + # if ($null -ne $completions.CompletionMatches) { + # $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + # $result += $completions.CompletionMatches | ConvertTo-Json -Compress + # } + # Get and send completions, note that CompleteCommand isn't included here as it's expensive + $completions = $( + ([System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix)); + ([System.Management.Automation.CompletionCompleters]::CompleteVariable($completionPrefix)); + ) + if ($null -ne $completions) { + $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + $result += $completions | ConvertTo-Json -Compress + } else { + $result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]" + } + } + } else { + # TODO: Consolidate this case with the above + # TODO: Try use this approach after the last whitespace for everything so intellisense is always consistent + + # Special case when the prefix is empty since TabExpansion2 doesn't handle it + if ($completionPrefix.Length -eq 0) { + # Get and send completions + $completions = $( + ([System.Management.Automation.CompletionCompleters]::CompleteFilename('')); + ([System.Management.Automation.CompletionCompleters]::CompleteVariable('')); + ) + if ($null -ne $completions) { + $result += ";0;0;0;" + $result += $completions | ConvertTo-Json -Compress + } } } + + # End completions sequence $result += "`a" Write-Host -NoNewLine $result diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index 6117f3ad916..f46bee2e073 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -26,6 +26,7 @@ import { ShellIntegrationOscPs } from 'vs/platform/terminal/common/xterm/shellIn const enum VSCodeOscPt { Completions = 'Completions', + CompletionsPwshCommands = 'CompletionsPwshCommands', CompletionsBash = 'CompletionsBash', CompletionsBashFirstWord = 'CompletionsBashFirstWord' } @@ -135,13 +136,24 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } private _sync(promptInputState: IPromptInputModelState): void { + + if ( + (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) && + (promptInputState.cursorIndex === 1 || promptInputState.value.substring(0, promptInputState.cursorIndex).match(/\s[^\s]$/)) + ) { + // TODO: Debounce? Prevent this flooding the channel + this._onAcceptedCompletion.fire('\x1b[24~e'); + } + this._mostRecentPromptInputState = promptInputState; + // this._onAcceptedCompletion.fire('\x1b[24~e'); if (!this._promptInputModel || !this._terminal || !this._suggestWidget || !this._initialPromptInputState) { return; } this._currentPromptInputState = promptInputState; + // Hide the widget if the cursor moves to the left of the initial position as the // completions are no longer valid if (this._currentPromptInputState.cursorIndex < this._initialPromptInputState.cursorIndex) { @@ -153,6 +165,10 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest const inputBeforeCursor = this._currentPromptInputState.value.substring(0, this._currentPromptInputState.cursorIndex); this._cursorIndexDelta = this._currentPromptInputState.cursorIndex - this._initialPromptInputState.cursorIndex; + console.log('setLineContext', { + inputBeforeCursor, + cursorIndexDelta: this._cursorIndexDelta + }); this._suggestWidget.setLineContext(new LineContext(inputBeforeCursor, this._cursorIndexDelta)); } @@ -191,6 +207,8 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest case VSCodeOscPt.Completions: this._handleCompletionsSequence(this._terminal, data, command, args); return true; + case VSCodeOscPt.CompletionsPwshCommands: + this._handleCompletionsPwshCommandsSequence(this._terminal, data, command, args); case VSCodeOscPt.CompletionsBash: this._handleCompletionsBashSequence(this._terminal, data, command, args); return true; @@ -204,18 +222,25 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest private _handleCompletionsSequence(terminal: Terminal, data: string, command: string, args: string[]): void { // Nothing to handle if the terminal is not attached - if (!terminal.element || !this._enableWidget) { + if (!terminal.element || !this._enableWidget || !this._promptInputModel) { return; } - const replacementIndex = parseInt(args[0]); - const replacementLength = parseInt(args[1]); - if (!args[3]) { - this._onBell.fire(); - return; - } + let replacementIndex = 0; //args.length === 0 ? 0 : parseInt(args[0]); + let replacementLength = this._promptInputModel.cursorIndex; //args.length === 0 ? 0 : parseInt(args[1]); - let completionList: IPwshCompletion[] | IPwshCompletion = JSON.parse(data.slice(command.length + args[0].length + args[1].length + args[2].length + 4/*semi-colons*/)); + console.log({ + replacementIndex, + replacementLength + }); + // TODO: Add bell back? + // if (!args[3]) { + // this._onBell.fire(); + // return; + // } + + const payload = data.slice(command.length + args[0].length + args[1].length + args[2].length + 4/*semi-colons*/); + let completionList: IPwshCompletion[] | IPwshCompletion = args.length === 0 || payload.length === 0 ? [] : JSON.parse(payload); if (!Array.isArray(completionList)) { completionList = [completionList]; } @@ -227,7 +252,23 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest }); }); - this._leadingLineContent = completions[0].completion.label.slice(0, replacementLength); + this._leadingLineContent = this._promptInputModel.value.substring(0, this._promptInputModel.cursorIndex); + + // If there's no space it means this is a command, add cached commands list to completions + if (!this._leadingLineContent.trim().includes(' ')) { + completions.push(...this._cachedPwshCommands); + } else { + replacementIndex = parseInt(args[0]); + replacementLength = parseInt(args[1]); + this._leadingLineContent = completions[0].completion.label.slice(0, replacementLength); + } + + console.log({ + replacementIndex, + replacementLength, + leadingLineContent: this._leadingLineContent + }); + this._cursorIndexDelta = 0; const model = new SimpleCompletionModel(completions, new LineContext(this._leadingLineContent, replacementIndex), replacementIndex, replacementLength); if (completions.length === 1) { @@ -240,6 +281,28 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._handleCompletionModel(model); } + private _cachedPwshCommands: Set = new Set(); + private _handleCompletionsPwshCommandsSequence(terminal: Terminal, data: string, command: string, args: string[]): void { + const type = args[0]; + let completionList: IPwshCompletion[] | IPwshCompletion = JSON.parse(data.slice(command.length + type.length + 2/*semi-colons*/)); + if (!Array.isArray(completionList)) { + completionList = [completionList]; + } + const set = this._cachedPwshCommands; + set.clear(); + + const completions = completionList.map((e: any) => { + return new SimpleCompletionItem({ + label: e.CompletionText, + icon: pwshTypeToIconMap[e.ResultType], + detail: e.ToolTip + }); + }); + for (const c of completions) { + set.add(c); + } + } + // TODO: These aren't persisted across reloads // TODO: Allow triggering anywhere in the first word based on the cached completions private _cachedBashAliases: Set = new Set(); @@ -384,14 +447,7 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest })); this._register(this._suggestWidget.onDidSelect(async e => this.acceptSelectedSuggestion(e))); this._register(this._suggestWidget.onDidHide(() => this._terminalSuggestWidgetVisibleContextKey.set(false))); - this._register(this._suggestWidget.onDidShow(() => { - this._initialPromptInputState = { - value: this._promptInputModel!.value, - cursorIndex: this._promptInputModel!.cursorIndex, - ghostTextIndex: this._promptInputModel!.ghostTextIndex - }; - this._terminalSuggestWidgetVisibleContextKey.set(true); - })); + this._register(this._suggestWidget.onDidShow(() => this._terminalSuggestWidgetVisibleContextKey.set(true))); } return this._suggestWidget; } From 506d3d214e4192b6dfbc9e09543768cc596a3b55 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:09:09 -0700 Subject: [PATCH 02/13] Fix error --- .../terminalContrib/suggest/browser/terminalSuggestAddon.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index f46bee2e073..faa5fcb396f 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -260,7 +260,7 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } else { replacementIndex = parseInt(args[0]); replacementLength = parseInt(args[1]); - this._leadingLineContent = completions[0].completion.label.slice(0, replacementLength); + this._leadingLineContent = completions[0]?.completion.label.slice(0, replacementLength) ?? ''; } console.log({ From e749f4e5f7bce358b7bcbe32b71c181e850dde65 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:16:45 -0700 Subject: [PATCH 03/13] Clean up --- .../browser/media/shellIntegration.ps1 | 91 +++++++++---------- .../suggest/browser/terminalSuggestAddon.ts | 25 +---- 2 files changed, 46 insertions(+), 70 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index 41d146b6606..af837986a78 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -210,54 +210,53 @@ function Send-Completions { # Start completions sequence $result = "$([char]0x1b)]633;Completions" - # Get completions - if ($completionPrefix.Length -gt 0) { - # If there is a space in the input, defer to TabExpansion2 as it's more complicated to - # determine valid completions - if ($completionPrefix.Contains(' ')) { - $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex - if ($null -ne $completions.CompletionMatches) { - $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" - $result += $completions.CompletionMatches | ConvertTo-Json -Compress - } - } - # If there is no space, get completions using CompletionCompleters as it gives us more - # control and works on the empty string - else { - # $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex - # if ($null -ne $completions.CompletionMatches) { - # $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" - # $result += $completions.CompletionMatches | ConvertTo-Json -Compress - # } - # Get and send completions, note that CompleteCommand isn't included here as it's expensive - $completions = $( - ([System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix)); - ([System.Management.Automation.CompletionCompleters]::CompleteVariable($completionPrefix)); - ) - if ($null -ne $completions) { - $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" - $result += $completions | ConvertTo-Json -Compress - } else { - $result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]" - } - } - } else { - # TODO: Consolidate this case with the above - # TODO: Try use this approach after the last whitespace for everything so intellisense is always consistent - - # Special case when the prefix is empty since TabExpansion2 doesn't handle it - if ($completionPrefix.Length -eq 0) { - # Get and send completions - $completions = $( - ([System.Management.Automation.CompletionCompleters]::CompleteFilename('')); - ([System.Management.Automation.CompletionCompleters]::CompleteVariable('')); - ) - if ($null -ne $completions) { - $result += ";0;0;0;" - $result += $completions | ConvertTo-Json -Compress - } + # If there is a space in the input, defer to TabExpansion2 as it's more complicated to + # determine what type of completions to use + if ($completionPrefix.Contains(' ')) { + $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex + if ($null -ne $completions.CompletionMatches) { + $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + $result += $completions.CompletionMatches | ConvertTo-Json -Compress } } + # If there is no space, get completions using CompletionCompleters as it gives us more + # control and works on the empty string + else { + # $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex + # if ($null -ne $completions.CompletionMatches) { + # $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + # $result += $completions.CompletionMatches | ConvertTo-Json -Compress + # } + # Get and send completions, note that CompleteCommand isn't included here as it's expensive + $completions = $( + ([System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix)); + ([System.Management.Automation.CompletionCompleters]::CompleteVariable($completionPrefix)); + ) + this + if ($null -ne $completions) { + $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" + $result += $completions | ConvertTo-Json -Compress + } else { + $result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]" + } + } + # } else { + # # TODO: Consolidate this case with the above + # # TODO: Try use this approach after the last whitespace for everything so intellisense is always consistent + + # # Special case when the prefix is empty since TabExpansion2 doesn't handle it + # if ($completionPrefix.Length -eq 0) { + # # Get and send completions + # $completions = $( + # ([System.Management.Automation.CompletionCompleters]::CompleteFilename('')); + # ([System.Management.Automation.CompletionCompleters]::CompleteVariable('')); + # ) + # if ($null -ne $completions) { + # $result += ";0;0;0;" + # $result += $completions | ConvertTo-Json -Compress + # } + # } + # } # End completions sequence $result += "`a" diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index faa5fcb396f..68e9c6388c9 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -136,11 +136,11 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } private _sync(promptInputState: IPromptInputModelState): void { - if ( (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) && (promptInputState.cursorIndex === 1 || promptInputState.value.substring(0, promptInputState.cursorIndex).match(/\s[^\s]$/)) ) { + // TODO: Allow the user to configure when completions are triggered - this is equivalent to editor.quickSuggestions // TODO: Debounce? Prevent this flooding the channel this._onAcceptedCompletion.fire('\x1b[24~e'); } @@ -229,16 +229,6 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest let replacementIndex = 0; //args.length === 0 ? 0 : parseInt(args[0]); let replacementLength = this._promptInputModel.cursorIndex; //args.length === 0 ? 0 : parseInt(args[1]); - console.log({ - replacementIndex, - replacementLength - }); - // TODO: Add bell back? - // if (!args[3]) { - // this._onBell.fire(); - // return; - // } - const payload = data.slice(command.length + args[0].length + args[1].length + args[2].length + 4/*semi-colons*/); let completionList: IPwshCompletion[] | IPwshCompletion = args.length === 0 || payload.length === 0 ? [] : JSON.parse(payload); if (!Array.isArray(completionList)) { @@ -263,21 +253,8 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._leadingLineContent = completions[0]?.completion.label.slice(0, replacementLength) ?? ''; } - console.log({ - replacementIndex, - replacementLength, - leadingLineContent: this._leadingLineContent - }); - this._cursorIndexDelta = 0; const model = new SimpleCompletionModel(completions, new LineContext(this._leadingLineContent, replacementIndex), replacementIndex, replacementLength); - if (completions.length === 1) { - const insertText = completions[0].completion.label.substring(replacementLength); - if (insertText.length === 0) { - this._onBell.fire(); - return; - } - } this._handleCompletionModel(model); } From 77927bcdec61626961127fa50d711589bc17e2ff Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 09:25:37 -0700 Subject: [PATCH 04/13] Quick suggestions vs trigger chars --- .../browser/media/shellIntegration.ps1 | 13 ++++++++++- .../suggest/browser/terminalSuggestAddon.ts | 23 +++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index af837986a78..303859ab04b 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -180,6 +180,18 @@ function Set-MappedKeyHandlers { # Send-Completions # } # } + # Set-PSReadLineKeyHandler -Chord "\" -ScriptBlock { + # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("\") + # if (!$Global:__VSCodeHaltCompletions) { + # Send-Completions + # } + # } + # Set-PSReadLineKeyHandler -Chord "/" -ScriptBlock { + # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("/") + # if (!$Global:__VSCodeHaltCompletions) { + # Send-Completions + # } + # } Set-PSReadLineKeyHandler -Chord 'F12,y' -ScriptBlock { $Global:__VSCodeHaltCompletions = $true @@ -232,7 +244,6 @@ function Send-Completions { ([System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix)); ([System.Management.Automation.CompletionCompleters]::CompleteVariable($completionPrefix)); ) - this if ($null -ne $completions) { $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" $result += $completions | ConvertTo-Json -Compress diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index 68e9c6388c9..91a6a932dd7 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -136,13 +136,22 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } private _sync(promptInputState: IPromptInputModelState): void { - if ( - (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) && - (promptInputState.cursorIndex === 1 || promptInputState.value.substring(0, promptInputState.cursorIndex).match(/\s[^\s]$/)) - ) { - // TODO: Allow the user to configure when completions are triggered - this is equivalent to editor.quickSuggestions - // TODO: Debounce? Prevent this flooding the channel - this._onAcceptedCompletion.fire('\x1b[24~e'); + if (!this._terminalSuggestWidgetVisibleContextKey.get()) { + // If input has been added + if (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) { + // Quick suggestions + if (promptInputState.cursorIndex === 1 || promptInputState.value.substring(0, promptInputState.cursorIndex).match(/\s[^\s]$/)) { + // TODO: Allow the user to configure when completions are triggered - this is equivalent to editor.quickSuggestions + // TODO: Debounce? Prevent this flooding the channel + this._onAcceptedCompletion.fire('\x1b[24~e'); + } + + // Trigger characters + const lastChar = promptInputState.value.at(promptInputState.cursorIndex - 1); + if (lastChar?.match(/[\\\/\-]/)) { + this._onAcceptedCompletion.fire('\x1b[24~e'); + } + } } this._mostRecentPromptInputState = promptInputState; From 676d4d8492c92c54bc690dedc2832af82e6f063c Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:12:01 -0700 Subject: [PATCH 05/13] Clean up suggestions, move all triggers to client --- .../browser/media/shellIntegration.ps1 | 29 --------------- .../suggest/browser/terminalSuggestAddon.ts | 37 +++++++++---------- 2 files changed, 17 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index 303859ab04b..a7b9c69cfd7 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -157,7 +157,6 @@ function Set-MappedKeyHandler { } } -$Global:__VSCodeHaltCompletions = $false function Set-MappedKeyHandlers { Set-MappedKeyHandler -Chord Ctrl+Spacebar -Sequence 'F12,a' Set-MappedKeyHandler -Chord Alt+Spacebar -Sequence 'F12,b' @@ -173,34 +172,6 @@ function Set-MappedKeyHandlers { Send-Completions } - # Suggest trigger characters - # Set-PSReadLineKeyHandler -Chord "-" -ScriptBlock { - # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("-") - # if (!$Global:__VSCodeHaltCompletions) { - # Send-Completions - # } - # } - # Set-PSReadLineKeyHandler -Chord "\" -ScriptBlock { - # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("\") - # if (!$Global:__VSCodeHaltCompletions) { - # Send-Completions - # } - # } - # Set-PSReadLineKeyHandler -Chord "/" -ScriptBlock { - # [Microsoft.PowerShell.PSConsoleReadLine]::Insert("/") - # if (!$Global:__VSCodeHaltCompletions) { - # Send-Completions - # } - # } - - Set-PSReadLineKeyHandler -Chord 'F12,y' -ScriptBlock { - $Global:__VSCodeHaltCompletions = $true - } - - Set-PSReadLineKeyHandler -Chord 'F12,z' -ScriptBlock { - $Global:__VSCodeHaltCompletions = $false - } - # TODO: When does this invalidate? Installing a new module could add new commands # Commands are expensive to complete and send over, do this ones for the empty string so we # don't need to do it each time the user requests. diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index 91a6a932dd7..ecf1ea09c0e 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -19,10 +19,12 @@ import { activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; import { ISuggestController } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys'; import type { ITerminalAddon, Terminal } from '@xterm/xterm'; + import { getListStyles } from 'vs/platform/theme/browser/defaultStyles'; import { TerminalCapability, type ITerminalCapabilityStore } from 'vs/platform/terminal/common/capabilities/capabilities'; import type { IPromptInputModel, IPromptInputModelState } from 'vs/platform/terminal/common/capabilities/commandDetection/promptInputModel'; import { ShellIntegrationOscPs } from 'vs/platform/terminal/common/xterm/shellIntegrationAddon'; +import type { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'; const enum VSCodeOscPt { Completions = 'Completions', @@ -135,21 +137,26 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._screen = screen; } + private _requestCompletions(): void { + // TODO: Debounce? Prevent this flooding the channel + this._onAcceptedCompletion.fire('\x1b[24~e'); + } + private _sync(promptInputState: IPromptInputModelState): void { if (!this._terminalSuggestWidgetVisibleContextKey.get()) { // If input has been added if (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) { // Quick suggestions if (promptInputState.cursorIndex === 1 || promptInputState.value.substring(0, promptInputState.cursorIndex).match(/\s[^\s]$/)) { - // TODO: Allow the user to configure when completions are triggered - this is equivalent to editor.quickSuggestions - // TODO: Debounce? Prevent this flooding the channel - this._onAcceptedCompletion.fire('\x1b[24~e'); + // TODO: Allow the user to configure terminal quickSuggestions + this._requestCompletions(); } // Trigger characters const lastChar = promptInputState.value.at(promptInputState.cursorIndex - 1); if (lastChar?.match(/[\\\/\-]/)) { - this._onAcceptedCompletion.fire('\x1b[24~e'); + // TODO: Allow the user to configure terminal suggestOnTriggerCharacters + this._requestCompletions(); } } } @@ -173,23 +180,15 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest if (this._terminalSuggestWidgetVisibleContextKey.get()) { const inputBeforeCursor = this._currentPromptInputState.value.substring(0, this._currentPromptInputState.cursorIndex); this._cursorIndexDelta = this._currentPromptInputState.cursorIndex - this._initialPromptInputState.cursorIndex; - - console.log('setLineContext', { - inputBeforeCursor, - cursorIndexDelta: this._cursorIndexDelta - }); this._suggestWidget.setLineContext(new LineContext(inputBeforeCursor, this._cursorIndexDelta)); } // Hide and clear model if there are no more items if (!this._suggestWidget.hasCompletions()) { this.hideSuggestWidget(); - // TODO: Don't request every time; refine completions - // this._onAcceptedCompletion.fire('\x1b[24~e'); return; } - // TODO: Expose on xterm.js const dimensions = this._getTerminalDimensions(); if (!dimensions.width || !dimensions.height) { return; @@ -235,8 +234,8 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest return; } - let replacementIndex = 0; //args.length === 0 ? 0 : parseInt(args[0]); - let replacementLength = this._promptInputModel.cursorIndex; //args.length === 0 ? 0 : parseInt(args[1]); + let replacementIndex = 0; + let replacementLength = this._promptInputModel.cursorIndex; const payload = data.slice(command.length + args[0].length + args[1].length + args[2].length + 4/*semi-colons*/); let completionList: IPwshCompletion[] | IPwshCompletion = args.length === 0 || payload.length === 0 ? [] : JSON.parse(payload); @@ -267,6 +266,7 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._handleCompletionModel(model); } + // TODO: These aren't persisted across reloads private _cachedPwshCommands: Set = new Set(); private _handleCompletionsPwshCommandsSequence(terminal: Terminal, data: string, command: string, args: string[]): void { const type = args[0]; @@ -387,9 +387,10 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } private _getTerminalDimensions(): { width: number; height: number } { + const cssCellDims = (this._terminal as any as { _core: IXtermCore })._core._renderService.dimensions.css.cell; return { - width: (this._terminal as any)._core._renderService.dimensions.css.cell.width, - height: (this._terminal as any)._core._renderService.dimensions.css.cell.height, + width: cssCellDims.width, + height: cssCellDims.height, }; } @@ -481,8 +482,6 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest // Send the completion this._onAcceptedCompletion.fire([ - // Disable suggestions - '\x1b[24~y', // Backspace to remove all additional input '\x7F'.repeat(additionalInput.length), // Backspace to remove left side of completion @@ -491,8 +490,6 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest finalCompletionLeftSide, // Write the completion finalCompletionRightSide, - // Enable suggestions - '\x1b[24~z', ].join('')); this.hideSuggestWidget(); From 6994e3c9c3ad8feda91d87f16c0b4b9a6ff20367 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:13:20 -0700 Subject: [PATCH 06/13] More polish --- .../browser/media/shellIntegration.ps1 | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index a7b9c69cfd7..eafe56abbba 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -184,9 +184,6 @@ function Set-MappedKeyHandlers { function Send-Completions { $commandLine = "" $cursorIndex = 0 - # TODO: Since fuzzy matching exists, should completions be provided only for character after the - # last space and then filter on the client side? That would let you trigger ctrl+space - # anywhere on a word and have full completions available [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$commandLine, [ref]$cursorIndex) $completionPrefix = $commandLine @@ -205,12 +202,7 @@ function Send-Completions { # If there is no space, get completions using CompletionCompleters as it gives us more # control and works on the empty string else { - # $completions = TabExpansion2 -inputScript $completionPrefix -cursorColumn $cursorIndex - # if ($null -ne $completions.CompletionMatches) { - # $result += ";$($completions.ReplacementIndex);$($completions.ReplacementLength);$($cursorIndex);" - # $result += $completions.CompletionMatches | ConvertTo-Json -Compress - # } - # Get and send completions, note that CompleteCommand isn't included here as it's expensive + # Note that CompleteCommand isn't included here as it's expensive $completions = $( ([System.Management.Automation.CompletionCompleters]::CompleteFilename($completionPrefix)); ([System.Management.Automation.CompletionCompleters]::CompleteVariable($completionPrefix)); @@ -222,23 +214,6 @@ function Send-Completions { $result += ";0;$($completionPrefix.Length);$($completionPrefix.Length);[]" } } - # } else { - # # TODO: Consolidate this case with the above - # # TODO: Try use this approach after the last whitespace for everything so intellisense is always consistent - - # # Special case when the prefix is empty since TabExpansion2 doesn't handle it - # if ($completionPrefix.Length -eq 0) { - # # Get and send completions - # $completions = $( - # ([System.Management.Automation.CompletionCompleters]::CompleteFilename('')); - # ([System.Management.Automation.CompletionCompleters]::CompleteVariable('')); - # ) - # if ($null -ne $completions) { - # $result += ";0;0;0;" - # $result += $completions | ConvertTo-Json -Compress - # } - # } - # } # End completions sequence $result += "`a" From 73f9a3d13312ad8089071654704fb7b46bcbf538 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:28:08 -0700 Subject: [PATCH 07/13] Improve comments --- .../contrib/terminal/browser/media/shellIntegration.ps1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index eafe56abbba..b48ccd4d75c 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -172,9 +172,10 @@ function Set-MappedKeyHandlers { Send-Completions } - # TODO: When does this invalidate? Installing a new module could add new commands - # Commands are expensive to complete and send over, do this ones for the empty string so we - # don't need to do it each time the user requests. + # TODO: When does this invalidate? Installing a new module could add new commands. We could expose a command to update? + # Commands are expensive to complete and send over, do this once for the empty string so we + # don't need to do it each time the user requests. Additionally we also want to do filtering + # and ranking on the client side with the full list of results. $result = "$([char]0x1b)]633;CompletionsPwshCommands;commands;" $result += [System.Management.Automation.CompletionCompleters]::CompleteCommand('') | ConvertTo-Json -Compress Write-Host -NoNewLine $result From c5b32bb6e942d451b78239acc2073e383da11ebf Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 10:29:15 -0700 Subject: [PATCH 08/13] Add another idea --- .../contrib/terminal/browser/media/shellIntegration.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 index b48ccd4d75c..f2f50c46717 100644 --- a/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 +++ b/src/vs/workbench/contrib/terminal/browser/media/shellIntegration.ps1 @@ -172,7 +172,7 @@ function Set-MappedKeyHandlers { Send-Completions } - # TODO: When does this invalidate? Installing a new module could add new commands. We could expose a command to update? + # TODO: When does this invalidate? Installing a new module could add new commands. We could expose a command to update? Track `(Get-Module).Count`? # Commands are expensive to complete and send over, do this once for the empty string so we # don't need to do it each time the user requests. Additionally we also want to do filtering # and ranking on the client side with the full list of results. From 7a91d684b364dc6635b73916099dde0aa676593a Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:09:56 -0700 Subject: [PATCH 09/13] Don't register on already disposed objects --- src/vs/workbench/contrib/terminal/browser/terminalInstance.ts | 3 +++ .../stickyScroll/browser/terminalStickyScrollOverlay.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index 97f735e675c..a53fb826303 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -1452,6 +1452,9 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } } }); + if (this.isDisposed) { + return; + } if (this.xterm?.shellIntegration) { this.capabilities.add(this.xterm.shellIntegration.capabilities); } diff --git a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts index eac420466bb..82bf0918221 100644 --- a/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts +++ b/src/vs/workbench/contrib/terminalContrib/stickyScroll/browser/terminalStickyScrollOverlay.ts @@ -119,6 +119,9 @@ export class TerminalStickyScrollOverlay extends Disposable { })); this._getSerializeAddonConstructor().then(SerializeAddon => { + if (this._store.isDisposed) { + return; + } this._serializeAddon = this._register(new SerializeAddon()); this._xterm.raw.loadAddon(this._serializeAddon); // Trigger a render as the serialize addon is required to render From d308e233405bf8d6e3c8e1135d1f1a8e0252a65e Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:18:41 -0700 Subject: [PATCH 10/13] Disable suggest unless pwsh --- src/vs/workbench/contrib/terminal/common/terminal.ts | 1 + .../suggest/browser/terminal.suggest.contribution.ts | 6 +++++- .../suggest/browser/terminalSuggestAddon.ts | 11 ++++++++--- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index a2c8e2a804e..71de8f0cceb 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -202,6 +202,7 @@ export interface ITerminalConfiguration { shellIntegration?: { enabled: boolean; decorationsEnabled: boolean; + suggestEnabled: boolean; }; enableImages: boolean; smoothScrolling: boolean; diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts index 512373ba4a2..73821b548f0 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts @@ -19,7 +19,7 @@ import { localize2 } from 'vs/nls'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode } from 'vs/base/common/keyCodes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { PosixShellType, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; class TerminalSuggestContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.suggest'; @@ -48,6 +48,10 @@ class TerminalSuggestContribution extends DisposableStore implements ITerminalCo } xtermOpen(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { + // While pwsh is the only supported shell, disable completely when not pwsh + if (this._instance.shellType !== 'pwsh') { + return; + } this._loadSuggestAddon(xterm.raw); this.add(this._contextKeyService.onDidChangeContext(e => { if (e.affectsSome(this._terminalSuggestWidgetContextKeys)) { diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index ecf1ea09c0e..b8af40c5e61 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -16,7 +16,7 @@ import { IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { activeContrastBorder } from 'vs/platform/theme/common/colorRegistry'; -import { ISuggestController } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { ISuggestController, ITerminalConfigurationService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys'; import type { ITerminalAddon, Terminal } from '@xterm/xterm'; @@ -99,7 +99,8 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest constructor( private readonly _capabilities: ITerminalCapabilityStore, private readonly _terminalSuggestWidgetVisibleContextKey: IContextKey, - @IInstantiationService private readonly _instantiationService: IInstantiationService + @IInstantiationService private readonly _instantiationService: IInstantiationService, + @ITerminalConfigurationService private readonly _terminalConfigurationService: ITerminalConfigurationService ) { super(); @@ -139,10 +140,15 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest private _requestCompletions(): void { // TODO: Debounce? Prevent this flooding the channel + // if (this._terminal. this._onAcceptedCompletion.fire('\x1b[24~e'); } private _sync(promptInputState: IPromptInputModelState): void { + if (!this._terminalConfigurationService.config.shellIntegration?.suggestEnabled) { + return; + } + if (!this._terminalSuggestWidgetVisibleContextKey.get()) { // If input has been added if (!this._mostRecentPromptInputState || promptInputState.cursorIndex > this._mostRecentPromptInputState.cursorIndex) { @@ -162,7 +168,6 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest } this._mostRecentPromptInputState = promptInputState; - // this._onAcceptedCompletion.fire('\x1b[24~e'); if (!this._promptInputModel || !this._terminal || !this._suggestWidget || !this._initialPromptInputState) { return; } From 2f6030c7046040748d1d5080cfa6508b61a673bf Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:19:13 -0700 Subject: [PATCH 11/13] Remove unused imports --- .../suggest/browser/terminal.suggest.contribution.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts index 73821b548f0..ba8f14ee8f9 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts @@ -19,7 +19,7 @@ import { localize2 } from 'vs/nls'; import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry'; import { KeyCode } from 'vs/base/common/keyCodes'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { PosixShellType, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { TerminalSettingId } from 'vs/platform/terminal/common/terminal'; class TerminalSuggestContribution extends DisposableStore implements ITerminalContribution { static readonly ID = 'terminal.suggest'; From e46f4aeb5f585d4e169960d91d7d7307166d1314 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 27 Apr 2024 07:45:36 -0700 Subject: [PATCH 12/13] Don't disable based on shell type --- .../suggest/browser/terminal.suggest.contribution.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts index ba8f14ee8f9..512373ba4a2 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminal.suggest.contribution.ts @@ -48,10 +48,6 @@ class TerminalSuggestContribution extends DisposableStore implements ITerminalCo } xtermOpen(xterm: IXtermTerminal & { raw: RawXtermTerminal }): void { - // While pwsh is the only supported shell, disable completely when not pwsh - if (this._instance.shellType !== 'pwsh') { - return; - } this._loadSuggestAddon(xterm.raw); this.add(this._contextKeyService.onDidChangeContext(e => { if (e.affectsSome(this._terminalSuggestWidgetContextKeys)) { From de91037b799a300a3ecce94df8a33797c16c1cd8 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Sat, 27 Apr 2024 07:47:11 -0700 Subject: [PATCH 13/13] Increase recorder data limit Fixes #211530 --- src/vs/platform/terminal/common/terminalRecorder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/platform/terminal/common/terminalRecorder.ts b/src/vs/platform/terminal/common/terminalRecorder.ts index d8fcb026948..79a828cc220 100644 --- a/src/vs/platform/terminal/common/terminalRecorder.ts +++ b/src/vs/platform/terminal/common/terminalRecorder.ts @@ -7,7 +7,7 @@ import { IPtyHostProcessReplayEvent } from 'vs/platform/terminal/common/capabili import { ReplayEntry } from 'vs/platform/terminal/common/terminalProcess'; const enum Constants { - MaxRecorderDataSize = 1024 * 1024 // 1MB + MaxRecorderDataSize = 10 * 1024 * 1024 // 10MB } interface RecorderEntry {