A Calustra - Eloy Coto Pereiro Home About Books

Org-Mode Workflow with Neovim: VISIBILITY directive


I have been using org-mode for a few years now. The Neovim support is good, and I love the way it handles tagging sections, links, formatting, and structure. I am also happy with the agenda support it provides.

However, one of the issues I've encountered is the inability to unfold specific sections. For instance, in my "work" note, where I track tasks ranging from emails sent to pending matters, I typically organize it by weeks. I always want the current week to be unfolded by default.

Recently, I experimented with Treesitter query in Neovim. It was an exciting experiment because I could filter all the sections with the directive VISIBILITY and unfold them on demand.

The query language is well described here, and with Neovim version 0.10, you can test it using the :EditQuery command.

The final code looks something like this:

function M:VISIBILITY()
    local query_string = [[
        ((directive name: (expr) @name value: (value) @value)
        ((#match? @name "VISIBILITY")))

    local parser = require('nvim-treesitter.parsers').get_parser()
    local query = vim.treesitter.query.parse(parser:lang(), query_string)
    local tree = parser:parse()[1]
    local result = query:iter_captures(tree:root(), 0)
    for _, n in result do
        if n:type() == "value" then
            local value = get_value_for_directive(n)
            if value == "children" then
                -- Get the parent section, and unfold all the children
                parent = get_parent_subsection(n)
                for child in parent:iter_children() do
                    pcall(unfold_node, child);
            elseif value == "all" then
            elseif value == "folded" then
                -- Do nothing for now
                -- unfold_node(n)
    vim.api.nvim_win_set_cursor(0, {1, 0})

Full code can be found here

Now, my life is much, much easier.


Related articles: