From 8f69abc66976605d32b59d38a1546c9bcedba151 Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Mon, 3 Nov 2025 23:10:49 +0200 Subject: [PATCH 1/7] use npm to build parsers --- src/Installer.ts | 40 ++++++++++++++++++-------------- src/test/suite/Installer.test.ts | 4 ++-- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/Installer.ts b/src/Installer.ts index e9dc6dad..26b2da79 100644 --- a/src/Installer.ts +++ b/src/Installer.ts @@ -68,7 +68,7 @@ export async function downloadAndBuildParser( parserNpmPackage: string, parserName: string, npm: string, - treeSitterCli: string, + rebuild: boolean = false, onData?: (data: string) => void ): Promise> { const logger = getLogger(); @@ -117,31 +117,37 @@ export async function downloadAndBuildParser( } // try to load parser optimistically - const loadResult = await loadParser(parsersDir, parserName); - if (loadResult.status === "ok") { - return ok(undefined); + if (!rebuild) { + const loadResult = await loadParser(parsersDir, parserName); + if (loadResult.status === "ok") { + return ok(undefined); + } + logger.log(`Optimistic load failed for parser ${parserName}`); } - logger.log(`Optimistic load failed, trying to build parser ${parserName}`); - const treeSitterCliOk = await runCmd(`${treeSitterCli} --version`); - if (treeSitterCliOk.status === "err") { + // if it fails, try to build it + logger.log(`Building parser ${parserName}`); + const installDepsResult = await runCmd(`${npm} install --verbose`, { cwd: parserDir }, (d) => + onData?.(d.toString()) + ); + if (installDepsResult.status === "err") { const msg = - `Parser ${parserName} requires local build, but - tree-sitter cli command '${treeSitterCli}' failed: - ${treeSitterCliOk.result[0].name} ${treeSitterCliOk.result[0].message.replace(/\n/g, " > ")}.` + - (treeSitterCliOk.result[1].length > 1 ? ` Logs: ${treeSitterCliOk.result[1].join(">")}` : ""); + "Failed to install parser dependencies > " + + installDepsResult.result[0].name + + ": " + + installDepsResult.result[0].message.replace(/\n/g, " > ") + + (installDepsResult.result[1].length > 1 ? ` Logs: ${installDepsResult.result[1].join(">")}` : ""); logger.log(msg); return err(msg); } - // if it fails, try to build it - const buildResult = await runCmd(`${treeSitterCli} build`, { cwd: parserDir }, (d) => + const buildResult = await runCmd(`${npm} rebuild --verbose`, { cwd: parserDir }, (d) => onData?.(d.toString()) ); if (buildResult.status === "err") { const msg = - "Failed to build parser using tree-sitter cli > " + + "Failed to build parser > " + buildResult.result[0].name + ": " + buildResult.result[0].message.replace(/\n/g, " > ") + @@ -191,7 +197,8 @@ export type GetLanguageError = { export async function getLanguage( parsersDir: string, languageId: string, - autoInstall = false + autoInstall = false, + rebuild = false ): Promise> { const logger = getLogger(); @@ -205,7 +212,6 @@ export async function getLanguage( const parserPackagePath = getAbsoluteParserDir(parsersDir, parserName); const npm = "npm"; - const treeSitterCli = configuration.getTreeSitterCliPath(); if (!existsSync(parserPackagePath)) { const doInstall = autoInstall @@ -258,7 +264,7 @@ export async function getLanguage( npmPackageName, parserName, npm, - treeSitterCli, + rebuild, (data) => progress.report({ message: data, increment: number++ }) ); } diff --git a/src/test/suite/Installer.test.ts b/src/test/suite/Installer.test.ts index ea0e4bfe..6f813334 100644 --- a/src/test/suite/Installer.test.ts +++ b/src/test/suite/Installer.test.ts @@ -9,7 +9,7 @@ import path from "path"; export async function testParser(language: string, content?: string): Promise { // fail the test if the parser could not be installed const testParsersDir = path.resolve(__dirname, "..", "..", "..", "test-parsers"); - const result = await Installer.getLanguage(testParsersDir, language, true); + const result = await Installer.getLanguage(testParsersDir, language, true, true); if (result.status === "err") { throw new Error(`Failed to install language: ${JSON.stringify(result.result)}`); } @@ -28,7 +28,7 @@ export async function testParser(language: string, content?: string): Promise Date: Mon, 3 Nov 2025 23:55:29 +0200 Subject: [PATCH 2/7] Remove require fallback from parser load Import should always work, this fallback just hides errors. --- src/Installer.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Installer.ts b/src/Installer.ts index 26b2da79..19c9eb02 100644 --- a/src/Installer.ts +++ b/src/Installer.ts @@ -37,14 +37,7 @@ export async function loadParser( try { logger.log(`Loading parser from ${bindingsDir}`); - let language: Language; - try { - language = ((await import(bindingsDir)) as { default: Language }).default; - } catch (_) { - // TODO(1/11/25): Always use import and remove this backup - // eslint-disable-next-line @typescript-eslint/no-require-imports - language = require(bindingsDir) as Language; - } + let language = ((await import(bindingsDir)) as { default: Language }).default; logger.log(`Got language: ${JSON.stringify(Object.keys(language))}`); From 8e29967fb3ac58a6dc9645f6c373fcc626183789 Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Tue, 4 Nov 2025 09:24:50 +0200 Subject: [PATCH 3/7] debug windows build --- src/Installer.ts | 4 ++-- src/test/suite/Installer.test.ts | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Installer.ts b/src/Installer.ts index 19c9eb02..1b057e5c 100644 --- a/src/Installer.ts +++ b/src/Installer.ts @@ -120,7 +120,7 @@ export async function downloadAndBuildParser( // if it fails, try to build it logger.log(`Building parser ${parserName}`); - const installDepsResult = await runCmd(`${npm} install --verbose`, { cwd: parserDir }, (d) => + const installDepsResult = await runCmd(`${npm} install --loglevel=silly`, { cwd: parserDir }, (d) => onData?.(d.toString()) ); if (installDepsResult.status === "err") { @@ -135,7 +135,7 @@ export async function downloadAndBuildParser( return err(msg); } - const buildResult = await runCmd(`${npm} rebuild --verbose`, { cwd: parserDir }, (d) => + const buildResult = await runCmd(`${npm} rebuild --loglevel=silly`, { cwd: parserDir }, (d) => onData?.(d.toString()) ); if (buildResult.status === "err") { diff --git a/src/test/suite/Installer.test.ts b/src/test/suite/Installer.test.ts index 6f813334..986eb3a5 100644 --- a/src/test/suite/Installer.test.ts +++ b/src/test/suite/Installer.test.ts @@ -27,7 +27,7 @@ export async function testParser(language: string, content?: string): Promise; }\nfunction Bar() { }"], @@ -64,7 +64,11 @@ suite("Installer integration tests", function () { ["Zig", "zig", 'const std = @import("std");\n\npub fn main() void { }'], ]; - prebuiltTests.forEach(([name, language, content]) => { + [["CSS", "css", "body { color: red; }"]].forEach(([name, language, content]) => { test(name, async () => await testParser(language, content)); }); + + // prebuiltTests.forEach(([name, language, content]) => { + // test(name, async () => await testParser(language, content)); + // }); }); From b2b99876e268b4b6d3165d68f4c8f7aa561ba8fd Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Tue, 4 Nov 2025 10:00:18 +0200 Subject: [PATCH 4/7] debug windows build 2 --- src/Installer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Installer.ts b/src/Installer.ts index 1b057e5c..696cc61d 100644 --- a/src/Installer.ts +++ b/src/Installer.ts @@ -8,6 +8,7 @@ import { existsSync, rmSync } from "fs"; import type { Language } from "tree-sitter"; import { getLogger } from "./outputChannel"; import { mkdir } from "fs/promises"; +import { pathToFileURL } from "node:url"; import which from "which"; const NPM_INSTALL_URL = "https://nodejs.org/en/download"; @@ -37,7 +38,7 @@ export async function loadParser( try { logger.log(`Loading parser from ${bindingsDir}`); - let language = ((await import(bindingsDir)) as { default: Language }).default; + let language = ((await import(pathToFileURL(bindingsDir).href)) as { default: Language }).default; logger.log(`Got language: ${JSON.stringify(Object.keys(language))}`); From e6bda00923b3a401ee83619f1482b8dad6142dd0 Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Tue, 4 Nov 2025 10:05:46 +0200 Subject: [PATCH 5/7] restore full installer tests --- src/test/suite/Installer.test.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/suite/Installer.test.ts b/src/test/suite/Installer.test.ts index 986eb3a5..6f813334 100644 --- a/src/test/suite/Installer.test.ts +++ b/src/test/suite/Installer.test.ts @@ -27,7 +27,7 @@ export async function testParser(language: string, content?: string): Promise; }\nfunction Bar() { }"], @@ -64,11 +64,7 @@ suite.only("Installer integration tests", function () { ["Zig", "zig", 'const std = @import("std");\n\npub fn main() void { }'], ]; - [["CSS", "css", "body { color: red; }"]].forEach(([name, language, content]) => { + prebuiltTests.forEach(([name, language, content]) => { test(name, async () => await testParser(language, content)); }); - - // prebuiltTests.forEach(([name, language, content]) => { - // test(name, async () => await testParser(language, content)); - // }); }); From 6662630b7c8826d81da44a82d7a35635c1c4d635 Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Tue, 4 Nov 2025 10:06:45 +0200 Subject: [PATCH 6/7] refactor installer --- src/Installer.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Installer.ts b/src/Installer.ts index 696cc61d..a90d8beb 100644 --- a/src/Installer.ts +++ b/src/Installer.ts @@ -17,7 +17,7 @@ export function getAbsoluteParserDir(parsersDir: string, parserName: string): st return path.resolve(path.join(parsersDir, parserName)); } -export function getAbsoluteBindingsDir(parsersDir: string, parserName: string): string { +export function getAbsoluteBindingsPath(parsersDir: string, parserName: string): string { return path.resolve(path.join(parsersDir, parserName, "bindings", "node", "index.js")); } @@ -28,17 +28,17 @@ export async function loadParser( ): Promise> { const logger = getLogger(); - const bindingsDir = getAbsoluteBindingsDir(parsersDir, parserName); - if (!existsSync(bindingsDir)) { - const msg = `Expected parser directory doesn't exist: ${bindingsDir}`; + const bindingsPath = getAbsoluteBindingsPath(parsersDir, parserName); + if (!existsSync(bindingsPath)) { + const msg = `Expected parser bindings don't exist: ${bindingsPath}`; logger.log(msg); return err(msg); } try { - logger.log(`Loading parser from ${bindingsDir}`); + logger.log(`Loading parser from ${bindingsPath}`); - let language = ((await import(pathToFileURL(bindingsDir).href)) as { default: Language }).default; + let language = ((await import(pathToFileURL(bindingsPath).href)) as { default: Language }).default; logger.log(`Got language: ${JSON.stringify(Object.keys(language))}`); @@ -52,8 +52,8 @@ export async function loadParser( return ok(language); } catch (error) { - logger.log(`Failed to load ${bindingsDir} > ${JSON.stringify(error)}`); - return err(`Failed to load ${bindingsDir} > ${JSON.stringify(error)}`); + logger.log(`Failed to load ${bindingsPath} > ${JSON.stringify(error)}`); + return err(`Failed to load ${bindingsPath} > ${JSON.stringify(error)}`); } } From 64b1ee458a5929ad00c186af80f118fa5bca3eb8 Mon Sep 17 00:00:00 2001 From: Tom Selfin Date: Tue, 4 Nov 2025 10:06:56 +0200 Subject: [PATCH 7/7] remove treeSitterCli config --- CHANGELOG.md | 4 + README.md | 1 - package.json | 763 +++++++++++++++++++++---------------------- src/configuration.ts | 8 - 4 files changed, 383 insertions(+), 393 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36e230fc..eae4e1a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ - Support for `node` v18, it might still work, but the extension now requires `node` v20+. +## Removed + +- `codeBlocks.treeSitterCliPath` configuration: The Extension now only requires `npm`. + # 0.7.0 Finally, switched to `node-tree-sitter`! 🎉 diff --git a/README.md b/README.md index 320625dd..eeadd6fc 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,6 @@ These are the default key bindings, they are only active when "block mode" is ac ### Global -- `codeBlocks.treeSitterCliPath`: Path to the `tree-sitter` cli command. Defaults to `tree-sitter` (assumes command is in PATH). - `codeBlocks.colors.enabled`: Whether Block Mode should color selections or not. Defaults to `false`. - `codeBlocks.colors.sibling`: CSS string for sibling selection background color. Defaults to `var(--vscode-editor-selectionHighlightBackground)`. - `codeBlocks.colors.parent`: CSS string for parent selection background color. Defaults to `var(--vscode-editor-linkedEditingBackground)`. diff --git a/package.json b/package.json index 28df660b..39324cd2 100644 --- a/package.json +++ b/package.json @@ -1,393 +1,388 @@ { - "name": "code-blocks", - "publisher": "selfint", - "displayName": "Code Blocks", - "description": "Move code blocks around", - "repository": { - "url": "https://github.com/selfint/code-blocks", - "type": "git" - }, - "bugs": { - "url": "https://github.com/selfint/code-blocks/issues", - "email": "selfint@gmail.com" - }, - "homepage": "https://github.com/selfint/code-blocks#readme", - "icon": "./assets/extension-logo.png", - "galleryBanner": { - "color": "#6295E3", - "theme": "dark" - }, - "version": "0.8.0", - "private": true, - "license": "MIT", - "engines": { - "vscode": "^1.105.0" - }, - "categories": [ - "Visualization", - "Other" - ], - "keywords": [ - "blocks", - "code-blocks", - "refactor", - "tree-sitter", - "treesitter", - "visualization" - ], - "preview": true, - "activationEvents": [ - "onLanguage" - ], - "main": "./out/extension.js", - "contributes": { - "customEditors": [ - { - "viewType": "codeBlocks.editor", - "displayName": "Code Blocks", - "selector": [ - { - "filenamePattern": "*" - } - ], - "priority": "option" - } + "name": "code-blocks", + "publisher": "selfint", + "displayName": "Code Blocks", + "description": "Move code blocks around", + "repository": { + "url": "https://github.com/selfint/code-blocks", + "type": "git" + }, + "bugs": { + "url": "https://github.com/selfint/code-blocks/issues", + "email": "selfint@gmail.com" + }, + "homepage": "https://github.com/selfint/code-blocks#readme", + "icon": "./assets/extension-logo.png", + "galleryBanner": { + "color": "#6295E3", + "theme": "dark" + }, + "version": "0.8.0", + "private": true, + "license": "MIT", + "engines": { + "vscode": "^1.105.0" + }, + "categories": [ + "Visualization", + "Other" ], - "commands": [ - { - "command": "codeBlocks.open", - "title": "Code Blocks: Open active file in Code Blocks editor" - }, - { - "command": "codeBlocks.openToTheSide", - "title": "Code Blocks: Open active file in Code Blocks editor to the side" - }, - { - "command": "codeBlocks.toggleActive", - "title": "Code Blocks: Toggle extension" - }, - { - "command": "codeBlocks.toggleBlockMode", - "title": "Code Blocks: Toggle block mode" - }, - { - "command": "codeBlocks.moveUp", - "title": "Code Blocks: Move selected block up" - }, - { - "command": "codeBlocks.moveDown", - "title": "Code Blocks: Move selected block down" - }, - { - "command": "codeBlocks.navigateUp", - "title": "Code Blocks: Navigate to previous block" - }, - { - "command": "codeBlocks.navigateDown", - "title": "Code Blocks: Navigate to next block" - }, - { - "command": "codeBlocks.navigateUpForce", - "title": "Code Blocks: Force navigate to previous block" - }, - { - "command": "codeBlocks.navigateDownForce", - "title": "Code Blocks: Force navigate to next block" - }, - { - "command": "codeBlocks.selectBlock", - "title": "Code Blocks: Select current block" - }, - { - "command": "codeBlocks.openTreeViewer", - "title": "Code Blocks: Open tree viewer" - }, - { - "command": "codeBlocks.selectParent", - "title": "Code Blocks: Scope selection - parent" - }, - { - "command": "codeBlocks.selectChild", - "title": "Code Blocks: Scope selection - child" - }, - { - "command": "codeBlocks.selectNext", - "title": "Code Blocks: Scope selection - next" - }, - { - "command": "codeBlocks.selectPrevious", - "title": "Code Blocks: Scope selection - previous" - }, - { - "command": "codeBlocks.toggleBlockModeColors", - "title": "Code Blocks: Toggle block mode colors" - } + "keywords": [ + "blocks", + "code-blocks", + "refactor", + "tree-sitter", + "treesitter", + "visualization" ], - "keybindings": [ - { - "command": "codeBlocks.moveUp", - "key": "alt+left", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.moveDown", - "key": "alt+right", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.navigateUp", - "key": "ctrl+left", - "mac": "cmd+left", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.navigateDown", - "key": "ctrl+right", - "mac": "cmd+right", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.navigateUpForce", - "key": "ctrl+up", - "mac": "cmd+up", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.navigateDownForce", - "key": "ctrl+down", - "mac": "cmd+down", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.selectNext", - "key": "shift+right", - "mac": "shift+right", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.selectPrevious", - "key": "shift+left", - "mac": "shift+left", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.selectParent", - "key": "shift+up", - "mac": "shift+up", - "when": "editorTextFocus && codeBlocks.blockMode" - }, - { - "command": "codeBlocks.selectChild", - "key": "shift+down", - "mac": "shift+down", - "when": "editorTextFocus && codeBlocks.blockMode" - } + "preview": true, + "activationEvents": [ + "onLanguage" ], - "configuration": { - "title": "CodeBlocks", - "properties": { - "codeBlocks.treeSitterCliPath": { - "type": "string", - "markdownDescription": "Path to the `tree-sitter` cli command, defaults to `tree-sitter`.", - "default": "tree-sitter" - }, - "codeBlocks.colors.enabled": { - "type": "boolean", - "description": "Whether block mode colors are enabled", - "default": false - }, - "codeBlocks.colors.sibling": { - "type": "string", - "description": "Background color of current block's siblings. Can be any valid css string.", - "default": "var(--vscode-editor-selectionHighlightBackground)" - }, - "codeBlocks.colors.parent": { - "type": "string", - "description": "Background color of current block's parent (only visible if there's no previous or next sibling). Can be any valid css string.", - "default": "var(--vscode-editor-linkedEditingBackground)" - }, - "codeBlocks.ignoredLanguageIds": { - "type": "array", - "markdownDescription": "Array of VScode [languageId](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers)s not to install/load parsers for.", - "default": [ - "plaintext", - "Log", - "ignore" - ] - }, - "codeBlocks.queries": { - "type": "array", - "markdownDescription": "Tree-sitter [queries](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax) to generate blocks, must contain a `@capture` (note that the entire match will be a block, not just the capture). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[python]\": {\"codeBlocks.queries\": [ \"(class_definition) @item\", \"(function_definition) @item\", \"(decorated_definition) @item\" ]}`", - "editPresentation": "multilineText", - "scope": "language-overridable" - }, - "codeBlocks.npmPackageName": { - "markdownDescription": "NPM package name of the tree-sitter grammar to use (defaults to `tree-sitter-`). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[yaml]\": {\"codeBlocks.npmPackageName\": \"@tree-sitter-grammars/tree-sitter-yaml\"}`.", - "scope": "language-overridable", - "type": [ - "string", - "null" - ] - }, - "codeBlocks.parserName": { - "type": [ - "string", - "null" - ], - "markdownDescription": "Name to save parser as (defaults to `tree-sitter-`). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[typescriptreact]\": {\"codeBlocks.parserName\": \"tree-sitter-typescript\"}`.", - "scope": "language-overridable" + "main": "./out/extension.js", + "contributes": { + "customEditors": [ + { + "viewType": "codeBlocks.editor", + "displayName": "Code Blocks", + "selector": [ + { + "filenamePattern": "*" + } + ], + "priority": "option" + } + ], + "commands": [ + { + "command": "codeBlocks.open", + "title": "Code Blocks: Open active file in Code Blocks editor" + }, + { + "command": "codeBlocks.openToTheSide", + "title": "Code Blocks: Open active file in Code Blocks editor to the side" + }, + { + "command": "codeBlocks.toggleActive", + "title": "Code Blocks: Toggle extension" + }, + { + "command": "codeBlocks.toggleBlockMode", + "title": "Code Blocks: Toggle block mode" + }, + { + "command": "codeBlocks.moveUp", + "title": "Code Blocks: Move selected block up" + }, + { + "command": "codeBlocks.moveDown", + "title": "Code Blocks: Move selected block down" + }, + { + "command": "codeBlocks.navigateUp", + "title": "Code Blocks: Navigate to previous block" + }, + { + "command": "codeBlocks.navigateDown", + "title": "Code Blocks: Navigate to next block" + }, + { + "command": "codeBlocks.navigateUpForce", + "title": "Code Blocks: Force navigate to previous block" + }, + { + "command": "codeBlocks.navigateDownForce", + "title": "Code Blocks: Force navigate to next block" + }, + { + "command": "codeBlocks.selectBlock", + "title": "Code Blocks: Select current block" + }, + { + "command": "codeBlocks.openTreeViewer", + "title": "Code Blocks: Open tree viewer" + }, + { + "command": "codeBlocks.selectParent", + "title": "Code Blocks: Scope selection - parent" + }, + { + "command": "codeBlocks.selectChild", + "title": "Code Blocks: Scope selection - child" + }, + { + "command": "codeBlocks.selectNext", + "title": "Code Blocks: Scope selection - next" + }, + { + "command": "codeBlocks.selectPrevious", + "title": "Code Blocks: Scope selection - previous" + }, + { + "command": "codeBlocks.toggleBlockModeColors", + "title": "Code Blocks: Toggle block mode colors" + } + ], + "keybindings": [ + { + "command": "codeBlocks.moveUp", + "key": "alt+left", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.moveDown", + "key": "alt+right", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.navigateUp", + "key": "ctrl+left", + "mac": "cmd+left", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.navigateDown", + "key": "ctrl+right", + "mac": "cmd+right", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.navigateUpForce", + "key": "ctrl+up", + "mac": "cmd+up", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.navigateDownForce", + "key": "ctrl+down", + "mac": "cmd+down", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.selectNext", + "key": "shift+right", + "mac": "shift+right", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.selectPrevious", + "key": "shift+left", + "mac": "shift+left", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.selectParent", + "key": "shift+up", + "mac": "shift+up", + "when": "editorTextFocus && codeBlocks.blockMode" + }, + { + "command": "codeBlocks.selectChild", + "key": "shift+down", + "mac": "shift+down", + "when": "editorTextFocus && codeBlocks.blockMode" + } + ], + "configuration": { + "title": "CodeBlocks", + "properties": { + "codeBlocks.colors.enabled": { + "type": "boolean", + "description": "Whether block mode colors are enabled", + "default": false + }, + "codeBlocks.colors.sibling": { + "type": "string", + "description": "Background color of current block's siblings. Can be any valid css string.", + "default": "var(--vscode-editor-selectionHighlightBackground)" + }, + "codeBlocks.colors.parent": { + "type": "string", + "description": "Background color of current block's parent (only visible if there's no previous or next sibling). Can be any valid css string.", + "default": "var(--vscode-editor-linkedEditingBackground)" + }, + "codeBlocks.ignoredLanguageIds": { + "type": "array", + "markdownDescription": "Array of VScode [languageId](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers)s not to install/load parsers for.", + "default": [ + "plaintext", + "Log", + "ignore" + ] + }, + "codeBlocks.queries": { + "type": "array", + "markdownDescription": "Tree-sitter [queries](https://tree-sitter.github.io/tree-sitter/using-parsers#query-syntax) to generate blocks, must contain a `@capture` (note that the entire match will be a block, not just the capture). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[python]\": {\"codeBlocks.queries\": [ \"(class_definition) @item\", \"(function_definition) @item\", \"(decorated_definition) @item\" ]}`", + "editPresentation": "multilineText", + "scope": "language-overridable" + }, + "codeBlocks.npmPackageName": { + "markdownDescription": "NPM package name of the tree-sitter grammar to use (defaults to `tree-sitter-`). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[yaml]\": {\"codeBlocks.npmPackageName\": \"@tree-sitter-grammars/tree-sitter-yaml\"}`.", + "scope": "language-overridable", + "type": [ + "string", + "null" + ] + }, + "codeBlocks.parserName": { + "type": [ + "string", + "null" + ], + "markdownDescription": "Name to save parser as (defaults to `tree-sitter-`). Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[typescriptreact]\": {\"codeBlocks.parserName\": \"tree-sitter-typescript\"}`.", + "scope": "language-overridable" + }, + "codeBlocks.subdirectory": { + "type": [ + "string", + "null" + ], + "markdownDescription": "Name of the subdirectory containing the tree-sitter grammar inside the npm package (leave empty to use the root directory). Use when an npm package contains multiple grammars. Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[typescript]\": {\"codeBlocks.subdirectory\": \"typescript\"}`.", + "scope": "language-overridable" + } + } }, - "codeBlocks.subdirectory": { - "type": [ - "string", - "null" - ], - "markdownDescription": "Name of the subdirectory containing the tree-sitter grammar inside the npm package (leave empty to use the root directory). Use when an npm package contains multiple grammars. Specified per [language ID](https://code.visualstudio.com/docs/languages/identifiers#_known-language-identifiers), example: `\"[typescript]\": {\"codeBlocks.subdirectory\": \"typescript\"}`.", - "scope": "language-overridable" + "configurationDefaults": { + "[github-actions-workflow]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-yaml", + "codeBlocks.parserName": "tree-sitter-yaml" + }, + "[jsonc]": { + "codeBlocks.npmPackageName": "tree-sitter-json" + }, + "[zig]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-zig" + }, + "[kotlin]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-kotlin" + }, + "[yaml]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-yaml" + }, + "[toml]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-toml" + }, + "[xml]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-xml", + "codeBlocks.subdirectory": "xml" + }, + "[markdown]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-markdown" + }, + "[shellscript]": { + "codeBlocks.npmPackageName": "tree-sitter-bash", + "codeBlocks.parserName": "tree-sitter-bash" + }, + "[rust]": { + "codeBlocks.queries": [ + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (function_item) @item)", + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (mod_item) @item)", + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (struct_item) @item)", + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (impl_item) @item)", + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (enum_item) @item)", + "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (field_declaration) @item)", + "(match_arm) @arm" + ] + }, + "[typescript]": { + "codeBlocks.subdirectory": "typescript", + "codeBlocks.queries": [ + "( (comment)* @header . (class_declaration) @item)", + "( (comment)* @header . (method_definition) @item)", + "( (comment)* @header . (function_declaration) @item)", + "( (comment)* @header . (export_statement) @item)" + ] + }, + "[typescriptreact]": { + "codeBlocks.npmPackageName": "tree-sitter-typescript", + "codeBlocks.parserName": "tree-sitter-typescript", + "codeBlocks.subdirectory": "tsx", + "codeBlocks.queries": [ + "( (comment)* @header . (class_declaration) @item)", + "( (comment)* @header . (method_definition) @item)", + "( (comment)* @header . (function_declaration) @item)", + "( (comment)* @header . (export_statement) @item)", + "(jsx_element) @item", + "(jsx_self_closing_element) @item" + ] + }, + "[javascriptreact]": { + "codeBlocks.npmPackageName": "tree-sitter-javascript", + "codeBlocks.parserName": "tree-sitter-javascript", + "codeBlocks.queries": [ + "( (comment)* @header . (class_declaration) @item)", + "( (comment)* @header . (method_definition) @item)", + "( (comment)* @header . (function_declaration) @item)", + "( (comment)* @header . (export_statement) @item)", + "(jsx_element) @item", + "(jsx_self_closing_element) @item" + ] + }, + "[svelte]": { + "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-svelte", + "codeBlocks.queries": [ + "( (comment)* @header . (element) @item)", + "( (comment)* @header . (each_statement) @item)", + "( (comment)* @header . (if_statement) @item)", + "( (comment)* @header . (style_element) @item)", + "( (comment)* @header . (script_element) @item)" + ] + }, + "[python]": { + "codeBlocks.queries": [ + "(class_definition) @item", + "(function_definition) @item", + "(decorated_definition) @item" + ] + }, + "[java]": { + "codeBlocks.queries": [ + "( (block_comment)* @header . (class_declaration) @item)", + "( (block_comment)* @header . (method_declaration) @item)" + ] + }, + "[csharp]": { + "codeBlocks.npmPackageName": "tree-sitter-c-sharp", + "codeBlocks.parserName": "tree-sitter-c_sharp" + } } - } }, - "configurationDefaults": { - "[github-actions-workflow]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-yaml", - "codeBlocks.parserName": "tree-sitter-yaml" - }, - "[jsonc]": { - "codeBlocks.npmPackageName": "tree-sitter-json" - }, - "[zig]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-zig" - }, - "[kotlin]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-kotlin" - }, - "[yaml]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-yaml" - }, - "[toml]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-toml" - }, - "[xml]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-xml", - "codeBlocks.subdirectory": "xml" - }, - "[markdown]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-markdown" - }, - "[shellscript]": { - "codeBlocks.npmPackageName": "tree-sitter-bash", - "codeBlocks.parserName": "tree-sitter-bash" - }, - "[rust]": { - "codeBlocks.queries": [ - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (function_item) @item)", - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (mod_item) @item)", - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (struct_item) @item)", - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (impl_item) @item)", - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (enum_item) @item)", - "(([ (attribute_item) (line_comment) ] @header . [ (attribute_item) (line_comment) ]* @header )? . (field_declaration) @item)", - "(match_arm) @arm" - ] - }, - "[typescript]": { - "codeBlocks.subdirectory": "typescript", - "codeBlocks.queries": [ - "( (comment)* @header . (class_declaration) @item)", - "( (comment)* @header . (method_definition) @item)", - "( (comment)* @header . (function_declaration) @item)", - "( (comment)* @header . (export_statement) @item)" - ] - }, - "[typescriptreact]": { - "codeBlocks.npmPackageName": "tree-sitter-typescript", - "codeBlocks.parserName": "tree-sitter-typescript", - "codeBlocks.subdirectory": "tsx", - "codeBlocks.queries": [ - "( (comment)* @header . (class_declaration) @item)", - "( (comment)* @header . (method_definition) @item)", - "( (comment)* @header . (function_declaration) @item)", - "( (comment)* @header . (export_statement) @item)", - "(jsx_element) @item", - "(jsx_self_closing_element) @item" - ] - }, - "[javascriptreact]": { - "codeBlocks.npmPackageName": "tree-sitter-javascript", - "codeBlocks.parserName": "tree-sitter-javascript", - "codeBlocks.queries": [ - "( (comment)* @header . (class_declaration) @item)", - "( (comment)* @header . (method_definition) @item)", - "( (comment)* @header . (function_declaration) @item)", - "( (comment)* @header . (export_statement) @item)", - "(jsx_element) @item", - "(jsx_self_closing_element) @item" - ] - }, - "[svelte]": { - "codeBlocks.npmPackageName": "@tree-sitter-grammars/tree-sitter-svelte", - "codeBlocks.queries": [ - "( (comment)* @header . (element) @item)", - "( (comment)* @header . (each_statement) @item)", - "( (comment)* @header . (if_statement) @item)", - "( (comment)* @header . (style_element) @item)", - "( (comment)* @header . (script_element) @item)" - ] - }, - "[python]": { - "codeBlocks.queries": [ - "(class_definition) @item", - "(function_definition) @item", - "(decorated_definition) @item" - ] - }, - "[java]": { - "codeBlocks.queries": [ - "( (block_comment)* @header . (class_declaration) @item)", - "( (block_comment)* @header . (method_declaration) @item)" - ] - }, - "[csharp]": { - "codeBlocks.npmPackageName": "tree-sitter-c-sharp", - "codeBlocks.parserName": "tree-sitter-c_sharp" - } + "scripts": { + "install:all": "yarn install --frozen-lockfile && cd webview-ui && yarn install --frozen-lockfile", + "start:webview": "cd webview-ui && yarn run dev", + "build:webview": "cd webview-ui && yarn run build && yarn run check", + "vscode:prepublish": "yarn run esbuild-base --minify", + "compile": "tsc -p ./", + "watch": "tsc -watch -p ./", + "pretest": "yarn run compile && yarn run lint", + "test": "node ./out/test/runTest.js", + "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --external:tree-sitter --format=cjs --platform=node", + "esbuild": "yarn run esbuild-base --sourcemap", + "esbuild-watch": "yarn run esbuild-base --sourcemap --watch", + "lint": "tsc --noEmit && eslint src --ext ts" + }, + "devDependencies": { + "@types/chai": "5.2.3", + "@types/glob": "8.1.0", + "@types/mocha": "10.0.10", + "@types/node": "24.9.2", + "@types/tar": "6.1.13", + "@types/vscode": "1.105.0", + "@types/which": "3.0.4", + "@typescript-eslint/eslint-plugin": "8.46.2", + "@typescript-eslint/parser": "8.46.2", + "@vscode/test-electron": "2.5.2", + "chai": "6.2.0", + "esbuild": "0.25.11", + "eslint": "9.38.0", + "glob": "11.0.3", + "mocha": "11.7.4", + "typescript": "5.9.3", + "typescript-eslint": "8.46.2" + }, + "dependencies": { + "tar": "7.5.2", + "tree-sitter": "0.25.0", + "which": "5.0.0" } - }, - "scripts": { - "install:all": "yarn install --frozen-lockfile && cd webview-ui && yarn install --frozen-lockfile", - "start:webview": "cd webview-ui && yarn run dev", - "build:webview": "cd webview-ui && yarn run build && yarn run check", - "vscode:prepublish": "yarn run esbuild-base --minify", - "compile": "tsc -p ./", - "watch": "tsc -watch -p ./", - "pretest": "yarn run compile && yarn run lint", - "test": "node ./out/test/runTest.js", - "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/extension.js --external:vscode --external:tree-sitter --format=cjs --platform=node", - "esbuild": "yarn run esbuild-base --sourcemap", - "esbuild-watch": "yarn run esbuild-base --sourcemap --watch", - "lint": "tsc --noEmit && eslint src --ext ts" - }, - "devDependencies": { - "@types/chai": "5.2.3", - "@types/glob": "8.1.0", - "@types/mocha": "10.0.10", - "@types/node": "24.9.2", - "@types/tar": "6.1.13", - "@types/vscode": "1.105.0", - "@types/which": "3.0.4", - "@typescript-eslint/eslint-plugin": "8.46.2", - "@typescript-eslint/parser": "8.46.2", - "@vscode/test-electron": "2.5.2", - "chai": "6.2.0", - "esbuild": "0.25.11", - "eslint": "9.38.0", - "glob": "11.0.3", - "mocha": "11.7.4", - "typescript": "5.9.3", - "typescript-eslint": "8.46.2" - }, - "dependencies": { - "tar": "7.5.2", - "tree-sitter": "0.25.0", - "which": "5.0.0" - } } diff --git a/src/configuration.ts b/src/configuration.ts index 291566d4..977d11ed 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -57,11 +57,3 @@ export function getColorConfig(): ColorConfig { parentColor: colorConfig?.parentColor ?? defaultParentColor, }; } - -export function getTreeSitterCliPath(): string { - const treeSitterCliPath = vscode.workspace - .getConfiguration("codeBlocks") - .get("treeSitterCliPath"); - - return treeSitterCliPath ?? "tree-sitter"; -}