Skip to content

fvalenza/vaultview.nvim

Repository files navigation

vaultview.nvim

A Neovim plugin to visualize your notes vault in a board-style view — for quick, contextual overviews without relying on a file tree (that is limited for this sort of overview).


VaultView allows users to create customizable boards that give a quick, visual overview of their note vault. Instead of navigating through a file tree, VaultView parses and displays your notes in boards or matrices — giving you an at-a-glance view of what’s inside and what each note contains.

With it, you can:

  • Quickly browse your vault in a structured, board-like interface.
  • See summaries or key content (like headings, links, or metadata) from your notes.
  • Open notes directly in Neovim or Obsidian.
  • Navigate the boards fluidly using Vim motions or custom pickers.
Can we have Bases at home ?

meme_bases_at_home

Table of Contents

⭐ Features

  • Search / Parse / Display specific files in a matrix or board view
  • Open the corresponding file in Neovim or Obsidian
  • Navigate between board entries using Vim motions or custom pickers
  • Fully customizable boards — define what subset of your vault each one displays
  • Access the files of your vault for quick edit from any Neovim project

🪄 Examples

Daily Notes Board (Carousel Layout):

img

Boards of Maps Of Content (Columns Layout):

img

What is a Map Of Content (MOC)?

A Map Of Content is a special type of note that serves as a hub or index that gives you an overview of a topic and quickly navigates you to the relevant notes. A MOC can typically be built within Obsidian by creating a file whose content is a list of links to other notes related to a specific subject. An optimized workflow to populate MOCs in Obsidian is to use [[links]] in notes that relate to the MOC topic and then display dynamically with Dataview plugin in the MOC file all notes that link to it.

For example:

- Projects.md -> the MOC file
- Project 1.md -> file containing [[Projects]]  (I usually put the link at the top of the file)
- Project 2.md -> file containing [[Projects]]

and the dynamically displayed content in Projects.md with Dataview would be (with links that can be followed): img

This concept of MOC can be applied to various note organization preferences.

The problem with this is that while you can click on the links in Obsidian, you can’t quickly get an overview of what’s inside each linked note without opening it + you can only display one MOC at a time.

Tip

With the VaultView plugin, you can create a board that displays all your MOCs at once, along with the headings (or whatever content_selector you prefer) inside each linked note — and navigate it quickly using Vim motions. Plus quickly open the file in either Neovim or Obsidian.

Quick edit of a file from the board: img

⚙️ How it works

The plugin is architectured around the concept of MVC (Model-View-Controller) pattern.

A board in VaultView consists of three main parts:

  1. Board Data (The Model)

The data is generated by a parser, which: read- Takes all (or a subset) of your vault’s files => "Input Selection"

  • Organizes it into a structured format => "Board Data Structuring"
  • Extracts and aggregates relevant information for each entry => "Content Selection"
Board
 ├── Pages
 │    ├── Lists (one column/block per list)
 │    │    ├── Entries (one card per entry)
 │    │    │    └── Content (displayed in cards)

Currently Supported Parsers:

  • Daily Note Parser -> Retrieves all daily notes in your vault, sorts them by year/month, and extracts headings for each day.
  • MOC Parser -> Finds all your MOC files and, for each one, lists all files linking to it — along with their headings (to display a TOC inside each card).
  1. View (The Controller) The View holds data and states related to one board. It delegates the rendering of the data to a specific layout.

  2. View Layout (The View)

The layout determines how the parsed data is displayed.

Currently Supported Layouts:

  • Vertical Carousel
  • Columns

💡 Why this plugin

I love Obsidian — especially for features like the Excalidraw plugin and great table handling. However, when it comes to navigation with hjkl and text editing, nothing beats Neovim.

What I missed most in Obsidian was a quick way to visualize my vault based on certain criteria — for example:

  • Seeing what’s inside all my MOCs (Maps of Content)
  • Browsing through all my Daily Notes

Obsidian has Dataview and Bases, but:

  • They’re confined within Obsidian’s UI.
  • They require a specific query/config language.
  • They lack the power of Vim motions.

I actually started thinking about VaultView before Obsidian Bases even existed — and it turned out to be a great way to learn Lua and Neovim plugin development.

External dependencies

Installation

{
    "fvalenza/vaultview",
    dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },
}

Configuration

