leodevbro / vscode-blockman

VSCode extension to highlight nested code blocks
https://github.com/leodevbro/vscode-blockman
MIT License
468 stars 17 forks source link
abstract-syntax-tree ast highlight-blocks indentation parser tokenizer vscode-api vscode-blockman vscode-extension

VS Code Marketplace Installs VS Code Marketplace Downloads VS Code Marketplace Version VS Code Marketplace Rating

Donation is really appreciated. Blockman is a hard work of many months. My name is Levan Katsadze (ლევან კაცაძე), 1995-03-03, from Tbilisi, Georgia (Not USA).

Buy Me A Coffee ko-fi facebook logo youtube logo




For better experience: Blockman will ask you to change these 7 items in VS Code settings (only one-time at the installation event). These 7 settings are very non-vital, so maybe you don't even need to backup them first.

// settings.json (User/Global config, not Workspace config)
// To open this file in VS Code, press F1, type 'settings json' and choose 'Preferences: Open Settings (JSON)'
{
    // ...
    "editor.inlayHints.enabled": "off",
    "editor.guides.indentation": false, // new API for indent guides. The old one is: "editor.renderIndentGuides": false,
    "editor.guides.bracketPairs": false, // advanced indent guides (But only for brackets) (This does not turn off editor.bracketPairColorization)
    "editor.wordWrap": "off",
    "diffEditor.wordWrap": "off",

    "workbench.colorCustomizations": {
        // ...
        "editor.lineHighlightBorder": "#9fced11f",
        "editor.lineHighlightBackground": "#1073cf2d"
    }
}




VS Code Blockman Icon

Blockman

VS Code Extension For Nested Block Highlighting

Watch Video Intro

You can toggle enable/disable: Press F1 and then type "blockman toggle".

Also You can go to Blockman settings and set Black List Of File Formats to disable Blockman for certain files.

alt text testing

Animated PNG:

alt text testing


Added NEW color combos as "Super gradients".

Blockman now supports gradients for both: borders and backgrounds.

super gradients color combos in Blockman

super gradients color combos in Blockman for Python


You can hide backgrounds and keep only borders.

Go to Blockman settings, find "N33 A01 B2" and type "45,0,0,2; none".

only borders instruction in Blockman


You can highlight all the parents of the focused block.

only borders instruction in Blockman


How to do it? Go to Blockman settings, find "N33 A03 B1" and delete "!".

"!" (exclamation mark) means the option is disabled.

only borders instruction in Blockman

Also you can type other colors and other propagation logic with your taste. See the instructions of advanced coloring.




Supported programming languages:

Non-indentation based languages: JavaScript, JSX, TypeScript, TSX, C, C#, C++, Java, Ruby, PHP, R, Go (Golang), Dart, Rust, Swift, PowerShell, SQL, HTML, CSS, LESS, SCSS and more...

Indentation based languages: currently Python and Yaml.


Python code:

alt text testing


If you use double width characters, then you may want to run the experimental command to support such characters. Press F1 and type the command name: Blockman Toggle Try Support Double Width Chars.

Such as,


Blockman settings

You can change nesting depth

alt text testing


You can choose color combos

alt text testing

alt text testing


You can choose right side padding strategies

alt text testing


You can change color of each depth

Colors can be any CSS color value: red, green... rgb(), hsl(), linear-gradient()...

alt text testing


You can change focused block colors and general border color

alt text testing


You can change basis of block analysis

(Curly brackets, square brackets, round brackets, tags, indentation)

alt text testing


Currently only Python and Yaml are supported from indentation based languages

alt text testing

You can provide other tokenizer algorithms and we can add them into this extension, so Blockman will be able to highlight blocks based on different or more advanced logic, or add support for other indentation based languages.


You can disable rendering single line blocks

alt text testing


All Blockman quick commands

Press F1 and find:

>Blockman Toggle Enable/Disable
>Blockman Toggle Enable/Disable And Force Show/Hide Indent Guides

>Blockman Select Focused --- Select text inside focused block
>Blockman Toggle Freeze/Unfreeze Focus

>Blockman Toggle Try Support Double Width Chars (e.g. Chinese)

>Blockman Clear State Storage --- revert back to the first installation state


All Blockman settings

// settings.json (User/Global config, not Workspace config)
// To open this file in VS Code, press F1, type 'settings json' and choose 'Preferences: Open Settings (JSON)'

