Skip to content

Commit 59505bd

Browse files
authored
Merge pull request #382 from mre/feat/377
Saved snippets searching
2 parents 418b789 + c38621a commit 59505bd

File tree

8 files changed

+150
-65
lines changed

8 files changed

+150
-65
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ Saved snippets are displayed in IntelliSense
121121

122122
![Preview](https://raw.githubusercontent.com/mre/vscode-snippet/master/contrib/snippets-storage/intellisense.gif)
123123

124+
### Searching for saved snippets
125+
126+
![Preview](https://raw.githubusercontent.com/mre/vscode-snippet/master/contrib/snippets-storage/search.gif)
127+
124128
## Contributing
125129

126130
See [CONTRIBUTING.md](./CONTRIBUTING.md)

contrib/snippets-storage/search.gif

207 KB
Loading

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
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.0.3",
5+
"version": "1.0.4",
66
"publisher": "vscode-snippet",
77
"engines": {
88
"vscode": "^1.74.0"

src/endpoints.ts

+62-37
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import { query } from "./query";
44
import { encodeRequest } from "./provider";
55
import snippet from "./snippet";
66
import { SnippetsTreeProvider, SnippetsTreeItem } from "./snippetsTreeProvider";
7+
import SnippetsStorage from "./snippetsStorage";
8+
import languages from "./languages";
79

810
export interface Request {
911
language: string;
1012
query: string;
13+
savedSnippetContent?: string;
1114
}
1215

1316
const loadingStatus = vscode.window.createStatusBarItem(
@@ -20,98 +23,116 @@ export async function findWithProvider(
2023
userQuery: string,
2124
verbose: boolean,
2225
number: number,
23-
openInNewEditor = true
26+
openInNewEditor = true,
27+
savedSnippetContent?: string
2428
) {
2529
let doc: vscode.TextDocument | null = null;
2630

27-
loadingStatus.show();
28-
try {
29-
const uri = encodeRequest(userQuery, language, verbose, number);
31+
if (!savedSnippetContent) {
32+
loadingStatus.show();
33+
try {
34+
const uri = encodeRequest(userQuery, language, verbose, number);
3035

31-
// Calls back into the provider
32-
doc = await vscode.workspace.openTextDocument(uri);
33-
} finally {
34-
loadingStatus.hide();
35-
}
36+
// Calls back into the provider
37+
doc = await vscode.workspace.openTextDocument(uri);
38+
} finally {
39+
loadingStatus.hide();
40+
}
3641

37-
try {
38-
doc = await vscode.languages.setTextDocumentLanguage(doc, language);
39-
} catch (e) {
40-
console.log(`Cannot set document language to ${language}: ${e}`);
42+
try {
43+
doc = await vscode.languages.setTextDocumentLanguage(doc, language);
44+
} catch (e) {
45+
console.log(`Cannot set document language to ${language}: ${e}`);
46+
}
4147
}
48+
4249
const editor = vscode.window.activeTextEditor;
4350

44-
// Open in new editor in case the respective config flag is set to true
51+
// Open in new editor in case there is no saved snippet content and the respective config flag is set to true
4552
// or there is no open user-created editor where we could paste the snippet in.
46-
if (openInNewEditor || !editor || editor.document.uri.scheme == "snippet") {
53+
if (
54+
!savedSnippetContent &&
55+
(openInNewEditor || !editor || editor.document.uri.scheme == "snippet")
56+
) {
4757
await vscode.window.showTextDocument(doc, {
4858
viewColumn: vscode.ViewColumn.Two,
4959
preview: true,
5060
preserveFocus: false,
5161
});
5262
} else {
53-
const snippet = new vscode.SnippetString(doc.getText());
63+
const text = savedSnippetContent ? savedSnippetContent : doc.getText();
64+
const snippet = new vscode.SnippetString(text);
5465
const success = await editor.insertSnippet(snippet);
5566
if (!success) {
5667
vscode.window.showInformationMessage("Error while opening snippet.");
5768
}
5869
}
5970
}
6071

61-
export async function getInput(): Promise<Request> {
72+
export async function getInput(
73+
snippetsStorage: SnippetsStorage
74+
): Promise<Request> {
6275
const language = await getLanguage();
63-
const userQuery = await query(language);
64-
return { language, query: userQuery };
76+
const userQuery = await query(language, snippetsStorage);
77+
return {
78+
language,
79+
query: userQuery.input,
80+
savedSnippetContent: userQuery.savedSnippetContent,
81+
};
6582
}
6683

67-
export async function findForLanguage() {
84+
export async function findForLanguage(snippetsStorage: SnippetsStorage) {
6885
const language = await pickLanguage();
69-
const userQuery = await query(language);
86+
const userQuery = await query(language, snippetsStorage);
7087
await findWithProvider(
7188
language,
72-
userQuery,
89+
userQuery.input,
7390
snippet.getVerbose(),
7491
0,
75-
getConfig("openInNewEditor")
92+
getConfig("openInNewEditor"),
93+
userQuery.savedSnippetContent
7694
);
7795
}
7896

79-
export async function findDefault() {
80-
const request = await getInput();
97+
export async function findDefault(snippetsStorage: SnippetsStorage) {
98+
const request = await getInput(snippetsStorage);
8199
await findWithProvider(
82100
request.language,
83101
request.query,
84102
snippet.getVerbose(),
85103
0,
86-
getConfig("openInNewEditor")
104+
getConfig("openInNewEditor"),
105+
request.savedSnippetContent
87106
);
88107
}
89108

90-
export async function findInplace() {
91-
const request = await getInput();
109+
export async function findInplace(snippetsStorage: SnippetsStorage) {
110+
const request = await getInput(snippetsStorage);
92111
await findWithProvider(
93112
request.language,
94113
request.query,
95114
snippet.getVerbose(),
96115
0,
97-
false
116+
false,
117+
request.savedSnippetContent
98118
);
99119
}
100120

101-
export async function findInNewEditor() {
102-
const request = await getInput();
121+
export async function findInNewEditor(snippetsStorage: SnippetsStorage) {
122+
const request = await getInput(snippetsStorage);
103123
await findWithProvider(
104124
request.language,
105125
request.query,
106126
snippet.getVerbose(),
107127
0,
108-
true
128+
true,
129+
request.savedSnippetContent
109130
);
110131
}
111132

112-
export async function showNextAnswer() {
133+
export async function showNextAnswer(snippetsStorage: SnippetsStorage) {
113134
if (!snippet.getCurrentQuery()) {
114-
return await findDefault();
135+
return await findDefault(snippetsStorage);
115136
}
116137
const answerNumber = snippet.getNextAnswerNumber();
117138
await findWithProvider(
@@ -123,9 +144,9 @@ export async function showNextAnswer() {
123144
);
124145
}
125146

126-
export async function showPreviousAnswer() {
147+
export async function showPreviousAnswer(snippetsStorage: SnippetsStorage) {
127148
if (!snippet.getCurrentQuery()) {
128-
return await findDefault();
149+
return await findDefault(snippetsStorage);
129150
}
130151
const answerNumber = snippet.getPreviousAnswerNumber();
131152
if (answerNumber == null) {
@@ -204,8 +225,12 @@ export function saveSnippet(treeProvider: SnippetsTreeProvider) {
204225
const defaultLabel = content.substring(0, 100);
205226
const fileName = editor.document.fileName;
206227
const indexOfLastDot = fileName.lastIndexOf(".");
228+
const extensionByLangId =
229+
languages.getExtensions(editor.document.languageId)[0] || "";
207230
const fileExtension =
208-
indexOfLastDot === -1 ? "" : fileName.slice(indexOfLastDot);
231+
indexOfLastDot === -1
232+
? extensionByLangId
233+
: fileName.slice(indexOfLastDot);
209234

210235
const nameInputOptions: vscode.InputBoxOptions = {
211236
ignoreFocusOut: false,

src/extension.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,27 @@ export function activate(ctx: vscode.ExtensionContext) {
1616
const snippetsTreeProvider = new SnippetsTreeProvider(ctx, snippetsStorage);
1717
new CompletionManager(ctx, snippetsStorage);
1818

19-
vscode.commands.registerCommand("snippet.find", endpoints.findDefault);
20-
vscode.commands.registerCommand(
21-
"snippet.findForLanguage",
22-
endpoints.findForLanguage
19+
vscode.commands.registerCommand("snippet.find", () =>
20+
endpoints.findDefault(snippetsStorage)
2321
);
24-
vscode.commands.registerCommand("snippet.findInplace", endpoints.findInplace);
25-
vscode.commands.registerCommand(
26-
"snippet.findInNewEditor",
27-
endpoints.findInNewEditor
22+
vscode.commands.registerCommand("snippet.findForLanguage", () =>
23+
endpoints.findForLanguage(snippetsStorage)
24+
);
25+
vscode.commands.registerCommand("snippet.findInplace", () =>
26+
endpoints.findInplace(snippetsStorage)
27+
);
28+
vscode.commands.registerCommand("snippet.findInNewEditor", () =>
29+
endpoints.findInNewEditor(snippetsStorage)
2830
);
2931
vscode.commands.registerCommand(
3032
"snippet.findSelectedText",
3133
endpoints.findSelectedText
3234
);
33-
vscode.commands.registerCommand(
34-
"snippet.showPreviousAnswer",
35-
endpoints.showPreviousAnswer
35+
vscode.commands.registerCommand("snippet.showPreviousAnswer", () =>
36+
endpoints.showPreviousAnswer(snippetsStorage)
3637
);
37-
vscode.commands.registerCommand(
38-
"snippet.showNextAnswer",
39-
endpoints.showNextAnswer
38+
vscode.commands.registerCommand("snippet.showNextAnswer", () =>
39+
endpoints.showNextAnswer(snippetsStorage)
4040
);
4141
vscode.commands.registerCommand(
4242
"snippet.toggleComments",

src/languages.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import * as vscode from "vscode";
2+
3+
class Languages {
4+
constructor(private readonly fileExtensions = new Map<string, string[]>()) {
5+
for (const extension of vscode.extensions.all) {
6+
const languages = extension.packageJSON.contributes.languages;
7+
if (languages) {
8+
for (const lang of languages) {
9+
fileExtensions.set(lang.id, lang.extensions);
10+
}
11+
}
12+
}
13+
}
14+
15+
getExtensions(languageId: string): string[] {
16+
return this.fileExtensions.get(languageId) || [];
17+
}
18+
}
19+
20+
export default new Languages();

src/query.ts

+47-11
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
import * as vscode from "vscode";
44
import { cache } from "./cache";
5+
import SnippetsStorage from "./snippetsStorage";
6+
import languages from "./languages";
57

6-
function quickPickCustom(items: vscode.QuickPickItem[]): Promise<string> {
8+
function quickPickCustom(
9+
items: vscode.QuickPickItem[]
10+
): Promise<string | vscode.QuickPickItem> {
711
return new Promise((resolve) => {
812
const quickPick = vscode.window.createQuickPick();
913
quickPick.title = 'Enter keywords for snippet search (e.g. "read file")';
@@ -14,9 +18,9 @@ function quickPickCustom(items: vscode.QuickPickItem[]): Promise<string> {
1418
});
1519

1620
quickPick.onDidAccept(() => {
17-
let search = "";
21+
let search: string | vscode.QuickPickItem = "";
1822
if (quickPick.activeItems.length) {
19-
search = quickPick.activeItems[0]["label"];
23+
search = quickPick.activeItems[0];
2024
} else {
2125
search = quickPick.value;
2226
}
@@ -27,24 +31,56 @@ function quickPickCustom(items: vscode.QuickPickItem[]): Promise<string> {
2731
});
2832
}
2933

30-
export async function query(language: string): Promise<string> {
34+
export interface QueryResult {
35+
input: string;
36+
savedSnippetContent?: string;
37+
}
38+
39+
export async function query(
40+
language: string,
41+
snippetsStorage: SnippetsStorage
42+
): Promise<QueryResult> {
3143
const suggestions = new Set(
3244
cache.state.get<string[]>(`snippet_suggestions_${language}`, [])
3345
);
3446

3547
const suggestionsQuickItems: Array<vscode.QuickPickItem> = [];
48+
const languageFileExtensions = languages.getExtensions(language);
49+
const savedSnippetDescription = "[saved snippet]";
50+
51+
for (const snippet of snippetsStorage.getSnippets()) {
52+
if (languageFileExtensions.includes(snippet.data.fileExtension)) {
53+
suggestionsQuickItems.push({
54+
label: snippet.data.label,
55+
detail: snippet.data.content,
56+
description: savedSnippetDescription,
57+
});
58+
}
59+
}
60+
3661
for (const suggestion of suggestions) {
3762
const tempQuickItem: vscode.QuickPickItem = {
3863
label: suggestion,
3964
description: "",
4065
};
4166
suggestionsQuickItems.push(tempQuickItem);
4267
}
43-
const input = await quickPickCustom(suggestionsQuickItems);
44-
suggestions.add(input);
45-
cache.state.update(
46-
`snippet_suggestions_${language}`,
47-
[...suggestions].sort()
48-
);
49-
return input;
68+
69+
const selectedItem = await quickPickCustom(suggestionsQuickItems);
70+
const input =
71+
typeof selectedItem === "string" ? selectedItem : selectedItem.label;
72+
const savedSnippetContent =
73+
typeof selectedItem === "string" ||
74+
selectedItem.description !== savedSnippetDescription
75+
? undefined
76+
: selectedItem.detail;
77+
78+
if (!savedSnippetContent) {
79+
suggestions.add(input);
80+
cache.state.update(
81+
`snippet_suggestions_${language}`,
82+
[...suggestions].sort()
83+
);
84+
}
85+
return { input, savedSnippetContent };
5086
}

0 commit comments

Comments
 (0)