Skip to content

Commit

Permalink
Merge pull request #418 from mre/feat/copy-snippet
Browse files Browse the repository at this point in the history
Add an ability to copy saved snippet to the clipboard
  • Loading branch information
VladBrok authored Sep 5, 2023
2 parents 7c1212a + 6561309 commit 9b8c5e9
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 15 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

![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
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 23 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -105,6 +105,16 @@
"command": "snippet.renameSnippet",
"category": "Snippet"
},
{
"title": "Copy",
"command": "snippet.copySnippet",
"category": "Snippet"
},
{
"title": "Find and copy",
"command": "snippet.findAndCopy",
"category": "Snippet"
},
{
"title": "New Folder",
"command": "snippet.createFolder",
Expand Down Expand Up @@ -147,6 +157,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."
}
}
},
Expand All @@ -164,15 +179,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": [
Expand Down
32 changes: 32 additions & 0 deletions src/clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as vscode from "vscode";
import { getConfig } from "./config";

export async function copySnippet(content: string): Promise<void> {
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
);
}
}
24 changes: 24 additions & 0 deletions src/endpoints.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -335,6 +336,29 @@ 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);
await clipboard.copySnippet(content);
};
}

export function findAndCopy(snippetsStorage: SnippetsStorage) {
return async () => {
const language = await getLanguage();
const userQuery = await query(language, snippetsStorage, true);

await clipboard.copySnippet(userQuery.savedSnippetContent);
};
}

export function createFolder(treeProvider: SnippetsTreeProvider) {
return async (item?: SnippetsTreeItem) => {
const opt: vscode.InputBoxOptions = {
Expand Down
8 changes: 8 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ export function activate(ctx: vscode.ExtensionContext) {
"snippet.renameSnippet",
endpoints.renameSnippet(snippetsTreeProvider)
);
vscode.commands.registerCommand(
"snippet.copySnippet",
endpoints.copySnippet(snippetsTreeProvider)
);
vscode.commands.registerCommand(
"snippet.findAndCopy",
endpoints.findAndCopy(snippetsStorage)
);
vscode.commands.registerCommand(
"snippet.createFolder",
endpoints.createFolder(snippetsTreeProvider)
Expand Down
29 changes: 19 additions & 10 deletions src/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import SnippetsStorage from "./snippetsStorage";
import languages from "./languages";

function quickPickCustom(
items: vscode.QuickPickItem[]
items: vscode.QuickPickItem[],
clearActiveItems = true
): Promise<string | vscode.QuickPickItem> {
return new Promise((resolve) => {
const quickPick = vscode.window.createQuickPick();
quickPick.title = 'Enter keywords for snippet search (e.g. "read file")';
quickPick.items = items;

quickPick.onDidChangeValue(() => {
quickPick.activeItems = [];
if (clearActiveItems) {
quickPick.activeItems = [];
}
});

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

export async function query(
language: string,
snippetsStorage: SnippetsStorage
snippetsStorage: SnippetsStorage,
suggestOnlySaved = false
): Promise<QueryResult> {
const suggestions = new Set(
cache.state.get<string[]>(`snippet_suggestions_${language}`, [])
Expand All @@ -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 =
Expand Down
4 changes: 4 additions & 0 deletions src/snippetsTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 9b8c5e9

Please sign in to comment.