// Each item is with default value
{
    // n01 and n02 are deprecated.
    "blockman.n03MaxDepth": 12, // -1 is no blocks, 0 is ground block, 1 is first depth blocks, 2 is second depth blocks
    "blockman.n04ColorComboPreset": "Classic Dark 1 (Gradients)", // This does not change VS Code theme. Choose preset combo of colors. Corresponding colors are overridden by custom colors (if not empty string). Also This setting can be overriden by the next 3 combo settings
    "blockman.n04Sub01ColorComboPresetForDarkTheme": "none", // Color combo to apply when current theme kind is Dark.
    "blockman.n04Sub02ColorComboPresetForLightTheme": "none", // Color combo to apply when current theme kind is Light.
    "blockman.n04Sub03ColorComboPresetForHighContrastTheme": "none", // Color combo to apply when current theme kind is High Contrast.

    "blockman.n04Sub04RightSideBaseOfBlocks": "Rightmost Edge Of Inner Content", // or "Rightmost Edge Of Viewport" or "Rightmost Edge Of File Content"
    "blockman.n04Sub05MinDistanceBetweenRightSideEdges": 0, // CSS pixels. 4 is probably good. Keep in mind that for some devices, CSS pixel is larger/smaller than physical pixel.
    "blockman.n04Sub06AdditionalPaddingRight": 0, // CSS pixels. Keep in mind that for some devices, CSS pixel is larger/smaller than physical pixel.

    "blockman.n05CustomColorOfDepth0": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.

    "blockman.n06CustomColorOfDepth1": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n07CustomColorOfDepth2": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n08CustomColorOfDepth3": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n09CustomColorOfDepth4": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n10CustomColorOfDepth5": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.

    "blockman.n11CustomColorOfDepth6": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n12CustomColorOfDepth7": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n13CustomColorOfDepth8": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n14CustomColorOfDepth9": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.
    "blockman.n15CustomColorOfDepth10": "", // Any CSS color, e.g. rgb, rgba, hsl. Type 'none' for same color as editor background.

    "blockman.n16EnableFocus": true, // Highlight block differently if caret is inside it.
    "blockman.n17CustomColorOfFocusedBlock": "", // Requires 'Enable Focus' to be true/enabled. Type 'same' if you want it to be same color as if not focused.
    "blockman.n18CustomColorOfFocusedBlockBorder": "", // Requires 'Enable Focus' to be true/enabled. Type 'same' if you want it to be same color as if not focused.
    "blockman.n19CustomColorOfBlockBorder": "",
    "blockman.n20CustomColorOfDepth0Border": "",

    "blockman.n21BorderRadius": 6,
    "blockman.n22AnalyzeCurlyBrackets": true, // Render blocks inside curly brackets {}, keep in mind: the parser/tokenizer will ignore brackets inside comments, inside strings and inside some other areas.
    "blockman.n23AnalyzeSquareBrackets": false, // Render blocks inside square brackets [], keep in mind: the parser/tokenizer will ignore brackets inside comments, inside strings and inside some other areas.
    "blockman.n24AnalyzeRoundBrackets": false, // Render blocks inside Round brackets (), keep in mind: the parser/tokenizer will ignore brackets inside comments, inside strings and inside some other areas.
    "blockman.n25AnalyzeTags": true, // Render blocks inside HTML/XML/JSX/TSX tags <tag></tag>, keep in mind: the parser/tokenizer will ignore tags inside comments, inside strings and inside some other areas.

    "blockman.n26AnalyzeIndentDedentTokens": true, // This option affects only files of indentation based languages like Python. Currently only Python and Yaml are supported for indentation analysis. Keep in mind: the parser/tokenizer will ignore indentations inside comments, inside strings and inside some other areas.
    "blockman.n27AlsoRenderBlocksInsideSingleLineAreas": false, // {I am a single line area} <p>Me too</p>. Focused single line block will still be rendered even if this setting is off. Use n27B01 to hide block of focused single line area.
    "blockman.n27B01HideBlockOfFocusedSingleLineArea": false, // {I am a single line area} <p>Me too</p>.

    "blockman.n28TimeToWaitBeforeRerenderAfterLastChangeEvent": 1.2, // (Seconds). For optimization: enter more time for slow computers. Less than 0.05 is NOT recommended even for fast computers.
    "blockman.n29TimeToWaitBeforeRerenderAfterLastFocusEvent": 0.2, // (Seconds). For optimization: enter more time for slow computers. Less than 0.2 is NOT recommended because double-clicking may become problematic.
    "blockman.n30TimeToWaitBeforeRerenderAfterLastScrollEvent": 0.1, // (Seconds). For optimization: enter more time for slow computers. Less than 0.05 is NOT recommended even for fast computers.
    "blockman.n31RenderIncrementBeforeAndAfterVisibleRange": 22, // Less is faster because less blocks will be rendered outside the viewport but scrolling may become less comfortable. If less than 1 (e.g. -5), the blocks will render in limited area.

    "blockman.n32BlackListOfFileFormats": "plaintext, markdown, ", // Disable Blockman for certain file formats, e.g. plaintext, markdown, css, less, scss, html, json, jsonc, typescriptreact, typescript, javascriptreact, javascript, python, go, dart, php, c, csharp, cpp, java. If the first character is '^' (caret symbol), the list will act as a white list, e.g. '^ typescript, typescriptreact'.

    // Advanced Coloring:
    // Video instruction: https://youtu.be/UsET6-kPu90

    // Textual instruction:
    // '!' means disabled.
    // Advanced coloring string, if enabled, will override basic coloring settings.

    // Right side: sequence of colors/gradients.

    // Left side:
    // --- FIRST number relates priority,
    // --- SECOND number relates zero-based index of first item of first loop, So it splits the sequence into what should not be looped and what should be looped,
    // --- THIRD number relates loop part reversion (0: original, 1: reversed),
    // --- FOURTH number relates looping strategy (0: all the continuation items to be 'neutral', 'neutral' means it will be overriden by any other setting, 1: Only the last item will be looped. Yes, it will ignore the SECOND option number (split index), 2: loop as forward, 3: loop as pair of forward and backward).

    // 'neutral' color means it will be overriden by any other coloring setting.
    // 'basic' color means it will set a color from basic color settings.

    // 'transparent' and partially transparent colors work fine for borders, but backgrounds have some problems with such values,
    // so, if you type 'transparent' on background, it will be the color of VS Code editor backgound.

    "blockman.n33A01B1FromDepth0ToInwardForAllBorders": "!10,0,0,0; red > green > blue",
    "blockman.n33A01B2FromDepth0ToInwardForAllBackgrounds": "!10,1,0,3; hsl(235, 30%, 7%) > hsl(0, 0%, 7.1%) > hsl(0, 0%, 9.5%) > hsl(0, 0%, 11.15%) > hsl(0, 0%, 12.8%)",

    "blockman.n33A02B1FromFocusToOutwardForAllBorders": "!20,0,0,0; red > green > blue",
    "blockman.n33A02B2FromFocusToOutwardForAllBackgrounds": "!20,0,0,0; red > green > blue",

    "blockman.n33A03B1FromDepth0ToInwardForFocusTreeBorders": "!30,1,0,2; linear-gradient(to right, hsl(251, 22%, 25%), hsl(292, 20%, 18%)) > linear-gradient(to right, hsl(20, 50%, 30%), hsl(250, 30%, 30%))",
    "blockman.n33A03B2FromDepth0ToInwardForFocusTreeBackgrounds": "!30,0,0,0; red > green > blue",

    "blockman.n33A04B1FromFocusToOutwardForFocusTreeBorders": "40,0,0,0; basic",
    "blockman.n33A04B2FromFocusToOutwardForFocusTreeBackgrounds": "40,0,0,0; basic",

    "blockman.n33A05B1FromFocusToInwardForAllBorders": "!50,0,0,0; red > green > blue",
    "blockman.n33A05B2FromFocusToInwardForAllBackgrounds": "!50,0,0,0; red > green > blue",

    //
    //
    //

    "blockman.n34A01BorderThicknessOfNonFocusedBlock": 1,
    "blockman.n34A02BorderThicknessOfFocusedBlock": 2,

    "blockman.n35A01DisableRecommendationDialog": false,

    "blockman.n36A01MaxCharCountInAnyLine": 3000 // Blockman will not work in a file if the file has at least one line with N (or more) number of chars.
}


