Skip to content

Commit 9b8c5e9

Browse files
authored
Merge pull request #418 from mre/feat/copy-snippet
Add an ability to copy saved snippet to the clipboard
2 parents 7c1212a + 6561309 commit 9b8c5e9

File tree

8 files changed

+119
-15
lines changed

8 files changed

+119
-15
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ A Visual Studio Code extension for [cht.sh](https://cht.sh/).
2626
- ${query} - the snippet query (search text)
2727
- ${index} - the index of the snippet (e.g. 2 for the third answer)
2828
- `insertWithDoubleClick`: insert snippet with double click.
29+
- `showCopySuccessNotification`: Whether to show a notification after the snippet is copied to the clipboard.
2930

3031
## Installation
3132

@@ -109,6 +110,12 @@ You can configure a keyboard shortcut. By default this is <kbd>⌘ Command</kbd>
109110

110111
![Preview](https://raw.githubusercontent.com/mre/vscode-snippet/master/contrib/snippets-storage/delete.gif)
111112

113+
### Copying a snippet to the clipboard
114+
115+
1. Open the Snippets section
116+
2. Right click on the snippet that you want to copy
117+
3. Select "Copy"
118+
112119
### Moving a snippet or a folder
113120

114121
You can move snippets or folders in the Snippets view by dragging and dropping them

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "snippet",
33
"displayName": "Snippet",
44
"description": "Insert a snippet from cht.sh for Python, JavaScript, Ruby, C#, Go, Rust (and any other language)",
5-
"version": "1.1.1",
5+
"version": "1.1.2",
66
"publisher": "vscode-snippet",
77
"engines": {
88
"vscode": "^1.74.0"
@@ -105,6 +105,16 @@
105105
"command": "snippet.renameSnippet",
106106
"category": "Snippet"
107107
},
108+
{
109+
"title": "Copy",
110+
"command": "snippet.copySnippet",
111+
"category": "Snippet"
112+
},
113+
{
114+
"title": "Find and copy",
115+
"command": "snippet.findAndCopy",
116+
"category": "Snippet"
117+
},
108118
{
109119
"title": "New Folder",
110120
"command": "snippet.createFolder",
@@ -147,6 +157,11 @@
147157
"type": "boolean",
148158
"default": false,
149159
"description": "Insert snippet with double click."
160+
},
161+
"snippet.showCopySuccessNotification": {
162+
"type": "boolean",
163+
"default": true,
164+
"description": "Whether to show a notification after the snippet is copied to the clipboard."
150165
}
151166
}
152167
},
@@ -164,15 +179,20 @@
164179
"when": "view == snippetsView",
165180
"group": "snippet.viewItemContext.baseGroup@1"
166181
},
182+
{
183+
"command": "snippet.copySnippet",
184+
"when": "view == snippetsView && viewItem == snippet",
185+
"group": "snippet.viewItemContext.baseGroup@2"
186+
},
167187
{
168188
"command": "snippet.renameSnippet",
169189
"when": "view == snippetsView",
170-
"group": "snippet.viewItemContext.baseGroup@2"
190+
"group": "snippet.viewItemContext.baseGroup@3"
171191
},
172192
{
173193
"command": "snippet.deleteSnippet",
174194
"when": "view == snippetsView",
175-
"group": "snippet.viewItemContext.baseGroup@3"
195+
"group": "snippet.viewItemContext.baseGroup@4"
176196
}
177197
],
178198
"editor/context": [

src/clipboard.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as vscode from "vscode";
2+
import { getConfig } from "./config";
3+
4+
export async function copySnippet(content: string): Promise<void> {
5+
try {
6+
await vscode.env.clipboard.writeText(content);
7+
8+
if (getConfig("showCopySuccessNotification")) {
9+
await showNotification();
10+
}
11+
} catch {
12+
vscode.window.showErrorMessage(
13+
"Failed to copy the snippet to the clipboard"
14+
);
15+
}
16+
}
17+
async function showNotification() {
18+
const doNotShowAgain = await vscode.window.showInformationMessage(
19+
"The snippet was copied to the clipboard",
20+
{ modal: false },
21+
"Do not show again"
22+
);
23+
24+
if (doNotShowAgain) {
25+
const config = vscode.workspace.getConfiguration("snippet");
26+
await config.update(
27+
"showCopySuccessNotification",
28+
false,
29+
vscode.ConfigurationTarget.Global
30+
);
31+
}
32+
}

src/endpoints.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from "vscode";
2+
import * as clipboard from "./clipboard";
23
import { pickLanguage, getLanguage, getConfig } from "./config";
34
import { query } from "./query";
45
import { encodeRequest } from "./provider";
@@ -335,6 +336,29 @@ export function renameSnippet(treeProvider: SnippetsTreeProvider) {
335336
};
336337
}
337338

