preface

The new project of the team adopts VH and VW units as a whole.

Project structures,

yeoman / VS Code Extension Generator

VSCode officially recommends using Yeoman and the VSCode Extension Generator to build projects

Yeoman / / installation
npm install -g yo generator-code

// Build the project
yo code
Copy the code

The directory structure

├─ Changelo.md ├─ Readme.md ├─ ├─ Package-lock. json // Package-lock. json ├─ Package. json // package.json ├─ SRC // SRC / │ ├─.ts // │ ├─.ts // │ ├─.ts // │ ├─.ts // │ ├─.ts // │ ├─.ts // ├ ─ ├ ─ use vscode extensiontest                                    // test├── ├─ ├─ vsc-extended-quickstartCopy the code

The basic function

  • Match code input, such as capture PXW automatically converted to VW based on ratio; PXH is automatically converted to VH according to the ratio,
  • The conversion ratio is configurable

Function implementation

process.ts

Process. ts implements the px to VH/VW conversion for the utility class that captures the user’s input of the corresponding character. The following methods are available:

class CSSPercent {...// Matches the trigger conditional character re
    regPxVw: RegExp = / [-]? [\d.]+)pxw/;  
    regPxVh: RegExp = / [-]? [\d.]+)pxh/;
    
    pxToPercent () {} // Convert px to the percentage method
    getBaseData () {} // Get default values (plugin default Settings)
    getPxStr () {}    // Capture the user input px field
    cover () {}       // call getPxStr and execute pxToPercent, completing px 2 vw/wh
}
Copy the code

The above methods are explained in detail below

cover

cover (text: string) { // text is the value passed in as user input
    let match = this.getPxStr(text); // Call getPxStr to match whether the PXW/PXH fields are present
    if(! match) {return null; }return this.pxToPercent(match[0]); // pxToPercent is called to complete the conversion
  }
Copy the code

getPxStr

// Matches whether the input character triggers the conversion
private getPxStr (str: string) {
    if (this.regPxVw.test(str)) {
      return str.match(this.regPxVw);
    } else if (this.regPxVh.test(str)) {
      return str.match(this.regPxVh);
    }

    return false;
  }
Copy the code

pxToPercent

// Implement the px => vh/vh conversion
private pxToPercent (pxStr: string) { // pxStr is a parameter that captures the user's input of px units
    interface BaseDataVale {
      unit: string;
      designValue: number;
    }
    const pxValue = parseFloat(pxStr);
    const baseData: BaseDataVale = this.getBaseData(pxStr); // Returns the corresponding basic configuration data according to the current character PXW or PXH
    const percentValue: number | string = +(pxValue / baseData.designValue * 100).toFixed(this.config.fixedDigits); 
    const percentValueStr: string = `${percentValue}${baseData.unit}`;
    // Return the required fields
    return {
      pxStr,
      pxValue,
      percentValue,
      percentValueStr
    };
  }
Copy the code

getBaseData

  // Returns the configuration data value based on the current value
  private getBaseData (str: string) {
    if (this.regPxVw.test(str)) {
      return {
        unit: 'vw'.designValue: this.config.designWidth
      };
    } else if (this.regPxVh.test(str)) {
      return {
        unit: 'vh'.designValue: this.config.designHeight
      };
    }

    return {
      unit: ' '.designValue: 0
    };
  }
Copy the code

We can call the function to check that the result is ok. Then we will use the extension of VSCode itself to get the input value and execute the CSSPercent method

provide.ts

The provider uses the CompletionItemProvider method provided by VSCode, the document address.

import * as vscode from 'vscode';
import CSSPercent from './process';

class CSSPercentProvider implements vscode.CompletionItemProvider { // CompletionItemProvider provides an optional item after the user types a character, uses this method to get the character and match the point to fire (PXW/PXH)
  constructor (private process: CSSPercent) {}

  provideCompletionItems (
    document: vscode.TextDocument,
    position: vscode.Position
  ): Thenable<vscode.CompletionItem[]> {
    return new Promise((resolve, reject) = > {
      const lineText = document.getText(new vscode.Range(position.with(undefined.0), position)); // Matches the current line character
      const result = this.process.cover(lineText); // Call the csspercent method
      if(! result) {return resolve([]);
      }
      // Provide the snippet option after the match, check to convert px => vw/vh
      const item = new vscode.CompletionItem(`${result.pxValue}px => ${result.percentValueStr}`, vscode.CompletionItemKind.Snippet);
      item.insertText = result.percentValueStr;
      returnresolve([item]); }); }}export default CSSPercentProvider;
Copy the code

extension.ts

The development of all functions has been completed in the above part, but our plug-in has not been registered successfully in vscode. At the same time, we also need to call the plug-in function according to the code language type. For example, if we execute this plug-in in js, ts and other files, it will cause unnecessary waste. Extension. ts does this part of the job.

'use strict';
import * as vscode from 'vscode';
import CSSPercent from './process';
import CSSPercentProvider from './provider';

let config;

export function activate(context: vscode.ExtensionContext) { // Vscode enables the plugin to invoke the activate method, and deactivate when it is destroyed/disabled

    config = vscode.workspace.getConfiguration('CSSPercent'); // Here we get our configuration options, written in package.json

    const process = new CSSPercent(config); // Pass in the default configuration, which is where the csspercent call to config comes from
    const provider = new CSSPercentProvider(process);

    const TYPES = [
        'html'.'vue'.'css'.'less'.'scss'.'sass'.'stylus'
    ];
    // Iterate over the type of text that needs to be executed to register the plug-in
    TYPES.forEach(item= > {
        let providerDisposable = vscode.languages.registerCompletionItemProvider(
            {
                scheme: 'file'.language: item
            },
            provider,
            'w'.// Where w is passed in, h is the tigger option for precise configuration of trigger conditions
            'h'
        );
        context.subscriptions.push(providerDisposable); // Complete the subscription
    });
}

Copy the code

package.json

Configuration items

    // config
   "contributes": {
        "configuration": {  // The configuration items will be found in the Settings after the plug-in is installed, so that different ratios can be converted according to different UI scripts
            "type": "object"."title": "CSS-Percent configuration"."properties": {
                "CSSPercent.designWidth": { // Design width, used to execute px => vw
                    "type": "number"."default": 1920."description": "design page's width (unit: px), default: 1920"
                },
                "CSSPercent.fixedDigits": { // Default decimal precision
                    "type": "number"."default": 4."description": "Px to percent decimal point maximum length, default: 4"
                },
                "CSSPercent.designHeight": { // Design height, used to execute px => vh
                    "type": "number"."default": 1080."description": "design page's height (unit: px), default: 1080"}}}}// Trigger language
    "activationEvents": [
        "onLanguage:html"."onLanguage:vue"."onLanguage:css"."onLanguage:less"."onLanguage:scss"."onLanguage:sass"."onLanguage:stylus"."onLanguage:tpl"
    ]

Copy the code

release

VSCode plug-ins need to be distributed using VSC. First, you need to register an Azure DevOps account, mainly according to the official documentation

NPM install -g vsce $vsce package. Vsix $vsce publish to MarketPlaceCopy the code

Full Project Address

Github.com/morehardy/v…

You can also search for css-percent installations in VSCode plug-ins

Welcome to star

reference

Code.visualstudio.com/api/working…

Code.visualstudio.com/api/referen…