branch: externals/org-remark commit e77787ca5d510701a1551b2feb7cf4e42d01891a Author: Noboru Ota <m...@nobiot.com> Commit: Noboru Ota <m...@nobiot.com>
refactor:spacer --- org-remark-icon.el | 4 +- org-remark-line.el | 134 +++++++++++++++++++++++++++++++++++------------------ org-remark.el | 91 +++++++++++++++++++----------------- 3 files changed, 141 insertions(+), 88 deletions(-) diff --git a/org-remark-icon.el b/org-remark-icon.el index 46b8c5eea6..39f5ffa809 100644 --- a/org-remark-icon.el +++ b/org-remark-icon.el @@ -5,7 +5,7 @@ ;; Author: Noboru Ota <m...@nobiot.com> ;; URL: https://github.com/nobiot/org-remark ;; Created: 29 July 2023 -;; Last modified: 07 August 2023 +;; Last modified: 14 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp @@ -137,7 +137,7 @@ DEFAULT FACE must be a named face. It is optinal and can be nil.") "Add icons to OVERLAYS. Each overlay is a highlight." (dolist (ov overlays) - ;; icons added to line highlighters differently from normal ones. + ;; icons added to line highlighters differently from normal ones. (cl-flet ((add-icon-maybe (icon) (cl-destructuring-bind (icon-name pred default-face) icon diff --git a/org-remark-line.el b/org-remark-line.el index 383fca9c09..e1ec071c4e 100644 --- a/org-remark-line.el +++ b/org-remark-line.el @@ -5,7 +5,7 @@ ;; Author: Noboru Ota <m...@nobiot.com> ;; URL: https://github.com/nobiot/org-remark ;; Created: 01 August 2023 -;; Last modified: 10 August 2023 +;; Last modified: 14 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp @@ -45,6 +45,11 @@ (defvar org-remark-line-ellipsis "…") +(defvar org-remark-line-minimum-margin-width 3) + +(defvar org-remark-line-margin-padding 1 + "Padding between the main text area the icon on the margin") + (defvar-local org-remark-line-delayed-put-overlay-functions '() "List of lambda functions that add a highlight. We need to delay adding highlight overlays until window is @@ -66,35 +71,38 @@ filefor the first time, the window has not been created before ;; line-highlight. (add-hook 'org-remark-find-dwim-functions #'org-remark-line-find 80 :local) + ;; olivetti sets DEPTH to t (=90). We need go lower priority than it (add-hook 'window-size-change-functions - #'org-remark-line-set-window-margins nil :local) + #'org-remark-line-set-window-margins 95 :local) + (setq left-margin-width org-remark-line-minimum-margin-width) ;;(org-remark-line-set-buffer-windows)) ) (remove-hook 'org-remark-find-dwim-functions #'org-remark-line-find :local) (remove-hook 'window-size-change-functions #'org-remark-line-set-window-margins :local))) -(defun org-remark-line-set-buffer-windows () - " -Adapted from Olivetti mode" - (mapc #'org-remark-line-set-window-margins - (get-buffer-window-list nil nil 'visible))) - -(defun org-remark-line-set-window-margins (window-or-frame) +;; (defun org-remark-line-set-buffer-windows () +;; " +;; Adapted from Olivetti mode" +;; (mapc #'org-remark-line-set-window-margins +;; (get-buffer-window-list nil nil 'visible))) +(defun org-remark-line-set-window-margins (window) "Set the margins of current window that displays current buffer. Return a cons of the form (LEFT-WIDTH . RIGHT-WIDTH). If a marginal area does not exist, its width will be returned as nil." - (when (and (windowp window-or-frame) org-remark-line-mode) + (when (and (windowp window) org-remark-line-mode) ;;(message "size change used with a window argument") - (when org-remark-line-delayed-put-overlay-functions - (dolist (fn (reverse org-remark-line-delayed-put-overlay-functions)) - (funcall fn)) - (setq org-remark-line-delayed-put-overlay-functions nil)) + ;; (when org-remark-line-delayed-put-overlay-functions + ;; (dolist (fn (reverse org-remark-line-delayed-put-overlay-functions)) + ;; (funcall fn)) + ;; (setq org-remark-line-delayed-put-overlay-functions nil)) (cl-destructuring-bind (left-width . right-width) (window-margins) - (when (or (eq left-width nil) (< left-width 3)) - (setq left-margin-width 3) + (when (or (eq left-width nil) (< left-width + org-remark-line-minimum-margin-width)) + ;; (setq left-margin-width org-remark-line-minimum-margin-width) (set-window-buffer (get-buffer-window) (current-buffer) 'keep-margins) - (set-window-margins nil 3)) + (set-window-margins nil org-remark-line-minimum-margin-width)) + (org-remark-highlights-load) (window-margins)))) (defun org-remark-line-pos-bol (pos) @@ -126,38 +134,76 @@ by `overlays-in'." (let ((bol (org-remark-line-pos-bol (point)))) (list bol bol))) -(cl-defmethod org-remark-highlight-mark-overlay (ov face (org-remark-type (eql 'line))) +(cl-defmethod org-remark-highlight-make-overlay (beg end face (org-remark-type (eql 'line))) "Put FACE and other necessary properties to the highlight OV. -This is a method for highlights of ORG-REMARK-TYPE \\='line\\='." +This is a method for highlights of ORG-REMARK-TYPE \\='line\\='. +Return OV" (if (get-buffer-window) ;; When revert-buffer is called, the window is already available ;; but window size won't change. - (org-remark-line-highlight-overlay-put ov face) - (push (lambda () - (org-remark-line-highlight-overlay-put ov face)) - org-remark-line-delayed-put-overlay-functions))) - -(defun org-remark-line-highlight-overlay-put (ov face &optional string) + (org-remark-line-highlight-overlay-put beg end face) + ;; window is still not created and assigned to the current buffer. + ;; Reload when it is. + (add-hook 'window-state-change-functions #'org-remark-line-reload 80 'local) + ;;(push (lambda () + ;; (org-remark-line-highlight-overlay-put beg end face)) + ;; org-remark-line-delayed-put-overlay-functions) + nil)) + +(defun org-remark-line-reload (window) + (when (windowp window) + (remove-hook 'window-state-change-functions + #'org-remark-line-reload 'local) + (org-remark-highlights-load))) + +(defun org-remark-line-highlight-overlay-put (beg end face &optional string) + ;;(when (or (car (window-margins)) (cdr (window-margins))) (let* ((face (or face 'org-remark-line-highlighter)) - ;;(left-margin (car (org-remark-line-set-window-margins - ;; (get-buffer-window)))) - ;;(left-margin 3) - ;;(spaces (- left-margin 1)) + ;; We need to be sure where the minimum-margin-width is set to the buffer + (left-margin (or (car (window-margins)) org-remark-line-minimum-margin-width)) (string (or string (with-temp-buffer ;;(insert-char ?\s spaces) - (insert org-remark-line-icon) - (buffer-string))))) + (insert org-remark-line-icon) + (buffer-string)))) + (string-length (length string)) + (spaces-base-length (- left-margin + (+ string-length org-remark-line-margin-padding))) + (spaces-length (if (> spaces-base-length 0) spaces-base-length 0)) + (spaces (with-temp-buffer (insert-char ?\s spaces-length) + (buffer-string))) + (spacer-ov (make-overlay beg end nil :front-advance)) + (ov (make-overlay beg end nil :front-advance))) + ;; Add a spacing overlay before the line-highlight overlay + (remove-overlays (overlay-start spacer-ov) (overlay-end spacer-ov) + 'category 'org-remark-spacer) + (overlay-put spacer-ov 'before-string (propertize " " + 'display + `((margin left-margin) + ,spaces))) + (overlay-put spacer-ov 'category 'org-remark-spacer) + (overlay-put spacer-ov 'insert-in-front-hooks + (list 'org-remark-line-highlight-modified)) + ;; line-highlight overlay (overlay-put ov 'before-string (propertize "! " 'display `((margin left-margin) ,(propertize string 'face face)))) (overlay-put ov 'insert-in-front-hooks (list 'org-remark-line-highlight-modified)) ov)) +(defun org-remark-line-highlight-find-spacer (pos) + (let ((highlights (overlays-in pos pos))) + (seq-find (lambda (ov) + (eql 'org-remark-spacer (overlay-get ov 'category))) + highlights))) + (defun org-remark-line-highlight-modified (ov after-p beg end &optional length) - "This is good! Move the overlay to follow the point when ENTER in the line." + "Move the overlay to follow the point when ENTER in the line." (when after-p (save-excursion (goto-char beg) (when (looking-at "\n") + ;; Spacer needs to move before the hightlight to keep the sequence. + (let ((spacer (org-remark-line-highlight-find-spacer beg))) + (when spacer (move-overlay spacer (1+ beg) (1+ beg)))) (move-overlay ov (1+ beg) (1+ beg)))))) (cl-defmethod org-remark-highlight-headline-text (ov (org-remark-type (eql 'line))) @@ -194,10 +240,11 @@ end of overlay being identical." ;; always follow the point, keeping the original place unless you ;; directly change the notes. That's not really an intutive behaviour, ;; though in some cases, it imay be useful. - (let* ((ov-start (overlay-start ov)) - (ov-line-bol (org-remark-line-pos-bol ov-start))) - (unless (= ov-start ov-line-bol) - (move-overlay ov ov-line-bol ov-line-bol)))) + (if (not (overlay-start ov)) (delete-overlay ov) + (let* ((ov-start (overlay-start ov)) + (ov-line-bol (org-remark-line-pos-bol ov-start))) + (unless (= ov-start ov-line-bol) + (move-overlay ov ov-line-bol ov-line-bol))))) (defun org-remark-line-icon-overlay-put (ov icon-string) ;; If the icon-string has a display properties, assume it is an icon image @@ -209,19 +256,18 @@ end of overlay being identical." 'face 'org-remark-line-highlighter)) (overlay-put ov 'before-string icon-string))) (icon-string - (setq icon-string (propertize icon-string - 'face 'org-remark-line-highlighter)) - (org-remark-line-highlight-overlay-put ov - 'org-remark-line-highlighter - icon-string)) + (let ((icon-string (propertize icon-string + 'face 'org-remark-line-highlighter))) + (overlay-put ov 'before-string (propertize " " 'display (list '(margin left-margin) icon-string))))) (t (ignore))))) (cl-defmethod org-remark-icon-overlay-put (ov icon-string (org-remark-type (eql 'line))) (if (get-buffer-window) (org-remark-line-icon-overlay-put ov icon-string) - (push - (lambda () (org-remark-line-icon-overlay-put ov icon-string)) - org-remark-line-delayed-put-overlay-functions))) + ;(push + ; (lambda () (org-remark-line-icon-overlay-put ov icon-string)) + ; org-remark-line-delayed-put-overlay-functions))) + )) (provide 'org-remark-line) ;;; org-remark-line.el ends here diff --git a/org-remark.el b/org-remark.el index eb353821f7..2fcc8a03e8 100644 --- a/org-remark.el +++ b/org-remark.el @@ -6,7 +6,7 @@ ;; URL: https://github.com/nobiot/org-remark ;; Version: 1.1.0 ;; Created: 22 December 2020 -;; Last modified: 07 August 2023 +;; Last modified: 14 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp, @@ -804,14 +804,18 @@ Optionally ID can be passed to find the exact ID match." ;; functions here mostly assume the current buffer is the source ;; buffer. -(cl-defgeneric org-remark-highlight-mark-overlay (_org-remark-type) - "Put FACE and other necessary properties to the highlight OV") +(cl-defgeneric org-remark-highlight-make-overlay (_beg _end _face _org-remark-type) + "Make overlay and return it +Put FACE and other necessary properties to the highlight OV") -(cl-defmethod org-remark-highlight-mark-overlay (ov face (_org-remark-type (eql nil))) +(cl-defmethod org-remark-highlight-make-overlay (beg end face + (_org-remark-type (eql nil))) "Put FACE and other necessary properties to the highlight OV. This is a method for highlights of default ORG-REMARK-TYPE, that is for a character range." - (overlay-put ov 'face (if face face 'org-remark-highlighter))) + (let ((ov (make-overlay beg end nil :front-advance))) + (overlay-put ov 'face (if face face 'org-remark-highlighter)) + ov)) (defun org-remark-highlight-mark (beg end &optional id mode label face properties) @@ -848,16 +852,16 @@ round-trip back to the notes file." ;; 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)) - (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)) - (org-remark-type (plist-get properties 'org-remark-type))) - (if (not filename) - (message (format "org-remark: Highlights not saved.\ + (org-with-wide-buffer + (let* ((org-remark-type (plist-get properties 'org-remark-type)) + (ov (org-remark-highlight-make-overlay beg end face org-remark-type)) + ;;(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))) + (if (not filename) + (message (format "org-remark: Highlights not saved.\ This buffer (%s) is not supported" (symbol-name major-mode))) - (org-with-wide-buffer - (org-remark-highlight-mark-overlay ov face org-remark-type) (while properties (let ((prop (pop properties)) (val (pop properties))) @@ -888,12 +892,12 @@ round-trip back to the notes file." (with-current-buffer notes-buf (unless (buffer-modified-p) (restore-buffer-modified-p t)) (save-buffer)))))) - (deactivate-mark) - (org-remark-highlights-housekeep) - (org-remark-highlights-sort) - (setq org-remark-source-setup-done t) - ;; Return overlay - ov))) + (deactivate-mark) + (org-remark-highlights-housekeep) + (org-remark-highlights-sort) + (setq org-remark-source-setup-done t) + ;; Return overlay + ov))) (defun org-remark-highlight-get-title () "Return the title of the source buffer. @@ -1479,28 +1483,31 @@ process." ;; file to another. Thus, in order to update the highlight overlays we ;; need to begin loading by clearing them first. This way, we avoid ;; duplicate of the same highlight. - (org-remark-highlights-clear) - ;; Loop highlights and add them to the current buffer - (let (overlays) ;; highlight overlays - (when-let* ((notes-filename (org-remark-notes-get-file-name)) - (default-dir default-directory) - (notes-buf (or (find-buffer-visiting notes-filename) - (find-file-noselect notes-filename))) - (source-buf (current-buffer))) - (with-demoted-errors - "Org-remark: error during loading highlights: %S" - ;; Load highlights with demoted errors -- this makes the loading - ;; robust against errors in loading. - (dolist (highlight (org-remark-highlights-get notes-buf)) - (push (org-remark-highlight-load highlight) overlays)) - (unless update (org-remark-notes-setup notes-buf source-buf)) - (if overlays - (progn (run-hook-with-args 'org-remark-highlights-after-load-functions - overlays notes-buf) - ;; Return t - t) - ;; if there is no overlays loaded, return nil - nil))))) + (if (not (get-buffer-window)) + ;; TODO + (add-hook 'window-state-change-functions #'org-remark-line-reload 95 'local) + (org-remark-highlights-clear) + ;; Loop highlights and add them to the current buffer + (let (overlays) ;; highlight overlays + (when-let* ((notes-filename (org-remark-notes-get-file-name)) + (default-dir default-directory) + (notes-buf (or (find-buffer-visiting notes-filename) + (find-file-noselect notes-filename))) + (source-buf (current-buffer))) + (with-demoted-errors + "Org-remark: error during loading highlights: %S" + ;; Load highlights with demoted errors -- this makes the loading + ;; robust against errors in loading. + (dolist (highlight (org-remark-highlights-get notes-buf)) + (push (org-remark-highlight-load highlight) overlays)) + (unless update (org-remark-notes-setup notes-buf source-buf)) + (if overlays + (progn (run-hook-with-args 'org-remark-highlights-after-load-functions + overlays notes-buf) + ;; Return t + t) + ;; if there is no overlays loaded, return nil + nil)))))) (defun org-remark-highlights-clear () "Delete all highlights in the buffer.