return {
	"fvalenza/vaultview.nvim",
	dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },

	keys = {
		{ "<leader>vv", "<Plug>(VaultView)", mode = "n", desc = "Open VaultView" },
	},

	config = function()

		vim.g.vaultview_configuration = {
			logging = {
				level = "info",
				use_console = false,
				use_file = false,
				output_path = "/tmp/vaultview.log",
				raw_debug_console = false, -- Used to output special strings breaking classic formatting
			},
			hints = {
				board_navigation = true,
				-- pages_navigation = false, -- TODO: not yet implemented
				-- entry_navigation = false, -- TODO: not yet implemented
			},
            selectors = {
                input = { -- list of custom input selectors. They keys can be used in board definitions
                    exemple_list_files = { -- a comma-separated list of file paths
                        "/path/to/file1.md",
                        "/path/to/file2.md",
                        "/path/to/file3.md",
                    },
                    exemple_lua_function =function(search_path) -- a function that returns a list of file paths from a given search_path
                        return {
                        }
                    end,
                    exemple_shell_command = [=[ your_shell_command ]=], -- Custom shell command to list files
                },
                entry_content= { -- custom content selectors can be defined here and chosen in the board configuration
                    -- shall be grep/awk/rg command lines
                },
            },
            vaults = {
                ["myVault"] = { -- Just a key used to reference the vault in board config but can be the same as obsidianVaultName
                    path = "/tmp/myVault/",
                    obsidianVaultName = "myVault", -- Name of the vault as known by Obsidian (used to build uri)
                },
            },
			boards = {
				{
                    vault = "myVault", -- key of the vault to use for this board.
					name = "dailyBoard", -- name of the board as printed in the top of UI
                    parser = "daily", -- parser used to retrieve information to display in the view -> currently supported parsers: "daily", "moc"
					viewlayout = "carousel", -- how information is displayed in the view -> currently supported layouts: "carousel", "columns"
                    input_selector = "yyyy-mm-dd.md",-- rule to select files to be included in the board. Can be a built-in selector or a user-defined one
                    subfolder = "vault/0-dailynotes", -- optional subfolder inside vault to limit the scope of the input files
                    content_selector = "h2", -- rule to select content inside each file to be displayed in the view. Can be a built-in selector or a user-defined one
				},
				{
                    vault = "obsidian:<workspace_name>", -- special syntax to directly reference an Obsidian vault configured in Obsidian.nvim plugin ( key of the workspace as defined in the `workspaces` section of obsidian.nvim plugin configuration)
					name = "mocBoard",
					parser = "moc",
					viewlayout = "columns",
                    input_selector = "*.md",
                    subfolder = "vault/1-MOCs",
                    content_selector = "h2",
				},
			},
            initial_board_idx = 1, -- index of the board to be displayed when opening the vaultview. Optional.
		}
	end,
}

Keybinds

Interaction with the VaultView UI is done through actions exposed as <Plug> mappings. This plugin defines default keybinds only inside the VaultView UI (through ftplugin/vaultview.lua).

The description of the default keybinds and associated actions/<Plug> is as follows:

