如何開發(fā)一個提示顏色代碼的VSCode插件

今天小編給大家分享一下如何開發(fā)一個提示顏色代碼的VS Code插件的相關知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

為企業(yè)提供做網(wǎng)站、網(wǎng)站制作、網(wǎng)站優(yōu)化、成都全網(wǎng)營銷推廣、競價托管、品牌運營等營銷獲客服務。成都創(chuàng)新互聯(lián)公司擁有網(wǎng)絡營銷運營團隊,以豐富的互聯(lián)網(wǎng)營銷經(jīng)驗助力企業(yè)精準獲客,真正落地解決中小企業(yè)營銷獲客難題,做到“讓獲客更簡單”。自創(chuàng)立至今,成功用技術實力解決了企業(yè)“網(wǎng)站建設、網(wǎng)絡品牌塑造、網(wǎng)絡營銷”三大難題,同時降低了營銷成本,提高了有效客戶轉化率,獲得了眾多企業(yè)客戶的高度認可!

需求

我在寫css時,經(jīng)常會有顏色選擇困難癥,雖然VS Code內(nèi)置的插件提供了取色器,但在256^3的顏色中去選取,未必能找到符合期望的顏色。于是我想要是有個顏色提示插件就好了,只要我輸入# + 顏色名,就能以代碼提示的方式,將對應的顏色列出來供我選擇。

獲取顏色

首先第一件事就是要有現(xiàn)成的顏色代碼,很快我就找到了這個網(wǎng)站:中國色

這個網(wǎng)站提供了500多種顏色的rgb值以及hex值,打開瀏覽器控制臺,輸入colorsArray就能全部拿到,這就是我想要的。

從網(wǎng)站底部的信息來看,這個網(wǎng)站是山寨自日本色,顏色據(jù)稱來自中科院科技情報編委會名詞室編寫、科學出版社1957年出版的《色譜》。

這個顏色來源是否可信我無從考證,隨便百度一下“中國傳統(tǒng)色”,就可以找到很多版本的所謂中國色,我在github上還找到了另一個接近2k star的中國色項目:中國傳統(tǒng)顏色手冊,這個網(wǎng)站使用的顏色與前者完全不同,是來自于一篇現(xiàn)在已經(jīng)無法查看的新浪博客,顏色數(shù)量我沒有統(tǒng)計,粗略估計在200以內(nèi)。

初始化項目

安裝開發(fā)工具

 npm i -g yo generator-code

新建項目

 yo code

Hello World

初始項目中有個Hello World,用VS Code打開項目,然后按F5(或者點擊“運行-->啟動調(diào)試”)可以開啟調(diào)試窗口。

然后在調(diào)試窗口下 Ctrl + Shift + P (或者點擊“設置-->命令面板”),輸入并選擇 Hello World 命令,就會在編輯器右下角彈出一個消息提示。

extension.ts是插件的入口文件:

 import * as vscode from 'vscode';
 
 // activate方法會在插件被激活時調(diào)用
 export function activate(context: vscode.ExtensionContext) {
     
     // 注冊命令,第一個參數(shù)是命令名稱,第二參數(shù)是回調(diào)
     let disposable = vscode.commands.registerCommand('chinese-colors.helloWorld', () => {
         // 彈出消息提示
         vscode.window.showInformationMessage('Hello World from Chinese Colors!');
     });
 
     // 添加到插件上下文
     context.subscriptions.push(disposable);
 }
 
 // deactivate方法會在插件失活時調(diào)用
 export function deactivate() {}

package.json

查看package.json,其中比較重要的兩項:

 {
     "activationEvents": [
         "onCommand:chinese-colors.helloWorld"
     ],
     "contributes": {
         "commands": [
             {
                 "command": "chinese-colors.helloWorld",
                 "title": "Hello World"
             }
         ]
     },
 }

activationEvents是插件的激活配置,它是一個數(shù)組,每一項對應一個激活插件的條件,格式為“<類型>:<名稱>”,onCommand是調(diào)用命令(也就是上面的輸入Hello World)。

contributes:一般翻譯為貢獻點,配置了一個“chinese-colors.helloWorld”,與activationEvents配置項對應。

其他packege.json配置見下表:

名稱必要類型說明
namestring插件名稱,必須為小寫且不能有空格。
versionstring插件版本
publisherstring發(fā)布者
enginesobject一個至少包含vscode鍵值對的對象,該鍵表示的是本插件可兼容的VS Code的版本,其值不能為*。比如 ^0.10.5 表示插件兼容VS Code的最低版本是0.10.5。
licensestring授權。如果有授權文檔LICENSE.md,可以把license值設為"SEE LICENSE IN LICENSE.md"。
displayNamestring插件市場中顯示的名字。
descriptionstring描述,說明本插件是什么以及做什么。
categoriesstring[]插件類型:[Languages, Snippets, Linters, Themes, Debuggers, Other]
keywordsarray一組 關鍵字或者 標記,方便在插件市場中查找。
galleryBannerobject插件市場中橫幅的樣式。
previewboolean在市場中把本插件標記為預覽版本。
mainstring插件的入口文件。
contributesobject一個描述插件 貢獻點 的對象。
activationEventsarray一組用于本插件的激活事件。
dependenciesobject生產(chǎn)環(huán)境Node.js依賴項。
devDependenciesobject開發(fā)環(huán)境Node.js依賴項。
extensionDependenciesarray一組本插件所需的其他插件的ID值。格式 ${publisher}.${name}。比如:vscode.csharp
scriptsobject和 npm的 scripts一樣,但還有一些額外VS Code特定字段。
iconstring一個128x128像素圖標的路徑。

用戶自定配置項

顏色代碼有多種表示方式,比較常用的是16進制(#ffffff)和rgb(255,255,255)這兩種,因此我需要讓用戶自己選擇采用哪種方式。

在contributes中有個configuration,允許用戶對插件進行一些自定義配置。

package.json

 {
     // ...
     "contributes": {
         "configuration": [{
             "title": "color mode",// 配置項名稱
             "properties": {
                 // 配置屬性
                 "RGB": {
                     "type": "boolean",  // 屬性值類型
                     "default": false,   // 屬性默認值
                     "description": "控制預設的中國色采用RGB格式"    // 屬性描述
                 }
             }
         }]
     },
 }

這樣就可以在擴展設置中進行一些自定義的設置:

我們可以通過workspace.getConfiguration()獲取用戶的配置。

 import { workspace } from "vscode";
 const configuration = workspace.getConfiguration();
 const isRGB = configuration.RGB;

代碼補全

API

代碼補全API:

vscode.languages.registerCompletionItemProvider(selector, provider, …triggerCharacters)

該方法有三個參數(shù):

參數(shù)Description
selector: string/string[]選擇編程語言,比如python
provider供應者配置對象
triggerCharacters: string/string[]觸發(fā)字符, 比如 .:

register completion item provider(注冊完成件供應者),這個provider也是比較費解的一個詞,直譯是供應者,我猜:代碼補全就相當于插件給我們供應了代碼,所以叫provider。

provider是一個對象,要求必須包含一個叫provideCompletionItems的方法,該方法需要返回一個數(shù)組,數(shù)組的每一項是一個CompletionItem對象,規(guī)定了代碼提示和補全的規(guī)則。

官方示例

 import * as vscode from 'vscode';
 
 export function activate(context: vscode.ExtensionContext) {
 
     // 注冊供應者:languages.registerCompletionItemProvider
     const provider2 = vscode.languages.registerCompletionItemProvider(
         'plaintext',// plaintext,表示對txt文檔激活該插件
         {
             // 實現(xiàn)provideCompletionItems方法
             // document的內(nèi)容見下文,position為當前光標的位置
             provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
 
                 // 獲取當前這行代碼
                 const linePrefix = document.lineAt(position).text.substr(0, position.character);
                 // 如果這行代碼不是以console.結尾,返回undefined,表示不會彈出代碼提示
                 if (!linePrefix.endsWith('console.')) {
                     return undefined;
                 }
 
                 // 返回CompletionItem對象組成的數(shù)組,補全代碼列表:log、warn、error
                 // CompletionItem對象可以自己創(chuàng)建,也可以像下面這樣new vscode.CompletionItem的方式創(chuàng)建
                 // vscode.CompletionItem()有兩個參數(shù): 
                 // 第一個是補全的代碼,第二個是代碼類型,用于控制顯示在每一行提示前的圖標
                 // vscode.CompletionItemKind.Method表示該代碼是一個方法
                 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:當前光標所處的位置。

document:用于獲取、控制文檔的內(nèi)容或狀態(tài),這里列舉幾個常用的方法和屬性:

  • 方法:

    • getWordRangeAtPosition(position): Range:獲取指定位置單詞的范圍(起始位置)

    • getText(Range):string:獲取指定范圍的文本

    • lineAt(position):string:獲取指定位置的文本

    • validatePosition(position):Position:獲取鼠標停留的位置

  • 屬性

    • lineCount:總代碼行數(shù)

    • languageId:語言名稱

    • isClosed:當前文件是否關閉

    • isDirty:當前文件的代碼是否更改未保存

CompletionItem對象

CompletionItem對象可以通過new vscode.CompletionItem()的方式創(chuàng)建,但它默認只能補全代碼,不能自定義替換,并不能滿足我的需求,因此需要自己創(chuàng)建。

CompletionItem對象包含的屬性:

屬性說明
detail: string語義化描述
documentation: string語義化描述
filterText: string代碼過濾。匹配輸入的內(nèi)容,沒有設置時,使用label
insertText: string插入、補全的代碼。沒有設置時,使用label
label: string默認的匹配代碼、補全代碼
kind代碼類型,控制顯示代碼提示前的圖標
sortText: string排序文本,與sortText匹配的提示代碼會排在靠前的位置
textEdit對補全代碼進行編輯,如果設置了textEdit,insertText會失效

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: '天依藍',
                 kind: CompletionItemKind.Color,
                 filterText: `#66ccff天依藍`,
                 label: '天依藍',
                 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關鍵配置:

 {
     "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": "控制預設的中國色采用RGB格式"
                 }
             }
         }]
     },
 }

