From 6d62f80a54a267619a86c9457d3c9bc2b232592f Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 14:48:27 -0700 Subject: [PATCH 01/19] refactor(vscode): disable noUnusedLocals and update build script. Extract InlineEditController --- clients/vscode/package.json | 2 +- clients/vscode/src/Commands.ts | 139 +-------------------- clients/vscode/src/extension.ts | 4 +- clients/vscode/src/inline-edit/index.ts | 156 ++++++++++++++++++++++++ clients/vscode/tsconfig.json | 2 +- 5 files changed, 163 insertions(+), 140 deletions(-) create mode 100644 clients/vscode/src/inline-edit/index.ts diff --git a/clients/vscode/package.json b/clients/vscode/package.json index dafc150ce0a7..e9c21fd69229 100644 --- a/clients/vscode/package.json +++ b/clients/vscode/package.json @@ -423,7 +423,7 @@ } }, "scripts": { - "build": "tsc --noEmit && tsup --minify", + "build": "tsc --noUnusedLocals --noEmit && tsup --minify", "watch": "tsc-watch --noEmit --onSuccess \"tsup\"", "dev": "code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", "dev:browser": "vscode-test-web --extensionDevelopmentPath=$PWD --browserType=chromium --port=3000 && pnpm watch", diff --git a/clients/vscode/src/Commands.ts b/clients/vscode/src/Commands.ts index 5438d2b638e0..60d1007fd0bc 100644 --- a/clients/vscode/src/Commands.ts +++ b/clients/vscode/src/Commands.ts @@ -6,19 +6,15 @@ import { ExtensionContext, CancellationTokenSource, Uri, - Position, - Selection, Disposable, InputBoxValidationSeverity, ProgressLocation, ThemeIcon, QuickPickItem, - QuickPickItemKind, } from "vscode"; import os from "os"; import path from "path"; import { strict as assert } from "assert"; -import { ChatEditCommand } from "tabby-agent"; import { Client } from "./lsp/Client"; import { Config, PastServerConfig } from "./Config"; import { ContextVariables } from "./ContextVariables"; @@ -28,6 +24,7 @@ import { GitProvider, Repository } from "./git/GitProvider"; import CommandPalette from "./CommandPalette"; import { showOutputPanel } from "./logger"; import { Issues } from "./Issues"; +import { InlineEditController } from "./inline-edit"; export class Commands { private chatEditCancellationTokenSource: CancellationTokenSource | null = null; @@ -290,7 +287,7 @@ export class Commands { if (!editor) { return; } - const startPosition = new Position(editor.selection.start.line, 0); + const editLocation = { uri: editor.document.uri.toString(), range: { @@ -301,138 +298,8 @@ export class Commands { }, }, }; - //ensure max length - const recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); - const suggestedCommand: ChatEditCommand[] = []; - const quickPick = window.createQuickPick(); - - const updateQuickPickList = () => { - const input = quickPick.value; - const list: (QuickPickItem & { value: string })[] = []; - list.push( - ...suggestedCommand.map((item) => ({ - label: item.label, - value: item.command, - iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), - description: item.source === "preset" ? item.command : "Suggested", - })), - ); - if (list.length > 0) { - list.push({ - label: "", - value: "", - kind: QuickPickItemKind.Separator, - alwaysShow: true, - }); - } - const recentlyCommandToAdd = recentlyCommand.filter((item) => !list.find((i) => i.value === item)); - list.push( - ...recentlyCommandToAdd.map((item) => ({ - label: item, - value: item, - iconPath: new ThemeIcon("history"), - description: "History", - buttons: [ - { - iconPath: new ThemeIcon("edit"), - }, - { - iconPath: new ThemeIcon("settings-remove"), - }, - ], - })), - ); - if (input.length > 0 && !list.find((i) => i.value === input)) { - list.unshift({ - label: input, - value: input, - iconPath: new ThemeIcon("run"), - description: "", - alwaysShow: true, - }); - } - quickPick.items = list; - }; - - const fetchingSuggestedCommandCancellationTokenSource = new CancellationTokenSource(); - this.client.chat.provideEditCommands( - { location: editLocation }, - { commands: suggestedCommand, callback: () => updateQuickPickList() }, - fetchingSuggestedCommandCancellationTokenSource.token, - ); - quickPick.placeholder = "Enter the command for editing"; - quickPick.matchOnDescription = true; - quickPick.onDidChangeValue(() => updateQuickPickList()); - quickPick.onDidHide(() => { - fetchingSuggestedCommandCancellationTokenSource.cancel(); - }); - quickPick.onDidAccept(() => { - quickPick.hide(); - const command = quickPick.selectedItems[0]?.value; - if (command) { - const updatedRecentlyCommand = [command] - .concat(recentlyCommand.filter((item) => item !== command)) - .slice(0, this.config.maxChatEditHistory); - this.config.chatEditRecentlyCommand = updatedRecentlyCommand; - - window.withProgress( - { - location: ProgressLocation.Notification, - title: "Editing in progress...", - cancellable: true, - }, - async (_, token) => { - editor.selection = new Selection(startPosition, startPosition); - this.contextVariables.chatEditInProgress = true; - if (token.isCancellationRequested) { - return; - } - this.chatEditCancellationTokenSource = new CancellationTokenSource(); - token.onCancellationRequested(() => { - this.chatEditCancellationTokenSource?.cancel(); - }); - try { - await this.client.chat.provideEdit( - { - location: editLocation, - command, - format: "previewChanges", - }, - this.chatEditCancellationTokenSource.token, - ); - } catch (error) { - if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { - window.showErrorMessage(error["message"]); - } - } - this.chatEditCancellationTokenSource.dispose(); - this.chatEditCancellationTokenSource = null; - this.contextVariables.chatEditInProgress = false; - editor.selection = new Selection(startPosition, startPosition); - }, - ); - } - }); - - quickPick.onDidTriggerItemButton((event) => { - const item = event.item; - const button = event.button; - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { - const index = recentlyCommand.indexOf(item.value); - if (index !== -1) { - recentlyCommand.splice(index, 1); - this.config.chatEditRecentlyCommand = recentlyCommand; - updateQuickPickList(); - } - } - - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { - quickPick.value = item.value; - } - }); - - quickPick.show(); + new InlineEditController(this.client, this.config, this.contextVariables, editor, editLocation ) }, "chat.edit.stop": async () => { this.chatEditCancellationTokenSource?.cancel(); diff --git a/clients/vscode/src/extension.ts b/clients/vscode/src/extension.ts index 52a99a6c7de0..6b61996c5196 100644 --- a/clients/vscode/src/extension.ts +++ b/clients/vscode/src/extension.ts @@ -88,9 +88,9 @@ export async function activate(context: ExtensionContext) { const issues = new Issues(client, config); const contextVariables = new ContextVariables(client, config); - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ /* @ts-expect-error noUnusedLocals */ + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ // @ts-ignore noUnusedLocals const statusBarItem = new StatusBarItem(context, client, config, issues, inlineCompletionProvider); - /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ /* @ts-expect-error noUnusedLocals */ + /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ // @ts-ignore noUnusedLocals const commands = new Commands( context, client, diff --git a/clients/vscode/src/inline-edit/index.ts b/clients/vscode/src/inline-edit/index.ts new file mode 100644 index 000000000000..652d8848b90f --- /dev/null +++ b/clients/vscode/src/inline-edit/index.ts @@ -0,0 +1,156 @@ +import { ChatEditCommand } from "tabby-agent"; +import { Config } from "../Config"; +import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, ProgressLocation, TextEditor, Selection, Position } from "vscode"; +import { Client } from "../lsp/Client"; +import { ContextVariables } from "../ContextVariables"; + +export class InlineEditController { + private chatEditCancellationTokenSource: CancellationTokenSource | null = null; + + constructor(private client: Client, private config: Config, + private contextVariables: ContextVariables, + editor: TextEditor, + editLocation: EditLocation) { + const recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); + const suggestedCommand: ChatEditCommand[] = []; + const quickPick = window.createQuickPick(); + + const updateQuickPickList = () => { + const input = quickPick.value; + const list: (QuickPickItem & { value: string })[] = []; + list.push( + ...suggestedCommand.map((item) => ({ + label: item.label, + value: item.command, + iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), + description: item.source === "preset" ? item.command : "Suggested", + })), + ); + if (list.length > 0) { + list.push({ + label: "", + value: "", + kind: QuickPickItemKind.Separator, + alwaysShow: true, + }); + } + const recentlyCommandToAdd = recentlyCommand.filter((item) => !list.find((i) => i.value === item)); + list.push( + ...recentlyCommandToAdd.map((item) => ({ + label: item, + value: item, + iconPath: new ThemeIcon("history"), + description: "History", + buttons: [ + { + iconPath: new ThemeIcon("edit"), + }, + { + iconPath: new ThemeIcon("settings-remove"), + }, + ], + })), + ); + if (input.length > 0 && !list.find((i) => i.value === input)) { + list.unshift({ + label: input, + value: input, + iconPath: new ThemeIcon("run"), + description: "", + alwaysShow: true, + }); + } + quickPick.items = list; + }; + + const fetchingSuggestedCommandCancellationTokenSource = new CancellationTokenSource(); + this.client.chat.provideEditCommands( + { location: editLocation }, + { commands: suggestedCommand, callback: () => updateQuickPickList() }, + fetchingSuggestedCommandCancellationTokenSource.token, + ); + + quickPick.placeholder = "Enter the command for editing"; + quickPick.matchOnDescription = true; + quickPick.onDidChangeValue(() => updateQuickPickList()); + quickPick.onDidHide(() => { + fetchingSuggestedCommandCancellationTokenSource.cancel(); + }); + + const startPosition = new Position(editLocation.range.start.line, editLocation.range.start.character); + quickPick.onDidAccept(() => { + quickPick.hide(); + const command = quickPick.selectedItems[0]?.value; + if (command) { + const updatedRecentlyCommand = [command] + .concat(recentlyCommand.filter((item) => item !== command)) + .slice(0, this.config.maxChatEditHistory); + this.config.chatEditRecentlyCommand = updatedRecentlyCommand; + + window.withProgress( + { + location: ProgressLocation.Notification, + title: "Editing in progress...", + cancellable: true, + }, + async (_, token) => { + editor.selection = new Selection(startPosition, startPosition); + this.contextVariables.chatEditInProgress = true; + if (token.isCancellationRequested) { + return; + } + this.chatEditCancellationTokenSource = new CancellationTokenSource(); + token.onCancellationRequested(() => { + this.chatEditCancellationTokenSource?.cancel(); + }); + try { + await this.client.chat.provideEdit( + { + location: editLocation, + command, + format: "previewChanges", + }, + this.chatEditCancellationTokenSource.token, + ); + } catch (error) { + if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { + window.showErrorMessage(error["message"]); + } + } + this.chatEditCancellationTokenSource.dispose(); + this.chatEditCancellationTokenSource = null; + this.contextVariables.chatEditInProgress = false; + editor.selection = new Selection(startPosition, startPosition); + }, + ); + } + }); + + quickPick.onDidTriggerItemButton((event) => { + const item = event.item; + const button = event.button; + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { + const index = recentlyCommand.indexOf(item.value); + if (index !== -1) { + recentlyCommand.splice(index, 1); + this.config.chatEditRecentlyCommand = recentlyCommand; + updateQuickPickList(); + } + } + + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { + quickPick.value = item.value; + } + }); + + quickPick.show(); + } +} + +interface EditLocation { + uri: string; + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }; +} \ No newline at end of file diff --git a/clients/vscode/tsconfig.json b/clients/vscode/tsconfig.json index 920eb6ef63ec..1a8f1d42a252 100644 --- a/clients/vscode/tsconfig.json +++ b/clients/vscode/tsconfig.json @@ -9,7 +9,7 @@ "noFallthroughCasesInSwitch": true, "noPropertyAccessFromIndexSignature": true, "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, + "noUnusedLocals": false, "noUnusedParameters": true, "allowSyntheticDefaultImports": true }, From e3e19764d5ab9588b393c49cf144a092b5f8dbe9 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 15:02:35 -0700 Subject: [PATCH 02/19] refactor(inline-edit): reorganize InlineChatEdit --- clients/vscode/src/Commands.ts | 3 +- clients/vscode/src/inline-edit/index.ts | 252 +++++++++++++----------- 2 files changed, 136 insertions(+), 119 deletions(-) diff --git a/clients/vscode/src/Commands.ts b/clients/vscode/src/Commands.ts index 60d1007fd0bc..af76ffe8416b 100644 --- a/clients/vscode/src/Commands.ts +++ b/clients/vscode/src/Commands.ts @@ -299,7 +299,8 @@ export class Commands { }, }; - new InlineEditController(this.client, this.config, this.contextVariables, editor, editLocation ) + const inlineEditController = new InlineEditController(this.client, this.config, this.contextVariables, editor, editLocation ); + inlineEditController.start() }, "chat.edit.stop": async () => { this.chatEditCancellationTokenSource?.cancel(); diff --git a/clients/vscode/src/inline-edit/index.ts b/clients/vscode/src/inline-edit/index.ts index 652d8848b90f..97830dc6df25 100644 --- a/clients/vscode/src/inline-edit/index.ts +++ b/clients/vscode/src/inline-edit/index.ts @@ -1,150 +1,166 @@ import { ChatEditCommand } from "tabby-agent"; import { Config } from "../Config"; -import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, ProgressLocation, TextEditor, Selection, Position } from "vscode"; +import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, ProgressLocation, TextEditor, Selection, Position, QuickPick, QuickPickItemButtonEvent } from "vscode"; import { Client } from "../lsp/Client"; import { ContextVariables } from "../ContextVariables"; export class InlineEditController { private chatEditCancellationTokenSource: CancellationTokenSource | null = null; + private quickPick: QuickPick; + + private recentlyCommand: string[] = []; + private suggestedCommand: ChatEditCommand[] = []; constructor(private client: Client, private config: Config, private contextVariables: ContextVariables, - editor: TextEditor, - editLocation: EditLocation) { - const recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); - const suggestedCommand: ChatEditCommand[] = []; - const quickPick = window.createQuickPick(); - - const updateQuickPickList = () => { - const input = quickPick.value; - const list: (QuickPickItem & { value: string })[] = []; - list.push( - ...suggestedCommand.map((item) => ({ - label: item.label, - value: item.command, - iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), - description: item.source === "preset" ? item.command : "Suggested", - })), - ); - if (list.length > 0) { - list.push({ - label: "", - value: "", - kind: QuickPickItemKind.Separator, - alwaysShow: true, - }); - } - const recentlyCommandToAdd = recentlyCommand.filter((item) => !list.find((i) => i.value === item)); - list.push( - ...recentlyCommandToAdd.map((item) => ({ - label: item, - value: item, - iconPath: new ThemeIcon("history"), - description: "History", - buttons: [ - { - iconPath: new ThemeIcon("edit"), - }, - { - iconPath: new ThemeIcon("settings-remove"), - }, - ], - })), - ); - if (input.length > 0 && !list.find((i) => i.value === input)) { - list.unshift({ - label: input, - value: input, - iconPath: new ThemeIcon("run"), - description: "", - alwaysShow: true, - }); - } - quickPick.items = list; - }; + private editor: TextEditor, + private editLocation: EditLocation) { + this.recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); const fetchingSuggestedCommandCancellationTokenSource = new CancellationTokenSource(); this.client.chat.provideEditCommands( { location: editLocation }, - { commands: suggestedCommand, callback: () => updateQuickPickList() }, + { commands: this.suggestedCommand, callback: () => this.updateQuickPickList() }, fetchingSuggestedCommandCancellationTokenSource.token, ); + const quickPick = window.createQuickPick(); quickPick.placeholder = "Enter the command for editing"; quickPick.matchOnDescription = true; - quickPick.onDidChangeValue(() => updateQuickPickList()); + quickPick.onDidChangeValue(() => this.updateQuickPickList()); quickPick.onDidHide(() => { fetchingSuggestedCommandCancellationTokenSource.cancel(); }); + quickPick.onDidAccept(this.onDidAccept, this); + quickPick.onDidTriggerItemButton(this.onDidTriggerItemButton, this); - const startPosition = new Position(editLocation.range.start.line, editLocation.range.start.character); - quickPick.onDidAccept(() => { - quickPick.hide(); - const command = quickPick.selectedItems[0]?.value; - if (command) { - const updatedRecentlyCommand = [command] - .concat(recentlyCommand.filter((item) => item !== command)) - .slice(0, this.config.maxChatEditHistory); - this.config.chatEditRecentlyCommand = updatedRecentlyCommand; - - window.withProgress( - { - location: ProgressLocation.Notification, - title: "Editing in progress...", - cancellable: true, - }, - async (_, token) => { - editor.selection = new Selection(startPosition, startPosition); - this.contextVariables.chatEditInProgress = true; - if (token.isCancellationRequested) { - return; - } - this.chatEditCancellationTokenSource = new CancellationTokenSource(); - token.onCancellationRequested(() => { - this.chatEditCancellationTokenSource?.cancel(); - }); - try { - await this.client.chat.provideEdit( - { - location: editLocation, - command, - format: "previewChanges", - }, - this.chatEditCancellationTokenSource.token, - ); - } catch (error) { - if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { - window.showErrorMessage(error["message"]); - } + this.quickPick = quickPick; + } + + start() { + this.quickPick.show() + } + + private onDidAccept() { + const startPosition = new Position(this.editLocation.range.start.line, this.editLocation.range.start.character); + const quickPick = this.quickPick; + quickPick.hide(); + + const command = quickPick.selectedItems[0]?.value; + if (command) { + const updatedRecentlyCommand = [command] + .concat(this.recentlyCommand.filter((item) => item !== command)) + .slice(0, this.config.maxChatEditHistory); + this.config.chatEditRecentlyCommand = updatedRecentlyCommand; + + window.withProgress( + { + location: ProgressLocation.Notification, + title: "Editing in progress...", + cancellable: true, + }, + async (_, token) => { + this.editor.selection = new Selection(startPosition, startPosition); + this.contextVariables.chatEditInProgress = true; + if (token.isCancellationRequested) { + return; + } + this.chatEditCancellationTokenSource = new CancellationTokenSource(); + token.onCancellationRequested(() => { + this.chatEditCancellationTokenSource?.cancel(); + }); + try { + await this.client.chat.provideEdit( + { + location: this.editLocation, + command, + format: "previewChanges", + }, + this.chatEditCancellationTokenSource.token, + ); + } catch (error) { + if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { + window.showErrorMessage(error["message"]); } - this.chatEditCancellationTokenSource.dispose(); - this.chatEditCancellationTokenSource = null; - this.contextVariables.chatEditInProgress = false; - editor.selection = new Selection(startPosition, startPosition); - }, - ); - } - }); + } + this.chatEditCancellationTokenSource.dispose(); + this.chatEditCancellationTokenSource = null; + this.contextVariables.chatEditInProgress = false; + this.editor.selection = new Selection(startPosition, startPosition); + }, + ); + } - quickPick.onDidTriggerItemButton((event) => { - const item = event.item; - const button = event.button; - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { - const index = recentlyCommand.indexOf(item.value); - if (index !== -1) { - recentlyCommand.splice(index, 1); - this.config.chatEditRecentlyCommand = recentlyCommand; - updateQuickPickList(); - } - } + } - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { - quickPick.value = item.value; + private onDidTriggerItemButton(event: QuickPickItemButtonEvent) { + const item = event.item; + const button = event.button; + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { + const index = this.recentlyCommand.indexOf(item.value); + if (index !== -1) { + this.recentlyCommand.splice(index, 1); + this.config.chatEditRecentlyCommand = this.recentlyCommand; + this.updateQuickPickList(); } - }); + } - quickPick.show(); + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { + this.quickPick.value = item.value; + } } + + private updateQuickPickList() { + const input = this.quickPick.value; + const list: (QuickPickItem & { value: string })[] = []; + list.push( + ...this.suggestedCommand.map((item) => ({ + label: item.label, + value: item.command, + iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), + description: item.source === "preset" ? item.command : "Suggested", + })), + ); + if (list.length > 0) { + list.push({ + label: "", + value: "", + kind: QuickPickItemKind.Separator, + alwaysShow: true, + }); + } + const recentlyCommandToAdd = this.recentlyCommand.filter((item) => !list.find((i) => i.value === item)); + list.push( + ...recentlyCommandToAdd.map((item) => ({ + label: item, + value: item, + iconPath: new ThemeIcon("history"), + description: "History", + buttons: [ + { + iconPath: new ThemeIcon("edit"), + }, + { + iconPath: new ThemeIcon("settings-remove"), + }, + ], + })), + ); + if (input.length > 0 && !list.find((i) => i.value === input)) { + list.unshift({ + label: input, + value: input, + iconPath: new ThemeIcon("run"), + description: "", + alwaysShow: true, + }); + } + this.quickPick.items = list; + }; +} + +interface EditCommand extends QuickPickItem { + value: string } interface EditLocation { From 4dcf11de274e905364c3130da9ea9f4727b34cec Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 15:41:55 -0700 Subject: [PATCH 03/19] restructure tsconfig.json --- clients/vscode/package.json | 2 +- clients/vscode/tsconfig.build.json | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 clients/vscode/tsconfig.build.json diff --git a/clients/vscode/package.json b/clients/vscode/package.json index e9c21fd69229..26483e5a25cf 100644 --- a/clients/vscode/package.json +++ b/clients/vscode/package.json @@ -423,7 +423,7 @@ } }, "scripts": { - "build": "tsc --noUnusedLocals --noEmit && tsup --minify", + "build": "tsc -p ./tsconfig.build.json --noEmit && tsup --minify", "watch": "tsc-watch --noEmit --onSuccess \"tsup\"", "dev": "code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", "dev:browser": "vscode-test-web --extensionDevelopmentPath=$PWD --browserType=chromium --port=3000 && pnpm watch", diff --git a/clients/vscode/tsconfig.build.json b/clients/vscode/tsconfig.build.json new file mode 100644 index 000000000000..21597ab21190 --- /dev/null +++ b/clients/vscode/tsconfig.build.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noUnusedLocals": true, + } +} From b67c4aa0bde81cc612558cda38b402f599f1148a Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 16:12:36 -0700 Subject: [PATCH 04/19] build(clients/tabby-agent): update watch script to modify dist/protocol.d.ts on success, to help trigger watch mode of vscode extension --- clients/tabby-agent/package.json | 3 ++- clients/vscode/package.json | 3 ++- package.json | 1 + turbo.json | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clients/tabby-agent/package.json b/clients/tabby-agent/package.json index 7a8ccb73608d..547dbb04354e 100644 --- a/clients/tabby-agent/package.json +++ b/clients/tabby-agent/package.json @@ -26,7 +26,8 @@ "types": "./dist/protocol.d.ts", "scripts": { "build": "tsup --minify", - "watch": "tsup --watch", + "watch": "tsup --watch --onSuccess \"echo '' >> dist/protocol.d.ts\"", + "vscode:dev": "pnpm watch", "openapi-codegen": "openapi-typescript ./openapi/tabby.json -o ./src/types/tabbyApi.d.ts", "test": "mocha", "lint": "eslint --ext .ts ./src && prettier --check .", diff --git a/clients/vscode/package.json b/clients/vscode/package.json index 26483e5a25cf..ddb76f61cf16 100644 --- a/clients/vscode/package.json +++ b/clients/vscode/package.json @@ -425,7 +425,8 @@ "scripts": { "build": "tsc -p ./tsconfig.build.json --noEmit && tsup --minify", "watch": "tsc-watch --noEmit --onSuccess \"tsup\"", - "dev": "code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", + "dev": "pnpm run watch && code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", + "vscode:dev": "pnpm run dev", "dev:browser": "vscode-test-web --extensionDevelopmentPath=$PWD --browserType=chromium --port=3000 && pnpm watch", "lint": "eslint --ext .ts ./src && prettier --check .", "lint:fix": "eslint --fix --ext .ts ./src && prettier --write .", diff --git a/package.json b/package.json index 9a8af67ce81e..b63299c27ce4 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "private": true, "scripts": { "build": "turbo build", + "vscode:dev": "turbo vscode:dev", "lint": "turbo lint", "lint:fix": "turbo lint:fix", "test": "turbo test" diff --git a/turbo.json b/turbo.json index 6f99ef0066c0..1173dd8708c9 100644 --- a/turbo.json +++ b/turbo.json @@ -14,6 +14,7 @@ }, "lint": {}, "lint:fix": {}, - "test": {} + "test": {}, + "vscode:dev": {} } } \ No newline at end of file From 619cf43999c2ce0f7bfe39e1c814bbaa1917d0da Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 17:50:39 -0700 Subject: [PATCH 05/19] streaming at line break --- clients/tabby-agent/src/lsp/ChatEditProvider.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 3b10cc9ba996..033ed0d24d1d 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -341,8 +341,10 @@ export class ChatEditProvider { const closeTag = inTag === "document" ? responseDocumentTag[1] : responseCommentTag?.[1]; if (!closeTag || !openTag) break; inTag = processBuffer(edit, inTag, openTag, closeTag); - await applyEdit(edit, isFirstEdit, false); - isFirstEdit = false; + if (isFirstEdit || delta.includes("\n")) { + await applyEdit(edit, isFirstEdit, false); + isFirstEdit = false; + } } } From 46c120a67a0e98d3c34f970df8dc55f088edd87f Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 17:50:47 -0700 Subject: [PATCH 06/19] Let CodeLensProvider using footer's markers --- .../tabby-agent/src/lsp/ChatEditProvider.ts | 64 ++++++++++++++----- .../tabby-agent/src/lsp/CodeLensProvider.ts | 36 ++++++----- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 033ed0d24d1d..aef665aae60c 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -23,6 +23,7 @@ import * as Diff from "diff"; import { TabbyAgent } from "../TabbyAgent"; import { isEmptyRange } from "../utils/range"; import { isBlank } from "../utils"; +import { getLogger } from "../logger"; export type Edit = { id: ChatEditToken; @@ -187,21 +188,26 @@ export class ChatEditProvider { if (!document) { return false; } - const header = document.getText({ - start: { - line: params.location.range.start.line, - character: 0, - }, - end: { - line: params.location.range.start.line + 1, - character: 0, - }, - }); - const match = /^<<<<<<<.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(header); - const markers = match?.[1]; - if (!match || !markers) { - return false; + + let markers; + let line = params.location.range.start.line; + for (; line < document.lineCount; line++) { + const lineText = document.getText({ + start: { line, character: 0 }, + end: { line: line + 1, character: 0 }, + }); + + const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(lineText); + markers = match?.[1]; + if (markers) { + break; + } } + + if (!markers) { + return false + } + const previewRange = { start: { line: params.location.range.start.line, @@ -257,6 +263,32 @@ export class ChatEditProvider { responseCommentTag?: string[], ): Promise { const applyEdit = async (edit: Edit, isFirst: boolean = false, isLast: boolean = false) => { + if (isFirst) { + const workspaceEdit: WorkspaceEdit = { + changes: { + [edit.location.uri]: [ + { + range: edit.editedRange, + newText: `<<<<<<< Inline Edit <>[${edit.id}]\n` + }, + ], + }, + }; + + await this.applyWorkspaceEdit({ + edit: workspaceEdit, + options: { + undoStopBefore: isFirst, + undoStopAfter: isLast, + }, + }); + + edit.editedRange = { + start: { line: edit.editedRange.start.line + 1, character: 0 }, + end: { line: edit.editedRange.start.line + 1, character: 0 }, + }; + } + const editedLines = this.generateChangesPreview(edit); const workspaceEdit: WorkspaceEdit = { changes: { @@ -407,7 +439,7 @@ export class ChatEditProvider { } else if (edit.state == "completed") { stateDescription = "Editing completed"; } - lines.push(`<<<<<<< ${stateDescription} {{markers}}[${edit.id}]`); + // lines.push(`<<<<<<< ${stateDescription} {{markers}}[${edit.id}]`); markers += "<"; // comments: split by new line or 80 chars const commentLines = edit.comments @@ -485,7 +517,7 @@ export class ChatEditProvider { lines.push(`>>>>>>> ${stateDescription} {{markers}}[${edit.id}]`); markers += ">"; // replace markers - lines[0] = lines[0]!.replace("{{markers}}", markers); + // lines[0] = lines[0]!.replace("{{markers}}", markers); lines[lines.length - 1] = lines[lines.length - 1]!.replace("{{markers}}", markers); return lines; } diff --git a/clients/tabby-agent/src/lsp/CodeLensProvider.ts b/clients/tabby-agent/src/lsp/CodeLensProvider.ts index 9f09bad12341..a3ea73714e6c 100644 --- a/clients/tabby-agent/src/lsp/CodeLensProvider.ts +++ b/clients/tabby-agent/src/lsp/CodeLensProvider.ts @@ -10,6 +10,7 @@ import { import { ServerCapabilities, CodeLens, CodeLensType, ChangesPreviewLineType } from "./protocol"; import { TextDocuments } from "./TextDocuments"; import { TextDocument } from "vscode-languageserver-textdocument"; +import { getLogger } from "../logger"; const codeLensType: CodeLensType = "previewChanges"; const changesPreviewLineType = { @@ -54,7 +55,7 @@ export class CodeLensProvider { const codeLenses: CodeLens[] = []; let lineInPreviewBlock = -1; let previewBlockMarkers = ""; - for (let line = 0; line < textDocument.lineCount; line++) { + for (let line = textDocument.lineCount - 1; line >= 0; line = line - 1) { if (token.isCancellationRequested) { return null; } @@ -64,15 +65,29 @@ export class CodeLensProvider { start: { line: line, character: 0 }, end: { line: line, character: text.length - 1 }, }; + const codeLensLocation: Location = { uri: uri, range: codeLensRange }; const lineCodeLenses: CodeLens[] = []; if (lineInPreviewBlock < 0) { - const match = /^<<<<<<<.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); + const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); const markers = match?.[1]; const editId = match?.[2]; if (match && markers && editId) { - lineInPreviewBlock = 0; previewBlockMarkers = markers; + lineInPreviewBlock = 0; + lineCodeLenses.push({ + range: codeLensRange, + data: { + type: codeLensType, + line: changesPreviewLineType.footer, + }, + }); + } + } else { + const match = /^<<<<<<<.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); + const editId = match?.[2]; + if (match && editId) { + lineInPreviewBlock = -1; lineCodeLenses.push({ range: codeLensRange, @@ -98,22 +113,9 @@ export class CodeLensProvider { line: changesPreviewLineType.header, }, }); - } - } else { - const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); - const editId = match?.[2]; - if (match && editId) { - lineInPreviewBlock = -1; - lineCodeLenses.push({ - range: codeLensRange, - data: { - type: codeLensType, - line: changesPreviewLineType.footer, - }, - }); } else { lineInPreviewBlock++; - const marker = previewBlockMarkers[lineInPreviewBlock]; + const marker = previewBlockMarkers[previewBlockMarkers.length - lineInPreviewBlock - 1]; let codeLens: CodeLens | undefined = undefined; switch (marker) { case "#": From 4989150c8ae9485c7c3660f85890c8cf03740a04 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 19:14:45 -0700 Subject: [PATCH 07/19] turn off background color of header / footer to avoid flickering --- clients/vscode/src/lsp/CodeLensMiddleware.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index 409cd2db6059..f1f67c529529 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -16,12 +16,12 @@ import { findTextEditor } from "./vscodeWindowUtils"; type CodeLens = VscodeCodeLens & TabbyCodeLens; const decorationTypeHeader = window.createTextEditorDecorationType({ - backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), + // backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, }); const decorationTypeFooter = window.createTextEditorDecorationType({ - backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), + // backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, }); From 2a0fd1624939e3f13fdfaf4302bc74ebeb1af0e6 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:21:36 -0700 Subject: [PATCH 08/19] support cancel from codelens --- .../tabby-agent/src/lsp/ChatEditProvider.ts | 5 ++ .../tabby-agent/src/lsp/CodeLensProvider.ts | 74 +++++++++++++------ clients/tabby-agent/src/lsp/protocol.ts | 2 +- clients/vscode/src/inline-edit/index.ts | 63 ++++++---------- clients/vscode/src/lsp/CodeLensMiddleware.ts | 32 ++++---- 5 files changed, 96 insertions(+), 80 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index aef665aae60c..59036aa8c1dc 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -184,6 +184,11 @@ export class ChatEditProvider { } async resolveEdit(params: ChatEditResolveParams): Promise { + if (params.action === "cancel") { + this.mutexAbortController?.abort(); + return false; + } + const document = this.documents.get(params.location.uri); if (!document) { return false; diff --git a/clients/tabby-agent/src/lsp/CodeLensProvider.ts b/clients/tabby-agent/src/lsp/CodeLensProvider.ts index a3ea73714e6c..b3b97ed50c87 100644 --- a/clients/tabby-agent/src/lsp/CodeLensProvider.ts +++ b/clients/tabby-agent/src/lsp/CodeLensProvider.ts @@ -89,30 +89,56 @@ export class CodeLensProvider { if (match && editId) { lineInPreviewBlock = -1; - lineCodeLenses.push({ - range: codeLensRange, - command: { - title: "Accept", - command: "tabby/chat/edit/resolve", - arguments: [{ location: codeLensLocation, action: "accept" }], - }, - data: { - type: codeLensType, - line: changesPreviewLineType.header, - }, - }); - lineCodeLenses.push({ - range: codeLensRange, - command: { - title: "Discard", - command: "tabby/chat/edit/resolve", - arguments: [{ location: codeLensLocation, action: "discard" }], - }, - data: { - type: codeLensType, - line: changesPreviewLineType.header, - }, - }); + if (previewBlockMarkers.includes(".")) { + lineCodeLenses.push({ + range: codeLensRange, + command: { + title: "$(sync~spin) Tabby is working...", + command: " ", + }, + data: { + type: codeLensType, + line: changesPreviewLineType.header, + }, + }); + lineCodeLenses.push({ + range: codeLensRange, + command: { + title: "Cancel", + command: "tabby/chat/edit/resolve", + arguments: [{ location: codeLensLocation, action: "cancel" }], + }, + data: { + type: codeLensType, + line: changesPreviewLineType.header, + }, + }); + } else { + lineCodeLenses.push({ + range: codeLensRange, + command: { + title: "$(check)Accept", + command: "tabby/chat/edit/resolve", + arguments: [{ location: codeLensLocation, action: "accept" }], + }, + data: { + type: codeLensType, + line: changesPreviewLineType.header, + }, + }); + lineCodeLenses.push({ + range: codeLensRange, + command: { + title: "$(remove-close)Discard", + command: "tabby/chat/edit/resolve", + arguments: [{ location: codeLensLocation, action: "discard" }], + }, + data: { + type: codeLensType, + line: changesPreviewLineType.header, + }, + }); + } } else { lineInPreviewBlock++; const marker = previewBlockMarkers[previewBlockMarkers.length - lineInPreviewBlock - 1]; diff --git a/clients/tabby-agent/src/lsp/protocol.ts b/clients/tabby-agent/src/lsp/protocol.ts index f04b7751b12a..50d5679c6e56 100644 --- a/clients/tabby-agent/src/lsp/protocol.ts +++ b/clients/tabby-agent/src/lsp/protocol.ts @@ -469,7 +469,7 @@ export type ChatEditResolveParams = { /** * The action to take for this edit. */ - action: "accept" | "discard"; + action: "accept" | "discard" | "cancel"; }; /** diff --git a/clients/vscode/src/inline-edit/index.ts b/clients/vscode/src/inline-edit/index.ts index 97830dc6df25..0ffefc463be8 100644 --- a/clients/vscode/src/inline-edit/index.ts +++ b/clients/vscode/src/inline-edit/index.ts @@ -1,6 +1,6 @@ import { ChatEditCommand } from "tabby-agent"; import { Config } from "../Config"; -import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, ProgressLocation, TextEditor, Selection, Position, QuickPick, QuickPickItemButtonEvent } from "vscode"; +import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, TextEditor, Selection, Position, QuickPick, QuickPickItemButtonEvent } from "vscode"; import { Client } from "../lsp/Client"; import { ContextVariables } from "../ContextVariables"; @@ -41,7 +41,7 @@ export class InlineEditController { this.quickPick.show() } - private onDidAccept() { + private async onDidAccept() { const startPosition = new Position(this.editLocation.range.start.line, this.editLocation.range.start.character); const quickPick = this.quickPick; quickPick.hide(); @@ -53,46 +53,31 @@ export class InlineEditController { .slice(0, this.config.maxChatEditHistory); this.config.chatEditRecentlyCommand = updatedRecentlyCommand; - window.withProgress( - { - location: ProgressLocation.Notification, - title: "Editing in progress...", - cancellable: true, - }, - async (_, token) => { - this.editor.selection = new Selection(startPosition, startPosition); - this.contextVariables.chatEditInProgress = true; - if (token.isCancellationRequested) { - return; - } - this.chatEditCancellationTokenSource = new CancellationTokenSource(); - token.onCancellationRequested(() => { - this.chatEditCancellationTokenSource?.cancel(); - }); - try { - await this.client.chat.provideEdit( - { - location: this.editLocation, - command, - format: "previewChanges", - }, - this.chatEditCancellationTokenSource.token, - ); - } catch (error) { - if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { - window.showErrorMessage(error["message"]); - } - } - this.chatEditCancellationTokenSource.dispose(); - this.chatEditCancellationTokenSource = null; - this.contextVariables.chatEditInProgress = false; - this.editor.selection = new Selection(startPosition, startPosition); - }, - ); + this.editor.selection = new Selection(startPosition, startPosition); + this.contextVariables.chatEditInProgress = true; + this.chatEditCancellationTokenSource = new CancellationTokenSource(); + try { + await this.client.chat.provideEdit( + { + location: this.editLocation, + command, + format: "previewChanges", + }, + this.chatEditCancellationTokenSource.token, + ); + } catch (error) { + if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { + window.showErrorMessage(error["message"]); + } + } + this.chatEditCancellationTokenSource.dispose(); + this.chatEditCancellationTokenSource = null; + this.contextVariables.chatEditInProgress = false; + this.editor.selection = new Selection(startPosition, startPosition); } - } + private onDidTriggerItemButton(event: QuickPickItemButtonEvent) { const item = event.item; const button = event.button; diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index f1f67c529529..8c80ba3a68ed 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -33,18 +33,18 @@ const decorationTypeComments = window.createTextEditorDecorationType({ isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedOpen, before: { - contentText: ">", - color: new ThemeColor("editorInlayHint.foreground"), - backgroundColor: new ThemeColor("editorInlayHint.background"), - fontWeight: "bold", - width: "10px", + // contentText: ">", + // color: new ThemeColor("editorInlayHint.foreground"), + // backgroundColor: new ThemeColor("editorInlayHint.background"), + // fontWeight: "bold", + // width: "10px", }, }); const decorationTypeUnchanged = window.createTextEditorDecorationType({ before: { - contentText: "", - fontWeight: "bold", - width: "10px", + // contentText: "", + // fontWeight: "bold", + // width: "10px", }, }); const decorationTypeInserted = window.createTextEditorDecorationType({ @@ -52,10 +52,10 @@ const decorationTypeInserted = window.createTextEditorDecorationType({ isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, before: { - contentText: "+", - backgroundColor: new ThemeColor("diffEditor.insertedTextBackground"), - fontWeight: "bold", - width: "10px", + // contentText: "+", + // backgroundColor: new ThemeColor("diffEditor.insertedTextBackground"), + // fontWeight: "bold", + // width: "10px", }, }); const decorationTypeDeleted = window.createTextEditorDecorationType({ @@ -63,10 +63,10 @@ const decorationTypeDeleted = window.createTextEditorDecorationType({ isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, before: { - contentText: "-", - backgroundColor: new ThemeColor("diffEditor.removedTextBackground"), - fontWeight: "bold", - width: "10px", + // contentText: "-", + // backgroundColor: new ThemeColor("diffEditor.removedTextBackground"), + // fontWeight: "bold", + // width: "10px", }, }); const decorationTypes: Record = { From 88d08e8352b630c0e5d76b9e8d9283c5a5f1ca89 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:35:01 -0700 Subject: [PATCH 09/19] update --- .../tabby-agent/src/lsp/ChatEditProvider.ts | 25 +++++++++++++------ .../tabby-agent/src/lsp/CodeLensProvider.ts | 6 ++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 59036aa8c1dc..c791a75060eb 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -201,7 +201,7 @@ export class ChatEditProvider { start: { line, character: 0 }, end: { line: line + 1, character: 0 }, }); - + const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(lineText); markers = match?.[1]; if (markers) { @@ -274,7 +274,7 @@ export class ChatEditProvider { [edit.location.uri]: [ { range: edit.editedRange, - newText: `<<<<<<< Inline Edit <>[${edit.id}]\n` + newText: `<<<<<<< [${edit.id}]\n` }, ], }, @@ -283,8 +283,8 @@ export class ChatEditProvider { await this.applyWorkspaceEdit({ edit: workspaceEdit, options: { - undoStopBefore: isFirst, - undoStopAfter: isLast, + undoStopBefore: true, + undoStopAfter: false, }, }); @@ -309,7 +309,7 @@ export class ChatEditProvider { await this.applyWorkspaceEdit({ edit: workspaceEdit, options: { - undoStopBefore: isFirst, + undoStopBefore: false, undoStopAfter: isLast, }, }); @@ -432,6 +432,7 @@ export class ChatEditProvider { // [+] inserted // [-] deleted // [>] footer + // [x] stopped // footer line // >>>>>>> End of changes private generateChangesPreview(edit: Edit): string[] { @@ -507,14 +508,22 @@ export class ChatEditProvider { lineIndex++; } if (inProgressChunk && lastDiff) { - pushDiffValue(lastDiff.value, "|"); + if (edit.state === "stopped") { + pushDiffValue(lastDiff.value, "x"); + } else { + pushDiffValue(lastDiff.value, "|"); + } } while (lineIndex < diffs.length - inProgressChunk) { const diff = diffs[lineIndex]; if (!diff) { break; } - pushDiffValue(diff.value, "."); + if (edit.state === "stopped") { + pushDiffValue(diff.value, "x"); + } else { + pushDiffValue(diff.value, "."); + } lineIndex++; } } @@ -562,4 +571,4 @@ export class ChatEditProvider { } return ""; } -} +} \ No newline at end of file diff --git a/clients/tabby-agent/src/lsp/CodeLensProvider.ts b/clients/tabby-agent/src/lsp/CodeLensProvider.ts index b3b97ed50c87..390cad57a09d 100644 --- a/clients/tabby-agent/src/lsp/CodeLensProvider.ts +++ b/clients/tabby-agent/src/lsp/CodeLensProvider.ts @@ -84,8 +84,8 @@ export class CodeLensProvider { }); } } else { - const match = /^<<<<<<<.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); - const editId = match?.[2]; + const match = /^<<<<<<< \[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); + const editId = match?.[1]; if (match && editId) { lineInPreviewBlock = -1; @@ -113,7 +113,7 @@ export class CodeLensProvider { line: changesPreviewLineType.header, }, }); - } else { + } else if (!previewBlockMarkers.includes("x")) { lineCodeLenses.push({ range: codeLensRange, command: { From ad611f3e649c96626967458d45a4458bf104defa Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:40:37 -0700 Subject: [PATCH 10/19] update --- clients/vscode/src/extension.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clients/vscode/src/extension.ts b/clients/vscode/src/extension.ts index 6b61996c5196..9182726cedc3 100644 --- a/clients/vscode/src/extension.ts +++ b/clients/vscode/src/extension.ts @@ -88,8 +88,10 @@ export async function activate(context: ExtensionContext) { const issues = new Issues(client, config); const contextVariables = new ContextVariables(client, config); + /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ /* eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error */ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ // @ts-ignore noUnusedLocals const statusBarItem = new StatusBarItem(context, client, config, issues, inlineCompletionProvider); + /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ /* eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error */ /* eslint-disable-next-line @typescript-eslint/no-unused-vars */ // @ts-ignore noUnusedLocals const commands = new Commands( context, From ada54ba0bdcdaf4b2ea409d5cb28ae41b3eb2538 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:45:02 -0700 Subject: [PATCH 11/19] update --- clients/tabby-agent/src/lsp/ChatEditProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index c791a75060eb..1c215d423140 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -23,7 +23,6 @@ import * as Diff from "diff"; import { TabbyAgent } from "../TabbyAgent"; import { isEmptyRange } from "../utils/range"; import { isBlank } from "../utils"; -import { getLogger } from "../logger"; export type Edit = { id: ChatEditToken; From 1c34e42b08ca5aaef3c4eeee9e83a155aa4df549 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:46:08 -0700 Subject: [PATCH 12/19] update --- clients/tabby-agent/src/lsp/CodeLensProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/tabby-agent/src/lsp/CodeLensProvider.ts b/clients/tabby-agent/src/lsp/CodeLensProvider.ts index 390cad57a09d..69170e7f99df 100644 --- a/clients/tabby-agent/src/lsp/CodeLensProvider.ts +++ b/clients/tabby-agent/src/lsp/CodeLensProvider.ts @@ -10,7 +10,6 @@ import { import { ServerCapabilities, CodeLens, CodeLensType, ChangesPreviewLineType } from "./protocol"; import { TextDocuments } from "./TextDocuments"; import { TextDocument } from "vscode-languageserver-textdocument"; -import { getLogger } from "../logger"; const codeLensType: CodeLensType = "previewChanges"; const changesPreviewLineType = { From d5e0d4857a80435c1bf645fb1791ee9e084ee080 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 28 Aug 2024 03:47:09 +0000 Subject: [PATCH 13/19] [autofix.ci] apply automated fixes --- .../tabby-agent/src/lsp/ChatEditProvider.ts | 6 +- clients/vscode/src/Commands.ts | 10 +- clients/vscode/src/inline-edit/index.ts | 291 +++++++++--------- clients/vscode/tsconfig.build.json | 2 +- 4 files changed, 164 insertions(+), 145 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 1c215d423140..66106441a9fc 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -209,7 +209,7 @@ export class ChatEditProvider { } if (!markers) { - return false + return false; } const previewRange = { @@ -273,7 +273,7 @@ export class ChatEditProvider { [edit.location.uri]: [ { range: edit.editedRange, - newText: `<<<<<<< [${edit.id}]\n` + newText: `<<<<<<< [${edit.id}]\n`, }, ], }, @@ -570,4 +570,4 @@ export class ChatEditProvider { } return ""; } -} \ No newline at end of file +} diff --git a/clients/vscode/src/Commands.ts b/clients/vscode/src/Commands.ts index af76ffe8416b..219f66ec65e5 100644 --- a/clients/vscode/src/Commands.ts +++ b/clients/vscode/src/Commands.ts @@ -299,8 +299,14 @@ export class Commands { }, }; - const inlineEditController = new InlineEditController(this.client, this.config, this.contextVariables, editor, editLocation ); - inlineEditController.start() + const inlineEditController = new InlineEditController( + this.client, + this.config, + this.contextVariables, + editor, + editLocation, + ); + inlineEditController.start(); }, "chat.edit.stop": async () => { this.chatEditCancellationTokenSource?.cancel(); diff --git a/clients/vscode/src/inline-edit/index.ts b/clients/vscode/src/inline-edit/index.ts index 0ffefc463be8..3a06929622f2 100644 --- a/clients/vscode/src/inline-edit/index.ts +++ b/clients/vscode/src/inline-edit/index.ts @@ -1,157 +1,170 @@ import { ChatEditCommand } from "tabby-agent"; import { Config } from "../Config"; -import { CancellationTokenSource, QuickPickItem, ThemeIcon, QuickPickItemKind, window, TextEditor, Selection, Position, QuickPick, QuickPickItemButtonEvent } from "vscode"; +import { + CancellationTokenSource, + QuickPickItem, + ThemeIcon, + QuickPickItemKind, + window, + TextEditor, + Selection, + Position, + QuickPick, + QuickPickItemButtonEvent, +} from "vscode"; import { Client } from "../lsp/Client"; import { ContextVariables } from "../ContextVariables"; export class InlineEditController { - private chatEditCancellationTokenSource: CancellationTokenSource | null = null; - private quickPick: QuickPick; - - private recentlyCommand: string[] = []; - private suggestedCommand: ChatEditCommand[] = []; - - constructor(private client: Client, private config: Config, - private contextVariables: ContextVariables, - private editor: TextEditor, - private editLocation: EditLocation) { - this.recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); - - const fetchingSuggestedCommandCancellationTokenSource = new CancellationTokenSource(); - this.client.chat.provideEditCommands( - { location: editLocation }, - { commands: this.suggestedCommand, callback: () => this.updateQuickPickList() }, - fetchingSuggestedCommandCancellationTokenSource.token, + private chatEditCancellationTokenSource: CancellationTokenSource | null = null; + private quickPick: QuickPick; + + private recentlyCommand: string[] = []; + private suggestedCommand: ChatEditCommand[] = []; + + constructor( + private client: Client, + private config: Config, + private contextVariables: ContextVariables, + private editor: TextEditor, + private editLocation: EditLocation, + ) { + this.recentlyCommand = this.config.chatEditRecentlyCommand.slice(0, this.config.maxChatEditHistory); + + const fetchingSuggestedCommandCancellationTokenSource = new CancellationTokenSource(); + this.client.chat.provideEditCommands( + { location: editLocation }, + { commands: this.suggestedCommand, callback: () => this.updateQuickPickList() }, + fetchingSuggestedCommandCancellationTokenSource.token, + ); + + const quickPick = window.createQuickPick(); + quickPick.placeholder = "Enter the command for editing"; + quickPick.matchOnDescription = true; + quickPick.onDidChangeValue(() => this.updateQuickPickList()); + quickPick.onDidHide(() => { + fetchingSuggestedCommandCancellationTokenSource.cancel(); + }); + quickPick.onDidAccept(this.onDidAccept, this); + quickPick.onDidTriggerItemButton(this.onDidTriggerItemButton, this); + + this.quickPick = quickPick; + } + + start() { + this.quickPick.show(); + } + + private async onDidAccept() { + const startPosition = new Position(this.editLocation.range.start.line, this.editLocation.range.start.character); + const quickPick = this.quickPick; + quickPick.hide(); + + const command = quickPick.selectedItems[0]?.value; + if (command) { + const updatedRecentlyCommand = [command] + .concat(this.recentlyCommand.filter((item) => item !== command)) + .slice(0, this.config.maxChatEditHistory); + this.config.chatEditRecentlyCommand = updatedRecentlyCommand; + + this.editor.selection = new Selection(startPosition, startPosition); + this.contextVariables.chatEditInProgress = true; + this.chatEditCancellationTokenSource = new CancellationTokenSource(); + try { + await this.client.chat.provideEdit( + { + location: this.editLocation, + command, + format: "previewChanges", + }, + this.chatEditCancellationTokenSource.token, ); - - const quickPick = window.createQuickPick(); - quickPick.placeholder = "Enter the command for editing"; - quickPick.matchOnDescription = true; - quickPick.onDidChangeValue(() => this.updateQuickPickList()); - quickPick.onDidHide(() => { - fetchingSuggestedCommandCancellationTokenSource.cancel(); - }); - quickPick.onDidAccept(this.onDidAccept, this); - quickPick.onDidTriggerItemButton(this.onDidTriggerItemButton, this); - - this.quickPick = quickPick; + } catch (error) { + if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { + window.showErrorMessage(error["message"]); + } + } + this.chatEditCancellationTokenSource.dispose(); + this.chatEditCancellationTokenSource = null; + this.contextVariables.chatEditInProgress = false; + this.editor.selection = new Selection(startPosition, startPosition); } - - start() { - this.quickPick.show() + } + + private onDidTriggerItemButton(event: QuickPickItemButtonEvent) { + const item = event.item; + const button = event.button; + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { + const index = this.recentlyCommand.indexOf(item.value); + if (index !== -1) { + this.recentlyCommand.splice(index, 1); + this.config.chatEditRecentlyCommand = this.recentlyCommand; + this.updateQuickPickList(); + } } - private async onDidAccept() { - const startPosition = new Position(this.editLocation.range.start.line, this.editLocation.range.start.character); - const quickPick = this.quickPick; - quickPick.hide(); - - const command = quickPick.selectedItems[0]?.value; - if (command) { - const updatedRecentlyCommand = [command] - .concat(this.recentlyCommand.filter((item) => item !== command)) - .slice(0, this.config.maxChatEditHistory); - this.config.chatEditRecentlyCommand = updatedRecentlyCommand; - - this.editor.selection = new Selection(startPosition, startPosition); - this.contextVariables.chatEditInProgress = true; - this.chatEditCancellationTokenSource = new CancellationTokenSource(); - try { - await this.client.chat.provideEdit( - { - location: this.editLocation, - command, - format: "previewChanges", - }, - this.chatEditCancellationTokenSource.token, - ); - } catch (error) { - if (typeof error === "object" && error && "message" in error && typeof error["message"] === "string") { - window.showErrorMessage(error["message"]); - } - } - this.chatEditCancellationTokenSource.dispose(); - this.chatEditCancellationTokenSource = null; - this.contextVariables.chatEditInProgress = false; - this.editor.selection = new Selection(startPosition, startPosition); - } + if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { + this.quickPick.value = item.value; } - - - private onDidTriggerItemButton(event: QuickPickItemButtonEvent) { - const item = event.item; - const button = event.button; - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "settings-remove") { - const index = this.recentlyCommand.indexOf(item.value); - if (index !== -1) { - this.recentlyCommand.splice(index, 1); - this.config.chatEditRecentlyCommand = this.recentlyCommand; - this.updateQuickPickList(); - } - } - - if (button.iconPath instanceof ThemeIcon && button.iconPath.id === "edit") { - this.quickPick.value = item.value; - } + } + + private updateQuickPickList() { + const input = this.quickPick.value; + const list: (QuickPickItem & { value: string })[] = []; + list.push( + ...this.suggestedCommand.map((item) => ({ + label: item.label, + value: item.command, + iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), + description: item.source === "preset" ? item.command : "Suggested", + })), + ); + if (list.length > 0) { + list.push({ + label: "", + value: "", + kind: QuickPickItemKind.Separator, + alwaysShow: true, + }); } - - private updateQuickPickList() { - const input = this.quickPick.value; - const list: (QuickPickItem & { value: string })[] = []; - list.push( - ...this.suggestedCommand.map((item) => ({ - label: item.label, - value: item.command, - iconPath: item.source === "preset" ? new ThemeIcon("run") : new ThemeIcon("spark"), - description: item.source === "preset" ? item.command : "Suggested", - })), - ); - if (list.length > 0) { - list.push({ - label: "", - value: "", - kind: QuickPickItemKind.Separator, - alwaysShow: true, - }); - } - const recentlyCommandToAdd = this.recentlyCommand.filter((item) => !list.find((i) => i.value === item)); - list.push( - ...recentlyCommandToAdd.map((item) => ({ - label: item, - value: item, - iconPath: new ThemeIcon("history"), - description: "History", - buttons: [ - { - iconPath: new ThemeIcon("edit"), - }, - { - iconPath: new ThemeIcon("settings-remove"), - }, - ], - })), - ); - if (input.length > 0 && !list.find((i) => i.value === input)) { - list.unshift({ - label: input, - value: input, - iconPath: new ThemeIcon("run"), - description: "", - alwaysShow: true, - }); - } - this.quickPick.items = list; - }; + const recentlyCommandToAdd = this.recentlyCommand.filter((item) => !list.find((i) => i.value === item)); + list.push( + ...recentlyCommandToAdd.map((item) => ({ + label: item, + value: item, + iconPath: new ThemeIcon("history"), + description: "History", + buttons: [ + { + iconPath: new ThemeIcon("edit"), + }, + { + iconPath: new ThemeIcon("settings-remove"), + }, + ], + })), + ); + if (input.length > 0 && !list.find((i) => i.value === input)) { + list.unshift({ + label: input, + value: input, + iconPath: new ThemeIcon("run"), + description: "", + alwaysShow: true, + }); + } + this.quickPick.items = list; + } } interface EditCommand extends QuickPickItem { - value: string + value: string; } interface EditLocation { - uri: string; - range: { - start: { line: number; character: number }; - end: { line: number; character: number }; - }; -} \ No newline at end of file + uri: string; + range: { + start: { line: number; character: number }; + end: { line: number; character: number }; + }; +} diff --git a/clients/vscode/tsconfig.build.json b/clients/vscode/tsconfig.build.json index 21597ab21190..ad64328a35fe 100644 --- a/clients/vscode/tsconfig.build.json +++ b/clients/vscode/tsconfig.build.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "noUnusedLocals": true, + "noUnusedLocals": true } } From 1f0007d2d2f5410fe659ceb8ce7945ba0774e448 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Tue, 27 Aug 2024 20:52:51 -0700 Subject: [PATCH 14/19] fix --- clients/vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/vscode/package.json b/clients/vscode/package.json index ddb76f61cf16..4863dde5a583 100644 --- a/clients/vscode/package.json +++ b/clients/vscode/package.json @@ -425,7 +425,7 @@ "scripts": { "build": "tsc -p ./tsconfig.build.json --noEmit && tsup --minify", "watch": "tsc-watch --noEmit --onSuccess \"tsup\"", - "dev": "pnpm run watch && code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", + "dev": "code --extensionDevelopmentPath=$PWD --disable-extensions && pnpm watch", "vscode:dev": "pnpm run dev", "dev:browser": "vscode-test-web --extensionDevelopmentPath=$PWD --browserType=chromium --port=3000 && pnpm watch", "lint": "eslint --ext .ts ./src && prettier --check .", From 7ca94fe694856d98f0a97c5019d796850797dde7 Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Wed, 28 Aug 2024 10:27:25 -0700 Subject: [PATCH 15/19] chore(agent): when apply inline edit, apply the first edit as soon as possible so codelens can display immediately --- clients/tabby-agent/src/lsp/ChatEditProvider.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 66106441a9fc..6be93468189c 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -357,11 +357,17 @@ export class ChatEditProvider { }; try { + if (!this.currentEdit) { + throw new Error("No current edit"); + } + let inTag: "document" | "comment" | false = false; - let isFirstEdit = true; + + // Insert the first line as early as possible so codelens can be shown + await applyEdit(this.currentEdit, true, false); for await (const delta of stream) { - if (!this.currentEdit || !this.mutexAbortController || this.mutexAbortController.signal.aborted) { + if (!this.mutexAbortController || this.mutexAbortController.signal.aborted) { break; } @@ -377,9 +383,8 @@ export class ChatEditProvider { const closeTag = inTag === "document" ? responseDocumentTag[1] : responseCommentTag?.[1]; if (!closeTag || !openTag) break; inTag = processBuffer(edit, inTag, openTag, closeTag); - if (isFirstEdit || delta.includes("\n")) { - await applyEdit(edit, isFirstEdit, false); - isFirstEdit = false; + if (delta.includes("\n")) { + await applyEdit(edit, false, false); } } } From fce29ebcef74094701041fd8d28f9dccc80d3ccc Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Wed, 28 Aug 2024 10:41:49 -0700 Subject: [PATCH 16/19] add highlight for in progress edit --- .../tabby-agent/src/lsp/ChatEditProvider.ts | 19 ++++++------------- .../tabby-agent/src/lsp/CodeLensProvider.ts | 8 ++++---- clients/vscode/src/lsp/CodeLensMiddleware.ts | 7 ++++++- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/clients/tabby-agent/src/lsp/ChatEditProvider.ts b/clients/tabby-agent/src/lsp/ChatEditProvider.ts index 6be93468189c..971331588256 100644 --- a/clients/tabby-agent/src/lsp/ChatEditProvider.ts +++ b/clients/tabby-agent/src/lsp/ChatEditProvider.ts @@ -201,8 +201,8 @@ export class ChatEditProvider { end: { line: line + 1, character: 0 }, }); - const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(lineText); - markers = match?.[1]; + const match = /^>>>>>>> (tabby-[0-9|a-z|A-Z]{6}) (\[.*\])/g.exec(lineText); + markers = match?.[2]; if (markers) { break; } @@ -273,7 +273,7 @@ export class ChatEditProvider { [edit.location.uri]: [ { range: edit.editedRange, - newText: `<<<<<<< [${edit.id}]\n`, + newText: `<<<<<<< ${edit.id}\n`, }, ], }, @@ -442,15 +442,8 @@ export class ChatEditProvider { private generateChangesPreview(edit: Edit): string[] { const lines: string[] = []; let markers = ""; - // header - let stateDescription = "Editing in progress"; - if (edit.state === "stopped") { - stateDescription = "Editing stopped"; - } else if (edit.state == "completed") { - stateDescription = "Editing completed"; - } // lines.push(`<<<<<<< ${stateDescription} {{markers}}[${edit.id}]`); - markers += "<"; + markers += "["; // comments: split by new line or 80 chars const commentLines = edit.comments .trim() @@ -532,8 +525,8 @@ export class ChatEditProvider { } } // footer - lines.push(`>>>>>>> ${stateDescription} {{markers}}[${edit.id}]`); - markers += ">"; + lines.push(`>>>>>>> ${edit.id} {{markers}}`); + markers += "]"; // replace markers // lines[0] = lines[0]!.replace("{{markers}}", markers); lines[lines.length - 1] = lines[lines.length - 1]!.replace("{{markers}}", markers); diff --git a/clients/tabby-agent/src/lsp/CodeLensProvider.ts b/clients/tabby-agent/src/lsp/CodeLensProvider.ts index 69170e7f99df..f55abdbc54a1 100644 --- a/clients/tabby-agent/src/lsp/CodeLensProvider.ts +++ b/clients/tabby-agent/src/lsp/CodeLensProvider.ts @@ -68,9 +68,9 @@ export class CodeLensProvider { const codeLensLocation: Location = { uri: uri, range: codeLensRange }; const lineCodeLenses: CodeLens[] = []; if (lineInPreviewBlock < 0) { - const match = /^>>>>>>>.+(<.*>)\[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); - const markers = match?.[1]; - const editId = match?.[2]; + const match = /^>>>>>>> (tabby-[0-9|a-z|A-Z]{6}) (\[.*\])/g.exec(text); + const editId = match?.[1]; + const markers = match?.[2]; if (match && markers && editId) { previewBlockMarkers = markers; lineInPreviewBlock = 0; @@ -83,7 +83,7 @@ export class CodeLensProvider { }); } } else { - const match = /^<<<<<<< \[(tabby-[0-9|a-z|A-Z]{6})\]/g.exec(text); + const match = /^<<<<<<< (tabby-[0-9|a-z|A-Z]{6})/g.exec(text); const editId = match?.[1]; if (match && editId) { lineInPreviewBlock = -1; diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index 8c80ba3a68ed..765501d7d80f 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -47,6 +47,11 @@ const decorationTypeUnchanged = window.createTextEditorDecorationType({ // width: "10px", }, }); +const decorationTypePending = window.createTextEditorDecorationType({ + backgroundColor: new ThemeColor("editorInlayHint.background"), + isWholeLine: true, + rangeBehavior: DecorationRangeBehavior.ClosedClosed, +}); const decorationTypeInserted = window.createTextEditorDecorationType({ backgroundColor: new ThemeColor("diffEditor.insertedTextBackground"), isWholeLine: true, @@ -74,7 +79,7 @@ const decorationTypes: Record = { footer: decorationTypeFooter, commentsFirstLine: decorationTypeComments, comments: decorationTypeComments, - waiting: decorationTypeUnchanged, + waiting: decorationTypePending, inProgress: decorationTypeInserted, unchanged: decorationTypeUnchanged, inserted: decorationTypeInserted, From 51cf6bad7da46858aef3d1e31549d43b246a549c Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Wed, 28 Aug 2024 21:31:18 -0700 Subject: [PATCH 17/19] update --- clients/vscode/src/lsp/CodeLensMiddleware.ts | 26 -------------------- 1 file changed, 26 deletions(-) diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index 765501d7d80f..a96e48154d20 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -16,12 +16,10 @@ import { findTextEditor } from "./vscodeWindowUtils"; type CodeLens = VscodeCodeLens & TabbyCodeLens; const decorationTypeHeader = window.createTextEditorDecorationType({ - // backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, }); const decorationTypeFooter = window.createTextEditorDecorationType({ - // backgroundColor: new ThemeColor("merge.incomingHeaderBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, }); @@ -32,20 +30,8 @@ const decorationTypeComments = window.createTextEditorDecorationType({ fontWeight: "normal", isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedOpen, - before: { - // contentText: ">", - // color: new ThemeColor("editorInlayHint.foreground"), - // backgroundColor: new ThemeColor("editorInlayHint.background"), - // fontWeight: "bold", - // width: "10px", - }, }); const decorationTypeUnchanged = window.createTextEditorDecorationType({ - before: { - // contentText: "", - // fontWeight: "bold", - // width: "10px", - }, }); const decorationTypePending = window.createTextEditorDecorationType({ backgroundColor: new ThemeColor("editorInlayHint.background"), @@ -56,23 +42,11 @@ const decorationTypeInserted = window.createTextEditorDecorationType({ backgroundColor: new ThemeColor("diffEditor.insertedTextBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, - before: { - // contentText: "+", - // backgroundColor: new ThemeColor("diffEditor.insertedTextBackground"), - // fontWeight: "bold", - // width: "10px", - }, }); const decorationTypeDeleted = window.createTextEditorDecorationType({ backgroundColor: new ThemeColor("diffEditor.removedTextBackground"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, - before: { - // contentText: "-", - // backgroundColor: new ThemeColor("diffEditor.removedTextBackground"), - // fontWeight: "bold", - // width: "10px", - }, }); const decorationTypes: Record = { header: decorationTypeHeader, From 39be5316ae9f9c00f20490eb997ac61f09aa65f3 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 04:32:21 +0000 Subject: [PATCH 18/19] [autofix.ci] apply automated fixes --- clients/vscode/src/lsp/CodeLensMiddleware.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index a96e48154d20..940502a54d91 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -31,8 +31,7 @@ const decorationTypeComments = window.createTextEditorDecorationType({ isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedOpen, }); -const decorationTypeUnchanged = window.createTextEditorDecorationType({ -}); +const decorationTypeUnchanged = window.createTextEditorDecorationType({}); const decorationTypePending = window.createTextEditorDecorationType({ backgroundColor: new ThemeColor("editorInlayHint.background"), isWholeLine: true, From a4ed7b52a85746bdf2b3f3bb55ef82fd4738002c Mon Sep 17 00:00:00 2001 From: Meng Zhang Date: Wed, 28 Aug 2024 21:44:40 -0700 Subject: [PATCH 19/19] update --- clients/vscode/src/lsp/CodeLensMiddleware.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/clients/vscode/src/lsp/CodeLensMiddleware.ts b/clients/vscode/src/lsp/CodeLensMiddleware.ts index 940502a54d91..bb5d110b0944 100644 --- a/clients/vscode/src/lsp/CodeLensMiddleware.ts +++ b/clients/vscode/src/lsp/CodeLensMiddleware.ts @@ -33,7 +33,6 @@ const decorationTypeComments = window.createTextEditorDecorationType({ }); const decorationTypeUnchanged = window.createTextEditorDecorationType({}); const decorationTypePending = window.createTextEditorDecorationType({ - backgroundColor: new ThemeColor("editorInlayHint.background"), isWholeLine: true, rangeBehavior: DecorationRangeBehavior.ClosedClosed, });