mirror of
https://github.com/org-roam/org-roam
synced 2025-08-01 12:17:21 -05:00
(chore): Cleanups for MELPA release (#251)
* (chore): require minimum Org version 9.3 * fix bytecompile errors for org-roam.el * fix checkdoc errors * fix more things
This commit is contained in:
@ -5,7 +5,7 @@
|
|||||||
;; URL: https://github.com/jethrokuan/org-roam
|
;; URL: https://github.com/jethrokuan/org-roam
|
||||||
;; Keywords: org-mode, roam, convenience
|
;; Keywords: org-mode, roam, convenience
|
||||||
;; Version: 1.0.0-rc1
|
;; Version: 1.0.0-rc1
|
||||||
;; Package-Requires: ((emacs "26.1") (org "9.0"))
|
;; Package-Requires: ((emacs "26.1") (org "9.3"))
|
||||||
|
|
||||||
;; This file is NOT part of GNU Emacs.
|
;; This file is NOT part of GNU Emacs.
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ It opens or creates a note with the given ref.
|
|||||||
(val (cdr k.v)))
|
(val (cdr k.v)))
|
||||||
(cons key (org-link-decode val)))) alist)))
|
(cons key (org-link-decode val)))) alist)))
|
||||||
(unless (assoc 'ref decoded-alist)
|
(unless (assoc 'ref decoded-alist)
|
||||||
(error "No ref key provided."))
|
(error "No ref key provided"))
|
||||||
(when-let ((title (cdr (assoc 'title decoded-alist))))
|
(when-let ((title (cdr (assoc 'title decoded-alist))))
|
||||||
(push (cons 'slug (org-roam--title-to-slug title)) decoded-alist))
|
(push (cons 'slug (org-roam--title-to-slug title)) decoded-alist))
|
||||||
(let* ((org-roam-capture-templates org-roam-ref-capture-templates)
|
(let* ((org-roam-capture-templates org-roam-ref-capture-templates)
|
||||||
|
160
org-roam.el
160
org-roam.el
@ -6,7 +6,7 @@
|
|||||||
;; URL: https://github.com/jethrokuan/org-roam
|
;; URL: https://github.com/jethrokuan/org-roam
|
||||||
;; Keywords: org-mode, roam, convenience
|
;; Keywords: org-mode, roam, convenience
|
||||||
;; Version: 1.0.0-rc1
|
;; Version: 1.0.0-rc1
|
||||||
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.0") (emacsql "3.0.0") (emacsql-sqlite "1.0.0"))
|
;; Package-Requires: ((emacs "26.1") (dash "2.13") (f "0.17.2") (s "1.12.0") (org "9.3") (emacsql "3.0.0") (emacsql-sqlite "1.0.0"))
|
||||||
|
|
||||||
;; This file is NOT part of GNU Emacs.
|
;; This file is NOT part of GNU Emacs.
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ Valid values are
|
|||||||
:group 'org-roam)
|
:group 'org-roam)
|
||||||
|
|
||||||
(defcustom org-roam-link-title-format "%s"
|
(defcustom org-roam-link-title-format "%s"
|
||||||
"The format string used when inserting org-roam links that use their title."
|
"The format string used when inserting Org-roam links that use their title."
|
||||||
:type 'string
|
:type 'string
|
||||||
:group 'org-roam)
|
:group 'org-roam)
|
||||||
|
|
||||||
@ -161,6 +161,8 @@ Performs a database upgrade when required."
|
|||||||
|
|
||||||
;;;; Entrypoint: (org-roam-sql)
|
;;;; Entrypoint: (org-roam-sql)
|
||||||
(defun org-roam-sql (sql &rest args)
|
(defun org-roam-sql (sql &rest args)
|
||||||
|
"Run SQL query on Org-roam database with ARGS.
|
||||||
|
SQL can be either the emacsql vector representation, or a string."
|
||||||
(if (stringp sql)
|
(if (stringp sql)
|
||||||
(emacsql (org-roam-db) (apply #'format sql args))
|
(emacsql (org-roam-db) (apply #'format sql args))
|
||||||
(apply #'emacsql (org-roam-db) sql args)))
|
(apply #'emacsql (org-roam-db) sql args)))
|
||||||
@ -188,24 +190,30 @@ Performs a database upgrade when required."
|
|||||||
(file :not-null)])))
|
(file :not-null)])))
|
||||||
|
|
||||||
(defun org-roam--db-init (db)
|
(defun org-roam--db-init (db)
|
||||||
|
"Initialize database DB with the correct schema and user version."
|
||||||
(emacsql-with-transaction db
|
(emacsql-with-transaction db
|
||||||
(pcase-dolist (`(,table . ,schema) org-roam--db-table-schemata)
|
(pcase-dolist (`(,table . ,schema) org-roam--db-table-schemata)
|
||||||
(emacsql db [:create-table $i1 $S2] table schema))
|
(emacsql db [:create-table $i1 $S2] table schema))
|
||||||
(emacsql db (format "PRAGMA user_version = %s" org-roam--db-version))))
|
(emacsql db (format "PRAGMA user_version = %s" org-roam--db-version))))
|
||||||
|
|
||||||
(defun org-roam--db-maybe-update (db version)
|
(defun org-roam--db-maybe-update (db version)
|
||||||
|
"Upgrades the database schema for DB, if VERSION is old."
|
||||||
(emacsql-with-transaction db
|
(emacsql-with-transaction db
|
||||||
'ignore
|
'ignore
|
||||||
;; Do nothing now
|
;; Do nothing now
|
||||||
version))
|
version))
|
||||||
|
|
||||||
(defun org-roam--db-close (&optional db)
|
(defun org-roam--db-close (&optional db)
|
||||||
|
"Closes the database connection for database DB.
|
||||||
|
If DB is nil, closes the database connection for the database in
|
||||||
|
the current `org-roam-directory'."
|
||||||
(unless db
|
(unless db
|
||||||
(setq db (org-roam--get-db-connection)))
|
(setq db (org-roam--get-db-connection)))
|
||||||
(when (and db (emacsql-live-p db))
|
(when (and db (emacsql-live-p db))
|
||||||
(emacsql-close db)))
|
(emacsql-close db)))
|
||||||
|
|
||||||
(defun org-roam--db-close-all ()
|
(defun org-roam--db-close-all ()
|
||||||
|
"Closes all database connections made by Org-roam."
|
||||||
(dolist (conn (hash-table-values org-roam--db-connection))
|
(dolist (conn (hash-table-values org-roam--db-connection))
|
||||||
(org-roam--db-close conn)))
|
(org-roam--db-close conn)))
|
||||||
|
|
||||||
@ -218,7 +226,7 @@ Performs a database upgrade when required."
|
|||||||
0)))
|
0)))
|
||||||
|
|
||||||
(defun org-roam--db-ensure-built ()
|
(defun org-roam--db-ensure-built ()
|
||||||
"Ensures that org-roam cache is built."
|
"Ensures that Org-roam cache is built."
|
||||||
(unless (org-roam--db-initialized-p)
|
(unless (org-roam--db-initialized-p)
|
||||||
(error "[Org-roam] your cache isn't built yet! Please run org-roam-build-cache")))
|
(error "[Org-roam] your cache isn't built yet! Please run org-roam-build-cache")))
|
||||||
|
|
||||||
@ -254,21 +262,21 @@ This is equivalent to removing the node from the graph."
|
|||||||
|
|
||||||
;;;;; Insertion
|
;;;;; Insertion
|
||||||
(defun org-roam--db-insert-links (links)
|
(defun org-roam--db-insert-links (links)
|
||||||
"Insert LINK into the org-roam cache."
|
"Insert LINKS into the Org-roam cache."
|
||||||
(org-roam-sql
|
(org-roam-sql
|
||||||
[:insert :into file-links
|
[:insert :into file-links
|
||||||
:values $v1]
|
:values $v1]
|
||||||
links))
|
links))
|
||||||
|
|
||||||
(defun org-roam--db-insert-titles (file titles)
|
(defun org-roam--db-insert-titles (file titles)
|
||||||
"Insert TITLES into the org-roam-cache."
|
"Insert TITLES for a FILE into the Org-roam cache."
|
||||||
(org-roam-sql
|
(org-roam-sql
|
||||||
[:insert :into titles
|
[:insert :into titles
|
||||||
:values $v1]
|
:values $v1]
|
||||||
(list (vector file titles))))
|
(list (vector file titles))))
|
||||||
|
|
||||||
(defun org-roam--db-insert-ref (file ref)
|
(defun org-roam--db-insert-ref (file ref)
|
||||||
"Insert REF into the Org-roam cache."
|
"Insert REF for FILE into the Org-roam cache."
|
||||||
(org-roam-sql
|
(org-roam-sql
|
||||||
[:insert :into refs
|
[:insert :into refs
|
||||||
:values $v1]
|
:values $v1]
|
||||||
@ -276,7 +284,7 @@ This is equivalent to removing the node from the graph."
|
|||||||
|
|
||||||
;;;;; Fetching
|
;;;;; Fetching
|
||||||
(defun org-roam--get-current-files ()
|
(defun org-roam--get-current-files ()
|
||||||
"Return a hash-table of file to buffer-string hash."
|
"Return a hash-table of file to the hash of its file contents."
|
||||||
(let* ((current-files (org-roam-sql [:select * :from files]))
|
(let* ((current-files (org-roam-sql [:select * :from files]))
|
||||||
(ht (make-hash-table :test #'equal)))
|
(ht (make-hash-table :test #'equal)))
|
||||||
(dolist (row current-files)
|
(dolist (row current-files)
|
||||||
@ -318,7 +326,7 @@ This is equivalent to removing the node from the graph."
|
|||||||
(org-roam--db-insert-links links))))
|
(org-roam--db-insert-links links))))
|
||||||
|
|
||||||
(defun org-roam--db-update-file (&optional file-path)
|
(defun org-roam--db-update-file (&optional file-path)
|
||||||
"Update org-roam caches for the FILE-PATH."
|
"Update Org-roam cache for FILE-PATH."
|
||||||
(let (buf)
|
(let (buf)
|
||||||
(if file-path
|
(if file-path
|
||||||
(setq buf (find-file-noselect file-path))
|
(setq buf (find-file-noselect file-path))
|
||||||
@ -383,12 +391,12 @@ This is equivalent to removing the node from the graph."
|
|||||||
:titles (length all-titles)
|
:titles (length all-titles)
|
||||||
:refs (length all-refs)
|
:refs (length all-refs)
|
||||||
:deleted (length (hash-table-keys current-files)))))
|
:deleted (length (hash-table-keys current-files)))))
|
||||||
(message (format "files: %s, links: %s, titles: %s, refs: %s, deleted: %s"
|
(message "files: %s, links: %s, titles: %s, refs: %s, deleted: %s"
|
||||||
(plist-get stats :files)
|
(plist-get stats :files)
|
||||||
(plist-get stats :links)
|
(plist-get stats :links)
|
||||||
(plist-get stats :titles)
|
(plist-get stats :titles)
|
||||||
(plist-get stats :refs)
|
(plist-get stats :refs)
|
||||||
(plist-get stats :deleted)))
|
(plist-get stats :deleted))
|
||||||
stats)))
|
stats)))
|
||||||
|
|
||||||
;;; Utilities
|
;;; Utilities
|
||||||
@ -433,7 +441,7 @@ https://github.com/kaushalmodi/ox-hugo/blob/a80b250987bc770600c424a10b3bca6ff728
|
|||||||
|
|
||||||
(defun org-roam--file-name-extension (filename)
|
(defun org-roam--file-name-extension (filename)
|
||||||
"Return file name extension for FILENAME.
|
"Return file name extension for FILENAME.
|
||||||
Like file-name-extension, but does not strip version number."
|
Like `file-name-extension', but does not strip version number."
|
||||||
(save-match-data
|
(save-match-data
|
||||||
(let ((file (file-name-nondirectory filename)))
|
(let ((file (file-name-nondirectory filename)))
|
||||||
(if (and (string-match "\\.[^.]*\\'" file)
|
(if (and (string-match "\\.[^.]*\\'" file)
|
||||||
@ -449,8 +457,8 @@ Like file-name-extension, but does not strip version number."
|
|||||||
(string= (org-roam--file-name-extension (file-name-sans-extension path)) "org")))))
|
(string= (org-roam--file-name-extension (file-name-sans-extension path)) "org")))))
|
||||||
|
|
||||||
(defun org-roam--org-roam-file-p (&optional file)
|
(defun org-roam--org-roam-file-p (&optional file)
|
||||||
"Return t if FILE is part of org-roam system, return nil otherwise.
|
"Return t if FILE is part of Org-roam system, nil otherwise.
|
||||||
If FILE is not specified, use the current-buffer file path."
|
If FILE is not specified, use the current buffer's file-path."
|
||||||
(let ((path (or file
|
(let ((path (or file
|
||||||
(buffer-file-name (current-buffer)))))
|
(buffer-file-name (current-buffer)))))
|
||||||
(and path
|
(and path
|
||||||
@ -471,7 +479,7 @@ Ignores hidden files and directories."
|
|||||||
(dolist (file files)
|
(dolist (file files)
|
||||||
(cond
|
(cond
|
||||||
((file-directory-p file)
|
((file-directory-p file)
|
||||||
(when (not (string-match dir-ignore-regexp file))
|
(unless (string-match dir-ignore-regexp file)
|
||||||
(setq result (append (org-roam--list-files file) result))))
|
(setq result (append (org-roam--list-files file) result))))
|
||||||
((and (file-readable-p file)
|
((and (file-readable-p file)
|
||||||
(org-roam--org-file-p file))
|
(org-roam--org-file-p file))
|
||||||
@ -479,7 +487,7 @@ Ignores hidden files and directories."
|
|||||||
result)))
|
result)))
|
||||||
|
|
||||||
(defun org-roam--list-all-files ()
|
(defun org-roam--list-all-files ()
|
||||||
"Return a list of all org-roam files within `org-roam-directory'."
|
"Return a list of all Org-roam files within `org-roam-directory'."
|
||||||
(org-roam--list-files (file-truename org-roam-directory)))
|
(org-roam--list-files (file-truename org-roam-directory)))
|
||||||
|
|
||||||
;;;; Org extraction functions
|
;;;; Org extraction functions
|
||||||
@ -560,10 +568,10 @@ specified via the #+ROAM_ALIAS property."
|
|||||||
(defun org-roam--title-to-slug (title)
|
(defun org-roam--title-to-slug (title)
|
||||||
"Convert TITLE to a filename-suitable slug."
|
"Convert TITLE to a filename-suitable slug."
|
||||||
(cl-flet* ((nonspacing-mark-p (char)
|
(cl-flet* ((nonspacing-mark-p (char)
|
||||||
(eq 'Mn (get-char-code-property char 'general-category)))
|
(eq 'Mn (get-char-code-property char 'general-category)))
|
||||||
(strip-nonspacing-marks (s)
|
(strip-nonspacing-marks (s)
|
||||||
(apply #'string (seq-remove #'nonspacing-mark-p
|
(apply #'string (seq-remove #'nonspacing-mark-p
|
||||||
(ucs-normalize-NFD-string s))))
|
(ucs-normalize-NFD-string s))))
|
||||||
(replace (title pair)
|
(replace (title pair)
|
||||||
(replace-regexp-in-string (car pair) (cdr pair) title)))
|
(replace-regexp-in-string (car pair) (cdr pair) title)))
|
||||||
(let* ((pairs `(("[^[:alnum:][:digit:]]" . "_") ;; convert anything not alphanumeric
|
(let* ((pairs `(("[^[:alnum:][:digit:]]" . "_") ;; convert anything not alphanumeric
|
||||||
@ -584,24 +592,24 @@ specified via the #+ROAM_ALIAS property."
|
|||||||
org-roam-directory)))
|
org-roam-directory)))
|
||||||
|
|
||||||
(defvar org-roam--capture-file-name-default "%<%Y%m%d%H%M%S>"
|
(defvar org-roam--capture-file-name-default "%<%Y%m%d%H%M%S>"
|
||||||
"The default file name format for org-roam templates.")
|
"The default file name format for Org-roam templates.")
|
||||||
|
|
||||||
(defvar org-roam--capture-header-default "#+TITLE: ${title}\n"
|
(defvar org-roam--capture-header-default "#+TITLE: ${title}\n"
|
||||||
"The default capture header for org-roam templates.")
|
"The default capture header for Org-roam templates.")
|
||||||
|
|
||||||
(defvar org-roam--capture-file-path nil
|
(defvar org-roam--capture-file-path nil
|
||||||
"The file path for the Org-roam capture. This variable is set
|
"The file path for the Org-roam capture.
|
||||||
during the Org-roam capture process.")
|
This variable is set during the Org-roam capture process.")
|
||||||
|
|
||||||
(defvar org-roam--capture-info nil
|
(defvar org-roam--capture-info nil
|
||||||
"An alist of additional information passed to the org-roam
|
"An alist of additional information passed to the Org-roam template.
|
||||||
template. This variable is populated dynamically, and is only
|
This variable is populated dynamically, and is only non-nil
|
||||||
non-nil during the org-roam capture process.")
|
during the Org-roam capture process.")
|
||||||
|
|
||||||
(defvar org-roam--capture-context nil
|
(defvar org-roam--capture-context nil
|
||||||
"A symbol, that reflects the context for obtaining the exact point in a file.
|
"A symbol, that reflects the context for obtaining the exact point in a file.
|
||||||
This variable is populated dynamically, and is only active during
|
This variable is populated dynamically, and is only active during
|
||||||
an org-roam capture process.
|
an Org-roam capture process.
|
||||||
|
|
||||||
The `title' context is used in `org-roam-insert' and
|
The `title' context is used in `org-roam-insert' and
|
||||||
`org-roam-find-file', where the capture process is triggered upon
|
`org-roam-find-file', where the capture process is triggered upon
|
||||||
@ -617,8 +625,10 @@ note with the given `ref'.")
|
|||||||
:file-name "%<%Y%m%d%H%M%S>-${slug}"
|
:file-name "%<%Y%m%d%H%M%S>-${slug}"
|
||||||
:head "#+TITLE: ${title}\n"
|
:head "#+TITLE: ${title}\n"
|
||||||
:unnarrowed t))
|
:unnarrowed t))
|
||||||
"Capture templates for Org-roam. The capture templates are an extension of
|
"Capture templates for Org-roam.
|
||||||
`org-capture-templates', and the documentation there also applies.
|
The capture templates are an extension of
|
||||||
|
`org-capture-templates', and the documentation there also
|
||||||
|
applies.
|
||||||
|
|
||||||
`org-capture-templates' are extended in 3 ways:
|
`org-capture-templates' are extended in 3 ways:
|
||||||
|
|
||||||
@ -637,7 +647,7 @@ This is an extension of org-capture's template expansion.
|
|||||||
|
|
||||||
First, it expands ${var} occurences in STR, using the INFO alist.
|
First, it expands ${var} occurences in STR, using the INFO alist.
|
||||||
If there is a ${var} with no matching var in the alist, the value
|
If there is a ${var} with no matching var in the alist, the value
|
||||||
of var is prompted for via completing-read.
|
of var is prompted for via `completing-read'.
|
||||||
|
|
||||||
Next, it expands the remaining template string using
|
Next, it expands the remaining template string using
|
||||||
`org-capture-fill-template'."
|
`org-capture-fill-template'."
|
||||||
@ -648,8 +658,9 @@ Next, it expands the remaining template string using
|
|||||||
(org-capture-fill-template)))
|
(org-capture-fill-template)))
|
||||||
|
|
||||||
(defun org-roam--capture-new-file ()
|
(defun org-roam--capture-new-file ()
|
||||||
"Creates a new file, by reading the file-name attribute of the
|
"Create a new file and return the file path.
|
||||||
currently active org-roam template. Returns the path to the new file."
|
This is achieved by reading the file-name attribute of the
|
||||||
|
currently active Org-roam template."
|
||||||
(let* ((name-templ (or (org-capture-get :file-name)
|
(let* ((name-templ (or (org-capture-get :file-name)
|
||||||
org-roam--capture-file-name-default))
|
org-roam--capture-file-name-default))
|
||||||
(new-id (s-trim (org-roam--fill-template
|
(new-id (s-trim (org-roam--fill-template
|
||||||
@ -657,7 +668,7 @@ currently active org-roam template. Returns the path to the new file."
|
|||||||
org-roam--capture-info)))
|
org-roam--capture-info)))
|
||||||
(file-path (org-roam--file-path-from-id new-id)))
|
(file-path (org-roam--file-path-from-id new-id)))
|
||||||
(when (file-exists-p file-path)
|
(when (file-exists-p file-path)
|
||||||
(error (format "File exists at %s, aborting." file-path)))
|
(error (format "File exists at %s, aborting" file-path)))
|
||||||
(org-roam--touch-file file-path)
|
(org-roam--touch-file file-path)
|
||||||
(write-region
|
(write-region
|
||||||
(org-roam--fill-template (or (org-capture-get :head)
|
(org-roam--fill-template (or (org-capture-get :head)
|
||||||
@ -668,11 +679,11 @@ currently active org-roam template. Returns the path to the new file."
|
|||||||
file-path))
|
file-path))
|
||||||
|
|
||||||
(defun org-roam--capture-get-point ()
|
(defun org-roam--capture-get-point ()
|
||||||
"Returns exact point to file for org-capture-template.
|
"Return exact point to file for org-capture-template.
|
||||||
The file to use is dependent on the context:
|
The file to use is dependent on the context:
|
||||||
|
|
||||||
If the search is via title, it is assumed that the file does not
|
If the search is via title, it is assumed that the file does not
|
||||||
yet exist, and org-roam will attempt to create new file.
|
yet exist, and Org-roam will attempt to create new file.
|
||||||
|
|
||||||
If the search is via ref, it is matched against the Org-roam database.
|
If the search is via ref, it is matched against the Org-roam database.
|
||||||
If there is no file with that ref, a file with that ref is created.
|
If there is no file with that ref, a file with that ref is created.
|
||||||
@ -698,9 +709,10 @@ This function is used solely in Org-roam's capture templates: see
|
|||||||
(_ (error "Invalid org-roam-capture-context"))))
|
(_ (error "Invalid org-roam-capture-context"))))
|
||||||
|
|
||||||
(defun org-roam-capture (&optional goto keys)
|
(defun org-roam-capture (&optional goto keys)
|
||||||
"Create a new file using an Org-roam template, and returns the
|
"Create a new file, and return the path to the edited file.
|
||||||
path to the edited file. The templates are defined at
|
The templates are defined at `org-roam-capture-templates'. The
|
||||||
`org-roam-capture-templates'."
|
GOTO and KEYS argument have the same functionality as
|
||||||
|
`org-capture'."
|
||||||
(let ((org-capture-templates org-roam-capture-templates)
|
(let ((org-capture-templates org-roam-capture-templates)
|
||||||
file-path)
|
file-path)
|
||||||
(when (= (length org-capture-templates) 1)
|
(when (= (length org-capture-templates) 1)
|
||||||
@ -716,7 +728,7 @@ path to the edited file. The templates are defined at
|
|||||||
"The point to jump to after the call to `org-roam-insert'.")
|
"The point to jump to after the call to `org-roam-insert'.")
|
||||||
|
|
||||||
(defun org-roam-insert (prefix)
|
(defun org-roam-insert (prefix)
|
||||||
"Find an org-roam file, and insert a relative org link to it at point.
|
"Find an Org-roam file, and insert a relative org link to it at point.
|
||||||
If PREFIX, downcase the title before insertion."
|
If PREFIX, downcase the title before insertion."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(let* ((region (and (region-active-p)
|
(let* ((region (and (region-active-p)
|
||||||
@ -758,7 +770,7 @@ If PREFIX, downcase the title before insertion."
|
|||||||
(defun org-roam--capture-advance-point ()
|
(defun org-roam--capture-advance-point ()
|
||||||
"Advances the point if it is updated.
|
"Advances the point if it is updated.
|
||||||
|
|
||||||
We need this function because typically org-capture prevents the
|
We need this function because typically `org-capture' prevents the
|
||||||
point from being advanced, whereas when a link is inserted, the
|
point from being advanced, whereas when a link is inserted, the
|
||||||
point moves some characters forward. This is added as a hook to
|
point moves some characters forward. This is added as a hook to
|
||||||
`org-capture-after-finalize-hook'."
|
`org-capture-after-finalize-hook'."
|
||||||
@ -784,7 +796,7 @@ point moves some characters forward. This is added as a hook to
|
|||||||
res))
|
res))
|
||||||
|
|
||||||
(defun org-roam-find-file ()
|
(defun org-roam-find-file ()
|
||||||
"Find and open an org-roam file."
|
"Find and open an Org-roam file."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((completions (org-roam--get-title-path-completions))
|
(let* ((completions (org-roam--get-title-path-completions))
|
||||||
(title (completing-read "File: " completions))
|
(title (completing-read "File: " completions))
|
||||||
@ -805,7 +817,7 @@ point moves some characters forward. This is added as a hook to
|
|||||||
(cadr row))) rows)))
|
(cadr row))) rows)))
|
||||||
|
|
||||||
(defun org-roam-find-ref (&optional info)
|
(defun org-roam-find-ref (&optional info)
|
||||||
"Find and open an org-roam file from a ref.
|
"Find and open an Org-roam file from a ref.
|
||||||
INFO is an alist containing additional information."
|
INFO is an alist containing additional information."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((completions (org-roam--get-ref-path-completions))
|
(let* ((completions (org-roam--get-ref-path-completions))
|
||||||
@ -815,14 +827,14 @@ INFO is an alist containing additional information."
|
|||||||
|
|
||||||
;;;; org-roam-switch-to-buffer
|
;;;; org-roam-switch-to-buffer
|
||||||
(defun org-roam--get-roam-buffers ()
|
(defun org-roam--get-roam-buffers ()
|
||||||
"Return a list of buffers that are org-roam files."
|
"Return a list of buffers that are Org-roam files."
|
||||||
(--filter (and (with-current-buffer it (derived-mode-p 'org-mode))
|
(--filter (and (with-current-buffer it (derived-mode-p 'org-mode))
|
||||||
(buffer-file-name it)
|
(buffer-file-name it)
|
||||||
(org-roam--org-roam-file-p (buffer-file-name it)))
|
(org-roam--org-roam-file-p (buffer-file-name it)))
|
||||||
(buffer-list)))
|
(buffer-list)))
|
||||||
|
|
||||||
(defun org-roam-switch-to-buffer ()
|
(defun org-roam-switch-to-buffer ()
|
||||||
"Switch to an existing org-roam buffer."
|
"Switch to an existing Org-roam buffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((roam-buffers (org-roam--get-roam-buffers))
|
(let* ((roam-buffers (org-roam--get-roam-buffers))
|
||||||
(names-and-buffers (mapcar (lambda (buffer)
|
(names-and-buffers (mapcar (lambda (buffer)
|
||||||
@ -896,36 +908,28 @@ Applies `org-roam-link-face' if PATH correponds to a Roam file."
|
|||||||
'org-roam-link
|
'org-roam-link
|
||||||
'org-link))
|
'org-link))
|
||||||
|
|
||||||
(defun org-roam--setup-file-links ()
|
|
||||||
"Set up `file:' Org links with org-roam-link-face."
|
|
||||||
(unless (version< org-version "9.2")
|
|
||||||
(org-link-set-parameters "file" :face 'org-roam--roam-link-face)))
|
|
||||||
|
|
||||||
(defun org-roam--teardown-file-links ()
|
|
||||||
"Teardown the setup done by Org-roam on file links.
|
|
||||||
This sets `file:' Org links to have the org-link face."
|
|
||||||
(unless (version< org-version "9.2")
|
|
||||||
(org-link-set-parameters "file" :face 'org-link)))
|
|
||||||
|
|
||||||
;;;; org-roam-backlinks-mode
|
;;;; org-roam-backlinks-mode
|
||||||
|
(defvar org-roam-backlinks-mode-map
|
||||||
|
(let ((km (make-sparse-keymap)))
|
||||||
|
(define-key km [mouse-1] 'org-roam-open-at-point)
|
||||||
|
(define-key km (kbd "RET") 'org-roam-open-at-point)
|
||||||
|
km)
|
||||||
|
"Keymap for `org-roam-backlinks-mode'.")
|
||||||
|
|
||||||
(define-derived-mode org-roam-backlinks-mode org-mode "Backlinks"
|
(define-derived-mode org-roam-backlinks-mode org-mode "Backlinks"
|
||||||
"Major mode for the org-roam backlinks buffer
|
"Major mode for the `org-roam-buffer'.
|
||||||
|
|
||||||
Bindings:
|
|
||||||
\\{org-roam-backlinks-mode-map}")
|
\\{org-roam-backlinks-mode-map}")
|
||||||
|
|
||||||
(define-key org-roam-backlinks-mode-map [mouse-1] 'org-roam-open-at-point)
|
|
||||||
(define-key org-roam-backlinks-mode-map (kbd "RET") 'org-roam-open-at-point)
|
|
||||||
|
|
||||||
(defun org-roam-open-at-point ()
|
(defun org-roam-open-at-point ()
|
||||||
"Open a link at point.
|
"Open a link at point.
|
||||||
|
|
||||||
When point is on an org-roam link, open the link in the org-roam window.
|
When point is on an Org-roam link, open the link in the Org-roam window.
|
||||||
|
|
||||||
When point is on the org-roam preview text, open the link in the org-roam
|
When point is on the Org-roam preview text, open the link in the Org-roam
|
||||||
window, and navigate to the point.
|
window, and navigate to the point.
|
||||||
|
|
||||||
If item at point is not org-roam specific, default to Org behaviour."
|
If item at point is not Org-roam specific, default to Org behaviour."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((context (org-element-context)))
|
(let ((context (org-element-context)))
|
||||||
(catch 'ret
|
(catch 'ret
|
||||||
@ -955,6 +959,7 @@ If item at point is not org-roam specific, default to Org behaviour."
|
|||||||
(find-file file)))
|
(find-file file)))
|
||||||
|
|
||||||
(defun org-roam--get-backlinks (file)
|
(defun org-roam--get-backlinks (file)
|
||||||
|
"Return the backlinks for FILE."
|
||||||
(org-roam-sql [:select [file-from, file-to, properties] :from file-links
|
(org-roam-sql [:select [file-from, file-to, properties] :from file-links
|
||||||
:where (= file-to $s1)]
|
:where (= file-to $s1)]
|
||||||
file))
|
file))
|
||||||
@ -979,7 +984,7 @@ If item at point is not org-roam specific, default to Org behaviour."
|
|||||||
(cons '(file . org-roam--find-file) org-link-frame-setup))
|
(cons '(file . org-roam--find-file) org-link-frame-setup))
|
||||||
(let ((inhibit-read-only t))
|
(let ((inhibit-read-only t))
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(when (not (eq major-mode 'org-roam-backlinks-mode))
|
(unless (eq major-mode 'org-roam-backlinks-mode)
|
||||||
(org-roam-backlinks-mode))
|
(org-roam-backlinks-mode))
|
||||||
(make-local-variable 'org-return-follows-link)
|
(make-local-variable 'org-return-follows-link)
|
||||||
(setq org-return-follows-link t)
|
(setq org-return-follows-link t)
|
||||||
@ -997,7 +1002,7 @@ If item at point is not org-roam specific, default to Org behaviour."
|
|||||||
file-from
|
file-from
|
||||||
(org-roam--get-title-or-slug file-from)))
|
(org-roam--get-title-or-slug file-from)))
|
||||||
(dolist (backlink bls)
|
(dolist (backlink bls)
|
||||||
(pcase-let ((`(,file-from ,file-to ,props) backlink))
|
(pcase-let ((`(,file-from _ ,props) backlink))
|
||||||
(insert (propertize
|
(insert (propertize
|
||||||
(s-trim (s-replace "\n" " "
|
(s-trim (s-replace "\n" " "
|
||||||
(plist-get props :content)))
|
(plist-get props :content)))
|
||||||
@ -1012,7 +1017,8 @@ If item at point is not org-roam specific, default to Org behaviour."
|
|||||||
(cl-defun org-roam--maybe-update-buffer (&key redisplay)
|
(cl-defun org-roam--maybe-update-buffer (&key redisplay)
|
||||||
"Reconstructs `org-roam-buffer'.
|
"Reconstructs `org-roam-buffer'.
|
||||||
This needs to be quick or infrequent, because this is run at
|
This needs to be quick or infrequent, because this is run at
|
||||||
`post-command-hook'."
|
`post-command-hook'. If REDISPLAY, force an update of
|
||||||
|
`org-roam-buffer'."
|
||||||
(let ((buffer (window-buffer)))
|
(let ((buffer (window-buffer)))
|
||||||
(when (and (or redisplay
|
(when (and (or redisplay
|
||||||
(not (eq org-roam--current-buffer buffer)))
|
(not (eq org-roam--current-buffer buffer)))
|
||||||
@ -1034,7 +1040,7 @@ Valid states are 'visible, 'exists and 'none."
|
|||||||
(t 'none))))
|
(t 'none))))
|
||||||
|
|
||||||
(defun org-roam--set-width (width)
|
(defun org-roam--set-width (width)
|
||||||
"Set the width of the org-roam buffer to `WIDTH'."
|
"Set the width of `org-roam-buffer' to `WIDTH'."
|
||||||
(unless (one-window-p)
|
(unless (one-window-p)
|
||||||
(let ((window-size-fixed)
|
(let ((window-size-fixed)
|
||||||
(w (max width window-min-width)))
|
(w (max width window-min-width)))
|
||||||
@ -1139,7 +1145,7 @@ into a digraph."
|
|||||||
(buffer-string))))
|
(buffer-string))))
|
||||||
|
|
||||||
(defun org-roam-show-graph (&optional prefix)
|
(defun org-roam-show-graph (&optional prefix)
|
||||||
"Generates and displays the Org-roam graph using `org-roam-graph-viewer'.
|
"Generate and displays the Org-roam graph using `org-roam-graph-viewer'.
|
||||||
If PREFIX, then the graph is generated but the viewer is not invoked."
|
If PREFIX, then the graph is generated but the viewer is not invoked."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
(declare (indent 0))
|
(declare (indent 0))
|
||||||
@ -1161,7 +1167,7 @@ If PREFIX, then the graph is generated but the viewer is not invoked."
|
|||||||
;;; The global minor org-roam-mode
|
;;; The global minor org-roam-mode
|
||||||
(defvar org-roam-mode-map
|
(defvar org-roam-mode-map
|
||||||
(make-sparse-keymap)
|
(make-sparse-keymap)
|
||||||
"Keymap for org-roam commands.")
|
"Keymap for `org-roam-mode'.")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-minor-mode org-roam-mode
|
(define-minor-mode org-roam-mode
|
||||||
@ -1199,26 +1205,26 @@ Otherwise, behave as if called interactively."
|
|||||||
;; Disable local hooks for all org-roam buffers
|
;; Disable local hooks for all org-roam buffers
|
||||||
(dolist (buf (org-roam--get-roam-buffers))
|
(dolist (buf (org-roam--get-roam-buffers))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(org-roam--teardown-file-links)
|
(org-link-set-parameters "file" :face 'org-link)
|
||||||
(remove-hook 'post-command-hook #'org-roam--maybe-update-buffer t)
|
(remove-hook 'post-command-hook #'org-roam--maybe-update-buffer t)
|
||||||
(remove-hook 'after-save-hook #'org-roam--db-update-file t))))))
|
(remove-hook 'after-save-hook #'org-roam--db-update-file t))))))
|
||||||
|
|
||||||
(defun org-roam--find-file-hook-function ()
|
(defun org-roam--find-file-hook-function ()
|
||||||
"Called by `find-file-hook' when `org-roam-mode' is on."
|
"Called by `find-file-hook' when mode `org-roam-mode' is on."
|
||||||
(when (org-roam--org-roam-file-p)
|
(when (org-roam--org-roam-file-p)
|
||||||
(setq org-roam-last-window (get-buffer-window))
|
(setq org-roam-last-window (get-buffer-window))
|
||||||
(add-hook 'post-command-hook #'org-roam--maybe-update-buffer nil t)
|
(add-hook 'post-command-hook #'org-roam--maybe-update-buffer nil t)
|
||||||
(add-hook 'after-save-hook #'org-roam--db-update-file nil t)
|
(add-hook 'after-save-hook #'org-roam--db-update-file nil t)
|
||||||
(org-roam--setup-file-links)
|
(org-link-set-parameters "file" :face 'org-roam--roam-link-face)
|
||||||
(org-roam--maybe-update-buffer :redisplay nil)))
|
(org-roam--maybe-update-buffer :redisplay nil)))
|
||||||
|
|
||||||
(defun org-roam--delete-file-advice (file &optional _trash)
|
(defun org-roam--delete-file-advice (file &optional _trash)
|
||||||
"Advice for maintaining cache consistency during file deletes."
|
"Advice for maintaining cache consistency when FILE is deleted."
|
||||||
(when (and (not (auto-save-file-name-p file))
|
(when (and (not (auto-save-file-name-p file))
|
||||||
(org-roam--org-roam-file-p file))
|
(org-roam--org-roam-file-p file))
|
||||||
(org-roam--db-clear-file (file-truename file))))
|
(org-roam--db-clear-file (file-truename file))))
|
||||||
|
|
||||||
(defun org-roam--rename-file-advice (file new-file &rest args)
|
(defun org-roam--rename-file-advice (file new-file &rest _args)
|
||||||
"Rename backlinks of FILE to refer to NEW-FILE."
|
"Rename backlinks of FILE to refer to NEW-FILE."
|
||||||
(when (and (not (auto-save-file-name-p file))
|
(when (and (not (auto-save-file-name-p file))
|
||||||
(not (auto-save-file-name-p new-file))
|
(not (auto-save-file-name-p new-file))
|
||||||
|
Reference in New Issue
Block a user