<repo_name>apriliandi246/vscode-css-sort<file_sep>/src/extension.ts
import * as vscode from "vscode";
import { parse, generate } from "css-tree";

export function activate(context: vscode.ExtensionContext) {
  const cssMinSort = vscode.commands.registerCommand("css-sort.min", () => {
    const editor = vscode.window.activeTextEditor;
    const cssCodeSelected = editor?.document.getText(editor.selection).trim();

    if (!editor) {
      vscode.window.showInformationMessage("Editor does not exist");
      return;
    }

    if (!cssCodeSelected) {
      vscode.window.showWarningMessage("No CSS code selected");
      return;
    }

    editor.edit((currentCssCode) => {
      currentCssCode.replace(
        editor.selection,
        sortCssProperties("min", cssCodeSelected)
      );
    });

    editor.document.save();
  });

  const cssMaxSort = vscode.commands.registerCommand("css-sort.max", () => {
    const editor = vscode.window.activeTextEditor;
    const cssCodeSelected = editor?.document.getText(editor.selection).trim();

    if (!editor) {
      vscode.window.showInformationMessage("Editor does not exist");
      return;
    }

    if (!cssCodeSelected) {
      vscode.window.showWarningMessage("No CSS code selected");
      return;
    }

    editor.edit((currentCssCode) => {
      currentCssCode.replace(
        editor.selection,
        sortCssProperties("max", cssCodeSelected)
      );
    });

    editor.document.save();
  });

  context.subscriptions.push(cssMinSort, cssMaxSort);
}

function sortCssProperties(pattern: string, cssCode: string): string {
  let sortedCssProperties: string = "";
  const cssAst = parse(cssCode, { parseValue: false });
  const arrCssProperties: string[] = generate(cssAst).split("}");

  // Single sort
  // Just css properties without css selector
  if (arrCssProperties[arrCssProperties.length - 1] !== "") {
    sortedCssProperties = cssCode
      .trim()
      .split("\n")
      .filter((property) => property.trim() !== "")
      .map((property) => property.trim() + ";")
      .sort((firstProperty, secondProperty) =>
        pattern === "min"
          ? firstProperty.length - secondProperty.length
          : secondProperty.length - firstProperty.length
      )
      .join("\n");
  }

  // Multiple sort
  // Can sort css properties more than one css selector with css properties
  if (arrCssProperties[arrCssProperties.length - 1] === "") {
    arrCssProperties.pop();

    for (let index = 0; index < arrCssProperties.length; index++) {
      const cssNode: string[] = arrCssProperties[index].split("{");
      const cssSelector: string = cssNode[0].trim();

      const cssProperties: string = cssNode[1]
        .trim()
        .split(";")
        .filter((property) => property.trim() !== "")
        .map((property) => property.trim() + ";")
        .sort((firstProperty, secondProperty) =>
          pattern === "min"
            ? firstProperty.length - secondProperty.length
            : secondProperty.length - firstProperty.length
        )
        .join("\n");

      sortedCssProperties += `${cssSelector} {\n ${cssProperties} \n}${
        index === arrCssProperties.length - 1 ? "\n" : "\n\n"
      }`;
    }
  }

  return sortedCssProperties;
}

export function deactivate() {}
<file_sep>/README.md
<h1 align="center">📶 CSS-Sort</h1>

<br>

### 👨‍💻 About

Vscode extension to sort your CSS properties and make them easy to read.

<h3 align="center">. . .</h3>

### 🚀 Demo

[🔗 Try it now](https://marketplace.visualstudio.com/items?itemName=apriliandi246.css-sort)

<h3 align="center">. . .</h3>

### 🧰 Tech Stack

[<img alt="typescript" src="https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white" />](https://www.typescriptlang.org/) — 
[<img alt="vscode" src="https://img.shields.io/badge/Visual_Studio_Code-0078D4?style=for-the-badge&logo=visual%20studio%20code&logoColor=white" />](https://code.visualstudio.com/api/get-started/your-first-extension)

<h3 align="center">. . .</h3>

### 📖 More about it

[🔗 Documentation](https://vscode-css-sort-website.vercel.app/)

[🔗 Why](https://apriliandi.xyz/blogs/my-first-vscode-extension)

<h3 align="right">(⌐■_■)</h3>
