diff --git a/package-lock.json b/package-lock.json index e92a1dc..bb3382d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10298,7 +10298,7 @@ } }, "packages/css-variables-language-server": { - "version": "2.6.1", + "version": "2.6.2", "license": "MIT", "dependencies": { "axios": "^0.27.2", @@ -10352,10 +10352,7 @@ } }, "packages/vscode-css-variables": { - "version": "2.6.1", - "dependencies": { - "css-variables-language-server": "*" - }, + "version": "2.6.3", "devDependencies": { "@types/mocha": "^9.1.1", "@types/node": "^18.7.13", @@ -10363,6 +10360,7 @@ "@typescript-eslint/eslint-plugin": "^5.35.1", "@typescript-eslint/parser": "^5.35.1", "@vscode/test-electron": "^2.1.5", + "css-variables-language-server": "*", "eslint": "^8.23.0", "eslint-config-airbnb-typescript": "^17.0.0", "mocha": "^10.0.0", diff --git a/packages/css-variables-language-server/src/index.ts b/packages/css-variables-language-server/src/index.ts index d8744b0..34501d1 100644 --- a/packages/css-variables-language-server/src/index.ts +++ b/packages/css-variables-language-server/src/index.ts @@ -199,10 +199,6 @@ connection.onCompletion( sortText: 'z', }; - if (isFunctionCall) { - completion.detail = varSymbol.value; - } - items.push(completion); }); @@ -318,6 +314,37 @@ connection.onDefinition((params) => { return null; }); +// search a css variable by name or value; +connection.onRequest('search', async (params): Promise => { + if (!params || typeof params !== 'string') { + return []; + } + const items: CompletionItem[] = []; + cssVariableManager.getAll().forEach((variable) => { + const varSymbol = variable.symbol; + const { name, value } = varSymbol; + + // either of name and value can compare to params + if (!name.includes(params) && !value.startsWith(params)) { + return; + } + const insertText = `var(${varSymbol.name})`; + const completion: CompletionItem = { + label: name, + detail: value, + documentation: value, + insertText, + kind: isColor(value) + ? CompletionItemKind.Color + : CompletionItemKind.Variable, + sortText: 'z', + }; + items.push(completion); + }); + + return items; +}); + // Make the text document manager listen on the connection // for open, change and close text document events documents.listen(connection); diff --git a/packages/vscode-css-variables/package.json b/packages/vscode-css-variables/package.json index 84ad2be..fcb1c5c 100644 --- a/packages/vscode-css-variables/package.json +++ b/packages/vscode-css-variables/package.json @@ -32,6 +32,12 @@ }, "main": "./dist/index.js", "contributes": { + "commands": [ + { + "command": "vscode-css-variables.search", + "title": "Search for css variable" + } + ], "configuration": { "title": "CSS Variables", "properties": { @@ -141,4 +147,4 @@ "publisherId": "411219bd-68b8-4df2-9a3b-1ac214fcfd05", "isPreReleaseVersion": false } -} +} \ No newline at end of file diff --git a/packages/vscode-css-variables/src/commands.ts b/packages/vscode-css-variables/src/commands.ts new file mode 100644 index 0000000..2e638aa --- /dev/null +++ b/packages/vscode-css-variables/src/commands.ts @@ -0,0 +1,18 @@ +import { commands, ExtensionContext, window } from "vscode"; +import { LanguageClient } from "vscode-languageclient/node"; +import search from "./commands/search"; + +export const commandsMap = { + "vscode-css-variables.search": search, +}; + +export default function registerCommands( + context: ExtensionContext, + client: LanguageClient +) { + Object.entries(commandsMap).forEach(([name, command]) => { + context.subscriptions.push( + commands.registerCommand(name, () => command(client)) + ); + }); +} diff --git a/packages/vscode-css-variables/src/commands/search.ts b/packages/vscode-css-variables/src/commands/search.ts new file mode 100644 index 0000000..cd36753 --- /dev/null +++ b/packages/vscode-css-variables/src/commands/search.ts @@ -0,0 +1,37 @@ +import { window } from "vscode"; +import { LanguageClient, CompletionItem } from "vscode-languageclient/node"; + +export default async function search(client: LanguageClient) { + const editor = window.activeTextEditor; + + // 获取当前选择的文本 + const selectedText = editor?.document.getText(editor.selection)?.trim() ?? ""; + // 将颜色值或简单文本作为搜索依据 + const defaultInput = /^(#[0-9A-Fa-f]{3,6})$|^[\w-]+$/.test(selectedText) + ? selectedText + : ""; + const input = await window.showInputBox({ + value: defaultInput, + prompt: "Enter the CSS variable name or value to search", + }); + if (!input) { + return; + } + + // 向 language server 发送请求,获取选项数据 + const options: CompletionItem[] = await client.sendRequest("search", input); + + // 如果没有查询到数据,就返回 + if (options.length === 0) { + window.showInformationMessage(`No css variable found for '${input}'`); + return; + } + + // 弹出命令选项,将选项数据提供给用户选择 + const selectedOption = await window.showQuickPick(options); + if (selectedOption && editor) { + editor.edit((edit) => { + edit.replace(editor.selection, selectedOption.insertText); + }); + } +} diff --git a/packages/vscode-css-variables/src/index.ts b/packages/vscode-css-variables/src/index.ts index f5bddb6..65567ef 100644 --- a/packages/vscode-css-variables/src/index.ts +++ b/packages/vscode-css-variables/src/index.ts @@ -12,6 +12,7 @@ import { ServerOptions, TransportKind, } from 'vscode-languageclient/node'; +import registerCommands from './commands'; let client: LanguageClient; @@ -76,6 +77,8 @@ export function activate(context: ExtensionContext) { // Start the client. This will also launch the server client.start(); + + registerCommands(context, client); } export function deactivate(): Thenable | undefined {