Things to consider

1) Each line of code must have less than 3000 (You can change this number) characters, otherwise blocks will not be rendered in entire file.

2) Please don't use non-monospace font. Use only monospace font like 'Oxygen Mono', 'BPG 2017 DejaVu Sans Mono' or other. Block-rendering is based on equal character-frame-widths, because pixel locations of characters is not accessible through VS Code API.

alt text testing

Just for the information, the letter "ლ" is Georgian alphabet character,
like: ა, ბ, გ, დ, ე, ვ, ზ, თ, ი, კ, ლ, მ, ნ, ო, პ, ჟ, რ, ს, ტ, უ, ფ, ქ, ღ, ყ, შ, ჩ, ც, ძ, წ, ჭ, ხ, ჯ, ჰ.

3) If you want to use mix of multiple fonts (like in the image above), Please don't use any non-monospace font. Use monospace fonts which have at least almost same width of character. For example: 'Oxygen Mono' and 'BPG 2017 DejaVu Sans Mono' have not only equal char frame width by themselves alone, but also almost equal char frame width to each other.

For Georgian (ქართული) language oriented developers: without multiple font mixing, just BPG 2017 DejaVu Sans Mono as a single font seems fine for me, and maybe you can use it too. For now, 2022, I think it is the one and only monospace font which has English (both lowercase and UPPERCASE) and Georgian lowercase letters, as well as Georgian UPPERCASE (known as Mtavruli/მთავრული) letters. You can also see the Unicode chart of Georgian lowercase and UPPERCASE letters.

