Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Extract Text From Files With Tree-Sitter In Neovim

TODO: Convert this example to HTML

This pulls the code block container languages used in a neopolitan file from `buf_in`` and prints them out to `buf_out``

Code

local append_text = function(out_bufnr, lines)
  vim.api.nvim_buf_set_lines(
    out_bufnr, -1, -1, false, lines
  )
end

local truncate_text = function(out_bufnr)
  vim.api.nvim_buf_set_lines(
    out_bufnr, 0, -1, false, {}
  )
end

local embedded_code = vim.treesitter.query.parse(
  "neopolitan",
  [[ (code_section
      attr_bool: (
        attr_bool
          attr_bool_value: (attr_bool_value) @language))
]])

local get_root = function(in_bufnr)
  local parser = vim.treesitter.get_parser(in_bufnr, "neopolitan", {})
  local tree = parser:parse()[1]
  return tree:root()
end

local format_thing = function(in_bufnr, out_bufnr)
  if vim.bo[in_bufnr].filetype ~= "neopolitan" then
    vim.notify "can only be used in neopolitan files"
    return
  end

  local root = get_root(in_bufnr)

  for id, node in embedded_code:iter_captures(root, in_bufnr, 0, -1) do
    local capture_key = embedded_code.captures[id]
    if capture_key == "language" then
      local text_string = vim.treesitter.get_node_text(node, in_bufnr)
      append_text(out_bufnr, { text_string })
    end
  end
end


local buf_in = 5
local buf_out = 8

truncate_text(buf_out)
format_thing(buf_in, buf_out)

Given this file

Code

-- title

tmp dev example

-- code
-- rust

fn main() {
  println!("here");
}

-- p

Some stuff

-- code
-- python

print("py")

-- p

etc...

The output would be

rust
python

Very cool stuff

References