Skip to content

Commit 90f6003

Browse files
authored
Merge pull request #193 from sourcery-ai/mob/chat-insert-or-replace-at-cursor
feat: adds a button to code snippets to add them to the editor
2 parents f5e2ae0 + 2c4bb01 commit 90f6003

File tree

3 files changed

+86
-12
lines changed

3 files changed

+86
-12
lines changed

media/chat.css

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,32 @@
155155
overflow: hidden;
156156
}
157157

158-
button.sidebar__chat-assistant--chat-bubble-text--code-copy-button {
158+
.sidebar__chat-assistant--chat-bubble-text--code-action-buttons {
159159
visibility: hidden;
160-
background: var(--vscode-button-secondaryBackground);
161-
border: 1px solid var(--vscode-panel-border);
162-
border-radius: var(--spacing-xxs);
160+
display: flex;
161+
flex-direction: row;
163162
position: absolute;
164-
display: block;
165163
top: var(--spacing-sm);
166164
right: var(--spacing-sm);
165+
}
166+
167+
.sidebar__chat-assistant--chat-bubble-text--code-action-buttons
168+
.sidebar__chat-assistant--chat-bubble-text--code-action-button:first-of-type {
169+
border-top-left-radius: var(--spacing-xxs);
170+
border-bottom-left-radius: var(--spacing-xxs);
171+
}
172+
173+
.sidebar__chat-assistant--chat-bubble-text--code-action-buttons
174+
.sidebar__chat-assistant--chat-bubble-text--code-action-button:last-of-type {
175+
border-top-right-radius: var(--spacing-xxs);
176+
border-bottom-right-radius: var(--spacing-xxs);
177+
border-left: none;
178+
}
179+
180+
button.sidebar__chat-assistant--chat-bubble-text--code-action-button {
181+
position: relative;
182+
background: var(--vscode-button-secondaryBackground);
183+
border: 1px solid var(--vscode-panel-border);
167184
color: var(--vscode-settings-textInputForeground);
168185
padding: var(--spacing-md);
169186
fill: var(--vscode-button-secondaryForeground);
@@ -181,13 +198,13 @@ button.sidebar__chat-assistant--chat-bubble-text--code-copy-button {
181198
top: var(--spacing-xxs);
182199
}
183200

184-
button.sidebar__chat-assistant--chat-bubble-text--code-copy-button:hover {
201+
button.sidebar__chat-assistant--chat-bubble-text--code-action-button:hover {
185202
background-color: var(--vscode-button-secondaryHoverBackground);
186203
}
187204

188205
.sidebar__chat-assistant--chat-bubble-text
189206
pre:hover
190-
button.sidebar__chat-assistant--chat-bubble-text--code-copy-button {
207+
.sidebar__chat-assistant--chat-bubble-text--code-action-buttons {
191208
visibility: visible;
192209
}
193210

src/chat.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ export type OpenLinkRequest = {
6060
link: string;
6161
};
6262

63+
type InsertAtCursorInstruction = {
64+
type: "insert_at_cursor";
65+
content: string;
66+
};
67+
6368
export class ChatProvider implements vscode.WebviewViewProvider {
6469
public static readonly viewType = "sourcery.chat";
6570

@@ -100,7 +105,13 @@ export class ChatProvider implements vscode.WebviewViewProvider {
100105
});
101106

102107
webviewView.webview.onDidReceiveMessage(
103-
async (request: ChatRequest | CancelRequest | OpenLinkRequest) => {
108+
async (
109+
request:
110+
| ChatRequest
111+
| CancelRequest
112+
| OpenLinkRequest
113+
| InsertAtCursorInstruction
114+
) => {
104115
switch (request.type) {
105116
case "chat_request": {
106117
vscode.commands.executeCommand("sourcery.chat_request", request);
@@ -135,6 +146,25 @@ export class ChatProvider implements vscode.WebviewViewProvider {
135146
}
136147
break;
137148
}
149+
case "insert_at_cursor": {
150+
const activeEditor = vscode.window.activeTextEditor;
151+
if (!activeEditor) {
152+
vscode.window.showErrorMessage("No active text editor!");
153+
return;
154+
}
155+
156+
activeEditor.edit((editBuilder) => {
157+
// Thank you coding assistant!
158+
if (!activeEditor.selection.isEmpty) {
159+
editBuilder.replace(activeEditor.selection, request.content);
160+
} else {
161+
editBuilder.insert(
162+
activeEditor.selection.active,
163+
request.content
164+
);
165+
}
166+
});
167+
}
138168
}
139169
}
140170
);

src/webview/chat.js

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,12 +177,11 @@ const LINE_HEIGHT = 36;
177177
`;
178178
button.title = "Copy to Clipboard";
179179
button.classList.add(
180-
"sidebar__chat-assistant--chat-bubble-text--code-copy-button"
180+
"sidebar__chat-assistant--chat-bubble-text--code-action-button"
181181
);
182-
block.appendChild(button);
183182
button.onclick = async () => {
184183
await navigator.clipboard.writeText(text);
185-
button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="sidebar__chat-assistant--code-block-action-button-icon"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>`;
184+
button.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="sidebar__chat-assistant--code-block-action-button-icon"><!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>`;
186185
};
187186
button.onblur = async () => {
188187
button.innerHTML = `
@@ -195,9 +194,37 @@ const LINE_HEIGHT = 36;
195194
</svg>
196195
`;
197196
};
197+
return button;
198198
}
199199
};
200200

201+
const setupReplaceButton = (block) => {
202+
let text = block.querySelector("code").innerText;
203+
let button = document.createElement("button");
204+
button.innerHTML = `
205+
<svg xmlns="http://www.w3.org/2000/svg" class="sidebar__chat-assistant--code-block-action-button-icon" viewBox="0 0 512 512"><path d="M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z"/></svg>
206+
`;
207+
button.title = "Insert code at cursor";
208+
button.classList.add(
209+
"sidebar__chat-assistant--chat-bubble-text--code-action-button"
210+
);
211+
button.onclick = async () => {
212+
vscode.postMessage({ type: "insert_at_cursor", content: text });
213+
};
214+
return button;
215+
};
216+
217+
const setupActionButtons = (block) => {
218+
let buttonGroup = document.createElement("div");
219+
buttonGroup.classList.add(
220+
"sidebar__chat-assistant--chat-bubble-text--code-action-buttons"
221+
);
222+
let copyButton = setupCopyButton(block);
223+
let replaceButton = setupReplaceButton(block);
224+
buttonGroup.append(copyButton, replaceButton);
225+
block.appendChild(buttonGroup);
226+
};
227+
201228
// Function to add an assistant message or add to the existing one
202229
function addAssistantMessageToUI(message) {
203230
cancelButton.disabled = false;
@@ -210,7 +237,7 @@ const LINE_HEIGHT = 36;
210237
currentAssistantMessage.innerHTML = message.textContent;
211238

212239
let blocks = currentAssistantMessage.querySelectorAll("pre");
213-
blocks.forEach(setupCopyButton);
240+
blocks.forEach(setupActionButtons);
214241

215242
let httpLinks =
216243
currentAssistantMessage.querySelectorAll('a[href*="http"]');

0 commit comments

Comments
 (0)