Skip to content

Commit 90370b9

Browse files
authored
Use import instead of require in Installer (#192)
1 parent e55977b commit 90370b9

8 files changed

Lines changed: 31 additions & 26 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
- `toml` and `xml` support, thanks [@sanarise](https://github.com/selfint/code-blocks/pull/186)!
1212

13+
- `css` support ([#191](https://github.com/selfint/code-blocks/issues/191)) by switching to more robust Parser loading method.
14+
1315
## Fixed
1416

1517
- Add 'Remove' option to notification if parser fails to load ([#180](https://github.com/selfint/code-blocks/issues/180)).

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ View your code's syntax tree directly
4545

4646
- `node` / `npm`: Used to download tree-sitter language parsers. Can be installed from [here](https://nodejs.org/en/download).
4747

48-
- **OPTIONAL:** `tree-sitter` / `node-gyp-build`: Used for tree-sitter language parsers that need to be locally built.
48+
- **OPTIONAL:** `tree-sitter`: Used for tree-sitter language parsers that need to be locally built.
4949

5050
After installing `npm`, can be installed by running:
51-
`npm i -g tree-sitter-cli node-gyp-build`.
51+
`npm i -g tree-sitter-cli`.
5252

5353
If you don't want to install these tools, there's a good chance you don't
5454
need them. Try the extension without it, it will notify you if they are required.
@@ -117,8 +117,7 @@ Or [create a pull request](https://github.com/selfint/code-blocks/pulls) with yo
117117
- `codeBlocks.npmPackageName`: [NPM](https://www.npmjs.com/) package name of the `tree-sitter` parser to use for the
118118
language. Defaults to `tree-sitter-<languageId>`, change if the package name doesn't match the languageId.
119119

120-
- `codeBlocks.parserName`: Filename of the WASM parser built by the `tree-sitter build --wasm` command, without the
121-
`.wasm` extension. Defaults to `tree-sitter-<languageId>`, change if the parser filename doesn't match the languageId.
120+
- `codeBlocks.parserName`: Name to save parser as (defaults to `tree-sitter-<languageID>`), change if the package name doesn't match the languageId (e.g., `tree-sitter-typescript` for `[typescriptreact]` languageId).
122121

123122
- `codeBlocks.subdirectory`: Directory inside the NPM package containing the `tree-sitter` grammar. Defaults to the
124123
root directory of the package, change if the grammar isn't there.

eslint.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export default defineConfig([
4444
"error",
4545
{
4646
argsIgnorePattern: "^_.*",
47+
varsIgnorePattern: "^_",
48+
caughtErrorsIgnorePattern: "^_",
4749
},
4850
],
4951

src/FileTree.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import * as vscode from "vscode";
22

33
import { Block, getQueryBlocks } from "./BlockTree";
4-
import Parser, { Query, SyntaxNode, Tree } from "tree-sitter";
4+
import Parser, { type Language, Query, SyntaxNode, Tree } from "tree-sitter";
55
import { Result, err, ok } from "./result";
66

7-
import { Language } from "./Installer";
87
import { Selection } from "./Selection";
98
import { getLanguageConfig } from "./configuration";
109
import { getLogger } from "./outputChannel";

src/Installer.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ import * as vscode from "vscode";
55
import { ExecException, ExecOptions, exec } from "child_process";
66
import { Result, err, ok } from "./result";
77
import { existsSync, rmSync } from "fs";
8-
import Parser from "tree-sitter";
8+
import type { Language } from "tree-sitter";
99
import { getLogger } from "./outputChannel";
1010
import { mkdir } from "fs/promises";
1111
import which from "which";
1212

1313
const NPM_INSTALL_URL = "https://nodejs.org/en/download";
1414

15-
export type Language = Parser.Language;
16-
1715
export function getAbsoluteParserDir(parsersDir: string, parserName: string): string {
1816
return path.resolve(path.join(parsersDir, parserName));
1917
}
@@ -22,11 +20,11 @@ export function getAbsoluteBindingsDir(parsersDir: string, parserName: string):
2220
return path.resolve(path.join(parsersDir, parserName, "bindings", "node", "index.js"));
2321
}
2422

25-
export function loadParser(
23+
export async function loadParser(
2624
parsersDir: string,
2725
parserName: string,
2826
subdirectory?: string
29-
): Result<Language, string> {
27+
): Promise<Result<Language, string>> {
3028
const logger = getLogger();
3129

3230
const bindingsDir = getAbsoluteBindingsDir(parsersDir, parserName);
@@ -39,12 +37,14 @@ export function loadParser(
3937
try {
4038
logger.log(`Loading parser from ${bindingsDir}`);
4139

42-
// using dynamic import causes issues on windows
43-
// make sure to test well on windows before changing this
44-
// TODO(02/11/24): change to dynamic import
45-
// let { default: language } = (await import(bindingsDir)) as { default: Language };
46-
// eslint-disable-next-line @typescript-eslint/no-require-imports
47-
let language = require(bindingsDir) as Language;
40+
let language: Language;
41+
try {
42+
language = ((await import(bindingsDir)) as { default: Language }).default;
43+
} catch (_) {
44+
// TODO(1/11/25): Always use import and remove this backup
45+
// eslint-disable-next-line @typescript-eslint/no-require-imports
46+
language = require(bindingsDir) as Language;
47+
}
4848

4949
logger.log(`Got language: ${JSON.stringify(Object.keys(language))}`);
5050

@@ -117,7 +117,7 @@ export async function downloadAndBuildParser(
117117
}
118118

119119
// try to load parser optimistically
120-
const loadResult = loadParser(parsersDir, parserName);
120+
const loadResult = await loadParser(parsersDir, parserName);
121121
if (loadResult.status === "ok") {
122122
return ok(undefined);
123123
}
@@ -136,7 +136,7 @@ export async function downloadAndBuildParser(
136136
}
137137

138138
// if it fails, try to build it
139-
const buildResult = await runCmd(`${treeSitterCli} generate`, { cwd: parserDir }, (d) =>
139+
const buildResult = await runCmd(`${treeSitterCli} build`, { cwd: parserDir }, (d) =>
140140
onData?.(d.toString())
141141
);
142142
if (buildResult.status === "err") {
@@ -272,7 +272,7 @@ export async function getLanguage(
272272
}
273273
}
274274

275-
const loadResult = loadParser(parsersDir, parserName, subdirectory);
275+
const loadResult = await loadParser(parsersDir, parserName, subdirectory);
276276
if (loadResult.status === "err") {
277277
const msg = `Failed to load parser for language ${languageId} > ${loadResult.result}`;
278278

src/examples/suite/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as path from "path";
22
import Mocha from "mocha";
3-
import { glob } from "glob"; // ✅ named import for v10+
3+
import { glob } from "glob";
44

55
export async function run(): Promise<void> {
66
let example = process.env.EXAMPLE;

src/test/suite/Installer.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import * as vscode from "vscode";
44
import Parser from "tree-sitter";
55
import { TreeViewer } from "../../TreeViewer";
66
import { openDocument } from "./testUtils";
7+
import path from "path";
78

89
export async function testParser(language: string, content?: string): Promise<void> {
910
// fail the test if the parser could not be installed
10-
const result = await Installer.getLanguage("test-parsers", language, true);
11+
const testParsersDir = path.resolve(__dirname, "..", "..", "..", "test-parsers");
12+
const result = await Installer.getLanguage(testParsersDir, language, true);
1113
if (result.status === "err") {
1214
throw new Error(`Failed to install language: ${JSON.stringify(result.result)}`);
1315
}
@@ -49,15 +51,15 @@ suite("Installer integration tests", function () {
4951
["Ruby", "ruby", "def foo\nend\ndef bar\nend"],
5052
// ["SQL", "sql"],
5153
["HTML", "html", "<html></html>"],
52-
// ["CSS", "css", "body { color: red; }"],
54+
["CSS", "css", "body { color: red; }"],
5355
["YAML", "yaml", "key: value"],
5456
["JSON", "json", '{ "key": "value" }'],
5557
["XML", "xml"],
5658
["Markdown", "markdown", "# Title"],
5759
// ["LaTeX", "latex"],
5860
["Bash", "shellscript", "echo 'Hello, World!'"],
5961
["TOML", "toml"],
60-
// ["Swift", "swift"],
62+
["Swift", "swift"],
6163
["Kotlin", "kotlin", "fun main() { }"],
6264
["Zig", "zig", 'const std = @import("std");\n\npub fn main() void { }'],
6365
];

tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"compilerOptions": {
3-
"module": "commonjs",
4-
"target": "ES2022",
3+
"module": "nodenext",
4+
"moduleResolution": "nodenext",
5+
"target": "ES2020",
56
"outDir": "out",
67
"lib": [
78
"ES2022",

0 commit comments

Comments
 (0)