Skip to content

Commit

Permalink
feat: support web (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Nov 22, 2024
1 parent 5c5b197 commit 3c8687d
Show file tree
Hide file tree
Showing 19 changed files with 707 additions and 1,258 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ indent_size = 2
end_of_line = lf
insert_final_newline = false
trim_trailing_whitespace = true

[*.ts]
quote_type = single
17 changes: 15 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,25 @@
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
"--extensionDevelopmentPath=${workspaceFolder}/out"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Run Web Extension",
"type": "extensionHost",
"debugWebWorkerHost": true,
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/out",
"--extensionDevelopmentKind=web"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
]
}
]
}
3 changes: 2 additions & 1 deletion .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ vsc-extension-quickstart.md
examples/**
demo.gif
.cssrem
.yarnrc.yml
.yarnrc.yml
scripts/**
55 changes: 0 additions & 55 deletions esbuild.js

This file was deleted.

22 changes: 11 additions & 11 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import typescriptEslint from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import tsParser from "@typescript-eslint/parser";

export default [
{
files: ['**/*.ts'],
files: ["**/*.ts"],
},
{
plugins: {
'@typescript-eslint': typescriptEslint,
"@typescript-eslint": typescriptEslint,
},

languageOptions: {
parser: tsParser,
ecmaVersion: 2022,
sourceType: 'module',
sourceType: "module",
},

rules: {
'@typescript-eslint/naming-convention': [
'warn',
"@typescript-eslint/naming-convention": [
"warn",
{
selector: 'import',
format: ['camelCase', 'PascalCase'],
selector: "import",
format: ["camelCase", "PascalCase"],
},
],

// curly: "warn",
// eqeqeq: "warn",
'no-throw-literal': 'warn',
semi: 'warn',
"no-throw-literal": "warn",
semi: "warn",
},
},
];
13 changes: 6 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
"license": "MIT",
"licenseUrl": "LICENSE",
"scripts": {
"vscode:prepublish": "yarn run package",
"compile": "yarn run check-types && yarn run lint && node esbuild.js",
"watch": "npm-run-all -p watch:*",
"watch:esbuild": "node esbuild.js --watch",
"watch:tsc": "tsc --noEmit --watch --project tsconfig.json",
"package": "yarn run check-types && yarn run lint && node esbuild.js --production",
"vscode:prepublish": "npm run check-types && tsx ./scripts/esbuild.js --production",
"compile": "yarn run check-types && yarn run lint && tsx ./scripts/esbuild.js",
"watch": "tsx ./scripts/esbuild.js --watch",
"package": "yarn run lint && yarn run check-types && tsx ./scripts/esbuild.js --production",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "yarn run compile-tests && yarn run compile && yarn run lint",
Expand All @@ -25,6 +23,7 @@
},
"l10n": "./l10n",
"main": "./out/extension",
"browser": "./out/extension.web",
"engines": {
"vscode": "^1.90.0"
},
Expand Down Expand Up @@ -272,7 +271,7 @@
"conventional-changelog-cli": "^5.0.0",
"esbuild": "^0.24.0",
"eslint": "^9.13.0",
"npm-run-all": "^4.1.5",
"tsx": "^4.19.2",
"typescript": "^5.6.3"
},
"dependencies": {
Expand Down
78 changes: 78 additions & 0 deletions scripts/esbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import * as esbuild from "esbuild";

const production = process.argv.includes("--production");
const watch = process.argv.includes("--watch");
const buildType = watch ? "watch" : "build";

function esbuildProblemMatcherPlugin(type: "web" | "node"): esbuild.Plugin {
const prefix = `[${buildType}/${type}]`;
return {
name: "esbuild-problem-matcher",
setup(build) {
build.onStart(() => {
console.log(prefix + " started");
});
build.onEnd((result) => {
result.errors.forEach(({ text, location }) => {
console.error(`✘ [ERROR] ${text}`);
if (location) {
console.error(
` ${location.file}:${location.line}:${location.column}:`
);
}
});
console.log(prefix + " finished");
});
},
};
}

const main = async () => {
const nodeContext = await esbuild.context({
entryPoints: ["src/extension.ts"],
bundle: true,
format: "cjs",
minify: production,
sourcemap: !production,
sourcesContent: false,
platform: "node",
outfile: "out/extension.js",
mainFields: ["module", "main"],
external: ["vscode"],
logLevel: "silent",
plugins: [esbuildProblemMatcherPlugin("node")],
});

const browserContext = await esbuild.context({
entryPoints: ["src/extension.ts"],
bundle: true,
format: "cjs",
minify: production,
sourcemap: !production,
sourcesContent: false,
platform: "browser",
outfile: "out/extension.web.js",
mainFields: ["browser", "module", "main"],
external: ["vscode"],
logLevel: "silent",
plugins: [esbuildProblemMatcherPlugin("web")],
// Node.js global to browser globalThis
define: {
global: "globalThis",
},
});

if (watch) {
await Promise.all([nodeContext.watch(), browserContext.watch()]);
} else {
await nodeContext.rebuild();
await browserContext.rebuild();
await nodeContext.dispose();
await browserContext.dispose();
}
};

main().catch((e) => {
console.error(e);
process.exit(1);
});
23 changes: 18 additions & 5 deletions src/completion.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import { CompletionItem, CompletionItemKind, CompletionItemProvider, MarkdownString, Position, Range, TextDocument } from 'vscode';
import {
CompletionItem,
CompletionItemKind,
CompletionItemProvider,
MarkdownString,
Position,
Range,
TextDocument,
} from 'vscode';
import { cog, isIngore } from './config';
import { CssRemProcess } from './process';
import { isDisabledNextLine } from './ignore-comment';

export default class implements CompletionItemProvider {
constructor(private _: string, private process: CssRemProcess) {}

provideCompletionItems(document: TextDocument, position: Position): Thenable<CompletionItem[]> {
provideCompletionItems(
document: TextDocument,
position: Position
): Thenable<CompletionItem[]> {
if (isIngore(document.uri)) return Promise.resolve([]);

return new Promise(resolve => {
return new Promise((resolve) => {
if (isDisabledNextLine(document, position.line)) return null;
const lineText = document.getText(new Range(position.with(undefined, 0), position));
const lineText = document.getText(
new Range(position.with(undefined, 0), position)
);
const res = this.process.convert(lineText);
if (res == null || res.length === 0) {
return resolve([]);
Expand All @@ -26,7 +39,7 @@ export default class implements CompletionItemProvider {
item.preselect = idx === 0;
item.insertText = i.value + (cog.addMark ? ` /* ${i.label} */` : ``);
return item;
}),
})
);
});
}
Expand Down
35 changes: 21 additions & 14 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
import { existsSync, readFileSync } from 'fs';
import * as JSONC from 'jsonc-parser';
import { join } from 'path';
import { Uri, workspace } from 'vscode';
import { Config } from './interface';
import { resetRules } from './rules';
import { minimatch } from 'minimatch';
import { findUri, readFile } from './fs';

export let cog!: Config;
export const cssremConfigFileName = '.cssrem';

function loadConfigViaFile(): void {
if (workspace.workspaceFolders == null || workspace.workspaceFolders?.length <= 0) {
async function loadConfigViaFile(): Promise<void> {
if (
workspace.workspaceFolders == null ||
workspace.workspaceFolders?.length <= 0
) {
return;
}

const cssremConfigPath = join(workspace.workspaceFolders[0].uri.fsPath, cssremConfigFileName);
if (!existsSync(cssremConfigPath)) {
console.log(`Not found file: ${cssremConfigPath}`);
const cssremConfigUri = await findUri(cssremConfigFileName);
if (cssremConfigUri == null) {
console.log(`Not found file: ${cssremConfigUri}`);
return;
}
const cogText = await readFile(cssremConfigUri);
if (cogText == null) {
console.log(`Can't read file: ${cssremConfigUri}`);
return;
}
try {
const res = JSONC.parse(readFileSync(cssremConfigPath).toString('utf-8'));
const res = JSONC.parse(cogText);
cog = {
...cog,
...res,
};
console.warn(`Use override config via ${cssremConfigPath} file`);
console.warn(`Use override config via ${cssremConfigUri} file`);
} catch (ex) {
console.warn(`Parse error in ${cssremConfigPath}`, ex);
console.warn(`Parse error in ${cssremConfigUri}`, ex);
}
}

Expand Down Expand Up @@ -57,18 +64,18 @@ function fixLanguages(): void {
];
}

export function loadConfig(): void {
export async function loadConfig(): Promise<void> {
cog = { ...(workspace.getConfiguration('cssrem') as any) };
Object.keys(cog).forEach(key => {
Object.keys(cog).forEach((key) => {
if (typeof (cog as any)[key] === 'function') delete (cog as any)[key];
});
loadConfigViaFile();
await loadConfigViaFile();
fixIngores();
fixLanguages();
resetRules();
console.log('Current config', cog);
}

export function isIngore(uri: Uri) {
return cog.ignores.some(p => minimatch(uri.path, p));
return cog.ignores.some((p) => minimatch(uri.path, p));
}
Loading

0 comments on commit 3c8687d

Please sign in to comment.