十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶(hù) + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂(yōu)售后,網(wǎng)站問(wèn)題一站解決
今天小編給大家分享一下如何開(kāi)發(fā)一個(gè)提示顏色代碼的VS Code插件的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

為企業(yè)提供做網(wǎng)站、網(wǎng)站制作、網(wǎng)站優(yōu)化、成都全網(wǎng)營(yíng)銷(xiāo)推廣、競(jìng)價(jià)托管、品牌運(yùn)營(yíng)等營(yíng)銷(xiāo)獲客服務(wù)。成都創(chuàng)新互聯(lián)公司擁有網(wǎng)絡(luò)營(yíng)銷(xiāo)運(yùn)營(yíng)團(tuán)隊(duì),以豐富的互聯(lián)網(wǎng)營(yíng)銷(xiāo)經(jīng)驗(yàn)助力企業(yè)精準(zhǔn)獲客,真正落地解決中小企業(yè)營(yíng)銷(xiāo)獲客難題,做到“讓獲客更簡(jiǎn)單”。自創(chuàng)立至今,成功用技術(shù)實(shí)力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營(yíng)銷(xiāo)”三大難題,同時(shí)降低了營(yíng)銷(xiāo)成本,提高了有效客戶(hù)轉(zhuǎn)化率,獲得了眾多企業(yè)客戶(hù)的高度認(rèn)可!
我在寫(xiě)css時(shí),經(jīng)常會(huì)有顏色選擇困難癥,雖然VS Code內(nèi)置的插件提供了取色器,但在256^3的顏色中去選取,未必能找到符合期望的顏色。于是我想要是有個(gè)顏色提示插件就好了,只要我輸入# + 顏色名,就能以代碼提示的方式,將對(duì)應(yīng)的顏色列出來(lái)供我選擇。
首先第一件事就是要有現(xiàn)成的顏色代碼,很快我就找到了這個(gè)網(wǎng)站:中國(guó)色
這個(gè)網(wǎng)站提供了500多種顏色的rgb值以及hex值,打開(kāi)瀏覽器控制臺(tái),輸入colorsArray就能全部拿到,這就是我想要的。
從網(wǎng)站底部的信息來(lái)看,這個(gè)網(wǎng)站是山寨自日本色,顏色據(jù)稱(chēng)來(lái)自中科院科技情報(bào)編委會(huì)名詞室編寫(xiě)、科學(xué)出版社1957年出版的《色譜》。
這個(gè)顏色來(lái)源是否可信我無(wú)從考證,隨便百度一下“中國(guó)傳統(tǒng)色”,就可以找到很多版本的所謂中國(guó)色,我在github上還找到了另一個(gè)接近2k star的中國(guó)色項(xiàng)目:中國(guó)傳統(tǒng)顏色手冊(cè),這個(gè)網(wǎng)站使用的顏色與前者完全不同,是來(lái)自于一篇現(xiàn)在已經(jīng)無(wú)法查看的新浪博客,顏色數(shù)量我沒(méi)有統(tǒng)計(jì),粗略估計(jì)在200以?xún)?nèi)。
安裝開(kāi)發(fā)工具
npm i -g yo generator-code
新建項(xiàng)目
yo code
初始項(xiàng)目中有個(gè)Hello World,用VS Code打開(kāi)項(xiàng)目,然后按F5(或者點(diǎn)擊“運(yùn)行-->啟動(dòng)調(diào)試”)可以開(kāi)啟調(diào)試窗口。
然后在調(diào)試窗口下 Ctrl + Shift + P (或者點(diǎn)擊“設(shè)置-->命令面板”),輸入并選擇 Hello World 命令,就會(huì)在編輯器右下角彈出一個(gè)消息提示。
extension.ts是插件的入口文件:
import * as vscode from 'vscode';
// activate方法會(huì)在插件被激活時(shí)調(diào)用
export function activate(context: vscode.ExtensionContext) {
// 注冊(cè)命令,第一個(gè)參數(shù)是命令名稱(chēng),第二參數(shù)是回調(diào)
let disposable = vscode.commands.registerCommand('chinese-colors.helloWorld', () => {
// 彈出消息提示
vscode.window.showInformationMessage('Hello World from Chinese Colors!');
});
// 添加到插件上下文
context.subscriptions.push(disposable);
}
// deactivate方法會(huì)在插件失活時(shí)調(diào)用
export function deactivate() {}
查看package.json,其中比較重要的兩項(xiàng):
{
"activationEvents": [
"onCommand:chinese-colors.helloWorld"
],
"contributes": {
"commands": [
{
"command": "chinese-colors.helloWorld",
"title": "Hello World"
}
]
},
}
activationEvents是插件的激活配置,它是一個(gè)數(shù)組,每一項(xiàng)對(duì)應(yīng)一個(gè)激活插件的條件,格式為“<類(lèi)型>:<名稱(chēng)>”,onCommand是調(diào)用命令(也就是上面的輸入Hello World)。
contributes:一般翻譯為貢獻(xiàn)點(diǎn),配置了一個(gè)“chinese-colors.helloWorld”,與activationEvents配置項(xiàng)對(duì)應(yīng)。
其他packege.json配置見(jiàn)下表:
| 名稱(chēng) | 必要 | 類(lèi)型 | 說(shuō)明 |
|---|---|---|---|
name | 是 | string | 插件名稱(chēng),必須為小寫(xiě)且不能有空格。 |
version | 是 | string | 插件版本 |
publisher | 是 | string | 發(fā)布者 |
engines | 是 | object | 一個(gè)至少包含vscode鍵值對(duì)的對(duì)象,該鍵表示的是本插件可兼容的VS Code的版本,其值不能為*。比如 ^0.10.5 表示插件兼容VS Code的最低版本是0.10.5。 |
license | 否 | string | 授權(quán)。如果有授權(quán)文檔LICENSE.md,可以把license值設(shè)為"SEE LICENSE IN LICENSE.md"。 |
displayName | 否 | string | 插件市場(chǎng)中顯示的名字。 |
description | 否 | string | 描述,說(shuō)明本插件是什么以及做什么。 |
categories | 否 | string[] | 插件類(lèi)型:[Languages, Snippets, Linters, Themes, Debuggers, Other] |
keywords | 否 | array | 一組 關(guān)鍵字或者 標(biāo)記,方便在插件市場(chǎng)中查找。 |
galleryBanner | 否 | object | 插件市場(chǎng)中橫幅的樣式。 |
preview | 否 | boolean | 在市場(chǎng)中把本插件標(biāo)記為預(yù)覽版本。 |
main | 否 | string | 插件的入口文件。 |
contributes | 否 | object | 一個(gè)描述插件 貢獻(xiàn)點(diǎn) 的對(duì)象。 |
activationEvents | 否 | array | 一組用于本插件的激活事件。 |
dependencies | 否 | object | 生產(chǎn)環(huán)境Node.js依賴(lài)項(xiàng)。 |
devDependencies | 否 | object | 開(kāi)發(fā)環(huán)境Node.js依賴(lài)項(xiàng)。 |
extensionDependencies | 否 | array | 一組本插件所需的其他插件的ID值。格式 ${publisher}.${name}。比如:vscode.csharp。 |
scripts | 否 | object | 和 npm的 scripts一樣,但還有一些額外VS Code特定字段。 |
icon | 否 | string | 一個(gè)128x128像素圖標(biāo)的路徑。 |
顏色代碼有多種表示方式,比較常用的是16進(jìn)制(#ffffff)和rgb(255,255,255)這兩種,因此我需要讓用戶(hù)自己選擇采用哪種方式。
在contributes中有個(gè)configuration,允許用戶(hù)對(duì)插件進(jìn)行一些自定義配置。
package.json:
{
// ...
"contributes": {
"configuration": [{
"title": "color mode",// 配置項(xiàng)名稱(chēng)
"properties": {
// 配置屬性
"RGB": {
"type": "boolean", // 屬性值類(lèi)型
"default": false, // 屬性默認(rèn)值
"description": "控制預(yù)設(shè)的中國(guó)色采用RGB格式" // 屬性描述
}
}
}]
},
}
這樣就可以在擴(kuò)展設(shè)置中進(jìn)行一些自定義的設(shè)置:
我們可以通過(guò)workspace.getConfiguration()獲取用戶(hù)的配置。
import { workspace } from "vscode";
const configuration = workspace.getConfiguration();
const isRGB = configuration.RGB;
代碼補(bǔ)全API:
vscode.languages.registerCompletionItemProvider(selector, provider, …triggerCharacters)
該方法有三個(gè)參數(shù):
| 參數(shù) | Description |
|---|---|
| selector: string/string[] | 選擇編程語(yǔ)言,比如python |
| provider | 供應(yīng)者配置對(duì)象 |
| triggerCharacters: string/string[] | 觸發(fā)字符, 比如 . 或 : |
register completion item provider(注冊(cè)完成件供應(yīng)者),這個(gè)provider也是比較費(fèi)解的一個(gè)詞,直譯是供應(yīng)者,我猜:代碼補(bǔ)全就相當(dāng)于插件給我們供應(yīng)了代碼,所以叫provider。
provider是一個(gè)對(duì)象,要求必須包含一個(gè)叫provideCompletionItems的方法,該方法需要返回一個(gè)數(shù)組,數(shù)組的每一項(xiàng)是一個(gè)CompletionItem對(duì)象,規(guī)定了代碼提示和補(bǔ)全的規(guī)則。
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
// 注冊(cè)供應(yīng)者:languages.registerCompletionItemProvider
const provider2 = vscode.languages.registerCompletionItemProvider(
'plaintext',// plaintext,表示對(duì)txt文檔激活該插件
{
// 實(shí)現(xiàn)provideCompletionItems方法
// document的內(nèi)容見(jiàn)下文,position為當(dāng)前光標(biāo)的位置
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
// 獲取當(dāng)前這行代碼
const linePrefix = document.lineAt(position).text.substr(0, position.character);
// 如果這行代碼不是以console.結(jié)尾,返回undefined,表示不會(huì)彈出代碼提示
if (!linePrefix.endsWith('console.')) {
return undefined;
}
// 返回CompletionItem對(duì)象組成的數(shù)組,補(bǔ)全代碼列表:log、warn、error
// CompletionItem對(duì)象可以自己創(chuàng)建,也可以像下面這樣new vscode.CompletionItem的方式創(chuàng)建
// vscode.CompletionItem()有兩個(gè)參數(shù):
// 第一個(gè)是補(bǔ)全的代碼,第二個(gè)是代碼類(lèi)型,用于控制顯示在每一行提示前的圖標(biāo)
// vscode.CompletionItemKind.Method表示該代碼是一個(gè)方法
return [
new vscode.CompletionItem('log', vscode.CompletionItemKind.Method),
new vscode.CompletionItem('warn', vscode.CompletionItemKind.Method),
new vscode.CompletionItem('error', vscode.CompletionItemKind.Method),
];
}
},
'.' // 以.作為觸發(fā)
);
context.subscriptions.push(provider2);
}
provideCompletionItems參數(shù):
position:當(dāng)前光標(biāo)所處的位置。
document:用于獲取、控制文檔的內(nèi)容或狀態(tài),這里列舉幾個(gè)常用的方法和屬性:
方法:
getWordRangeAtPosition(position): Range:獲取指定位置單詞的范圍(起始位置)
getText(Range):string:獲取指定范圍的文本
lineAt(position):string:獲取指定位置的文本
validatePosition(position):Position:獲取鼠標(biāo)停留的位置
屬性
lineCount:總代碼行數(shù)
languageId:語(yǔ)言名稱(chēng)
isClosed:當(dāng)前文件是否關(guān)閉
isDirty:當(dāng)前文件的代碼是否更改未保存
CompletionItem對(duì)象可以通過(guò)new vscode.CompletionItem()的方式創(chuàng)建,但它默認(rèn)只能補(bǔ)全代碼,不能自定義替換,并不能滿(mǎn)足我的需求,因此需要自己創(chuàng)建。
CompletionItem對(duì)象包含的屬性:
| 屬性 | 說(shuō)明 |
|---|---|
| detail: string | 語(yǔ)義化描述 |
| documentation: string | 語(yǔ)義化描述 |
| filterText: string | 代碼過(guò)濾。匹配輸入的內(nèi)容,沒(méi)有設(shè)置時(shí),使用label |
| insertText: string | 插入、補(bǔ)全的代碼。沒(méi)有設(shè)置時(shí),使用label |
| label: string | 默認(rèn)的匹配代碼、補(bǔ)全代碼 |
| kind | 代碼類(lèi)型,控制顯示代碼提示前的圖標(biāo) |
| sortText: string | 排序文本,與sortText匹配的提示代碼會(huì)排在靠前的位置 |
| textEdit | 對(duì)補(bǔ)全代碼進(jìn)行編輯,如果設(shè)置了textEdit,insertText會(huì)失效 |
kind的取值:
Class
Color
Constructor
Enum
Field
File
Function
Interface
Keyword
Method
Module
Property
Reference
Snippet
Text
Unit
Value
Variable
import * as vscode from "vscode";
import { CompletionItemKind } from "vscode";
export function activate(context: vscode.ExtensionContext) {
const cc = vscode.languages.registerCompletionItemProvider(
"css",
{
provideCompletionItems() {
return [
{
detail: '#66ccff',
documentation: '天依藍(lán)',
kind: CompletionItemKind.Color,
filterText: `#66ccff天依藍(lán)`,
label: '天依藍(lán)',
insertText: '#66ccff'
},
{
detail: '#39c5bb',
documentation: '初音綠',
kind: CompletionItemKind.Color,
filterText: `#39c5bb初音綠`,
label: '初音綠',
insertText: '#39c5bb'
}
];
},
},
"#"
);
context.subscriptions.push(cc);
}
export function deactivate() {}
記得要在package.json里配置激活:
"activationEvents": [
"onLanguage:css"
]
package.json關(guān)鍵配置:
{
"activationEvents": [
"onLanguage:css",
"onLanguage:scss",
"onLanguage:sass",
"onLanguage:less",
"onLanguage:stylus",
"onLanguage:html",
"onLanguage:xml",
"onLanguage:json",
"onLanguage:javascript",
"onLanguage:typescript",
"onLanguage:javascriptreact",
"onLanguage:typescriptreact",
"onLanguage:vue",
"onLanguage:vue-html"
],
"contributes": {
"configuration": [{
"title": "Chinese Colors",
"properties": {
"RGB": {
"type": "boolean",
"default": false,
"description": "控制預(yù)設(shè)的中國(guó)色采用RGB格式"
}
}
}]
},
}
顏色列表colors.ts:
// 聲明Color類(lèi)型
export type Color = {
rgb: number[];
hex: string;
name: string;
phonics: string;
};
// 這里只列兩個(gè)顏色
export const colors: Color[] = [
{
rgb: [92, 34, 35],
hex: "#5c2223",
name: "暗玉紫",
phonics: "anyuzi",
},
{
rgb: [238, 162, 164],
hex: "#eea2a4",
name: "牡丹粉紅",
phonics: "mudanfenhong",
},
// ...
]
extensions.ts
import * as vscode from "vscode";
import { workspace, CompletionItemKind } from "vscode";
import { colors, Color } from "./colors";
const isRgb = workspace.getConfiguration().RGB;
export function activate(context: vscode.ExtensionContext) {
const cc = vscode.languages.registerCompletionItemProvider(
[
"css",
"scss",
"sass",
"less",
"stylus",
"html",
"xml",
"json",
"javascript",
"typescript",
"javascriptreact",
"typescriptreact",
"vue",
"vue-html",
],// activationEvents
{
provideCompletionItems() {
const list = [] as CompletionItemKind[];
colors.forEach((color: Color) => {
list.push({
detail: isRgb ? rgb : hex,
documentation: color.name,
kind: CompletionItemKind.Color,
filterText: "#" + color.name + color.phonics,
label: color.name,
insertText: isRgb ? rgb : hex,
});
});
return list;
},
},
"#"
);
context.subscriptions.push(cc);
}
export function deactivate() {}
如此,代碼補(bǔ)全的功能已經(jīng)基本實(shí)現(xiàn),實(shí)際開(kāi)發(fā)時(shí),為了便于維護(hù),需要將這部分邏輯抽離出來(lái)。
接下來(lái),需要實(shí)現(xiàn)顏色的預(yù)覽,雖然VS Code內(nèi)置的插件已經(jīng)實(shí)現(xiàn)了這項(xiàng)功能,但我的需求是:不僅能預(yù)覽顏色,還得顯示顏色名稱(chēng)。
實(shí)現(xiàn)顏色預(yù)覽需要用到裝飾效果,涉及以下這些API:
window.createTextEditorDecorationType(options):創(chuàng)建裝飾效果的類(lèi)型
window.activeTextEditor.setDecorations(decorationType, decorations):添加裝飾效果至文檔
window.onDidChangeActiveTextEditor:文檔內(nèi)容變化事件
workspace.onDidChangeTextDocument:切換文檔事件
首先來(lái)看一下官方提供的示例片段
import * as vscode from 'vscode';
// 插件激活時(shí)調(diào)用
export function activate(context: vscode.ExtensionContext) {
console.log('decorator sample is activated');
let timeout: NodeJS.Timer | undefined = undefined;
// 為small numbers創(chuàng)建裝飾效果類(lèi)型
const smallNumberDecorationType = vscode.window.createTextEditorDecorationType({
// 以下是裝飾效果的樣式
borderWidth: '1px',
borderStyle: 'solid',
overviewRulerColor: 'blue',
overviewRulerLane: vscode.OverviewRulerLane.Right,
light: {
// 亮色主題下的邊框顏色
borderColor: 'darkblue'
},
dark: {
// 暗色主題下的邊框顏色
borderColor: 'lightblue'
}
});
// 為large numbers創(chuàng)建裝飾效果類(lèi)型
const largeNumberDecorationType = vscode.window.createTextEditorDecorationType({
cursor: 'crosshair',
// 設(shè)置裝飾的背景顏色, 在package.json中可以配置該名稱(chēng)對(duì)應(yīng)的顏色
backgroundColor: { id: 'myextension.largeNumberBackground' }
});
// activeEditor是當(dāng)前活躍(展示)的文檔編輯器實(shí)例
let activeEditor = vscode.window.activeTextEditor;
// updateDecorations方法,在每次文檔被更新或切換文檔時(shí)調(diào)用。
function updateDecorations() {
if (!activeEditor) {
return;
}
// 匹配數(shù)字的正則
const regEx = /\d+/g;
// 獲取文檔的文本
const text = activeEditor.document.getText();
// 裝飾效果數(shù)組,用于歸集每一個(gè)Decoration對(duì)象
const smallNumbers: vscode.DecorationOptions[] = [];
const largeNumbers: vscode.DecorationOptions[] = [];
let match;
while ((match = regEx.exec(text))) {
// 獲取匹配結(jié)果的起始位置
const startPos = activeEditor.document.positionAt(match.index);// 開(kāi)始位置
const endPos = activeEditor.document.positionAt(match.index + match[0].length);// 結(jié)束位置
// Decoration對(duì)象
const decoration = {
// 裝飾效果的位置
range: new vscode.Range(startPos, endPos),
// 鼠標(biāo)懸停(hover)的提示信息
hoverMessage: 'Number **' + match[0] + '**'
};
// 將符合的結(jié)果歸集
if (match[0].length < 3) {
smallNumbers.push(decoration);
} else {
largeNumbers.push(decoration);
}
}
// 添加裝飾效果
activeEditor.setDecorations(smallNumberDecorationType, smallNumbers);
activeEditor.setDecorations(largeNumberDecorationType, largeNumbers);
}
// 給方法節(jié)流
function triggerUpdateDecorations(throttle = false) {
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
if (throttle) {
timeout = setTimeout(updateDecorations, 500);
} else {
updateDecorations();
}
}
// 打開(kāi)文檔時(shí)調(diào)用一次
if (activeEditor) {
triggerUpdateDecorations();
}
// 切換文檔時(shí)調(diào)用
vscode.window.onDidChangeActiveTextEditor(editor => {
// 這一步賦值是必須的,確保activeEditor是當(dāng)前打開(kāi)的文檔編輯器實(shí)例
activeEditor = editor;
if (editor) {
triggerUpdateDecorations();
}
}, null, context.subscriptions);
// 文檔內(nèi)容發(fā)送改變時(shí)調(diào)用
vscode.workspace.onDidChangeTextDocument(event => {
if (activeEditor && event.document === activeEditor.document) {
triggerUpdateDecorations(true);
}
}, null, context.subscriptions);
}
DecorationType是通過(guò)window.createTextEditorDecorationType(options)創(chuàng)建的對(duì)象,它主要用來(lái)設(shè)置裝飾效果的樣式,其實(shí)就是css樣式,比如border、color、backgroundColor等等。
如果要在匹配結(jié)果之前或之后添加裝飾,可以添加before/after字段進(jìn)行設(shè)置,還可以分別給dark、light模式配置不同的樣式。
const decorationType = window.createTextEditorDecorationType({
// 在匹配位置之前添加裝飾效果:
before: {
color: '#eee',
backgroundColor: '#fff',
width: 'fit-content'
}
})
由于該方法支持的樣式字段有限,有些樣式(比如line-height)無(wú)法在options里直接添加,但我們可以在任意字段后添加分號(hào),將這些樣式寫(xiě)在后面,比如:
const decorationType = window.createTextEditorDecorationType({
// 在匹配位置之后添加裝飾效果:
after: {
color: '#333',
backgroundColor: '#fff',
width: 'fit-content',
height: '0.8em',
// fontSize: '0.6em', 這么設(shè)置是無(wú)效的,因?yàn)椴⒉恢С謋ontSize字段,
// 但我們可以將其添加在任意字段后面
fontStyle: 'normal;font-size:0.6em;line-height:0.8em'
}
})
具體支持哪些字段,可以查看此API的官方文檔:
VS Code API | Visual Studio Code Extension API
Decoration對(duì)象有三個(gè)屬性:
range:裝飾效果的位置,range對(duì)象可以通過(guò)new vscode.Range(start, end)創(chuàng)建
hoverMessage:鼠標(biāo)懸停時(shí)的提示信息
renderOptions:和decorationType類(lèi)似,可以單獨(dú)對(duì)每一個(gè)裝飾效果設(shè)置樣式。但只支持before、after、dark、light四個(gè)字段,也就是說(shuō),無(wú)法再對(duì)匹配的內(nèi)容本身設(shè)置樣式。
由于實(shí)現(xiàn)的代碼比較長(zhǎng),和上述官方示例其實(shí)差不多,這里就不再貼出來(lái)了,感興趣的可以我去文章開(kāi)頭的倉(cāng)庫(kù)地址查看。
值得一提的是,為了顏色的名稱(chēng)在不同的顏色背景下都能清晰的顯現(xiàn),我這里用到了一個(gè)計(jì)算對(duì)比色的方法,貼出來(lái)供參考:
// 通過(guò)hex值計(jì)算應(yīng)該使用的字體顏色
function getContrastColor(hexcolor: string) {
const r = parseInt(hexcolor.substring(1, 2), 16)
const g = parseInt(hexcolor.substring(3, 4), 16)
const b = parseInt(hexcolor.substring(5, 6), 16)
const yiq = (r * 299 + g * 587 + b * 114) / 1000
return yiq >= 8 ? 'black' : 'white'
}
打包命令:
vsce package
如果打包失敗,可能的原因:
packege.json缺少上文表格中必要的配置項(xiàng)
VS Code版本與packege.json里設(shè)置的版本不兼容
根目錄下缺少README.md文件
根目錄下缺少LICENSE.md文件
以上就是“如何開(kāi)發(fā)一個(gè)提示顏色代碼的VS Code插件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。