Skip to content

jonathanchu/grove

Repository files navigation

grove.el

An Obsidian-like note-taking mode for Emacs. One keybinding opens a full workspace with a file tree sidebar and your org notes.

grove-screenshot.png

https://melpa.org/packages/grove-badge.svg https://img.shields.io/badge/license-GPL--3.0-blue.svg

Features

  • File tree sidebar with expand/collapse, indent guides, current file tracking, item counts, optional nerd font icons, and note preview on navigation
  • Quick capture — just type, first line becomes the title, saved to your inbox
  • Wikilinks[[note title]] syntax with font-lock, click to follow, create on missing
  • Backlinks — ripgrep-powered, computed on demand, displayed in a side panel
  • Daily notes — one keybinding for today, yesterday, or tomorrow
  • Search — full-text ripgrep search with optional Consult integration
  • Tag search — find notes by #hashtag or org :tag: syntax
  • Inbox review — triage untagged notes
  • Graph view — visualize note connections via Graphviz

No database. No external Emacs dependencies. Just org files, a directory, and ripgrep.

Requirements

  • Emacs 29.1+
  • ripgrep (rg) on your PATH

Optional:

Installation

MELPA

Grove is available on MELPA. After adding MELPA to your package archives:

(use-package grove
  :ensure t
  :bind-keymap ("C-c v" . grove-command-map)
  :custom
  (grove-directory "~/notes/")
  :config
  (global-grove-mode 1))

global-grove-mode activates grove-mode in any org buffer that lives inside grove-directory, which enables wikilink font-locking and the C-c C-l keybinding for inserting links. Omit it if you’d rather enable grove-mode manually per buffer.

Manual

Clone the repository and add it to your load path:

(use-package grove
  :load-path "~/path/to/grove"
  :bind-keymap ("C-c v" . grove-command-map)
  :custom
  (grove-directory "~/notes/")
  :config
  (global-grove-mode 1))

Usage

Set your vault directory and press C-c v v to open the workspace.

KeyCommandDescription
C-c v vgrove-openOpen the grove workspace
C-c v qgrove-closeClose and restore layout
C-c v ngrove-captureQuick capture a new note
C-c v fgrove-findFind note by title
C-c v sgrove-searchFull-text ripgrep search
C-c v dgrove-dailyOpen today’s daily note
C-c v bgrove-backlinksShow backlinks for note
C-c v tgrove-search-tagSearch by tag
C-c v igrove-inbox-reviewTriage untagged notes
C-c v lgrove-link-insertInsert a wikilink
C-c v ggrove-graphShow vault graph

Tree sidebar

KeyAction
RETOpen file / toggle dir
TABToggle directory expand
n / C-nNext entry (with preview)
p / C-pPrevious entry (with preview)
gRefresh tree
qClose sidebar

Capture

C-c v n opens *grove-capture*, a blank org buffer. Type freely — no prompts, no template. The first line becomes the title; everything below becomes the body.

  • C-c C-c saves to the inbox
  • C-c C-k discards

For example, typing:

Project ideas for next quarter

- migrate to ripgrep
- add a graph view

and pressing C-c C-c writes inbox/project-ideas-for-next-quarter.org:

#+title: Project ideas for next quarter

- migrate to ripgrep
- add a graph view

Filenames are derived from the title (lowercased, spaces to dashes). A numeric suffix is appended on collision.

Inbox review

C-c v i opens *grove-inbox*, a triage buffer that lists notes needing attention. The buffer groups notes by the reason they showed up — currently, Untagged: notes with no #+filetags: line and no inline #hashtags.

KeyAction
RETVisit the note at point
n / pMove to next / previous line
gRefresh the buffer
qClose the buffer

The intended workflow is short loops: open the inbox, jump into a note with RET, add tags or wikilinks, save, and either come back with C-c v i or refresh in place with g. Notes drop off the list as you tag them, so the buffer doubles as a progress indicator.

The list is built from the vault cache, so it covers your whole vault — not just files under grove-inbox-directory. Tag a note anywhere and it disappears from the next refresh.

Graph

C-c v g renders a graph of all notes and their [[wikilinks]] using Graphviz. Requires dot on your PATH.

The graph display adapts to your frame width — on wide frames (160+ columns) it opens as a right side panel, otherwise it uses a full buffer. You can override this with grove-graph-display: 'side, 'buffer, or 'auto (default).

Use + / - to zoom in/out and 0 to fit to window.

Configuration

;; Required: set your vault directory
(setq grove-directory "~/notes/")

;; Optional: customize subdirectories (defaults shown)
(setq grove-inbox-directory "inbox")
(setq grove-daily-directory "daily")

;; Optional: daily note filename format (default shown)
(setq grove-daily-format "%Y-%m-%d")

;; Optional: tree sidebar width (default shown)
(setq grove-tree-width 30)

;; Optional: show nerd font icons in the tree sidebar
(setq grove-tree-icons t)

;; Optional: graph view settings (defaults shown)
(setq grove-graph-layout "neato")    ; or "dot", "fdp", "sfdp"
(setq grove-graph-display 'auto)     ; or 'side, 'buffer
(setq grove-graph-min-width 160)     ; frame width threshold for auto

License

GPL-3.0. See LICENSE.

About

An Obsidian-like note-taking mode for Emacs

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors