branch: externals/org-remark commit 5e4b27afe38c313312e4041993acfbf32eddc21c Author: Vedang Manerikar <ved.maneri...@gmail.com> Commit: Vedang Manerikar <ved.maneri...@gmail.com>
feat: Support taking annotations in eww buffers. EWW buffers are not associated with a file, which causes `buffer-file-name` to return nil. This change extracts the functionality to find the source filename into a separate function. Earlier, `org-remark` used `buffer-file-name` to find the source filename. This allows us to handle `eww-mode` within the new function (and potentially more such modes in the future). We also add `org-remark-auto-on` to the `eww-after-render-hook` to make sure that existing annotations are loaded. The end result is that it is now possible to annotate web-pages inside EWW. Function introduced: 1. `org-remark-source-find-file-name` - All direct calls to `buffer-file-name` are now replaced by this function. Functions changed: 1. `org-remark-global-tracking-mode` - `org-remark-auto-on` runs on EWW render completion. 2. `org-remark-highlight-get-title` - This function can also extract the highlight title from the EWW URL now. --- org-remark-global-tracking.el | 8 ++++++-- org-remark.el | 44 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/org-remark-global-tracking.el b/org-remark-global-tracking.el index c9d5d212ee..d333c7c2ea 100644 --- a/org-remark-global-tracking.el +++ b/org-remark-global-tracking.el @@ -30,6 +30,7 @@ ;;; Code: (declare-function org-remark-mode "org-remark") +(declare-function org-remark-source-find-file-name "org-remark") (defvaralias 'org-remark-notes-file-path 'org-remark-notes-file-name) @@ -69,7 +70,8 @@ readable, the function automatically activates `org-remark'." (cond (org-remark-global-tracking-mode ;; Activate - (add-hook 'find-file-hook #'org-remark-auto-on)) + (progn (add-hook 'find-file-hook #'org-remark-auto-on) + (add-hook 'eww-after-render-hook #'org-remark-auto-on))) (t ;; Deactivate (remove-hook 'find-file-hook #'org-remark-auto-on)))) @@ -83,7 +85,9 @@ This is the default function for the customizing variable When the current buffer is visiting a file, the name of marginal notes file will be \"FILE-notes.org\", adding \"-notes.org\" as a suffix to the file name without the extension." - (concat (file-name-sans-extension (buffer-file-name)) "-notes.org")) + (concat (file-name-sans-extension + (file-name-nondirectory (org-remark-source-find-file-name))) + "-notes.org")) (defalias 'org-remark-notes-file-path-function 'org-remark-notes-file-name-function) diff --git a/org-remark.el b/org-remark.el index a50ce1c866..8737d83d69 100644 --- a/org-remark.el +++ b/org-remark.el @@ -377,6 +377,15 @@ marginal notes file. The expected values are nil, :load and '(:underline "gold" :background "lemon chiffon") '(CATEGORY "important"))) +(defun org-remark-source-find-file-name () + "Assumes that we are currently in the source buffer. +Returns the filename for the soure buffer. We use this filename +to identify the source buffer in all operations related to +marginalia." + (if (eq major-mode 'eww-mode) + (let ((url-parsed (url-generic-parse-url (eww-current-url)))) + (concat (url-host url-parsed) (url-filename url-parsed))) + (buffer-file-name))) (defun org-remark-save () "Save all the highlights tracked in current buffer to notes file. @@ -389,7 +398,7 @@ in the current buffer. Each highlight is an overlay." (interactive) (org-remark-highlights-housekeep) (org-remark-highlights-sort) - (let ((filename (buffer-file-name))) + (let ((filename (org-remark-source-find-file-name))) (dolist (h org-remark-highlights) (let ((beg (overlay-start h)) (end (overlay-end h)) @@ -697,7 +706,7 @@ to the database." ;; for mode, nil and :change result in saving the highlight. :load ;; bypasses save. (unless (eq mode :load) - (let ((filename (buffer-file-name))) + (let ((filename (org-remark-source-find-file-name))) (if filename (org-remark-highlight-save filename beg end @@ -712,8 +721,17 @@ to the database." "Return the title of the current buffer. Utility function to work with a single highlight overlay." (or (cadr (assoc "TITLE" (org-collect-keywords '("TITLE")))) - (file-name-sans-extension - (file-name-nondirectory (buffer-file-name))))) + (let* ((full-name (org-remark-source-find-file-name)) + (filename (if (and (string= "" (file-name-nondirectory full-name)) + (string-match "[\/]+\\'" full-name)) + ;; The name ends with a / (possibly a URL). + ;; Trim all the slashes at the end of the + ;; name. + (replace-match "" t t full-name) + full-name))) + (if (or (null filename) (string= "" filename)) + (error "Could not extract highlight title") + (file-name-sans-extension (file-name-nondirectory filename)))))) (defun org-remark-highlight-get-org-id (point) "Return Org-ID closest to POINT. @@ -952,7 +970,8 @@ Each highlight is a list in the following structure: ;; current-buffer to source-file-name. Issue #39 FIXME: A way to make ;; this sequence agnostic is preferred, if there is a function that ;; visit file but not set the current buffer - (when-let ((source-file-name (org-remark-source-get-file-name (buffer-file-name))) + (when-let ((source-file-name (org-remark-source-get-file-name + (org-remark-source-find-file-name))) (notes-buf (find-file-noselect (org-remark-notes-get-file-name)))) ;; TODO check if there is any relevant notes for the current file ;; This can be used for adding icon to the highlight @@ -1073,12 +1092,19 @@ Case 2. The overlay points to no buffer This case happens when overlay is deleted by `overlay-delete' but the variable not cleared." (dolist (ov org-remark-highlights) - ;; Both start and end of an overlay are identical; this should not happen - ;; when you manually mark a text region. A typical cause of this case is - ;; when you delete a region that contains a highlight overlay. + ;; Both start and end of an overlay are identical; this should not + ;; happen when you manually mark a text region. A typical cause of + ;; this case is when you delete a region that contains a highlight + ;; overlay. This also happens when EWW reloads the buffer or + ;; re-renders any part of the buffer. This is because it removes + ;; overlays on re-render by calling `remove-overlays', which edits + ;; the overlay-start and overlay-end properties. To guard against + ;; this, we check if the buffer is write-able and only remove the + ;; annotation when it is. (when (and (overlay-buffer ov) (= (overlay-start ov) (overlay-end ov))) - (org-remark-notes-remove (overlay-get ov 'org-remark-id)) + (when (not buffer-read-only) + (org-remark-notes-remove (overlay-get ov 'org-remark-id))) (delete-overlay ov)) (unless (overlay-buffer ov) (setq org-remark-highlights (delete ov org-remark-highlights))))