Take continuation prompt into account for pwsh

This commit is contained in:
Daniel Imms
2024-04-17 15:49:26 -07:00
parent 3f8d7d13b0
commit 5dde2fba0c
5 changed files with 36 additions and 4 deletions
@@ -178,6 +178,7 @@ export interface ICommandDetectionCapability {
readonly onCommandExecuted: Event<ITerminalCommand>;
readonly onCommandInvalidated: Event<ITerminalCommand[]>;
readonly onCurrentCommandInvalidated: Event<ICommandInvalidationRequest>;
setContinuationPrompt(value: string): void;
setCwd(value: string): void;
setIsWindowsPty(value: boolean): void;
setIsCommandStorageDisabled(): void;
@@ -26,6 +26,8 @@ export interface IPromptInputModel {
readonly value: string;
readonly cursorIndex: number;
setContinuationPrompt(value: string): void;
}
export class PromptInputModel extends Disposable implements IPromptInputModel {
@@ -33,6 +35,7 @@ export class PromptInputModel extends Disposable implements IPromptInputModel {
private _commandStartMarker: IMarker | undefined;
private _commandStartX: number = 0;
private _continuationPrompt: string | undefined;
private _value: string = '';
get value() { return this._value; }
@@ -61,7 +64,10 @@ export class PromptInputModel extends Disposable implements IPromptInputModel {
this._register(onCommandStart(e => this._handleCommandStart(e as { marker: IMarker })));
this._register(onCommandExecuted(() => this._handleCommandExecuted()));
}
setContinuationPrompt(value: string): void {
this._continuationPrompt = value;
}
private _handleCommandStart(command: { marker: IMarker }) {
@@ -116,13 +122,17 @@ export class PromptInputModel extends Disposable implements IPromptInputModel {
// Add multi-lines
const absoluteCursorY = buffer.baseY + buffer.cursorY;
for (let y = commandStartY + 1; y <= absoluteCursorY; y++) {
const text = buffer.getLine(y)?.translateToString(true);
if (text) {
this._value += `\n${text}`;
let lineText = buffer.getLine(y)?.translateToString(true);
if (lineText) {
if (this._continuationPrompt && lineText.startsWith(this._continuationPrompt)) {
lineText = lineText.substring(this._continuationPrompt.length);
}
this._value += `\n${lineText}`;
if (y === absoluteCursorY) {
// TODO: Detect continuation
// For pwsh: (Get-PSReadLineOption).ContinuationPrompt
// TODO: Wide/emoji length support
this._cursorIndex = Math.max(this._value.length - text.length + buffer.cursorX, 0);
this._cursorIndex = Math.max(this._value.length - lineText.length + buffer.cursorX, 0);
}
}
}
@@ -199,6 +199,10 @@ export class CommandDetectionCapability extends Disposable implements ICommandDe
}
}
setContinuationPrompt(value: string): void {
this._promptInputModel.setContinuationPrompt(value);
}
setCwd(value: string) {
this._cwd = value;
}
@@ -160,6 +160,8 @@ const enum VSCodeOscPt {
* - `IsWindows` - Indicates whether the terminal is using a Windows backend like winpty or
* conpty. This may be used to enable additional heuristics as the positioning of the shell
* integration sequences are not guaranteed to be correct. Valid values: `True`, `False`.
* - `ContinuationPrompt` - Reports the continuation prompt that is printed at the start of
* multi-line inputs.
*
* WARNING: Any other properties may be changed and are not guaranteed to work in the future.
*/
@@ -379,6 +381,10 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
return true;
}
switch (key) {
case 'ContinuationPrompt': {
this._updateContinuationPrompt(value);
return true;
}
case 'Cwd': {
this._updateCwd(value);
return true;
@@ -404,6 +410,11 @@ export class ShellIntegrationAddon extends Disposable implements IShellIntegrati
return false;
}
private _updateContinuationPrompt(value: string) {
const commandDetection = this.capabilities.get(TerminalCapability.CommandDetection);
commandDetection?.setContinuationPrompt(value);
}
private _updateCwd(value: string) {
value = sanitizeCwd(value);
this._createOrGetCwdDetection().updateCwd(value);
@@ -135,6 +135,12 @@ else {
[Console]::Write("$([char]0x1b)]633;P;IsWindows=$IsWindows`a")
}
# Set ContinuationPrompt property
$ContinuationPrompt = (Get-PSReadLineOption).ContinuationPrompt
if ($ContinuationPrompt) {
[Console]::Write("$([char]0x1b)]633;P;ContinuationPrompt=$(__VSCode-Escape-Value $ContinuationPrompt)`a")
}
# Set always on key handlers which map to default VS Code keybindings
function Set-MappedKeyHandler {
param ([string[]] $Chord, [string[]]$Sequence)