From 16bf69e034bee7159c5df53eca1efbf14542d7f1 Mon Sep 17 00:00:00 2001 From: VladBrok Date: Sun, 3 Sep 2023 14:26:46 +0300 Subject: [PATCH 1/3] add an ability to copy snippet to the clipboard --- package-lock.json | 4 ++-- package.json | 21 +++++++++++++++++--- src/endpoints.ts | 38 +++++++++++++++++++++++++++++++++++++ src/extension.ts | 4 ++++ src/snippetsTreeProvider.ts | 4 ++++ 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index bfacc0e8..974b0a7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "snippet", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "snippet", - "version": "1.1.1", + "version": "1.1.2", "license": "MIT", "dependencies": { "@vscode/vsce": "^2.21.0", diff --git a/package.json b/package.json index f9c8a8e1..a8788a04 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "snippet", "displayName": "Snippet", "description": "Insert a snippet from cht.sh for Python, JavaScript, Ruby, C#, Go, Rust (and any other language)", - "version": "1.1.1", + "version": "1.1.2", "publisher": "vscode-snippet", "engines": { "vscode": "^1.74.0" @@ -105,6 +105,11 @@ "command": "snippet.renameSnippet", "category": "Snippet" }, + { + "title": "Copy", + "command": "snippet.copySnippet", + "category": "Snippet" + }, { "title": "New Folder", "command": "snippet.createFolder", @@ -147,6 +152,11 @@ "type": "boolean", "default": false, "description": "Insert snippet with double click." + }, + "snippet.showCopySuccessNotification": { + "type": "boolean", + "default": true, + "description": "Whether to show a notification after the snippet is copied to the clipboard." } } }, @@ -164,15 +174,20 @@ "when": "view == snippetsView", "group": "snippet.viewItemContext.baseGroup@1" }, + { + "command": "snippet.copySnippet", + "when": "view == snippetsView && viewItem == snippet", + "group": "snippet.viewItemContext.baseGroup@2" + }, { "command": "snippet.renameSnippet", "when": "view == snippetsView", - "group": "snippet.viewItemContext.baseGroup@2" + "group": "snippet.viewItemContext.baseGroup@3" }, { "command": "snippet.deleteSnippet", "when": "view == snippetsView", - "group": "snippet.viewItemContext.baseGroup@3" + "group": "snippet.viewItemContext.baseGroup@4" } ], "editor/context": [ diff --git a/src/endpoints.ts b/src/endpoints.ts index 8988b776..9246bcf3 100644 --- a/src/endpoints.ts +++ b/src/endpoints.ts @@ -335,6 +335,44 @@ export function renameSnippet(treeProvider: SnippetsTreeProvider) { }; } +export function copySnippet(treeProvider: SnippetsTreeProvider) { + return async (item: SnippetsTreeItem) => { + if (!item) { + vscode.window.showInformationMessage( + 'Copy a snippet right clicking on it in the list and selecting "Copy"' + ); + return; + } + + const content = treeProvider.storage.getSnippet(item.id); + + try { + await vscode.env.clipboard.writeText(content); + + if (getConfig("showCopySuccessNotification")) { + const hideNotification = await vscode.window.showInformationMessage( + "The snippet was copied to the clipboard", + { modal: false }, + "Do not show again" + ); + + if (hideNotification) { + const config = vscode.workspace.getConfiguration("snippet"); + await config.update( + "showCopySuccessNotification", + false, + vscode.ConfigurationTarget.Global + ); + } + } + } catch { + vscode.window.showErrorMessage( + "Failed to copy the snippet to the clipboard" + ); + } + }; +} + export function createFolder(treeProvider: SnippetsTreeProvider) { return async (item?: SnippetsTreeItem) => { const opt: vscode.InputBoxOptions = { diff --git a/src/extension.ts b/src/extension.ts index a86ddf92..e56823df 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -59,6 +59,10 @@ export function activate(ctx: vscode.ExtensionContext) { "snippet.renameSnippet", endpoints.renameSnippet(snippetsTreeProvider) ); + vscode.commands.registerCommand( + "snippet.copySnippet", + endpoints.copySnippet(snippetsTreeProvider) + ); vscode.commands.registerCommand( "snippet.createFolder", endpoints.createFolder(snippetsTreeProvider) diff --git a/src/snippetsTreeProvider.ts b/src/snippetsTreeProvider.ts index c92635b2..c3e7198b 100644 --- a/src/snippetsTreeProvider.ts +++ b/src/snippetsTreeProvider.ts @@ -113,6 +113,10 @@ export class SnippetsTreeItem extends vscode.TreeItem { this.id = id; this.tooltip = content; + this.contextValue = + collapsibleState === vscode.TreeItemCollapsibleState.None + ? "snippet" + : "folder"; if (collapsibleState !== vscode.TreeItemCollapsibleState.None) { return; From 4e4c0ded58c224c9802aa5a7ad493ed66210d66c Mon Sep 17 00:00:00 2001 From: VladBrok Date: Sun, 3 Sep 2023 14:29:28 +0300 Subject: [PATCH 2/3] update docs --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 1c1dec2f..4125d24b 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ A Visual Studio Code extension for [cht.sh](https://cht.sh/). - ${query} - the snippet query (search text) - ${index} - the index of the snippet (e.g. 2 for the third answer) - `insertWithDoubleClick`: insert snippet with double click. +- `showCopySuccessNotification`: Whether to show a notification after the snippet is copied to the clipboard. ## Installation @@ -109,6 +110,12 @@ You can configure a keyboard shortcut. By default this is ⌘ Command ![Preview](https://raw.githubusercontent.com/mre/vscode-snippet/master/contrib/snippets-storage/delete.gif) +### Copying a snippet to the clipboard + +1. Open the Snippets section +2. Right click on the snippet that you want to copy +3. Select "Copy" + ### Moving a snippet or a folder You can move snippets or folders in the Snippets view by dragging and dropping them From 65613099a70f6eb1de609d29576d57ae31cb0c12 Mon Sep 17 00:00:00 2001 From: VladBrok Date: Mon, 4 Sep 2023 21:38:48 +0300 Subject: [PATCH 3/3] add "find and copy" command --- package.json | 5 +++++ src/clipboard.ts | 32 ++++++++++++++++++++++++++++++++ src/endpoints.ts | 32 +++++++++----------------------- src/extension.ts | 4 ++++ src/query.ts | 29 +++++++++++++++++++---------- 5 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 src/clipboard.ts diff --git a/package.json b/package.json index a8788a04..95fe0bcf 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,11 @@ "command": "snippet.copySnippet", "category": "Snippet" }, + { + "title": "Find and copy", + "command": "snippet.findAndCopy", + "category": "Snippet" + }, { "title": "New Folder", "command": "snippet.createFolder", diff --git a/src/clipboard.ts b/src/clipboard.ts new file mode 100644 index 00000000..61e371a7 --- /dev/null +++ b/src/clipboard.ts @@ -0,0 +1,32 @@ +import * as vscode from "vscode"; +import { getConfig } from "./config"; + +export async function copySnippet(content: string): Promise { + try { + await vscode.env.clipboard.writeText(content); + + if (getConfig("showCopySuccessNotification")) { + await showNotification(); + } + } catch { + vscode.window.showErrorMessage( + "Failed to copy the snippet to the clipboard" + ); + } +} +async function showNotification() { + const doNotShowAgain = await vscode.window.showInformationMessage( + "The snippet was copied to the clipboard", + { modal: false }, + "Do not show again" + ); + + if (doNotShowAgain) { + const config = vscode.workspace.getConfiguration("snippet"); + await config.update( + "showCopySuccessNotification", + false, + vscode.ConfigurationTarget.Global + ); + } +} diff --git a/src/endpoints.ts b/src/endpoints.ts index 9246bcf3..5010286a 100644 --- a/src/endpoints.ts +++ b/src/endpoints.ts @@ -1,4 +1,5 @@ import * as vscode from "vscode"; +import * as clipboard from "./clipboard"; import { pickLanguage, getLanguage, getConfig } from "./config"; import { query } from "./query"; import { encodeRequest } from "./provider"; @@ -345,31 +346,16 @@ export function copySnippet(treeProvider: SnippetsTreeProvider) { } const content = treeProvider.storage.getSnippet(item.id); + await clipboard.copySnippet(content); + }; +} - try { - await vscode.env.clipboard.writeText(content); - - if (getConfig("showCopySuccessNotification")) { - const hideNotification = await vscode.window.showInformationMessage( - "The snippet was copied to the clipboard", - { modal: false }, - "Do not show again" - ); +export function findAndCopy(snippetsStorage: SnippetsStorage) { + return async () => { + const language = await getLanguage(); + const userQuery = await query(language, snippetsStorage, true); - if (hideNotification) { - const config = vscode.workspace.getConfiguration("snippet"); - await config.update( - "showCopySuccessNotification", - false, - vscode.ConfigurationTarget.Global - ); - } - } - } catch { - vscode.window.showErrorMessage( - "Failed to copy the snippet to the clipboard" - ); - } + await clipboard.copySnippet(userQuery.savedSnippetContent); }; } diff --git a/src/extension.ts b/src/extension.ts index e56823df..b30c116e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -63,6 +63,10 @@ export function activate(ctx: vscode.ExtensionContext) { "snippet.copySnippet", endpoints.copySnippet(snippetsTreeProvider) ); + vscode.commands.registerCommand( + "snippet.findAndCopy", + endpoints.findAndCopy(snippetsStorage) + ); vscode.commands.registerCommand( "snippet.createFolder", endpoints.createFolder(snippetsTreeProvider) diff --git a/src/query.ts b/src/query.ts index d4e4cfd1..b0ad1f21 100644 --- a/src/query.ts +++ b/src/query.ts @@ -6,7 +6,8 @@ import SnippetsStorage from "./snippetsStorage"; import languages from "./languages"; function quickPickCustom( - items: vscode.QuickPickItem[] + items: vscode.QuickPickItem[], + clearActiveItems = true ): Promise { return new Promise((resolve) => { const quickPick = vscode.window.createQuickPick(); @@ -14,7 +15,9 @@ function quickPickCustom( quickPick.items = items; quickPick.onDidChangeValue(() => { - quickPick.activeItems = []; + if (clearActiveItems) { + quickPick.activeItems = []; + } }); quickPick.onDidAccept(() => { @@ -38,7 +41,8 @@ export interface QueryResult { export async function query( language: string, - snippetsStorage: SnippetsStorage + snippetsStorage: SnippetsStorage, + suggestOnlySaved = false ): Promise { const suggestions = new Set( cache.state.get(`snippet_suggestions_${language}`, []) @@ -58,15 +62,20 @@ export async function query( } } - for (const suggestion of suggestions) { - const tempQuickItem: vscode.QuickPickItem = { - label: suggestion, - description: "", - }; - suggestionsQuickItems.push(tempQuickItem); + if (!suggestOnlySaved) { + for (const suggestion of suggestions) { + const tempQuickItem: vscode.QuickPickItem = { + label: suggestion, + description: "", + }; + suggestionsQuickItems.push(tempQuickItem); + } } - const selectedItem = await quickPickCustom(suggestionsQuickItems); + const selectedItem = await quickPickCustom( + suggestionsQuickItems, + !suggestOnlySaved + ); const input = typeof selectedItem === "string" ? selectedItem : selectedItem.label; const savedSnippetContent =