For English language oriented developers: the same statement above goes here.


4) If you want to use ligatured monospace font like "Fira Code" (Typographic ligatures are when multiple characters appear to combine into a single character), please make sure that the font maintains the text width on every line with ligatures like there were no ligatures. "Fira Code" seems fine, and maybe most of ligatured monospace fonts are fine.

5) Recommended to turn off word wrap. Blocks will not render properly if there is any word wrapping.

alt text testing


6) Recommended to turn off "Editor: Guides: Indentation" (new) / "Editor: Render Indent Guides" (old).

alt text testing


7) Recommended to set pale color (e.g. pale blue) to lineHighlightBorder and lineHighlightBackground like this:

alt text testing

alt text testing

// settings.json
// To open this file (as global config) in VS Code, press F1, type 'settings json' and choose 'Preferences: Open Settings (JSON)'
{
    // ...
    "workbench.colorCustomizations": {
        // ...
        "editor.lineHighlightBorder": "#9fced11f",
        "editor.lineHighlightBackground": "#1073cf2d",

        // Or for specific VS Code themes:
        "[Default Dark+]": {
            // ...
            // "editor.lineHighlightBorder": "#9fced11f"
            // "editor.lineHighlightBackground": "#1073cf2d",
        },
        "[Abyss]": {
            // ...
            // "editor.lineHighlightBorder": "#9fced11f",
            // "editor.lineHighlightBackground": "#1073cf2d"
        }
    }
}


Optimization Notes

Optimization is taken very seriously, half of the work is dedicated just for the optimization.

If a file is already analyzed, rendering blocks takes about 0.02 seconds with default Blockman settings. So, rendering is not a big issue, but analyzing is quite heavy work. Here are some test cases of some programming languages:

Yaml file:
    analyze: 0.70 seconds (10,000 lines), 0.06 seconds (1,000 lines)

Dart file:
    analyze: 0.90 seconds (10,000 lines), 0.09 seconds (1,000 lines)

CSharp file:
    analyze: 1.40 seconds (10,000 lines), 0.15 seconds (1,000 lines)

TSX file:
    analyze: 1.60 seconds (10,000 lines), 0.17 seconds (1,000 lines)

JavaScript file:
    analyze: 2.70 seconds (10,000 lines), 0.28 seconds (1,000 lines)

Python file:
   analyze: 10.70 seconds (10,000 lines), 0.86 seconds (1,000 lines)

So, currently I'm trying to find more optimized ways to analyze files, especially for Python langauge.


Big thanks to these source codes

Bracket Pair Colorizer 2 (by CoenraadS)

Highlight Matching Tag (by vincaslt)

dt-python-parser (by DTStack)


Also Big thanks

From 1.1.0 version, manual setup of line height and char width is not needed anymore, thanks to alexdima (Alexandru Dima).

From 1.2.0 version, the problem of block-rendering widths at the locations of Color Decorators have been fixed for most of monospace fonts. Thanks to rioV8 from stackoverflow.


Published In:

Github repository: https://github.com/leodevbro/vscode-blockman

Marketplace: https://marketplace.visualstudio.com/items?itemName=leodevbro.blockman

Open VSX: https://open-vsx.org/extension/leodevbro/blockman


Donation

Buy Me A Coffee: https://www.buymeacoffee.com/leodevbro

Ko-fi: https://ko-fi.com/leodevbro

Bank account (USD): GE08TB7774936615100013 (TBCBGE22)

Bank account (GEL/Lari): GE18TB7774936515100011 (TBCBGE22)