Skip to content

Commit 6af0425

Browse files
authored
feat(amazon lsp): add copyToClipboard implementation (aws#6980)
## Problem There was no implementation for the `copyToClipboard` message received from LSP for Amazon Q. The functionality did work because of the [MynahUI implementation](https://github.com/aws/mynah-ui/blob/b56a4b1df828eaa22515ef0f5af211eec24a5f89/src/helper/chat-item.ts#L36C1-L37C1), but for UI consistency to consider edge cases with webview clipboard, we decided to handle it explicitly. ## Solution Call the `copyToClipboard` function and add unit tests --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent c21be70 commit 6af0425

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

packages/amazonq/src/lsp/chat/messages.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ import {
2323
insertToCursorPositionNotificationType,
2424
} from '@aws/language-server-runtimes/protocol'
2525
import { v4 as uuidv4 } from 'uuid'
26-
import { window } from 'vscode'
26+
import * as vscode from 'vscode'
2727
import { Disposable, LanguageClient, Position, State, TextDocumentIdentifier } from 'vscode-languageclient'
2828
import * as jose from 'jose'
2929
import { AmazonQChatViewProvider } from './webviewProvider'
3030
import { AuthUtil } from 'aws-core-vscode/codewhisperer'
31-
import { AmazonQPromptSettings } from 'aws-core-vscode/shared'
31+
import { AmazonQPromptSettings, messages } from 'aws-core-vscode/shared'
3232

3333
export function registerLanguageServerEventListener(languageClient: LanguageClient, provider: AmazonQChatViewProvider) {
3434
languageClient.onDidChangeState(({ oldState, newState }) => {
@@ -62,11 +62,15 @@ export function registerMessageListeners(
6262

6363
switch (message.command) {
6464
case COPY_TO_CLIPBOARD:
65-
// TODO see what we need to hook this up
6665
languageClient.info('[VSCode Client] Copy to clipboard event received')
66+
try {
67+
await messages.copyToClipboard(message.params.code)
68+
} catch (e) {
69+
languageClient.error(`[VSCode Client] Failed to copy to clipboard: ${(e as Error).message}`)
70+
}
6771
break
6872
case INSERT_TO_CURSOR_POSITION: {
69-
const editor = window.activeTextEditor
73+
const editor = vscode.window.activeTextEditor
7074
let textDocument: TextDocumentIdentifier | undefined = undefined
7175
let cursorPosition: Position | undefined = undefined
7276
if (editor) {
@@ -119,8 +123,8 @@ export function registerMessageListeners(
119123
)
120124

121125
const editor =
122-
window.activeTextEditor ||
123-
window.visibleTextEditors.find((editor) => editor.document.languageId !== 'Log')
126+
vscode.window.activeTextEditor ||
127+
vscode.window.visibleTextEditors.find((editor) => editor.document.languageId !== 'Log')
124128
if (editor) {
125129
message.params.cursorPosition = [editor.selection.active]
126130
message.params.textDocument = { uri: editor.document.uri.toString() }

packages/amazonq/test/unit/amazonq/lsp/chat/messages.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AuthUtil } from 'aws-core-vscode/codewhisperer'
99
import { registerMessageListeners } from '../../../../../src/lsp/chat/messages'
1010
import { AmazonQChatViewProvider } from '../../../../../src/lsp/chat/webviewProvider'
1111
import { secondaryAuth, authConnection, AuthFollowUpType } from 'aws-core-vscode/amazonq'
12+
import { messages } from 'aws-core-vscode/shared'
1213

1314
describe('registerMessageListeners', () => {
1415
let languageClient: LanguageClient
@@ -126,4 +127,35 @@ describe('registerMessageListeners', () => {
126127
})
127128
})
128129
})
130+
131+
describe('COPY_TO_CLIPBOARD', () => {
132+
let copyToClipboardStub: sinon.SinonStub
133+
const testCode = 'test'
134+
const copyMessage = {
135+
command: 'copyToClipboard',
136+
params: {
137+
code: testCode,
138+
},
139+
}
140+
141+
beforeEach(() => {
142+
copyToClipboardStub = sandbox.stub().resolves()
143+
sandbox.stub(messages, 'copyToClipboard').get(() => copyToClipboardStub)
144+
})
145+
146+
it('successfully copies code to clipboard', async () => {
147+
await messageHandler(copyMessage)
148+
149+
sinon.assert.calledWith(copyToClipboardStub, testCode)
150+
})
151+
152+
it('handles clipboard copy failure', async () => {
153+
const errorMessage = 'Failed to copy'
154+
copyToClipboardStub.rejects(new Error(errorMessage))
155+
156+
await messageHandler(copyMessage)
157+
158+
sinon.assert.calledWith(errorStub, `[VSCode Client] Failed to copy to clipboard: ${errorMessage}`)
159+
})
160+
})
129161
})

0 commit comments

Comments
 (0)