顏色列表colors.ts

 // 聲明Color類型
 export type Color = {
   rgb: number[];
   hex: string;
   name: string;
   phonics: string;
 };
 
 // 這里只列兩個顏色
 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() {}

如此,代碼補全的功能已經(jīng)基本實現(xiàn),實際開發(fā)時,為了便于維護,需要將這部分邏輯抽離出來。

顏色預覽

接下來,需要實現(xiàn)顏色的預覽,雖然VS Code內(nèi)置的插件已經(jīng)實現(xiàn)了這項功能,但我的需求是:不僅能預覽顏色,還得顯示顏色名稱。

API

實現(xiàn)顏色預覽需要用到裝飾效果,涉及以下這些API:

window.createTextEditorDecorationType(options):創(chuàng)建裝飾效果的類型

window.activeTextEditor.setDecorations(decorationType, decorations):添加裝飾效果至文檔

window.onDidChangeActiveTextEditor:文檔內(nèi)容變化事件

workspace.onDidChangeTextDocument:切換文檔事件

官方示例

首先來看一下官方提供的示例片段

import * as vscode from 'vscode';

// 插件激活時調(diào)用
export function activate(context: vscode.ExtensionContext) {

	console.log('decorator sample is activated');

	let timeout: NodeJS.Timer | undefined = undefined;

    // 為small numbers創(chuàng)建裝飾效果類型
	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)建裝飾效果類型
	const largeNumberDecorationType = vscode.window.createTextEditorDecorationType({
		cursor: 'crosshair',
		// 設置裝飾的背景顏色, 在package.json中可以配置該名稱對應的顏色
		backgroundColor: { id: 'myextension.largeNumberBackground' }
	});

    // activeEditor是當前活躍(展示)的文檔編輯器實例
	let activeEditor = vscode.window.activeTextEditor;

    // updateDecorations方法,在每次文檔被更新或切換文檔時調(diào)用。
	function updateDecorations() {
		if (!activeEditor) {
			return;
		}
        // 匹配數(shù)字的正則
		const regEx = /\d+/g;
        // 獲取文檔的文本
		const text = activeEditor.document.getText();
        // 裝飾效果數(shù)組,用于歸集每一個Decoration對象
		const smallNumbers: vscode.DecorationOptions[] = [];
		const largeNumbers: vscode.DecorationOptions[] = [];
		let match;
		while ((match = regEx.exec(text))) {
            // 獲取匹配結果的起始位置
			const startPos = activeEditor.document.positionAt(match.index);// 開始位置
			const endPos = activeEditor.document.positionAt(match.index + match[0].length);// 結束位置
            // Decoration對象
			const decoration = {
                // 裝飾效果的位置
                range: new vscode.Range(startPos, endPos), 
                // 鼠標懸停(hover)的提示信息
                hoverMessage: 'Number **' + match[0] + '**' 
            };
            // 將符合的結果歸集
			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();
		}
	}

    // 打開文檔時調(diào)用一次
	if (activeEditor) {
		triggerUpdateDecorations();
	}
    
	// 切換文檔時調(diào)用
	vscode.window.onDidChangeActiveTextEditor(editor => {
        // 這一步賦值是必須的,確保activeEditor是當前打開的文檔編輯器實例
		activeEditor = editor;
		if (editor) {
			triggerUpdateDecorations();
		}
	}, null, context.subscriptions);

    // 文檔內(nèi)容發(fā)送改變時調(diào)用
	vscode.workspace.onDidChangeTextDocument(event => {
		if (activeEditor && event.document === activeEditor.document) {
			triggerUpdateDecorations(true);
		}
	}, null, context.subscriptions);

}

