branch: externals/org-remark commit a2311005ffc9edaf415bdf18996f5fb3824123a3 Author: Noboru Ota <m...@nobiot.com> Commit: Noboru Ota <m...@nobiot.com>
fix(line): Ensure line hl ovs are always at bol --- org-remark-icon.el | 30 ++++++++++++------ org-remark-line.el | 39 ++++++++++++++++++++--- org-remark.el | 93 ++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 117 insertions(+), 45 deletions(-) diff --git a/org-remark-icon.el b/org-remark-icon.el index bf324f9f30..7b68bce085 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: 01 August 2023 +;; Last modified: 03 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp @@ -133,16 +133,26 @@ 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) - (unless (string= "line" (overlay-get ov 'org-remark-type)) ;; icons added to line highlighters differently from normal ones. - (cl-flet ((add-icon-maybe (icon) - (cl-destructuring-bind - (icon-name pred default-face) icon - (when (funcall pred ov) - (org-remark-icon-propertize icon-name ov default-face))))) - (let ((icon-string - (mapconcat #'add-icon-maybe org-remark-icons))) - (when icon-string (overlay-put ov 'after-string icon-string))))))) + (cl-flet ((add-icon-maybe (icon) + (cl-destructuring-bind + (icon-name pred default-face) icon + (when (funcall pred ov) + (org-remark-icon-propertize icon-name ov default-face))))) + (let ((icon-string + (mapconcat #'add-icon-maybe org-remark-icons))) + (when icon-string (org-remark-icon-overlay-put + ov icon-string + (overlay-get ov 'org-remark-type))))))) + +(cl-defgeneric org-remark-icon-overlay-put (ov icon-string _org-remark-type) + "Default method to deal with icon. + This is used when a method specific \\='org-remark-type\\=' not + implemented." + (ignore)) + +(cl-defmethod org-remark-icon-overlay-put (ov icon-string (org-remark-type (eql nil))) + (overlay-put ov 'after-string icon-string)) (defun org-remark-icon-propertize (icon-name highlight default-face) "Return a propertized string. diff --git a/org-remark-line.el b/org-remark-line.el index 1512021c35..a306946c8d 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: 02 August 2023 +;; Last modified: 03 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp @@ -41,6 +41,8 @@ (defvar org-remark-line-icon "*") +(defvar org-remark-line-heading-title-max-length 40) + (defvar org-remark-line-ellipsis "…") (defun org-remark-line-pos-bol (pos) @@ -52,7 +54,7 @@ (defun org-remark-line-highlight-p (highlight) "Return t if HIGHLIGHT is one for the line. HIGHLIGHT is an overlay." - (string= "line" (overlay-get highlight 'org-remark-type))) + (eql 'line (overlay-get highlight 'org-remark-type))) (defun org-remark-line-find (&optional point) "Return the line-highight (overlay) of the current line. @@ -123,8 +125,37 @@ If the line is shorter than x, then up to the newline char." (string= line-text "")) "Empty line highlight" (setq line-text (string-trim-left line-text)) - (if (length< line-text 40) line-text - (concat (substring line-text 0 39) org-remark-line-ellipsis))))) + (if (length< line-text + (1+ org-remark-line-heading-title-max-length)) + line-text + (concat (substring line-text 0 org-remark-line-heading-title-max-length) + org-remark-line-ellipsis))))) + +(cl-defmethod org-remark-highlights-adjust-positions-p ((org-remark-type (eql 'line))) + nil) + +(cl-defmethod org-remark-highlights-housekeep-delete-p (_ov + (org-remark-type (eql 'line))) + "Always return nil when ORG-REMARK-TYPE is \\='line\\='. +Line-highlights are designed to be zero length with the start and +end of overlay being identical." + nil) + +(cl-defmethod org-remark-highlights-housekeep-remark-type (ov + (org-remark-type (eql 'line))) + "Ensure line-highlight OV is always at the beginning of line." + ;; if `pos-bol' is used to move, you can actually get the highlight to + ;; 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)))) + +;; (defun org-remark-line-inspect-overlay () +;; (interactive) +;; (car (overlays-in (point) (point)))) (provide 'org-remark-line) ;;; org-remark-line.el ends here diff --git a/org-remark.el b/org-remark.el index 437649b00d..c05623b144 100644 --- a/org-remark.el +++ b/org-remark.el @@ -1,4 +1,4 @@ -;;; org-remark.el --- Highlight & annotate any text files -*- lexical-binding: t; -*- + ;;; org-remark.el --- Highlight & annotate any text files -*- lexical-binding: t; -*- ;; Copyright (C) 2020-2023 Free Software Foundation, Inc. @@ -6,7 +6,7 @@ ;; URL: https://github.com/nobiot/org-remark ;; Version: 1.1.0 ;; Created: 22 December 2020 -;; Last modified: 02 August 2023 +;; Last modified: 03 August 2023 ;; Package-Requires: ((emacs "27.1") (org "9.4")) ;; Keywords: org-mode, annotation, note-taking, marginal-notes, wp, @@ -762,9 +762,9 @@ 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))) +;; (cl-defgeneric org-remark-highlight-mark-overlay (_org-remark-type)) -(cl-defmethod org-remark-highlight-mark-overlay (ov face (org-remark-type (eql nil))) +(cl-defmethod org-remark-highlight-mark-overlay (ov face (_org-remark-type (eql nil))) (overlay-put ov 'face (if face face 'org-remark-highlighter))) (defun org-remark-highlight-mark @@ -987,7 +987,7 @@ buffer for automatic sync." ;;; Return notes-props notes-props)) -(cl-defgeneric org-remark-highlight-headline-text ((org-remark-type))) +(cl-defgeneric org-remark-highlight-headline-text (_ov _org-remark-type)) (cl-defmethod org-remark-highlight-headline-text (ov (org-remark-type (eql nil))) "Assume it is called within `org-with-wide-buffer' of the source." @@ -1538,7 +1538,9 @@ Return t. This is a private function; house keep is automatically done on mark, save, and remove -- before sort-highlights. -Case 1. Both start and end of an overlay are identical +Case 1. Both start and end of an overlay are identical _and_ it's + not a line-highlight, which is designed to be zero length + with the start and end identical This should not happen when you manually mark a text region. A typical cause of this case is when you delete a @@ -1563,26 +1565,49 @@ Case 2. The overlay points to no buffer ;; 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) - (not (string= "line" (overlay-get ov 'org-remark-type))) - (= (overlay-start ov) (overlay-end ov))) - (when (and (not buffer-read-only) - (not (derived-mode-p 'special-mode))) - ;; Buffer-size 0 happens for a package like nov.el. It erases - ;; the buffer (size 0) and renders a new page in the same - ;; buffer. In this case, buffer is writable. - ;; - ;; TODO Relying on the current major mode being derived from - ;; special-mode may not be the best. - (org-remark-notes-remove (overlay-get ov 'org-remark-id))) - ;; Removing the notes here is meant to be to automatically remove - ;; notes when you delete a region that contains a higlight - ;; overlay. - (delete-overlay ov)) - (unless (overlay-buffer ov) - (setq org-remark-highlights (delete ov org-remark-highlights)))) + (let ((org-remark-type (overlay-get ov 'org-remark-type))) + (when (and (overlay-buffer ov) + (= (overlay-start ov) (overlay-end ov)) + (org-remark-highlights-housekeep-delete-p + ov org-remark-type)) + ;; When the buffer is writable and visitnig a file to change it. + ;; That is, a "normal" buffer. If it is writable and yet derived + ;; from a special mode, we consider the case to be in the + ;; rendering process of the mode, and thus do not want to put into + ;; the bin as part of housekeeping. + (when (and (not buffer-read-only) + (not (derived-mode-p 'special-mode))) + ;; Buffer-size 0 happens for a package like nov.el. It erases + ;; the buffer (size 0) and renders a new page in the same + ;; buffer. In this case, buffer is writable. + ;; + ;; TODO Relying on the current major mode being derived from + ;; special-mode may not be the best. + ;; Removing the notes here is meant to be to automatically remove + ;; notes when you delete a region that contains a higlight + ;; overlay. + (org-remark-notes-remove (overlay-get ov 'org-remark-id))) + (delete-overlay ov)) + ;; Before deleting `org-remark-highlights', add a handler per + ;; org-remark-type + (org-remark-highlights-housekeep-remark-type ov org-remark-type) + ;; Update `org-remark-highlights' by removing the deleted overlays + (unless (overlay-buffer ov) + (setq org-remark-highlights (delete ov org-remark-highlights))))) t) +(cl-defgeneric org-remark-highlights-housekeep-delete-p (_ov _org-remark-type) + "Additional predicate to delete during housekeep. +Default is always t. Implement method specific to +\\='\org-remark-type\=' and return nil the highlight must be +kept. + +The current buffer is source buffer." + t) + +(cl-defgeneric org-remark-highlights-housekeep-remark-type (_ov _org-remark-type) + (ignore)) + (defun org-remark-highlights-adjust-positions (overlays _notes-buf) "Run dolist and delgate the actual adjustment to another function. @@ -1597,15 +1622,21 @@ extensions." (let ((highlight-text (overlay-get ov '*org-remark-original-text))) ;; Check that the original text exists AND it is different to the ;; current text - (when (and highlight-text - (not (string= "line" (overlay-get ov 'org-remark-type))) - (not (org-remark-string= - highlight-text - (buffer-substring-no-properties - (overlay-start ov) (overlay-end ov))))) + (when + (and (org-remark-highlights-adjust-positions-p (overlay-get ov 'org-remark-type)) + highlight-text + (not (org-remark-string= + highlight-text + (buffer-substring-no-properties + (overlay-start ov) (overlay-end ov))))) (org-remark-highlight-adjust-position-after-load ov highlight-text))))) +(cl-defgeneric org-remark-highlights-adjust-positions-p (_org-remark-type) + "Return t if adjust-positions feature is relevant +Default is t and evaluated per ORG-REMARK-TYPE." + t) + ;;;;; Other utilities (defun org-remark-source-get-file-name (filename) @@ -1628,7 +1659,7 @@ If FILENAME is nil, return nil." ;; (run-hook-with-args-until-success ;; 'org-remark-beg-end-dwim-functions)) -(cl-defgeneric org-remark-beg-end (org-remark-type) +(cl-defgeneric org-remark-beg-end (_org-remark-type) (org-remark-region-or-word)) (defun org-remark-region-or-word ()