initial commit
This commit is contained in:
218
README.org
Normal file
218
README.org
Normal file
@@ -0,0 +1,218 @@
|
||||
#+title: org-roam-project
|
||||
#+author: Luis
|
||||
#+language: en
|
||||
|
||||
Per-project [[https://www.orgroam.com/][org-roam]] databases via [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Projects.html][project.el]].
|
||||
|
||||
* Overview
|
||||
|
||||
=org-roam-project= extends org-roam so that each =project.el=-recognised project
|
||||
(a Git repository, or any directory with a VCS root) can have its own isolated
|
||||
notes directory and SQLite database.
|
||||
|
||||
When you work inside a project, the =org-roam-project-*= commands scope
|
||||
automatically to that project's notes and database. Your personal zettelkasten
|
||||
— the global =org-roam-directory= — is completely unaffected.
|
||||
|
||||
#+begin_example
|
||||
Personal zettelkasten Project notes
|
||||
┌──────────────────┐ ┌──────────────────────────┐
|
||||
│ ~/org-roam/ │ │ ~/code/my-project/ │
|
||||
│ │ │ notes/ ← notes │
|
||||
│ ~/.emacs.d/ │ │ notes/.org-roam.db ← DB │
|
||||
│ org-roam.db │ └──────────────────────────┘
|
||||
└──────────────────┘
|
||||
▲ ▲
|
||||
(not in a project) (inside a project)
|
||||
#+end_example
|
||||
|
||||
* Requirements
|
||||
|
||||
- Emacs 28.1 or later (=project.el= is built in)
|
||||
- [[https://github.com/org-roam/org-roam][org-roam]] 2.2.0 or later
|
||||
- A working org-roam setup (=org-roam-directory= already configured)
|
||||
|
||||
* Installation
|
||||
|
||||
** Manual
|
||||
|
||||
Clone or copy =org-roam-project.el= somewhere on your =load-path=, then:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(require 'org-roam-project)
|
||||
(org-roam-project-mode)
|
||||
#+end_src
|
||||
|
||||
** use-package
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-roam-project
|
||||
:load-path "path/to/org-roam-project"
|
||||
:after org-roam
|
||||
:config
|
||||
(org-roam-project-mode))
|
||||
#+end_src
|
||||
|
||||
* Quick start
|
||||
|
||||
1. Open any file inside a =project.el= project (e.g. a Git repository).
|
||||
|
||||
2. Initialise org-roam for that project:
|
||||
|
||||
#+begin_example
|
||||
M-x org-roam-project-init
|
||||
#+end_example
|
||||
|
||||
This creates the notes subdirectory (=notes/= by default), adds the database
|
||||
file to =.gitignore= if one is present, and runs an initial database sync.
|
||||
|
||||
3. Start taking notes:
|
||||
|
||||
#+begin_example
|
||||
M-x org-roam-project-node-find ; find or create a note
|
||||
M-x org-roam-project-capture ; capture a new note
|
||||
#+end_example
|
||||
|
||||
4. These commands are also available from the project dispatch menu:
|
||||
|
||||
#+begin_example
|
||||
C-x p p ; project-switch-project
|
||||
n ; Roam find (org-roam-project-node-find)
|
||||
N ; Roam capture (org-roam-project-capture)
|
||||
#+end_example
|
||||
|
||||
* Commands
|
||||
|
||||
| Command | Description |
|
||||
|-----------------------------------+------------------------------------------------------------------|
|
||||
| =org-roam-project-init= | Initialise the current project (create dir, update .gitignore, sync DB) |
|
||||
| =org-roam-project-node-find= | Find or create a node in the project (like =org-roam-node-find=) |
|
||||
| =org-roam-project-node-insert= | Insert a link to a project node (like =org-roam-node-insert=) |
|
||||
| =org-roam-project-capture= | Capture a new project note (like =org-roam-capture=) |
|
||||
| =org-roam-project-buffer-toggle= | Toggle the backlinks buffer scoped to the project |
|
||||
| =org-roam-project-db-sync= | Manually re-sync the project's org-roam database |
|
||||
|
||||
* Configuration
|
||||
|
||||
** Customisation variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|-------------------------------------+------------------+------------------------------------------------------|
|
||||
| =org-roam-project-notes-subdir= | ="notes"= | Subdirectory within the project root for notes |
|
||||
| =org-roam-project-db-filename= | =".org-roam.db"= | Filename of the per-project SQLite database |
|
||||
| =org-roam-project-auto-create= | =nil= | Automatically create the notes dir if it is missing |
|
||||
|
||||
These can be changed globally:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-project-notes-subdir "docs/notes"
|
||||
org-roam-project-db-filename ".roam.db")
|
||||
#+end_src
|
||||
|
||||
** Per-project configuration via =.dir-locals.el=
|
||||
|
||||
All three variables are declared =safe-local-variable=, so they can be
|
||||
overridden in a project's =.dir-locals.el= without Emacs prompting you:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
;; ~/code/my-project/.dir-locals.el
|
||||
((nil . ((org-roam-project-notes-subdir . "docs/notes")
|
||||
(org-roam-project-db-filename . ".org-roam.db"))))
|
||||
#+end_src
|
||||
|
||||
This lets different projects store their notes in different places without
|
||||
changing the global defaults.
|
||||
|
||||
** Automatic notes directory creation
|
||||
|
||||
By default, commands signal an error when the project's notes directory does
|
||||
not exist, reminding you to run =org-roam-project-init= first. If you prefer
|
||||
the directory to be created automatically on first use, set:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-roam-project-auto-create t)
|
||||
#+end_src
|
||||
|
||||
* How it works
|
||||
|
||||
** Context detection
|
||||
|
||||
Every command calls =org-roam-project--context= which:
|
||||
|
||||
1. Calls =(project-current)= to detect the project from the current
|
||||
=default-directory=.
|
||||
2. Reads =org-roam-project-notes-subdir= and =org-roam-project-db-filename=,
|
||||
respecting any =.dir-locals.el= values for the project root.
|
||||
3. Returns the absolute paths to the notes directory and database file, or
|
||||
=nil= if the notes directory does not exist.
|
||||
|
||||
** Scoping via =let=-binding
|
||||
|
||||
Rather than patching org-roam internals, the package simply =let=-binds
|
||||
=org-roam-directory= and =org-roam-db-location= around every call:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(let ((org-roam-directory "/path/to/project/notes")
|
||||
(org-roam-db-location "/path/to/project/notes/.org-roam.db"))
|
||||
(org-roam-node-find))
|
||||
#+end_src
|
||||
|
||||
Because org-roam's internal connection cache is keyed by =org-roam-directory=,
|
||||
multiple project databases can be open simultaneously with no conflicts.
|
||||
|
||||
** Autosync on save
|
||||
|
||||
When =org-roam-project-mode= is active, an =:around= advice on
|
||||
=org-roam-db-update-file= intercepts every save. If the file being saved lives
|
||||
inside a project's initialised notes directory, the advice temporarily binds
|
||||
the project context so the update goes to the right database. Files saved
|
||||
outside any project's notes directory continue to update the global database as
|
||||
normal.
|
||||
|
||||
** project-switch-commands integration
|
||||
|
||||
With =org-roam-project-mode= enabled, two entries are added to
|
||||
=project-switch-commands=:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(org-roam-project-node-find "Roam find" ?n)
|
||||
(org-roam-project-capture "Roam capture" ?N)
|
||||
#+end_src
|
||||
|
||||
These appear in the =C-x p p= dispatch menu and work correctly with
|
||||
=project-current-directory-override=, so switching to a project with
|
||||
=C-x p p= and then pressing =n= opens that project's notes, not the global
|
||||
zettelkasten.
|
||||
|
||||
* File layout
|
||||
|
||||
After running =org-roam-project-init= in a project, the layout looks like:
|
||||
|
||||
#+begin_example
|
||||
~/code/my-project/
|
||||
├── .git/
|
||||
├── .gitignore ← .org-roam.db appended automatically
|
||||
├── src/
|
||||
│ └── ...
|
||||
└── notes/ ← org-roam-project-notes-subdir
|
||||
├── .org-roam.db ← org-roam-project-db-filename (not committed)
|
||||
├── 20260101T120000--my-first-note.org
|
||||
└── 20260215T090000--another-note.org
|
||||
#+end_example
|
||||
|
||||
* Limitations
|
||||
|
||||
- *No cross-project linking.* Each project database is isolated. Links between
|
||||
a project note and your personal zettelkasten (or another project) will not
|
||||
appear as backlinks.
|
||||
|
||||
- *Global capture templates.* Per-project capture templates are not yet
|
||||
supported. The global =org-roam-capture-templates= are used in all projects.
|
||||
As a workaround, you can set =org-roam-capture-templates= via =.dir-locals.el=.
|
||||
|
||||
- *No graph visualisation scoping.* =org-roam-ui= (if you use it) is not
|
||||
automatically scoped to the project database.
|
||||
|
||||
* License
|
||||
|
||||
GPLv3 or later. See the header of =org-roam-project.el= for details.
|
||||
Reference in New Issue
Block a user