Skip to content

Instantly share code, notes, and snippets.

@chrispahm
Created April 14, 2023 12:55
Show Gist options
  • Select an option

  • Save chrispahm/1fb69c89eb6774d7c62ad131e3b57c41 to your computer and use it in GitHub Desktop.

Select an option

Save chrispahm/1fb69c89eb6774d7c62ad131e3b57c41 to your computer and use it in GitHub Desktop.

Revisions

  1. chrispahm created this gist Apr 14, 2023.
    87 changes: 87 additions & 0 deletions RegexFoldingRangeProvider.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,87 @@
    const vscode = require('vscode');

    module.exports = class RegexFoldingRangeProvider {

    constructor(filters = {}, bufferTop = 0, bufferBottom = 0) {
    const {more = [], less = []} = filters;
    this.bufferBottom = bufferBottom;
    this.bufferTop = bufferTop;
    this.checkString = (str) => {
    // Check if the string matches any of the regexes in the "more" array
    let moreResult = more.some(regex => regex.test(str));

    // Check if the string matches any of the regexes in the "less" array
    let lessResult = less.some(regex => regex.test(str));

    // Return true if moreResult is true and lessResult is false
    return moreResult && !lessResult;
    }
    }

    // This method is called by VSCode to get the folding ranges for a document
    provideFoldingRanges(document, context, token) {
    // Loop through each line of the document
    let linesToDisplay = [];
    for (let i = 0; i < document.lineCount; i++) {
    // Get the current line
    let line = document.lineAt(i);

    // Check if the line passes the regex test
    if (this.checkString(line.text)) {
    linesToDisplay.push(i);
    }
    }

    // create a new array of numbers, that adds the bufferBottom and bufferTop
    // paddings to the lines to display
    let linesToDisplayWithBuffer = [];
    linesToDisplay.forEach((lineIndex) => {
    const start = lineIndex - this.bufferTop;
    const end = lineIndex + this.bufferBottom;
    for (let i = start; i <= end; i++) {
    if (i >= 0 && i < document.lineCount && !linesToDisplayWithBuffer.includes(i)) {
    linesToDisplayWithBuffer.push(i);
    }
    }
    });

    linesToDisplayWithBuffer.sort((a, b) => a - b);

    // from the array of lines to display, we create
    // an array of ranges that should NOT be displayed
    const ranges = [];
    let start = 0;
    let end = 0;
    for (let i = 0; i < document.lineCount; i++) {
    if (linesToDisplayWithBuffer.includes(i)) {
    // this line should be visible!
    // if there is a range that is not empty, push it to the ranges array
    if (start !== end) {
    ranges.push({
    start,
    end
    });
    }
    start = i;
    end = i;
    } else {
    // this line should be hidden!
    end = i;
    }
    }
    // push the last range
    if (start !== end) {
    ranges.push({
    start,
    end
    });
    }

    const foldingRanges = ranges.map(range => (
    new vscode.FoldingRange(range.start, range.end, vscode.FoldingRangeKind.Region)
    ));

    // Return the array of folding ranges
    return foldingRanges
    }
    }