ぬじろぐ

好きなゲーム発表ぬこちゃん

Monaco editorにMarkdownのFolding Range Providerを追加する


Monaco editorをただのMarkdownエディタにするテスト。
とりあえずブラウザ上で動かすことはできたけど、そのままではコードの折り畳みやリストの入力補助は動作しないみたい…
で、入力補助の機能を追加はgithubで見つけたのですが、折り畳みについては探しても見つからなかったので…こういうのみんな自分で作ってんの?それとも需要ないの?


monacoの設定部分に以下のコードを追加します。

monaco.languages.registerFoldingRangeProvider("markdown", {
    provideFoldingRanges: function (model, context, token) {
        const lines = model.getLinesContent(); // ドキュメントの各行を取得
        const ranges = [];
        const headerStack = []; // 見出し階層のスタック

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i];
            const match = line.match(/^(#+)\s/); // Markdown の見出しに一致 (#, ##, ###)

            if (match) {
                const level = match[1].length; // '#' の数で見出しレベルを判定
                const start = i; // 現在の行

                // スタックを調整して階層を管理
                while (headerStack.length > 0 && headerStack[headerStack.length - 1].level >= level) {
                    const popped = headerStack.pop(); // スタックから要素を取り出す
                    ranges.push({
                        start: popped.start + 1, // 折り畳み範囲の開始行 (1-indexed)
                        end: i, // 現在の行が終了行 (0-indexed)
                        kind: monaco.languages.FoldingRangeKind.Region, // 任意の範囲
                    });
                }

                // 現在の見出しをスタックに追加
                headerStack.push({ level, start });
            }
        }

        // 残ったスタックを処理 (ファイル末尾まで折り畳み)
        while (headerStack.length > 0) {
            const popped = headerStack.pop();
            ranges.push({
                start: popped.start + 1,
                end: lines.length,
                kind: monaco.languages.FoldingRangeKind.Region,
            });
        }

        return ranges;
    },
});


動作サンプルつけようと思ったけど、ローカルでは動くのにwebに上げると動かない…なんでや

[コード](https://github.com/nujisato/monaco-markdown-folding)