2026.01.16
#vim#markdown
blog
neovimのmarkdown折りたたみを改造した
課題
markdownでメモをする時、読みやすさのために「見出しごとの折りたたみ」をしたい しかし、デフォルト設定の挙動がいまいち気に食わなかった...
やったこと
treesitterの設定をいじって折りたたみ(fold)ルールを変更する
vim.treesitter.query.set(
"markdown",
"folds",
"([(fenced_code_block) (indented_code_block) (section)] @fold (#trim! @fold))"
)
補足
うまく動いているとはいえわかっていない部分が多かったため、Gemini先生に聞いてみました
vim.treesitter.query.set()の解説と意図
このLuaコードは、Vim/Neovimでtreesitterという構文解析エンジンを使用して、Markdownファイルの折りたたみ(fold)ルールを設定しています。
コードの概要
簡単に言うと、この設定はMarkdownファイルを開いたときに、以下の要素を自動で折りたためるようにするためのものです。
- コードブロック: バッククォート(```)で囲まれたブロック
- インデントされたコードブロック: 4つのスペースまたはタブでインデントされたブロック
- セクション(見出し):
#で始まる見出し
これにより、長いMarkdownドキュメントでも、コードブロックや各セクションを折りたたんで、ドキュメント全体の構造をすばやく把握し、必要な部分だけを表示できるようになります。
詳細な説明
vim.treesitter.query.set()
この関数は、指定された言語とクエリタイプに対して、treesitterクエリを設定するために使用されます。
"markdown": これは、設定を適用する言語を指定しています。ここでは、Markdownファイルにこの設定が適用されます。"folds": これは、設定するクエリのタイプを指定しています。"folds"は、テキストの折りたたみルールを定義するためのものです。
([(fenced_code_block) (indented_code_block) (section)] @fold (#trim! @fold))
これが実際のtreesitterクエリです。このクエリは、treesitterの構文ツリーを走査して、折りたたむべきノードを特定します。
(...): これはキャプチャグループで、折りたたむノードを特定するためのルールをまとめています。(fenced_code_block):fenced_code_blockは、```で囲まれたコードブロックを指します。(indented_code_block):indented_code_blockは、インデントされたコードブロックを指します。(section):sectionは、#、##などで始まる見出し(ヘッダー)を指します。@fold: これはキャプチャです。fenced_code_block、indented_code_block、sectionにマッチしたノードに@foldという名前を付けています。treesitterは、この@foldというキャプチャ名を持つノードを折りたたみ可能な要素として認識します。(#trim! @fold): これは**述語(predicate)です。#trim!は、@foldでキャプチャされたノードの空白行をトリム(削除)**するように指示しています。これにより、折りたたまれたときに余分な空白行が表示されず、見た目がきれいに整います。