DecorationType

DecorationType是通過window.createTextEditorDecorationType(options)創(chuàng)建的對象,它主要用來設置裝飾效果的樣式,其實就是css樣式,比如border、color、backgroundColor等等。

如果要在匹配結果之前或之后添加裝飾,可以添加before/after字段進行設置,還可以分別給dark、light模式配置不同的樣式。

const decorationType =  window.createTextEditorDecorationType({
    // 在匹配位置之前添加裝飾效果:
    before: {
        color: '#eee',
        backgroundColor: '#fff',
        width: 'fit-content'
    }
})

由于該方法支持的樣式字段有限,有些樣式(比如line-height)無法在options里直接添加,但我們可以在任意字段后添加分號,將這些樣式寫在后面,比如:

const decorationType =  window.createTextEditorDecorationType({
    // 在匹配位置之后添加裝飾效果:
    after: {
        color: '#333',
        backgroundColor: '#fff',
        width: 'fit-content',
        height: '0.8em',
        // fontSize: '0.6em', 這么設置是無效的,因為并不支持fontSize字段,
        // 但我們可以將其添加在任意字段后面
        fontStyle: 'normal;font-size:0.6em;line-height:0.8em'
    }
})

具體支持哪些字段,可以查看此API的官方文檔:

VS Code API | Visual Studio Code Extension API

Decoration對象

Decoration對象有三個屬性:

  • range:裝飾效果的位置,range對象可以通過new vscode.Range(start, end)創(chuàng)建

  • hoverMessage:鼠標懸停時的提示信息

  • renderOptions:和decorationType類似,可以單獨對每一個裝飾效果設置樣式。但只支持before、after、dark、light四個字段,也就是說,無法再對匹配的內(nèi)容本身設置樣式。

示例

由于實現(xiàn)的代碼比較長,和上述官方示例其實差不多,這里就不再貼出來了,感興趣的可以我去文章開頭的倉庫地址查看。

值得一提的是,為了顏色的名稱在不同的顏色背景下都能清晰的顯現(xiàn),我這里用到了一個計算對比色的方法,貼出來供參考:

// 通過hex值計算應該使用的字體顏色
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缺少上文表格中必要的配置項

  • VS Code版本與packege.json里設置的版本不兼容

  • 根目錄下缺少README.md文件

  • 根目錄下缺少LICENSE.md文件

以上就是“如何開發(fā)一個提示顏色代碼的VS Code插件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)站題目:如何開發(fā)一個提示顏色代碼的VSCode插件
本文URL:http://bm7419.com/article8/ipdcop.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供電子商務、企業(yè)建站、外貿(mào)網(wǎng)站建設、企業(yè)網(wǎng)站制作、微信小程序網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司