339+
export function copySnippet(treeProvider: SnippetsTreeProvider) {
340+
return async (item: SnippetsTreeItem) => {
341+
if (!item) {
342+
vscode.window.showInformationMessage(
343+
'Copy a snippet right clicking on it in the list and selecting "Copy"'
344+
);
345+
return;
346+
}
347+
348+
const content = treeProvider.storage.getSnippet(item.id);
349+
await clipboard.copySnippet(content);
350+
};
351+
}
352+
353+
export function findAndCopy(snippetsStorage: SnippetsStorage) {
354+
return async () => {
355+
const language = await getLanguage();
356+
const userQuery = await query(language, snippetsStorage, true);
357+
358+
await clipboard.copySnippet(userQuery.savedSnippetContent);
359+
};
360+
}
361+
338362
export function createFolder(treeProvider: SnippetsTreeProvider) {
339363
return async (item?: SnippetsTreeItem) => {
340364
const opt: vscode.InputBoxOptions = {

src/extension.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ export function activate(ctx: vscode.ExtensionContext) {
5959
"snippet.renameSnippet",
6060
endpoints.renameSnippet(snippetsTreeProvider)
6161
);
62+
vscode.commands.registerCommand(
63+
"snippet.copySnippet",
64+
endpoints.copySnippet(snippetsTreeProvider)
65+
);
66+
vscode.commands.registerCommand(
67+
"snippet.findAndCopy",
68+
endpoints.findAndCopy(snippetsStorage)
69+
);
6270
vscode.commands.registerCommand(
6371
"snippet.createFolder",
6472
endpoints.createFolder(snippetsTreeProvider)

src/query.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ import SnippetsStorage from "./snippetsStorage";
66
import languages from "./languages";
77

88
function quickPickCustom(
9-
items: vscode.QuickPickItem[]
9+
items: vscode.QuickPickItem[],
10+
clearActiveItems = true
1011
): Promise<string | vscode.QuickPickItem> {
1112
return new Promise((resolve) => {
1213
const quickPick = vscode.window.createQuickPick();
1314
quickPick.title = 'Enter keywords for snippet search (e.g. "read file")';
1415
quickPick.items = items;
1516

1617
quickPick.onDidChangeValue(() => {
17-
quickPick.activeItems = [];
18+
if (clearActiveItems) {
19+
quickPick.activeItems = [];
20+
}
1821
});
1922

2023
quickPick.onDidAccept(() => {
@@ -38,7 +41,8 @@ export interface QueryResult {
3841

3942
export async function query(
4043
language: string,
41-
snippetsStorage: SnippetsStorage
44+
snippetsStorage: SnippetsStorage,
45+
suggestOnlySaved = false
4246
): Promise<QueryResult> {
4347
const suggestions = new Set(
4448
cache.state.get<string[]>(`snippet_suggestions_${language}`, [])
@@ -58,15 +62,20 @@ export async function query(
5862
}
5963
}
6064

61-
for (const suggestion of suggestions) {
62-
const tempQuickItem: vscode.QuickPickItem = {
63-
label: suggestion,
64-
description: "",
65-
};
66-
suggestionsQuickItems.push(tempQuickItem);
65+
if (!suggestOnlySaved) {
66+
for (const suggestion of suggestions) {
67+
const tempQuickItem: vscode.QuickPickItem = {
68+
label: suggestion,
69+
description: "",
70+
};
71+
suggestionsQuickItems.push(tempQuickItem);
72+
}
6773
}
6874

69-
const selectedItem = await quickPickCustom(suggestionsQuickItems);
75+
const selectedItem = await quickPickCustom(
76+
suggestionsQuickItems,
77+
!suggestOnlySaved
78+
);
7079
const input =
7180
typeof selectedItem === "string" ? selectedItem : selectedItem.label;
7281
const savedSnippetContent =

src/snippetsTreeProvider.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ export class SnippetsTreeItem extends vscode.TreeItem {
113113

114114
this.id = id;
115115
this.tooltip = content;
116+
this.contextValue =
117+
collapsibleState === vscode.TreeItemCollapsibleState.None
118+
? "snippet"
119+
: "folder";
116120

117121
if (collapsibleState !== vscode.TreeItemCollapsibleState.None) {
118122
return;

0 commit comments

Comments
 (0)