Key Plug Description
(VaultView) Toggles VaultView UI
q (VaultViewHide) Closes VaultView UI
? (VaultViewHelp) Open help
p (VaultViewPreviousBoard) Go to previous board
n (VaultViewNextBoard) Go to next board
<S-h> (VaultViewPreviousPage) Go to previous page in current board
<S-l> (VaultViewNextPage) Go to next page in current board
<M-h> (VaultViewFirstList) Go to first list in current page
h (VaultViewPreviousList) Go to previous list in current page
c (VaultViewCenterList) Go to center list in current page
l (VaultViewNextList) Go to next list in current page
<M-l> (VaultViewLastList) Go to last list in current page
gg (VaultViewFirstEntry) Go to first entry in current list (jumps entry's pages)
k (VaultViewPreviousEntry) Go to previous entry in current list
j (VaultViewNextEntry) Go to next entry in current list
G (VaultViewLastEntry) Go to last entry in current list (jumps entry's pages)
<A-k> (VaultViewPreviousPageInList) Go to previous entry's page in current list
<A-j> (VaultViewNextPageInList) Go to next entry's page in current list
o (VaultViewOpenInNeovim) Open file of currently selected entry in Neovim
<CR> (VaultViewOpenInObsidian) Open file of currently selected entry in Obsidian
r (VaultViewRefreshEntry) Refresh Content displayed for selected entry
R (VaultViewFastRefresh) Refresh Content displayed for all entries (do NOT reparse vault for new entries)
1 (VaultViewBoard1) Go To Board 1
2 (VaultViewBoard2) Go To Board 2
3 (VaultViewBoard3) Go To Board 3
4 (VaultViewBoard4) Go To Board 4
5 (VaultViewBoard5) Go To Board 5
6 (VaultViewBoard6) Go To Board 6
7 (VaultViewBoard7) Go To Board 7
8 (VaultViewBoard8) Go To Board 8
9 (VaultViewBoard9) Go To Board 9

Overwriting Default keybinds

To overwrite the default keybinds, the advised way is to create your own ftplugin/vaultview.lua (or ftplugin/vaultview-error.lua for corrupted boards) in your Neovim configuration folder (e.g. ~/.config/nvim/ftplugin/vaultview.lua). In this file, set your preferred keybindings using vim.keymap.set with the {buffer = true} option. For example:

vim.keymap.set("n", "<C-n>", "<Plug>(VaultViewNextBoard)", { buffer = true })

or using LazyVim you can put it directly in the keys section of the plugin specification:

{
    "fvalenza/vaultview",
    dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },
    keys = {
		{ "<leader>vv", "<Plug>(VaultView)", mode = "n", desc = "Open VaultView" },
    },
}

Warning

No default keybind is set to open the VaultView UI and putting a keymap to <Plug>(VaultView) in ftplugin/vaultview.lua would not work. It is expected from the user to set at least this keymap in their Neovim configuration file or to use :VaultView open command.

Input and Content selectors

The plugin comes with some default input and content selectors that can be used in the board configuration. In the configuration one can specify custom ones for input selector as either : a list of files, a shell command returning a list of files, or a Lua function returning a list of files. content_selectors only accepts shell commands returning content lines for each entry. The current default ones are:

local input_selectors = {
    ["*"] = [[find %q -type f | sort ]], -- all files
    ["*.md"] = [[find %q -type f -name '*.md' | sort ]], -- all markdown files
    ["yyyy-mm-dd.md"] = [[find %q -type f | sort | grep -E '/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])\.md$']], -- all markdown files with name matching yyyy-mm-dd.md
}

local content_selectors = {
    headings = [=[grep -E '^#+[[:space:]]+.+' %q | sed -E 's/^#+[[:space:]]+//' ]=],
    h1 = [=[grep -E '^#[[:space:]]+.+' %q | sed -E 's/^#[[:space:]]+//' ]=],
    h2 = [=[grep -E '^##[[:space:]]+.+' %q | sed -E 's/^##[[:space:]]+//' ]=],
    h3 = [=[grep -E '^###[[:space:]]+.+' %q | sed -E 's/^###[[:space:]]+//' ]=],
    h4 = [=[grep -E '^####[[:space:]]+.+' %q | sed -E 's/^####[[:space:]]+//' ]=],
    h2_awk_noexcalidraw = [=[awk '/^# Excalidraw Data/ { exit } /^##[[:space:]]+.+/ { sub(/^##[[:space:]]+/, ""); print }' %q]=],
    h2_rg_noexcalidraw = [=[rg --until-pattern '^# Excalidraw Data' '^##[[:space:]]+.+$' %q | sed -E 's/^##[[:space:]]+//' ]=],
}

Custom parsers

One can provide in the configuration their own custom parsers by providing a function to the "parser" field of a board configuration. The function should take as input the vault subtable of the configuration and the board configuration table:

Obsdian.nvim integration

One can configure a board to use an Obsidian vault configured in the Obsidian.nvim plugin by using the special syntax obsidian:<workspace_name> in the vault field of the board configuration, where <workspace_name> is the key of the workspace as defined in the workspaces section of obsidian.nvim plugin configuration.

Special case: obsidian:CURRENT can be used to reference the curren workspace opened in Obsidian.nvim plugin.

Warning

Current state of obsidian.nvim integration is subject to change:

  • obsidian:CURRENT syntax may disappear in the future
  • if workspace key name is not the same as name of Obsidian Vault, opening in obsidian won't work
--- parse a vault folder to create a board data structure depending on the board configuration
--- @param vault_path string
--- @param boardConfig vaultview.BoardConfig
---
--- @return table boardData The BoardDataStructure required by ViewLayouts
parser = function(vault_path,  boardConfig)
end

Warning: First stable release (v1.0.0) of this plugin is still to come, hence the API for custom parsers may change in future releases.

Usage

Once setup and your neovim instance running, you can use the following commands to interact with VaultView.

:VaultView open
:VaultView close
:VaultView refresh

or you can map your preferred keybinding to <Plug>(VaultView) to open the main VaultView window.

Roadmap

See roadmap

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors