Emacs as a knowledge manager

Table of Contents

Description

The following notebook aims to show how use emacs to manage relationship between notes.

Set-up indications

To load the current file,

  1. add site-lisp to load-path

         (add-to-list 'load-path (concat user-emacs-directory "site-lisp"))
    
  2. set the desired support
(setopt user/knowledge-management-system 'org-node)
  1. then, load the configuration file

         (load "knowledge-management" t t)
    

Configurations

;;; -*- lexical-binding: t; -*-

Set the default knowledge management system

(defvar user/knowledge-management-system 'native "The knowledge system management backend. Supported backends include ‘native’, ‘denote’, ‘org-roam’, ‘org-node’ and ‘vulpea’")

TODO Native

Denote set-up

Set-up knowledge management system

(setopt user/knowledge-management-system 'denote)

General

  (use-package denote
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :hook
    (dired-mode . denote-dired-mode)
    (after-init .  denote-rename-buffer-mode)
    :bind
    (("C-c d n" . denote-open-or-create)
     ("C-c d r" . denote-rename-file)
     ("C-c d l" . denote-link)
     ("C-c d b" . denote-backlinks)
     ("C-c d d" . denote-dired)
     ("C-c d g" . denote-grep))
    :config
    (setopt denote-directory (expand-file-name (concat org-directory "/Denote/")))
    )

Citar integration

  (use-package citar-denote
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :preface
    (bind-key "C-c w n" #'citar-denote-open-note)
    :hook
    (after-init . citar-denote-mode)
    ;; Bind all available commands
    :bind (("C-c w d" . citar-denote-dwim)
         ("C-c w e" . citar-denote-open-reference-entry)
         ("C-c w a" . citar-denote-add-citekey)
         ("C-c w k" . citar-denote-remove-citekey)
         ("C-c w r" . citar-denote-find-reference)
         ("C-c w l" . citar-denote-link-reference)
         ("C-c w f" . citar-denote-find-citation)
         ("C-c w x" . citar-denote-nocite)
         ("C-c w y" . citar-denote-cite-nocite)
         ("C-c w z" . citar-denote-nobib))
    :config
    (setopt citar-denote-file-type 'org)
    (setopt citar-denote-keyword "bib")
    (setopt citar-denote-signature nil)
    (setopt citar-denote-subdir nil)
    (setopt citar-denote-template nil)
    (setopt citar-denote-title-format "title")
    (setopt citar-denote-title-format-andstr "and")
    (setopt citar-denote-title-format-authors 1)
    (setopt citar-denote-use-bib-keywords nil)
    )

Journaling

  (use-package denote-journal
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :after org
    :bind
    ("C-c d j" . denote-journal-new-or-existing-entry)
    :hook
    (calendar-mode . denote-journal-calendar-mode)
    :config
    (add-to-list 'org-capture-templates
               '("j" "Journal" entry
                   (file+olp denote-journal-capture-entry-for-today  "Journal")
                   "* %(denote-journal-capture-timestamp) %^{Subject?}"))
    (add-to-list 'org-capture-templates
               '("a" "Appointment" entry
                   (file+olp denote-journal-capture-entry-for-date "Appointments")
                   "* %(denote-journal-capture-timestamp) %^{Subject?}"))
    )

TODO Project integration

Offer a specific link between a project and a note.

  (use-package denote-project-notes
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :config
    (require 'project)
    (keymap-set project-prefix-map "n" #'denote-project-notes-dwim)
    (add-to-list 'project-switch-commands '(denote-project-notes-dwim "Notes" "n"))
    )

Agenda integration

  (use-package denote-agenda
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :hook
    (after-init . denote-agenda-insinuate)
    )

Exploration

  (use-package denote-explore
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t
    :bind
    (;; Statistics
     ("C-c e s n" . denote-explore-count-notes)
     ("C-c e s k" . denote-explore-count-keywords)
     ("C-c e s e" . denote-explore-barchart-filetypes)
     ("C-c e s w" . denote-explore-barchart-keywords)
     ("C-c e s t" . denote-explore-barchart-timeline)
     ;; Random walks
     ("C-c e w n" . denote-explore-random-note)
     ("C-c e w r" . denote-explore-random-regex)
     ("C-c e w l" . denote-explore-random-link)
     ("C-c e w k" . denote-explore-random-keyword)
     ;; Denote Janitor
     ("C-c e j d" . denote-explore-duplicate-notes)
     ("C-c e j D" . denote-explore-duplicate-notes-dired)
     ("C-c e j l" . denote-explore-missing-links)
     ("C-c e j z" . denote-explore-zero-keywords)
     ("C-c e j s" . denote-explore-single-keywords)
     ("C-c e j r" . denote-explore-rename-keywords)
     ("C-c e j y" . denote-explore-sync-metadata)
     ("C-c e j i" . denote-explore-isolated-files)
     ;; Visualise denote
     ("C-c e n" . denote-explore-network)
     ("C-c e r" . denote-explore-network-regenerate)
     ("C-c e d" . denote-explore-barchart-degree)
     ("C-c e b" . denote-explore-barchart-backlinks))
    :config
    ;; Where to store network data and in which format
    (setopt denote-explore-network-directory (file-truename (concat denote-directory "/network")))
    (setopt denote-explore-network-filename "denote-network")
    ;; (setopt denote-explore-network-keywords-ignore "<keywords list>")
    ;; (setopt denote-explore-network-regex-ignore "<regex>")
    (setopt denote-explore-network-format 'd3.js)
    (setopt denote-explore-network-d3-colours 'SchemeObservable10)
    (setopt denote-explore-network-d3-js "https://d3js.org/d3.v7.min.js")
    ;; (setopt denote-explore-network-d3-template "<file path>")
    ;; (setopt denote-explore-network-graphviz-header "<header strings>")
    (setopt denote-explore-network-graphviz-filetype 'svg)
    )
  (use-package denote-sequence
    :if (eq user/knowledge-management-system 'denote) 
    :ensure t)

Org-roam set-up

(setopt user/knowledge-management-system 'org-roam)

General

  (use-package org-roam
    :if (eq user/knowledge-management-system 'org-roam) 
    :ensure t
    :bind
    ("C-c n l" . org-roam-buffer-toggle)
    ("C-c n f" . org-roam-node-find)
    ("C-c n i" . org-roam-node-insert)
    ("C-c n c" . org-roam-capture)
    :hook
    (after-init . org-roam-db-autosync-mode)
    :config
    (setq org-roam-directory (file-truename (concat org-directory "/Roam/")))
    (setq org-roam-db-location (file-truename (concat org-roam-directory "org-roam.db")))
    ;; If you're using a vertical completion framework, you might want a more informative completion interface
    (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
    ;; If using org-roam-protocol
    ;; (require 'org-roam-protocol)
    )

Dailies/Journaling

  (use-package org-roam-dailies
    :if (eq user/knowledge-management-system 'org-roam) 
    :bind
    ("C-c n j" . org-roam-dailies-capture-today)
    )

Citar integration

  (use-package citar-org-roam
    :if (eq user/knowledge-management-system 'org-roam) 
    :ensure t
    :after (citar org-roam)
    :config
    (citar-org-roam-mode)
    (setq citar-org-roam-note-title-template "${author} - ${title}")
    )

Graph visualiation

  • Via graphviz

    Need graphviz as a depedency.

      (use-package org-roam-graph
        :if (eq user/knowledge-management-system 'org-roam) 
        :ensure t
        :bind
        ("C-c n g" . org-roam-graph)
        )
    
  • Web-based option
      (use-package websocket
        :if (eq user/knowledge-management-system 'org-roam) 
        :ensure t)
      (use-package org-roam-ui
        :if (eq user/knowledge-management-system 'org-roam) 
        :ensure t
        :bind
        ("C-c n G" . org-roam-ui-open)
        :config
        (setq org-roam-ui-sync-theme t
              org-roam-ui-follow t
              org-roam-ui-update-on-save t
              org-roam-ui-open-on-start t)
        )
    

TODO Better search (via consult)

TODO Contextual interacation (via embark)

TODO Efficient query (via org-ql)


CNCL Bibtex integration

  • State "CNCL" from [2026-04-27 Mon 22:03]

Org node set-up

(setopt user/knowledge-management-system 'org-node)

General

(setopt user/org-node-directory (expand-file-name (concat org-directory "/Node/")))
(use-package org-mem
  :ensure t
  :if (eq user/knowledge-management-system 'org-node)
  :config
  (require 'org-mem-updater)
  (org-mem-updater-mode +1)
  (setopt org-mem-watch-dirs `(,user/org-node-directory))
  )

(use-package org-node
  :ensure t
  :if (eq user/knowledge-management-system 'org-node) 
  :bind-keymap
  ("C-c n" . org-node-global-prefix-map)
  :config
  (org-node-cache-mode +1)
  (with-eval-after-load 'org
    (keymap-set org-mode-map "M-o n" org-node-org-prefix-map))
  ;; (keymap-global-set "C-c n" org-node-global-prefix-map)
  (setopt org-node-data-dir user/org-node-directory)
  (setopt org-node-alter-candidates t)
  ;; (setopt org-node-affixation-fn #'org-node-prepend-olp)
  (setopt org-node-affixation-fn #'org-node-prepend-tags-and-olp)
  ;; (setopt org-node-affixation-fn #'org-node-prepend-olp-append-tags)
  ;; (setopt org-node-affixation-fn #'org-node-prepend-olp-append-tags-use-frame-width)
  (setopt org-node-filter-fn
          (lambda (node) 
            ;; (string-search "/Journal/" (org-mem-file node))
            ;; (or (string-search "/Journal/" (org-mem-file node)) (string-search "/Node/" (org-mem-file node)))
            (string-search "/Node/" (org-mem-file node))
            ))
  )

Citar integration

(use-package citar-org-node
  :ensure t
  :if (eq user/knowledge-management-system 'org-node) 
  :after (:any citar org-node)
  :bind ( :map org-mode-map
          ("C-c b a" . citar-org-node-add-refs)
          ("C-c b o" . citar-org-node-open-resource))
  :config
  (citar-org-node-mode 1))

Journaling

(use-package org-node-seq
  :ensure org-node
  :if (eq user/knowledge-management-system 'org-node) 
  :config
  (setopt org-node-seq-defs
        (list
         (org-node-seq-def-on-filepath-sort-by-basename
          "n" "Note" (expand-file-name org-node-data-dir) nil nil)
         (org-node-seq-def-on-filepath-sort-by-basename
          "d" "Dailies" (expand-file-name (concat org-node-data-dir "Journal")) nil t)))
  :hook
  (after-init . org-node-seq-mode)
  )

TODO Vulpea

(setopt user/knowledge-management-system 'vulpea)

Journaling

(use-package vulpea-journal
  :if (eq user/knowledge-management-system 'vulpea) 
  :ensure t
  :after (vulpea vulpea-ui)
  :bind
  (("C-c v j" . vulpea-journal))
  :config
  (vulpea-journal-setup))

Created: 2026-07-19 Sun 16:45

Validate