diff --git a/docs/lsp.md b/docs/lsp.md index f1c2fb8834f..884c7cce378 100644 --- a/docs/lsp.md +++ b/docs/lsp.md @@ -25,6 +25,7 @@ sequenceDiagram ``` ## Language Server Debugging + If you want to connect a local version of language-servers to aws-toolkit-vscode, follow these steps: 1. Clone https://github.com/aws/language-servers.git and set it up in the same workspace as this project by cmd+shift+p and "add folder to workspace" and selecting the language-servers folder that you just cloned. Your VS code folder structure should look like below. @@ -57,13 +58,16 @@ If you want to connect a local version of language-servers to aws-toolkit-vscode 6. (Optional): Enable `"amazonq.trace.server": "on"` or `"amazonq.trace.server": "verbose"` in your VSCode settings to view detailed log messages sent to/from the language server. These log messages will show up in the "Amazon Q Language Server" output channel ### Breakpoints Work-Around + If the breakpoints in your language-servers project remain greyed out and do not trigger when you run `Launch LSP with Debugging`, your debugger may be attaching to the language server before it has launched. You can follow the work-around below to avoid this problem. If anyone fixes this issue, please remove this section. + 1. Set your breakpoints and click `Launch LSP with Debugging` 2. Once the debugging session has started, click `Launch LSP with Debugging` again, then `Cancel` on any pop-ups that appear 3. On the debug panel, click `Attach to Language Server (amazonq)` next to the red stop button 4. Click `Launch LSP with Debugging` again, then `Cancel` on any pop-ups that appear ## Language Server Runtimes Debugging + If you want to connect a local version of language-server-runtimes to aws-toolkit-vscode, follow these steps: 1. Clone https://github.com/aws/language-server-runtimes.git and set it up in the same workspace as this project by cmd+shift+p and "add folder to workspace" and selecting the language-server-runtimes folder that you just cloned. Your VS code folder structure should look like below. @@ -75,6 +79,7 @@ If you want to connect a local version of language-server-runtimes to aws-toolki /amazonq /language-server-runtimes ``` + 2. Inside of the language-server-runtimes project run: ``` npm install diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index c8893d445ea..c30480b3b63 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -554,6 +554,21 @@ ] }, "commands": [ + { + "command": "aws.amazonq.stopCmdExecution", + "title": "Stop Amazon Q Command Execution", + "category": "%AWS.amazonq.title%" + }, + { + "command": "aws.amazonq.runCmdExecution", + "title": "Run Amazon Q Command Execution", + "category": "%AWS.amazonq.title%" + }, + { + "command": "aws.amazonq.rejectCmdExecution", + "title": "Reject Amazon Q Command Execution", + "category": "%AWS.amazonq.title%" + }, { "command": "_aws.amazonq.notifications.dismiss", "title": "%AWS.generic.dismiss%", @@ -843,6 +858,24 @@ } ], "keybindings": [ + { + "command": "aws.amazonq.stopCmdExecution", + "key": "ctrl+shift+backspace", + "mac": "cmd+shift+backspace", + "when": "aws.amazonq.amazonqChatLSP.isRunning" + }, + { + "command": "aws.amazonq.runCmdExecution", + "key": "ctrl+shift+enter", + "mac": "cmd+shift+enter", + "when": "aws.amazonq.amazonqChatLSP.isRunning" + }, + { + "command": "aws.amazonq.rejectCmdExecution", + "key": "ctrl+shift+r", + "mac": "cmd+shift+r", + "when": "aws.amazonq.amazonqChatLSP.isRunning" + }, { "command": "_aws.amazonq.focusChat.keybinding", "win": "win+alt+i", @@ -1325,26 +1358,40 @@ "fontCharacter": "\\f1de" } }, - "aws-schemas-registry": { + "aws-sagemaker-code-editor": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1df" } }, - "aws-schemas-schema": { + "aws-sagemaker-jupyter-lab": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1e0" } }, - "aws-stepfunctions-preview": { + "aws-schemas-registry": { "description": "AWS Contributed Icon", "default": { "fontPath": "./resources/fonts/aws-toolkit-icons.woff", "fontCharacter": "\\f1e1" } + }, + "aws-schemas-schema": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e2" + } + }, + "aws-stepfunctions-preview": { + "description": "AWS Contributed Icon", + "default": { + "fontPath": "./resources/fonts/aws-toolkit-icons.woff", + "fontCharacter": "\\f1e3" + } } }, "walkthroughs": [ diff --git a/packages/amazonq/src/lsp/chat/commands.ts b/packages/amazonq/src/lsp/chat/commands.ts index 9135be6d8d4..e95eae58d1b 100644 --- a/packages/amazonq/src/lsp/chat/commands.ts +++ b/packages/amazonq/src/lsp/chat/commands.ts @@ -78,7 +78,10 @@ export function registerCommands(provider: AmazonQChatViewProvider) { params: {}, }) }) - }) + }), + registerShellCommandShortCut('aws.amazonq.runCmdExecution', 'run-shell-command', provider), + registerShellCommandShortCut('aws.amazonq.rejectCmdExecution', 'reject-shell-command', provider), + registerShellCommandShortCut('aws.amazonq.stopCmdExecution', 'stop-shell-command', provider) ) } @@ -123,3 +126,14 @@ export async function focusAmazonQPanel() { await Commands.tryExecute('aws.amazonq.AmazonQChatView.focus') await Commands.tryExecute('aws.amazonq.AmazonCommonAuth.focus') } + +function registerShellCommandShortCut(commandName: string, buttonId: string, provider: AmazonQChatViewProvider) { + return Commands.register(commandName, async () => { + void focusAmazonQPanel().then(() => { + void provider.webview?.postMessage({ + command: 'aws/chat/executeShellCommandShortCut', + params: { id: buttonId }, + }) + }) + }) +} diff --git a/packages/amazonq/src/lsp/chat/webviewProvider.ts b/packages/amazonq/src/lsp/chat/webviewProvider.ts index 7d51648398d..109a6afd10f 100644 --- a/packages/amazonq/src/lsp/chat/webviewProvider.ts +++ b/packages/amazonq/src/lsp/chat/webviewProvider.ts @@ -13,6 +13,7 @@ import { Webview, } from 'vscode' import * as path from 'path' +import * as os from 'os' import { globals, isSageMaker, @@ -149,7 +150,7 @@ export class AmazonQChatViewProvider implements WebviewViewProvider { const vscodeApi = acquireVsCodeApi() const hybridChatConnector = new HybridChatAdapter(${(await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'},${featureConfigData},${welcomeCount},${disclaimerAcknowledged},${regionProfileString},${disabledCommands},${isSMUS},${isSM},vscodeApi.postMessage) const commands = [hybridChatConnector.initialQuickActions[0]] - qChat = amazonQChat.createChat(vscodeApi, {disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, agenticMode: true, quickActionCommands: commands, modelSelectionEnabled: ${modelSelectionEnabled}}, hybridChatConnector, ${JSON.stringify(featureConfigData)}); + qChat = amazonQChat.createChat(vscodeApi, {os: "${os.platform()}", disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, agenticMode: true, quickActionCommands: commands, modelSelectionEnabled: ${modelSelectionEnabled}}, hybridChatConnector, ${JSON.stringify(featureConfigData)}); } window.addEventListener('message', (event) => { /** diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index e9066678698..202acb34f0e 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -38,6 +38,7 @@ import { getClientId, extensionVersion, isSageMaker, + setContext, } from 'aws-core-vscode/shared' import { processUtils } from 'aws-core-vscode/shared' import { activate } from './chat/activation' @@ -164,6 +165,7 @@ export async function startLanguageServer( pinnedContextEnabled: true, imageContextEnabled: true, mcp: true, + shortcut: true, reroute: true, modelSelection: true, workspaceFilePath: vscode.workspace.workspaceFile?.fsPath, @@ -247,6 +249,17 @@ async function onLanguageServerReady( if (Experiments.instance.get('amazonqChatLSP', true)) { await activate(client, encryptionKey, resourcePaths.ui) + + await setContext('aws.amazonq.amazonqChatLSP.isRunning', true) + getLogger().info('Amazon Q Chat LSP context flag set on client activated') + + // Add a disposable to reset the context flag when the client stops + toDispose.push({ + dispose: async () => { + await setContext('aws.amazonq.amazonqChatLSP.isRunning', false) + getLogger().info('Amazon Q Chat LSP context flag reset on client disposal') + }, + }) } const refreshInterval = auth.startTokenRefreshInterval(10 * oneSecond) diff --git a/packages/core/src/shared/vscode/setContext.ts b/packages/core/src/shared/vscode/setContext.ts index 08d651578dc..9754dc1c5fe 100644 --- a/packages/core/src/shared/vscode/setContext.ts +++ b/packages/core/src/shared/vscode/setContext.ts @@ -40,6 +40,7 @@ export type contextKey = | 'gumby.wasQCodeTransformationUsed' | 'amazonq.inline.codelensShortcutEnabled' | 'aws.toolkit.lambda.walkthroughSelected' + | 'aws.amazonq.amazonqChatLSP.isRunning' const contextMap: Partial> = {}