Skip to content

A widget-based sidebar for Emacs that displays contextual information (stats, outline, backlinks, links) for vulpea notes

Notifications You must be signed in to change notification settings

d12frosted/vulpea-ui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vulpea-ui

Sidebar infrastructure and widget framework for vulpea notes.

CI version

Screenshot

Features

  • Per-frame sidebar with configurable position and size
  • Widget system built on vui components
  • Default widgets: outline, backlinks, forward links, stats
  • Easy API for creating custom widgets
  • Auto-hide when switching to non-vulpea buffers

Installation

Dependencies

  • Emacs 29.1+
  • vulpea (v2, v2-rewrite branch)
  • vui

Using straight.el

(straight-use-package
 '(vulpea-ui :host github :repo "d12frosted/vulpea-ui"))

Using elpaca

(elpaca (vulpea-ui :host github :repo "d12frosted/vulpea-ui"))

Usage

(require 'vulpea-ui)

;; Open sidebar
(vulpea-ui-sidebar-open)

;; Or toggle with a keybinding
(global-set-key (kbd "C-c v s") #'vulpea-ui-sidebar-toggle)

Automatic sidebar

To automatically open the sidebar when entering org-mode buffers:

(add-hook 'org-mode-hook #'vulpea-ui-sidebar-open)

Configuration

Sidebar position and size

;; Position: 'right (default), 'left, 'top, 'bottom
(setq vulpea-ui-sidebar-position 'right)

;; Size as fraction of frame (0.0-1.0)
(setq vulpea-ui-sidebar-size 0.33)

Outline widget

;; Maximum heading depth (nil = unlimited)
(setq vulpea-ui-outline-max-depth 3)

Backlinks widget

;; Show/hide content previews
(setq vulpea-ui-backlinks-show-preview t)

;; Lines to show in prose previews
(setq vulpea-ui-backlinks-preview-lines 2)

;; Characters before/after link in prose previews
(setq vulpea-ui-backlinks-prose-chars-before 30)
(setq vulpea-ui-backlinks-prose-chars-after 50)

;; Filter which notes appear in backlinks
;; (function receiving vulpea-note, return non-nil to include)
(setq vulpea-ui-backlinks-note-filter
      (lambda (note)
        (not (member "archive" (vulpea-note-tags note)))))

;; Filter by context type
;; t = all types, or a list of: meta, header, table, list, quote, code, footnote, prose
(setq vulpea-ui-backlinks-context-types t)

;; Sorting: nil (no sorting), 'title-asc, 'title-desc, or custom function
(setq vulpea-ui-backlinks-sort 'title-asc)

Behaviour options

;; Auto-hide sidebar when switching to non-vulpea buffers
(setq vulpea-ui-sidebar-auto-hide t)

;; Start widgets collapsed
(setq vulpea-ui-default-widget-collapsed nil)

Performance

For large org files or many backlinks, enable fast parsing:

;; Skip org-mode hooks during parsing (faster but may cause issues
;; if your setup depends on mode hooks for org-element parsing)
(setq vulpea-ui-fast-parse t)

Commands

CommandDescription
vulpea-ui-sidebar-openOpen the sidebar
vulpea-ui-sidebar-closeClose the sidebar
vulpea-ui-sidebar-toggleToggle sidebar visibility
vulpea-ui-sidebar-refreshForce refresh content

Sidebar keybindings

KeyAction
qClose sidebar
gRefresh content
TABNavigate to next widget
S-TABNavigate to previous widget
RETActivate widget at point

For quick navigation to any widget, consider ace-link-vui.

Default widgets

Stats widget

Screenshot

Shows character count, word count, and link count for the current note.

Outline widget

Screenshot

Displays the heading structure of the note. Click headings to navigate.

Backlinks widget

Screenshot

Shows notes that link to the current note, grouped by file with:

  • Heading path context (where in the document the link appears)
  • Content preview with context type indicators:
    • meta property
    • § header
    • table
    • · list item
    • > quote
    • λ code
    • footnote
    • (no indicator) prose

Links widget

Screenshot

Shows notes that the current note links to.

Widget Registration

Widgets are registered with vulpea-ui-register-widget, which allows filtering by predicate and ordering.

Built-in widgets

vulpea-ui registers these widgets by default:

WidgetOrderComponent
stats100vulpea-ui-widget-stats
outline200vulpea-ui-widget-outline
backlinks300vulpea-ui-widget-backlinks
links400vulpea-ui-widget-links

Registering widgets

(vulpea-ui-register-widget 'my-widget
  :component 'my-custom-widget-component
  :predicate #'my-note-predicate  ; optional: only show when this returns non-nil
  :order 150)                      ; optional: default 100

Modifying widget properties

;; Change a widget's order
(vulpea-ui-widget-set 'stats :order 50)

;; Remove a widget
(vulpea-ui-unregister-widget 'links)

How it works

  1. Widgets are filtered by their :predicate (if any) against the current note
  2. Remaining widgets are sorted by :order (ascending)
  3. Each widget’s :component is rendered

This allows packages like vulpea-journal to register context-specific widgets that only appear when viewing certain notes.

Custom widgets

Create custom widgets using vui’s defcomponent macro:

(defcomponent my-custom-widget ()
  "My custom widget."
  :render
  (let ((note (use-vulpea-ui-note)))
    (vui-component 'vulpea-ui-widget
      :title "My Widget"
      :count 42
      :children
      (lambda ()
        (vui-text "Custom content here")))))

Register the widget:

(vulpea-ui-register-widget 'my-widget
  :component 'my-custom-widget
  :order 250)  ; after outline, before backlinks

For context-specific widgets (e.g., only for notes with a certain tag):

(defun my-project-note-p (note)
  "Return non-nil if NOTE is a project note."
  (member "project" (vulpea-note-tags note)))

(vulpea-ui-register-widget 'project-tasks
  :component 'my-project-tasks-widget
  :predicate #'my-project-note-p
  :order 150)

Utility Functions

vulpea-ui-clean-org-markup

Cleans org-mode markup from text for display purposes:

(vulpea-ui-clean-org-markup text)

Transformations:

  • Links: [[url][title]]title, [[url]]url (bare [[id:...]] links are removed)
  • Drawers: :PROPERTIES:...:END: blocks are removed
  • Metadata: #+TITLE:, #+FILETAGS:, etc. lines are removed
  • Whitespace: multiple spaces/tabs collapsed to single space

Useful for rendering previews in custom widgets.

Faces

FaceDescription
vulpea-ui-widget-header-faceWidget header text
vulpea-ui-widget-count-faceWidget count numbers
vulpea-ui-outline-heading-faceOutline headings
vulpea-ui-stats-faceStatistics text
vulpea-ui-backlink-preview-faceBacklink preview text
vulpea-ui-backlink-heading-faceBacklink heading path
vulpea-ui-backlink-meta-key-faceMeta block keys
vulpea-ui-backlink-meta-value-faceMeta block values
vulpea-ui-backlink-context-faceContext type indicators

Related Projects

  • vulpea-journal - Daily journaling with calendar, navigation, and “on this day” widgets
  • ace-link-vui - Ace-link style navigation for VUI buffers

License

Copyright (C) 2024-2025 Boris Buliga

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

About

A widget-based sidebar for Emacs that displays contextual information (stats, outline, backlinks, links) for vulpea notes

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published