Skip to content

selfint/code-blocks

Repository files navigation

logo

Visual Studio Marketplace Version Visual Studio Marketplace Downloads Visual Studio Marketplace Installs GitHub CI GitHub last commit GitHub issues GitHub stars


Code blocks

Supercharge your editor with syntactically aware code navigation and manipulation, in any language supported by tree-sitter.

Features

Block mode

Syntactically aware code selection (e.g. select scope), navigation (e.g. goto next function) and manipulation (e.g. re-order function parameters), right inside your editor.

rust_parameters_example

Code Blocks Editor

Birds eye view over all your code blocks, with point and click refactoring.

svelte-1

Tree viewer

View your code's syntax tree directly

tree_viewer

Requirements

  • node / npm: Used to download tree-sitter language parsers. Can be installed from here.

  • tree-sitter: Used to build tree-sitter language parsers. After installing npm, can be installed by running:

    $ npm i -g tree-sitter-cli
  • emcc: Emscripten compiler, used by tree-sitter to compile parsers to WASM. Can be provided either through:

    • Emscripten (preferred): Provides emcc directly.

    • Docker: Provides emcc via the emscripten/emsdk image. Note that the first parser installation can take some time (depending on internet speed), since the image is 1.68GB. Next installs will re-use the image and should take a few seconds at most.

Commands

Command Usage
codeBlocks.toggleActive Toggle auto-parsing current file
codeBlocks.toggleBlockMode Toggle Block Mode, will toggleActive if auto-parsing disabled
codeBlocks.toggleBlockModeColors Toggle Block Mode sibling/parent highlights
codeBlocks.open Reopen current file with Code Blocks editor
codeBlocks.openToTheSide Open current file with Code Blocks editor on the side
codeBlocks.openTreeViewer View current file syntax tree
codeBlocks.moveUp Swap block with its previous sibling
codeBlocks.moveDown Swap block with its next sibling
codeBlocks.navigateUp Navigate to previous sibling
codeBlocks.navigateDown Navigate to next sibling
codeBlocks.navigateUpForce Navigate to parent start
codeBlocks.navigateDownForce Navigate to parent end
codeBlocks.selectBlock Expand selection to previous sibling
codeBlocks.selectPrevious Expand selection to previous sibling
codeBlocks.selectNext Expand selection to next sibling
codeBlocks.selectParent Expand selection to parent
codeBlocks.selectChild Contract selection to first child

Keybindings

These are the default key bindings, they are only active when "block mode" is active, and when the cursor is inside a text editor tab:

Command Keybinding (cmd on mac)
codeBlocks.moveUp alt+left
codeBlocks.moveDown alt+right
codeBlocks.navigateUp ctrl/cmd+left
codeBlocks.navigateDown ctrl/cmd+right
codeBlocks.navigateUpForce ctrl/cmd+up
codeBlocks.navigateDownForce ctrl/cmd+down
codeBlocks.selectBlock -
codeBlocks.selectPrevious shift+left
codeBlocks.selectNext shift+right
codeBlocks.selectParent shift+up
codeBlocks.selectChild shift+down

Configuration

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).
  • codeBlocks.ignoredLanguageIds: Array of VScode languageIds not to install/load parsers for.

Language specific (advanced)

These configurations are set at the languageId level.

Most languages should just work™, if you find a language that requires manual configuration please create an issue. Or create a pull request with your configuration added to the configurationDefaults section of the package.json file.

  • codeBlocks.npmPackageName: NPM package name of the tree-sitter parser to use for the language. Defaults to tree-sitter-<languageId>, change if the package name doesn't match the languageId.

  • codeBlocks.parserName: Filename of the WASM parser built by the tree-sitter build-wasm command, without the .wasm extension. Defaults to tree-sitter-<languageId>, change if the parser filename doesn't match the languageId.

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

  • codeBlocks.queries: Tree-sitter queries to generate blocks, must contain at least one @capture. The name of the capture doesn't matter, the entire match will be a block.

    Required by Code Blocks Editor.

    Optional for Block Mode - will auto-expand a selection if it is contained by a block.

Example configuration for tsx

Language ID: typescriptreact

NPM package name: tree-sitter-typescript

WASM parser name: tree-sitter-ts.wasm

Desired blocks: JSX blocks, and documentation comments should be merged with documentees.

{
    // language ID of .tsx files is 'typescriptreact'
    "[typescriptreact]": {
        // languageID != package name
        "codeBlocks.npmPackageName": "tree-sitter-typescript",
        // languageID != parser name
        "codeBlocks.parserName": "tree-sitter-tsx",
        // tree-sitter-typescript package contains a 'typescript' dir and a 'tsx' dir, so we need to specify 'tsx
        "codeBlocks.subdirectory": "tsx",
        "codeBlocks.queries": [
            // group documentation comments with their documentees
            "( (comment)* @header . (class_declaration) @item)",
            "( (comment)* @header . (method_definition) @item)",
            "( (comment)* @header . (function_declaration) @item)",
            "( (comment)* @header . (export_statement) @item)",
            // build blocks from jsx elements
            "(jsx_element) @item",
            "(jsx_self_closing_element) @item"
        ]
    }
}

Custom editors

  • Code Blocks Editor (viewType codeBlocks.editor): UI for moving code blocks inside a file. Useful when refactoring large blocks over long distances.

Known Issues

  • Out of bounds memory access (#154): For now, reloading the editor fixes this.

License

MIT License © 2023 Tom Selfin

Gallery

Block Mode - Move - Rust - Functions

Block Mode - Move - Rust - Functions

Block Mode - Move - Rust - Match arms

Block Mode - Move - Rust - Match arms

Block Mode - Move - Rust - Parameters

Block Mode - Move - Rust - Parameters

Block Mode - Select - Rust

Block Mode - Select - Rust

Block Mode - Select - TypeScript

Block Mode - Select - TypeScript

Block Mode - Select - TypeScript - Selection expands to block

Block Mode - Select - TypeScript - Selection expands to block

Tree Viewer

Tree Viewer