emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/org-remark 5fb747a419 9/9: Merge branch 'notes-sync'


From: ELPA Syncer
Subject: [elpa] externals/org-remark 5fb747a419 9/9: Merge branch 'notes-sync'
Date: Tue, 27 Dec 2022 19:58:32 -0500 (EST)

branch: externals/org-remark
commit 5fb747a419366a33e6659a992ada8a35aa8bd655
Merge: 00e56e12a6 854856059f
Author: Noboru Ota <me@nobiot.com>
Commit: Noboru Ota <me@nobiot.com>

    Merge branch 'notes-sync'
---
 README.org                    |  12 ++
 org-remark-eww.el             |  79 ++++++++++
 org-remark-global-tracking.el |  58 ++++---
 org-remark.el                 | 352 +++++++++++++++++++++++++++++++-----------
 4 files changed, 391 insertions(+), 110 deletions(-)

diff --git a/README.org b/README.org
index 75d6efd284..e653ebf66c 100644
--- a/README.org
+++ b/README.org
@@ -110,3 +110,15 @@ This section is created by Org-remark for the source file. 
It serves as an examp
 ** defmacro org-remark-create
 
 This macro was inspired by 
[[https://github.com/jkitchin/ov-highlight][Ov-highlight]].  It's by John 
Kitchin (author of Org-ref). Great UX for markers with hydra. Saves the marker 
info and comments directly within the Org file as Base64 encoded string. It 
uses overlays with using ~ov~ package.
+
+* org-remark
+:PROPERTIES:
+:org-remark-file: org-remark.el
+:END:
+
+** org-remark-notes-send-data
+
+** org-remark-highlights-load
+
+** goto
+This is no longer empty.
diff --git a/org-remark-eww.el b/org-remark-eww.el
new file mode 100644
index 0000000000..f5a27c42e9
--- /dev/null
+++ b/org-remark-eww.el
@@ -0,0 +1,79 @@
+;;; org-remark-eww.el --- Enable Org-remark for EWW -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; Author: Vedang Manerikar <ved.manerikar@gmail.com>
+;;         Noboru Ota <me@nobiot.com>
+;; URL: https://github.com/nobiot/org-remark
+;; Created: 23 December 2022
+;; Last modified: 24 December 2022
+;; Package-Requires: ((emacs "27.1") (org "9.4"))
+;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp
+
+;; This file is not part of GNU Emacs.
+
+;; 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.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;  This file is part of org-remark.
+
+;;  This feature to support for EWW was originally added by Vedang
+;;  Manerika with commit 5e4b27ar feat: Support taking annotations in eww
+;;  buffers.  nobit has refactored it as a separate file.
+
+;;; Code:
+
+(require 'eww)
+(declare-function org-remark-auto-on "org-remark-global-tracking")
+
+;;;###autoload
+(define-minor-mode org-remark-eww-mode
+  "Enable Org-remark to work with EWW."
+  :global t
+  :group 'org-remark
+  (if org-remark-eww-mode
+      ;; Enable
+      (progn
+        (add-hook 'eww-after-render-hook #'org-remark-auto-on)
+        (add-hook 'org-remark-source-find-file-name-functions
+                  #'org-remark-eww-find-file-name)
+        (add-hook 'org-remark-highlight-link-to-source-functions
+                  #'org-remark-eww-highlight-link-to-source))
+      ;; Disable
+      (remove-hook 'eww-after-render-hook #'org-remark-auto-on)
+      (remove-hook 'org-remark-source-find-file-name-functions
+                   #'org-remark-eww-find-file-name)
+      (remove-hook 'org-remark-highlight-link-to-source-functions
+                   #'org-remark-eww-highlight-link-to-source)))
+
+(defun org-remark-eww-find-file-name ()
+  "Return URL without the protocol as the file name for the website.
+It assumes the buffer is the source website to be annotated.
+This function is meant to be set to hook
+`org-remark-source-find-file-name-functions'."
+  (when (eq major-mode 'eww-mode)
+    (let ((url-parsed (url-generic-parse-url (eww-current-url))))
+      (concat (url-host url-parsed) (url-filename url-parsed)))))
+
+(defun org-remark-eww-highlight-link-to-source (filename)
+  "Return URL pointinting to the source website (FILENAME).
+It assumes https:
+This function is meant to be set to hook
+`org-remark-highlight-link-to-source-functions'."
+  (when (eq major-mode 'eww-mode)
+    ;;; FIXME we shhould not assume https?
+    (concat "[[https://"; filename "]]")))
+
+(provide 'org-remark-eww)
+;;; org-remark-eww.el ends here
diff --git a/org-remark-global-tracking.el b/org-remark-global-tracking.el
index 445db3d183..a2b70ea8fb 100644
--- a/org-remark-global-tracking.el
+++ b/org-remark-global-tracking.el
@@ -5,7 +5,7 @@
 ;; Author: Noboru Ota <me@nobiot.com>
 ;; URL: https://github.com/nobiot/org-remark
 ;; Created: 15 August 2021
-;; Last modified: 14 December 2022
+;; Last modified: 24 December 2022
 ;; Package-Requires: ((emacs "27.1") (org "9.4"))
 ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp
 
@@ -55,6 +55,12 @@ suffix to the file name without the extension."
           (file "marginalia.org")
           (function org-remark-notes-file-name-function)))
 
+(defcustom org-remark-highlight-link-to-source-functions nil
+  "Abnormal hook called to create a link to source in notes file.
+Each one is called with FILENAME as an argument."
+  :group 'org-remark
+  :type '(repeat function))
+
 ;;;###autoload
 (define-minor-mode org-remark-global-tracking-mode
   "Automatically activates local minor mode `org-remark-mode'.
@@ -66,15 +72,13 @@ readable, the function automatically activates 
`org-remark'."
   :lighter " ormk-auto"
   :global t
   :group 'org-remark
-  (cond
-   (org-remark-global-tracking-mode
-    ;; Activate
-    (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))))
+  (if org-remark-global-tracking-mode
+    ;; Enable
+      (add-hook 'find-file-hook #'org-remark-auto-on)
+    ;; Disable
+    (remove-hook 'find-file-hook #'org-remark-auto-on)))
 
+;;; Functions
 (defun org-remark-notes-file-name-function ()
   "Return a marginal notes file name for the current buffer.
 
@@ -84,15 +88,22 @@ 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
-           (file-name-nondirectory (org-remark-source-find-file-name)))
-          "-notes.org"))
+  (if buffer-file-name
+      (concat (file-name-sans-extension
+               (file-name-nondirectory (org-remark-source-find-file-name)))
+              "-notes.org")
+    ;; If buffer is not visiting a file, a default file name.  If this
+    ;; file name is not suitable, either override the function or set
+    ;; the user option to a custom function.
+    (expand-file-name "marginalia.org" user-emacs-directory)))
 
 (defalias
-  'org-remark-notes-file-path-function 'org-remark-notes-file-name-function)
+  'org-remark-notes-file-path-function
+  'org-remark-notes-file-name-function)
 
 (make-obsolete
- 'org-remark-notes-file-path-function 'org-remark-notes-file-name-function 
"0.2.0" )
+ 'org-remark-notes-file-path-function
+ 'org-remark-notes-file-name-function "0.2.0" )
 
 ;;;; Private Functions
 
@@ -109,18 +120,21 @@ This function is meant to be added to `find-file-hook' by
   "Return the name of marginal notes file for current buffer."
   (if (functionp org-remark-notes-file-name)
       (funcall org-remark-notes-file-name)
-    ;; If not function, assume string and return it as the file path.
-    org-remark-notes-file-name))
+    ;; If not function, assume string and return it as the file name.
+    ;; TODO when buffer is not visitng a file, assume file resides in
+    ;; `user-emacs-directory'
+    (if buffer-file-name org-remark-notes-file-name
+      (expand-file-name org-remark-notes-file-name user-emacs-directory))))
 
 (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
+Returns the filename for the source 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)))
+marginal notes."
+  (let ((filename (or buffer-file-name
+                      (run-hook-with-args-until-success
+                       'org-remark-source-find-file-name-functions))))
+    filename))
 
 (provide 'org-remark-global-tracking)
 
diff --git a/org-remark.el b/org-remark.el
index 47905e731b..b764651e17 100644
--- a/org-remark.el
+++ b/org-remark.el
@@ -6,7 +6,7 @@
 ;; URL: https://github.com/nobiot/org-remark
 ;; Version: 1.0.5
 ;; Created: 22 December 2020
-;; Last modified: 14 December 2022
+;; Last modified: 26 December 2022
 ;; Package-Requires: ((emacs "27.1") (org "9.4"))
 ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp,
 
@@ -128,6 +128,10 @@ returned by `org-remark-notes-get-file-name'.")
 (defvar-local org-remark-highlights-hidden nil
   "Keep hidden/shown state of the highlights in current buffer.")
 
+;; TODO org-remark-sync?
+(defvar-local org-remark-notes-setup-done nil)
+(defvar-local org-remark-source-setup-done nil)
+
 (defvar org-remark-last-notes-buffer nil
   "Stores the cloned indirect buffer visiting the notes file.
 It is meant to exist only one of these in each Emacs session.")
@@ -177,6 +181,8 @@ text region:
 
 %S
 
+Return the overlay.
+
 When this function is used interactively, it will generate a new
 ID, always assuming it is working on a new highlighted text
 region, and Org-remark will start tracking the highlight's
@@ -184,7 +190,10 @@ location in the current buffer.
 
 When this function is called from Elisp, ID can be optionally
 passed, indicating to Org-remark that it is an existing
-highlight.  In this case, no new ID gets generated."
+highlight.  In this case, no new ID gets generated.
+
+When the pen itself defines the help-echo property, it will have
+the priority over the excerpt of the marginal notes."
                   (or face "`org-remark-highlighter'") properties)
          (interactive (org-remark-region-or-word))
          (org-remark-highlight-mark beg end id mode ,label ,face ,properties))
@@ -345,6 +354,8 @@ When this function is used interactively, it will generate 
a new
 ID, always assuming it is working on a new highlighted text
 region.
 
+Return the highlight overlay.
+
 A Org headline entry for the highlight will be created in the
 marginal notes file specified by
 `org-remark-notes-get-file-name'.  If the file does not exist
@@ -371,11 +382,11 @@ marginal notes file.  The expected values are nil, :load 
and
 (when org-remark-create-default-pen-set
   ;; Create default pen set.
   (org-remark-create "red-line"
-                     '(:underline (:color "dark red" :style wave))
-                     '(CATEGORY "review" help-echo "Review this"))
+                     `(:underline (:color "dark red" :style wave))
+                     `(CATEGORY "review" help-echo "Review this"))
   (org-remark-create "yellow"
-                     '(:underline "gold" :background "lemon chiffon")
-                     '(CATEGORY "important")))
+                     `(:underline "gold" :background "lemon chiffon")
+                     `(CATEGORY "important")))
 
 (defun org-remark-save ()
   "Save all the highlights tracked in current buffer to notes file.
@@ -390,9 +401,9 @@ in the current buffer.  Each highlight is an overlay."
   (org-remark-highlights-sort)
   (let ((filename (org-remark-source-find-file-name)))
     (dolist (h org-remark-highlights)
-      (let ((beg (overlay-start h))
-            (end (overlay-end h))
-            (props (overlay-properties h)))
+      (let* ((beg (overlay-start h))
+             (end (overlay-end h))
+             (props (overlay-properties h)))
         (org-remark-highlight-save filename beg end props)))))
 
 (defun org-remark-open (point &optional view-only)
@@ -640,6 +651,26 @@ If there are more than one, return CAR of the list."
       (setq overlays (cdr overlays)))
     (car found)))
 
+(defun org-remark-find-overlay-in (beg end &optional id)
+  "Return one org-remark overlay between BEG and END.
+If there are more than one, return CAR of the list.
+Optioanlly ID can be passed to find the exacth ID match."
+  (let* ((overlays (overlays-in beg end))
+         found)
+    (while overlays
+      (let ((overlay (car overlays)))
+        (if (overlay-get overlay 'org-remark-id)
+            (setq found (cons overlay found))))
+      (setq overlays (cdr overlays)))
+    (when id (setq found
+                   (seq-filter
+                    (lambda (ov)
+                      (equal (overlay-get ov 'org-remark-id) id))
+                    found)))
+    (car found)))
+
+
+
 
 ;;;; org-remark-highlight
 ;;   Work on a single highlight
@@ -654,6 +685,8 @@ nil, this function will use the default face 
`org-remark-highlighter'
 This function will add LABEL and PROPERTIES as overlay
 properties.  PROPERTIES is a plist of pairs of a symbol and value.
 
+Return the hightliht overlay.
+
 When this function is used interactively, it will generate a new
 ID, always assuming it is working on a new highlighted text
 region, and Org-remark will start tracking the highlight's
@@ -677,35 +710,44 @@ to the database."
   ;; When highlights are toggled hidden, only the new one gets highlighted in
   ;; the wrong toggle state.
   (when org-remark-highlights-hidden (org-remark-highlights-show))
-  ;; Add highlight to the text
-  (org-with-wide-buffer
-   (let ((ov (make-overlay beg end nil :front-advance))
-         ;; UUID is too long; does not have to be the full length
-         (id (if id id (substring (org-id-uuid) 0 8))))
-     (overlay-put ov 'face (if face face 'org-remark-highlighter))
-     (while properties
-       (let ((prop (pop properties))
-             (val (pop properties)))
-         (overlay-put ov prop val)))
-     (when label (overlay-put ov 'org-remark-label label))
-     (overlay-put ov 'org-remark-id id)
-     ;; Keep track of the overlay in a local variable. It's a list that is
-     ;; guaranteed to contain only org-remark overlays as opposed to the one
-     ;; returned by `overlay-lists' that lists any overlays.
-     (push ov org-remark-highlights)
-     ;; for mode, nil and :change result in saving the highlight.  :load
-     ;; bypasses save.
-     (unless (eq mode :load)
-       (let ((filename (org-remark-source-find-file-name)))
-         (if filename
-             (org-remark-highlight-save filename
-                                        beg end
-                                        (overlay-properties ov)
-                                        (org-remark-highlight-get-title))
-           (message "org-remark: Highlights not saved; buffer is not visiting 
a file"))))))
-  (deactivate-mark)
-  (org-remark-highlights-housekeep)
-  (org-remark-highlights-sort))
+  (let ((ov (make-overlay beg end nil :front-advance))
+        ;; UUID is too long; does not have to be the full length
+        (id (if id id (substring (org-id-uuid) 0 8)))
+        (filename (org-remark-source-find-file-name))
+        (notes-props))
+    (if (not filename) (message "org-remark: Highlights not saved; buffer is 
not supported")
+      (org-with-wide-buffer
+       (overlay-put ov 'face (if face face 'org-remark-highlighter))
+       (while properties
+         (let ((prop (pop properties))
+               (val (pop properties)))
+           (overlay-put ov prop val)))
+       (when label (overlay-put ov 'org-remark-label label))
+       (overlay-put ov 'org-remark-id id)
+       ;; Keep track of the overlay in a local variable. It's a list that is
+       ;; guaranteed to contain only org-remark overlays as opposed to the one
+       ;; returned by `overlay-lists' that lists any overlays.
+       (push ov org-remark-highlights)
+       ;; for mode, nil and :change result in saving the highlight.  :load
+       ;; bypasses save.
+       (unless (eq mode :load)
+         (setq notes-props
+               (org-remark-highlight-save filename
+                                          beg end
+                                          (overlay-properties ov)
+                                          (org-remark-highlight-get-title)))
+         ;;; Get props for create and change any way
+         (when notes-props
+           ;; TODO. The function should be based on parameters
+           (unless (overlay-get ov 'help-echo)
+             (overlay-put ov 'help-echo (plist-get notes-props :body)))
+           (overlay-put ov '_org-remark-note-body
+                        (plist-get notes-props :body)))))
+      (deactivate-mark)
+      (org-remark-highlights-housekeep)
+      (org-remark-highlights-sort)
+      ;; Return overlay
+      ov)))
 
 (defun org-remark-highlight-get-title ()
   "Return the title of the current buffer.
@@ -733,7 +775,7 @@ non-nil.  Returns nil otherwise, or when no Org-ID is 
found."
 (defun org-remark-highlight-save (filename beg end props &optional title)
   "Save a single HIGHLIGHT in the marginal notes file.
 
-Return t.
+Return the highlight's data properties list (TODO refer to ...).
 
 FILENAME specifies the name of source file with which the marginal notes
 file is associated.
@@ -766,35 +808,43 @@ buffer with search option \"::line-number\".
 ORGID can be passed to this function.  If user option
 `org-remark-use-org-id' is non-nil, this function will add an
 Org-ID link in the body text of the headline, linking back to the
-source with using ORGID."
+source with using ORGID.
+
+When a new notes file is created, add
+`org-remark-notes-sync-with-source' to `after-save-hook'."
   (let* ((filename (org-remark-source-get-file-name filename))
          (id (plist-get props 'org-remark-id))
          (text (org-with-wide-buffer (buffer-substring-no-properties beg end)))
          (notes-buf (find-file-noselect (org-remark-notes-get-file-name)))
          (main-buf (current-buffer))
          (line-num (org-current-line beg))
-         (orgid (org-remark-highlight-get-org-id beg)))
+         (orgid (org-remark-highlight-get-org-id beg))
+         (link (if buffer-file-name
+                   (concat "[[file:" filename
+                           (when line-num (format "::%d" line-num)) "]]")
+                 (run-hook-with-args-until-success
+                  'org-remark-highlight-link-to-source-functions filename)))
+         (notes-props))
+    ;;; Set up notes buffer for sync, etc.
+    (org-remark-notes-setup notes-buf (current-buffer) filename)
     (with-current-buffer notes-buf
       (when (featurep 'org-remark-convert-legacy) 
(org-remark-convert-legacy-data))
       ;;`org-with-wide-buffer is a macro that should work for non-Org file'
       (org-with-wide-buffer
-       (let ((file-headline (or (org-find-property
-                                 org-remark-prop-source-file filename)
-                                (progn
-                                  ;; If file-headline does not exist, create 
one at the bottom
-                                  (goto-char (point-max))
-                                  ;; Ensure to be in the beginning of line to 
add a new headline
-                                  (when (eolp) (open-line 1) (forward-line 1) 
(beginning-of-line))
-                                  (insert (concat "* " title "\n"))
-                                  (org-set-property 
org-remark-prop-source-file filename)
-                                  (org-up-heading-safe) (point))))
+       (let ((file-headline
+              (or (org-find-property
+                   org-remark-prop-source-file filename)
+                  (progn
+                    ;; If file-headline does not exist, create one at the 
bottom
+                    (goto-char (point-max))
+                    ;; Ensure to be in the beginning of line to add a new 
headline
+                    (when (eolp) (open-line 1) (forward-line 1) 
(beginning-of-line))
+                    (insert (concat "* " title "\n"))
+                    (org-set-property org-remark-prop-source-file filename)
+                    (org-up-heading-safe) (point))))
              (id-headline (org-find-property org-remark-prop-id id)))
          ;; Add org-remark-link with updated line-num as a property
-         (plist-put props "org-remark-link" (concat
-                                             "[[file:"
-                                             filename
-                                             (when line-num (format "::%d" 
line-num))
-                                             "]]"))
+         (when link (plist-put props "org-remark-link" link))
          (if id-headline
              (progn
                (goto-char id-headline)
@@ -816,20 +866,34 @@ source with using ORGID."
            (insert (concat "** " text "\n"))
            (org-remark-notes-set-properties beg end props)
            (when (and orgid org-remark-use-org-id)
-               (insert (concat "[[id:" orgid "]" "[" title "]]"))))))
-      (cond
-       ;; fix GH issue #19
-       ;; Temporarily remove `org-remark-save' from the `after-save-hook'
-       ;; When the marginal notes buffer is the source buffer
-       ((eq notes-buf main-buf)
+             (insert (concat "[[id:" orgid "]" "[" title "]]"))))
+         (setq notes-props (list :body (org-remark-notes-get-text)))))
+      ;; (cond
+      ;;  ;; fix GH issue #19
+      ;;  ;; Temporarily remove `org-remark-save' from the `after-save-hook'
+      ;;  ;; When the marginal notes buffer is the source buffer
+      ;;  ((eq notes-buf main-buf)
+      ;;   (remove-hook 'after-save-hook #'org-remark-save t)
+      ;;   (save-buffer)
+      ;;   (add-hook 'after-save-hook #'org-remark-save nil t))
+      ;;  ;; When marginal notes buffer is separate from the source buffer, 
save the
+      ;;  ;; notes buffer
+      ;;  ((buffer-modified-p)
+
+      ;;  Now that the notes-sync is put into after-save-buffer, we need
+      ;;  to remove stop saving or remove 'after-save-hook temporarily
+      ;;  to avoid (infinite) loop.
+
+      ;;   (save-buffer)))
+      (when (eq notes-buf main-buf)
         (remove-hook 'after-save-hook #'org-remark-save t)
-        (save-buffer)
-        (add-hook 'after-save-hook #'org-remark-save nil t))
-       ;; When marginal notes buffer is separate from the source buffer, save 
the
-       ;; notes buffer
-       ((buffer-modified-p)
-        (save-buffer)))
-      t)))
+        (remove-hook 'after-save-hook #'org-remark-notes-sync-with-source t)
+        ;;(save-buffer)
+        (set-buffer-modified-p nil)
+        ;;(add-hook 'after-save-hook #'org-remark-save t)
+        ;;(add-hook 'after-save-hook #'org-remark-notes-sync-with-source t))
+        )
+      notes-props)))
 
 
 ;;;;; org-remark-notes
@@ -911,10 +975,16 @@ And the following are also reserved for Org-remark:
 For PROPS, if the property name is CATEGORY \(case-sensitive\) or
 prefixed with \"org-remark-\" set them to to headline's property
 drawer."
+
   (org-set-property org-remark-prop-source-beg
                     (number-to-string beg))
   (org-set-property org-remark-prop-source-end
                     (number-to-string end))
+
+  ;; Delete property
+  ;; `org-delete-property'
+  (org-entry-delete nil "CATEGORY")
+
   (while props
     (let ((p (pop props))
           (v (pop props)))
@@ -925,10 +995,55 @@ drawer."
         (org-set-property p v))))
   t)
 
+(defun org-remark-notes-get-text ()
+  "Return the text body of a highlight in the notes buffer."
+  (let ((full-text
+         (save-excursion
+           (org-end-of-meta-data :full)
+           (if
+               ;; handle empty annotation
+               ;; (org-end-of-meta-data :full) took us to next org heading):
+               (or (looking-at org-heading-regexp)
+                   (eobp)) ;; end of buffer
+               "[empty entry]"
+             (buffer-substring-no-properties
+              (point)
+              (org-end-of-subtree))))))
+    (if (< 200 (length full-text))
+        (substring-no-properties full-text 0 200)
+      full-text)))
+
+
 
 ;;;;; org-remark-highlights
 ;;    Work on all the highlights in the current buffer
 
+(defvar-local org-remark-notes-source-buffers '()
+  "List of source buffers that have loaded the notes.
+Each note's buffer locally keeps track of the source buffers that
+have loaded notes from itself.  Buffers in this list may be
+killed so that this needs to be checked with `buffer-live-p'.")
+
+(defun org-remark-highlight-load (highlight)
+  (let* ((id (plist-get highlight :id))
+         (location (plist-get highlight :location))
+         (beg (car location))
+         (end (cdr location))
+         (label (plist-get highlight :label))
+         (ov nil)
+         (props (plist-get highlight :props)))
+    (let ((fn (intern (concat "org-remark-mark-" label))))
+      (unless (functionp fn) (setq fn #'org-remark-mark))
+      (setq ov (funcall fn beg end id :load))
+      ;; TODO Generalize the part that updates properties.
+      ;; :body should not be the fixed property.
+      ;; '(:text (val . fn) :prop1 (val . fn) :prop2 (val .fn))
+      ;; (dolist list)
+      (unless (overlay-get ov 'help-echo)
+        (overlay-put ov 'help-echo (plist-get props :body)))
+      (overlay-put ov '*org-remark-note-body
+                   (plist-get props :body)))))
+
 (defun org-remark-highlights-load ()
   "Visit `org-remark-notes-file' & load the saved highlights onto current 
buffer.
 If there is no highlights or annotations for current buffer,
@@ -942,27 +1057,81 @@ configuration.  It automatically turns on 
`org-remark-mode'.
 Otherwise, do not forget to turn on `org-remark-mode' manually to
 load the highlights"
   ;; Loop highlights and add them to the current buffer
-  (dolist (highlight (org-remark-highlights-get))
-    (let ((id (car highlight))
-          (beg (caadr highlight))
-          (end (cdadr highlight))
-          (label (caddr highlight)))
-      (let ((fn (intern (concat "org-remark-mark-" label))))
-        (unless (functionp fn) (setq fn #'org-remark-mark))
-        (funcall fn beg end id :load)))))
-
-(defun org-remark-highlights-get ()
+  (let ((notes-buf (find-file-noselect (org-remark-notes-get-file-name)))
+        (source-file-name (org-remark-source-get-file-name
+                           (org-remark-source-find-file-name)))
+        (source-buf (current-buffer)))
+    (dolist (highlight (org-remark-highlights-get notes-buf source-file-name))
+      (org-remark-highlight-load highlight))
+    (org-remark-notes-setup notes-buf source-buf source-file-name)
+    (setq org-remark-source-setup-done t))
+  t)
+
+(defun org-remark-notes-setup (notes-buf source-buf source-file-name)
+  ;;; Start tracking the source buffer in the notes buffer as local variable.
+  ;;; This adds variable only to the base-buffer and not to the indrect buffer.
+  (let ((source-setup-done org-remark-source-setup-done))
+    (with-current-buffer notes-buf
+      (unless (and org-remark-notes-setup-done source-setup-done)
+        (cl-pushnew (cons source-buf source-file-name)
+                    org-remark-notes-source-buffers)
+        (add-hook 'after-save-hook #'org-remark-notes-sync-with-source nil 
:local)
+        (setq org-remark-notes-setup-done t)))))
+
+(defun org-remark-notes-housekeep ()
+ "Remove killed buffers from `org-remark-notes-source-buffers'."
+ (setq org-remark-notes-source-buffers
+       (seq-filter #'(lambda (pair) (buffer-live-p (car pair)))
+                   org-remark-notes-source-buffers)))
+
+(defun org-remark-notes-update-source (source-buffer source-file-name)
+  "Update source with notes props.
+Trigger by on-save of the notes."
+  ;; Assume the current buffer is the notes file (indrect or base).
+  (let* ((new-highlights
+          (org-remark-highlights-get (current-buffer) source-file-name)))
+    (with-current-buffer source-buffer
+      (dolist (highlight new-highlights)
+        (let* ((location (plist-get highlight :location))
+               (beg (car location))
+               (end (cdr location))
+               (id (plist-get highlight :id))
+               (ov (org-remark-find-overlay-in beg end id)))
+          ;; FIXME Currently the when clause is used to guard against
+          ;; the case where a highlight overlay is not found.  It should
+          ;; be an edge case but the highlight could have moved to a
+          ;; completely new location where the old location does not
+          ;; overlap with the new location at all.
+          (when ov (delete-overlay ov))
+          (org-remark-highlight-load highlight))))))
+
+(defun org-remark-notes-sync-with-source ()
+  "
+It is meant to be used in `after-save-hook'.
+Look at the base buffer for org-remark-notes-source-buffers."
+  ;;; Assume the current buffer is either the indirect or notes buffer
+  ;;; in question.
+  (let* ((notes-buffer (or (buffer-base-buffer) (current-buffer))))
+    (with-current-buffer notes-buffer
+      (org-remark-notes-housekeep)
+      (dolist (pair org-remark-notes-source-buffers)
+        ;; pair is (SOURCE-BUF . SOURCE-FILE-NAME)
+        ;; SOUCE-FILE-NAME is the reference used in notes file
+        (let ((source-buf (car pair))
+              (source-file-name (cdr pair)))
+          (org-remark-notes-update-source source-buf source-file-name))))))
+
+(defun org-remark-highlights-get (notes-buf source-file-name)
   "Return a list of highlights from the marginal notes file.
 The file name is returned by `org-remark-notes-get-file-name'.
-Each highlight is a list in the following structure:
-    (ID (BEG . END) LABEL)"
+Each highlight is a property list in the following properties:
+    (:id ID :location (BEG . END) :label LABEL :props '(PROPERTIES)"
   ;; Set source-file-name first, as `find-file-noselect' will set the
   ;; 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
-                                (org-remark-source-find-file-name)))
-             (notes-buf (find-file-noselect (org-remark-notes-get-file-name))))
+  (when-let ((source-file-name source-file-name)
+             (notes-buf notes-buf))
     ;; TODO check if there is any relevant notes for the current file
     ;; This can be used for adding icon to the highlight
     (let ((highlights))
@@ -990,10 +1159,12 @@ Each highlight is a list in the following structure:
                                                org-remark-prop-source-beg)))
                           (end (string-to-number
                                 (org-entry-get (point)
-                                               org-remark-prop-source-end))))
-                 (push (list id
-                             (cons beg end)
-                             (org-entry-get (point) "org-remark-label"))
+                                               org-remark-prop-source-end)))
+                          (text (org-remark-notes-get-text)))
+                 (push (list :id id
+                             :location (cons beg end)
+                             :label    (org-entry-get (point) 
"org-remark-label")
+                             :props    (list :body text))
                        highlights))))
            highlights))))))
 
@@ -1077,6 +1248,11 @@ Case 1. Both start and end of an overlay are identical
         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'.
+
 Case 2. The overlay points to no buffer
 
         This case happens when overlay is deleted by



reply via email to

[Prev in Thread] Current Thread [Next in Thread]