* [PATCH] Add mode for automatically unhiding emphasis markers in the current region @ 2020-06-01 14:14 Shankar Rao 2020-06-01 15:33 ` Shankar Rao 0 siblings, 1 reply; 16+ messages in thread From: Shankar Rao @ 2020-06-01 14:14 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 7251 bytes --] * lisp/org.el: (org-auto-emphasis-unhide-at-point): Parameter that controls the behavior of Org Auto Emphasis mode. It can be one of the values nil, t, and 'right-edge, and works similarly to the parameter `prettify-symbols-unprettify-at-point' for `prettify-symbols-mode'. (org-do-emphasis-faces): When hiding emphasis markers, add additional text properties 'org-emph-start and org-emph-end to the emphasized region. (org-auto-emphasis--current-region-bounds): Local variable containing the bounds of the region whose emphasis markers are currently unhidden. (org-auto-emphasis--get-prop-as-list): Helper function that returns Org Auto Emphasis properties as a list. (org-auto-emphasis--post-command-hook): Function added to `post-command-hook' that rehides emphasis markers for the previous region and unhides emphasis marks for the current region. (org-auto-emphasis-mode): Toggles Org Auto Emphasis mode. Can be added to `org-mode-hook' to be enabled for all org-mode files. This code was adapted from prettify-symbols-mode in prog-mode.el I have not yet signed the papers assigning copyright to the FSF. I sent a request for the papers to assign@gnu.org, but have not yet received a response. Shankar Rao --- lisp/org.el | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 7ff7ec685..870c5c958 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -3644,6 +3644,19 @@ following symbols: :type 'boolean :safe #'booleanp) +(defcustom org-auto-emphasis-unhide-at-point nil + "If non-nil, unhide the emphasis markers for the region when point is on it. +If set to the symbol `right-edge', also unhide the emphasis +markers if point is immediately after the emphasized region. The +emphasis markers will be rehidden as soon as point moves away +from the region. If set to nil, the emphasis markers remain +hidden even when point is in the region." + :version "25.1" + :type '(choice (const :tag "Never unhide emphasis markers" nil) + (const :tag "Unhide emphasis markers when point is inside" t) + (const :tag "Unhide emphasis markers when point is inside or at right edge" right-edge)) + :group 'org-appearance) + (defcustom org-hide-macro-markers nil "Non-nil mean font-lock should hide the brackets marking macro calls." :group 'org-appearance @@ -5056,12 +5069,77 @@ stacked delimiters is N. Escaping delimiters is not possible." '(font-lock-multiline t org-emphasis t)) (when (and org-hide-emphasis-markers (not (org-at-comment-p))) - (add-text-properties (match-end 4) (match-beginning 5) - '(invisible org-link)) - (add-text-properties (match-beginning 3) (match-end 3) - '(invisible org-link))) + (let ((s1 (match-beginning 3)) + (e1 (match-end 3)) + (s2 (match-end 4)) + (e2 (match-beginning 5))) + (add-text-properties s2 e2 '(invisible org-link)) + (add-text-properties s1 e1 '(invisible org-link)) + (add-text-properties s1 e2 + `(org-emph-start ,s1 org-emph-end ,e2)))) (throw :exit t)))))))) +(defvar-local org-auto-emphasis--current-region-bounds nil) + +(defun org-auto-emphasis--get-prop-as-list (prop) + "Helper function to get org-auto-emphasis properties as a list. +If `org-auto-emphasis-unhide-at-point' is set to `t' then return +the text property PROP at point in a list. If +`org-auto-emphasis-unhide-at-point' is set to `right-edge', the +also include the text property PROP at point-1 unless we are at +the beginning of the buffer." + (remove nil + (list (get-text-property (point) prop) + (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge) + (not (bobp))) + (get-text-property (1- (point)) prop))))) + +(defun org-auto-emphasis--post-command-hook () + ;; Rehide emphasis markers for the previous region. + (when (and org-auto-emphasis--current-region-bounds + (or (< (point) (car org-auto-emphasis--current-region-bounds)) + (> (point) (cadr org-auto-emphasis--current-region-bounds)) + (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge)) + (= (point) (cadr org-auto-emphasis--current-region-bounds))))) + (apply #'font-lock-flush org-auto-emphasis--current-region-bounds) + (setq org-auto-emphasis--current-region-bounds nil)) + ;; Unhide emphasis markers for the current region. + (when-let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start)) + (e (org-auto-emphasis--get-prop-as-list 'org-emph-end)) + (s (apply #'min s)) + (e (apply #'max e))) + (with-silent-modifications + (setq org-auto-emphasis--current-region-bounds (list s e)) + (remove-text-properties s (1+ s) '(invisible org-link)) + (remove-text-properties (1- e) e '(invisible org-link))))) + +(define-minor-mode org-auto-emphasis-mode + "Toggle Org Auto Emphasis mode. +This mode, when enabled, unhides emphasis markers for the region +at point, depending on the value of +`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG, +enable Org Auto Emphasis mode if ARG is positive, and disable it +otherwise. If called from Lisp, enable the mode if ARG is +omitted or nil. + +To enable this in all org-mode files, add the following line to init.el: + + (add-hook 'org-mode #'org-auto-emphasis-mode) +" + :init-value nil + (if org-auto-emphasis-mode + ;; Turn on + (progn + (setq-local font-lock-extra-managed-props + (append font-lock-extra-managed-props + '(org-emph-start org-emph-end))) + (when org-auto-emphasis-unhide-at-point + (add-hook 'post-command-hook + #'org-auto-emphasis--post-command-hook nil t)) + (font-lock-flush)) + ;; Turn off + (remove-hook 'post-command-hook #'org-auto-emphasis--post-command-hook t))) + (defun org-emphasize (&optional char) "Insert or change an emphasis, i.e. a font like bold or italic. If there is an active region, change that region to a new emphasis. @@ -20482,16 +20560,15 @@ With ARG, repeats or can move backward if negative." (beginning-of-line)) (_ nil))) (cl-incf arg)) - (while (and (> arg 0) (re-search-forward regexp nil t)) + (while (and (> arg 0) (re-search-forward regexp nil :move)) (pcase (get-char-property-and-overlay (point) 'invisible) (`(outline . ,o) (goto-char (overlay-end o)) - (skip-chars-forward " \t\n") - (end-of-line)) + (end-of-line 2)) (_ (end-of-line))) (cl-decf arg)) - (if (> arg 0) (goto-char (point-max)) (beginning-of-line)))) + (when (/= arg initial-arg) (beginning-of-line)))) (defun org-previous-visible-heading (arg) "Move to the previous visible heading. @@ -20830,11 +20907,10 @@ ones already marked." (set-mark (save-excursion (goto-char (mark)) - (goto-char (org-element-property :end (org-element-at-point))) - (point))) + (goto-char (org-element-property :end (org-element-at-point))))) (let ((element (org-element-at-point))) (end-of-line) - (push-mark (min (point-max) (org-element-property :end element)) t t) + (push-mark (org-element-property :end element) t t) (goto-char (org-element-property :begin element)))))) (defun org-narrow-to-element () -- 2.17.1 [-- Attachment #2: Type: text/html, Size: 8382 bytes --] ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-01 14:14 [PATCH] Add mode for automatically unhiding emphasis markers in the current region Shankar Rao @ 2020-06-01 15:33 ` Shankar Rao 2020-06-22 5:40 ` Kyle Meyer 0 siblings, 1 reply; 16+ messages in thread From: Shankar Rao @ 2020-06-01 15:33 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1.1: Type: text/plain, Size: 8252 bytes --] Sorry, I've never submitted a patch before. Looking through this mailing list, I see that you're supposed to attach the .patch file to the e-mail, so here it is. This patch adds a minor mode that makes emphasis markers be automatically unhidden when the point is inside the region of emphasis and then the markers are rehidden when the point is moved elsewhere. I posted this on /r/orgmode on reddit ( https://www.reddit.com/r/orgmode/comments/gss1g4/update_i_made_my_own_sbrorgemphasizemode_that/), and people there suggested that I submit this here as a patch. Shankar On Mon, Jun 1, 2020 at 4:14 PM Shankar Rao <shankar.rao@gmail.com> wrote: > * lisp/org.el: > (org-auto-emphasis-unhide-at-point): Parameter that controls the > behavior of Org Auto Emphasis mode. It can be one of the values nil, t, > and > 'right-edge, and works similarly to the parameter > `prettify-symbols-unprettify-at-point' for `prettify-symbols-mode'. > (org-do-emphasis-faces): When hiding emphasis markers, add additional > text properties 'org-emph-start and org-emph-end to the emphasized > region. > (org-auto-emphasis--current-region-bounds): Local variable containing > the bounds of the region whose emphasis markers are currently > unhidden. > (org-auto-emphasis--get-prop-as-list): Helper function that returns > Org Auto Emphasis properties as a list. > (org-auto-emphasis--post-command-hook): Function added to > `post-command-hook' that rehides emphasis markers for the previous > region and unhides emphasis marks for the current region. > (org-auto-emphasis-mode): Toggles Org Auto Emphasis mode. Can be > added to `org-mode-hook' to be enabled for all org-mode files. > > This code was adapted from prettify-symbols-mode in prog-mode.el > > I have not yet signed the papers assigning copyright to the FSF. I sent a > request for the papers to assign@gnu.org, but have not yet received a > response. > > Shankar Rao > > --- > lisp/org.el | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 87 insertions(+), 11 deletions(-) > > diff --git a/lisp/org.el b/lisp/org.el > index 7ff7ec685..870c5c958 100644 > --- a/lisp/org.el > +++ b/lisp/org.el > @@ -3644,6 +3644,19 @@ following symbols: > :type 'boolean > :safe #'booleanp) > > +(defcustom org-auto-emphasis-unhide-at-point nil > + "If non-nil, unhide the emphasis markers for the region when point is > on it. > +If set to the symbol `right-edge', also unhide the emphasis > +markers if point is immediately after the emphasized region. The > +emphasis markers will be rehidden as soon as point moves away > +from the region. If set to nil, the emphasis markers remain > +hidden even when point is in the region." > + :version "25.1" > + :type '(choice (const :tag "Never unhide emphasis markers" nil) > + (const :tag "Unhide emphasis markers when point is > inside" t) > + (const :tag "Unhide emphasis markers when point is > inside or at right edge" right-edge)) > + :group 'org-appearance) > + > (defcustom org-hide-macro-markers nil > "Non-nil mean font-lock should hide the brackets marking macro calls." > :group 'org-appearance > @@ -5056,12 +5069,77 @@ stacked delimiters is N. Escaping delimiters is > not possible." > '(font-lock-multiline t org-emphasis t)) > (when (and org-hide-emphasis-markers > (not (org-at-comment-p))) > - (add-text-properties (match-end 4) (match-beginning 5) > - '(invisible org-link)) > - (add-text-properties (match-beginning 3) (match-end 3) > - '(invisible org-link))) > + (let ((s1 (match-beginning 3)) > + (e1 (match-end 3)) > + (s2 (match-end 4)) > + (e2 (match-beginning 5))) > + (add-text-properties s2 e2 '(invisible org-link)) > + (add-text-properties s1 e1 '(invisible org-link)) > + (add-text-properties s1 e2 > + `(org-emph-start ,s1 org-emph-end ,e2)))) > (throw :exit t)))))))) > > +(defvar-local org-auto-emphasis--current-region-bounds nil) > + > +(defun org-auto-emphasis--get-prop-as-list (prop) > + "Helper function to get org-auto-emphasis properties as a list. > +If `org-auto-emphasis-unhide-at-point' is set to `t' then return > +the text property PROP at point in a list. If > +`org-auto-emphasis-unhide-at-point' is set to `right-edge', the > +also include the text property PROP at point-1 unless we are at > +the beginning of the buffer." > + (remove nil > + (list (get-text-property (point) prop) > + (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge) > + (not (bobp))) > + (get-text-property (1- (point)) prop))))) > + > +(defun org-auto-emphasis--post-command-hook () > + ;; Rehide emphasis markers for the previous region. > + (when (and org-auto-emphasis--current-region-bounds > + (or (< (point) (car org-auto-emphasis--current-region-bounds)) > + (> (point) (cadr org-auto-emphasis--current-region-bounds)) > + (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge)) > + (= (point) (cadr org-auto-emphasis--current-region-bounds))))) > + (apply #'font-lock-flush org-auto-emphasis--current-region-bounds) > + (setq org-auto-emphasis--current-region-bounds nil)) > + ;; Unhide emphasis markers for the current region. > + (when-let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start)) > + (e (org-auto-emphasis--get-prop-as-list 'org-emph-end)) > + (s (apply #'min s)) > + (e (apply #'max e))) > + (with-silent-modifications > + (setq org-auto-emphasis--current-region-bounds (list s e)) > + (remove-text-properties s (1+ s) '(invisible org-link)) > + (remove-text-properties (1- e) e '(invisible org-link))))) > + > +(define-minor-mode org-auto-emphasis-mode > + "Toggle Org Auto Emphasis mode. > +This mode, when enabled, unhides emphasis markers for the region > +at point, depending on the value of > +`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG, > +enable Org Auto Emphasis mode if ARG is positive, and disable it > +otherwise. If called from Lisp, enable the mode if ARG is > +omitted or nil. > + > +To enable this in all org-mode files, add the following line to init.el: > + > + (add-hook 'org-mode #'org-auto-emphasis-mode) > +" > + :init-value nil > + (if org-auto-emphasis-mode > + ;; Turn on > + (progn > + (setq-local font-lock-extra-managed-props > + (append font-lock-extra-managed-props > + '(org-emph-start org-emph-end))) > + (when org-auto-emphasis-unhide-at-point > + (add-hook 'post-command-hook > + #'org-auto-emphasis--post-command-hook nil t)) > + (font-lock-flush)) > + ;; Turn off > + (remove-hook 'post-command-hook > #'org-auto-emphasis--post-command-hook t))) > + > (defun org-emphasize (&optional char) > "Insert or change an emphasis, i.e. a font like bold or italic. > If there is an active region, change that region to a new emphasis. > @@ -20482,16 +20560,15 @@ With ARG, repeats or can move backward if > negative." > (beginning-of-line)) > (_ nil))) > (cl-incf arg)) > - (while (and (> arg 0) (re-search-forward regexp nil t)) > + (while (and (> arg 0) (re-search-forward regexp nil :move)) > (pcase (get-char-property-and-overlay (point) 'invisible) > (`(outline . ,o) > (goto-char (overlay-end o)) > - (skip-chars-forward " \t\n") > - (end-of-line)) > + (end-of-line 2)) > (_ > (end-of-line))) > (cl-decf arg)) > - (if (> arg 0) (goto-char (point-max)) (beginning-of-line)))) > + (when (/= arg initial-arg) (beginning-of-line)))) > > (defun org-previous-visible-heading (arg) > "Move to the previous visible heading. > @@ -20830,11 +20907,10 @@ ones already marked." > (set-mark > (save-excursion > (goto-char (mark)) > - (goto-char (org-element-property :end (org-element-at-point))) > - (point))) > + (goto-char (org-element-property :end (org-element-at-point))))) > (let ((element (org-element-at-point))) > (end-of-line) > - (push-mark (min (point-max) (org-element-property :end element)) t t) > + (push-mark (org-element-property :end element) t t) > (goto-char (org-element-property :begin element)))))) > > (defun org-narrow-to-element () > -- > 2.17.1 > [-- Attachment #1.2: Type: text/html, Size: 9508 bytes --] [-- Attachment #2: 0001-Add-mode-for-automatically-unhiding-emphasis-markers.patch --] [-- Type: application/octet-stream, Size: 7404 bytes --] From c1af9efbad7993deb5c483979b7624edf8b26e8d Mon Sep 17 00:00:00 2001 From: Shankar Rao <shankar.rao@gmail.com> Date: Mon, 1 Jun 2020 14:42:51 +0200 Subject: [PATCH] Add mode for automatically unhiding emphasis markers in the current region * lisp/org.el: (org-auto-emphasis-unhide-at-point): Parameter that controls the behavior of Org Auto Emphasis mode. It can be one of the values nil, t, and 'right-edge, and works similarly to the parameter `prettify-symbols-unprettify-at-point' for `prettify-symbols-mode'. (org-do-emphasis-faces): When hiding emphasis markers, add additional text properties 'org-emph-start and org-emph-end to the emphasized region. (org-auto-emphasis--current-region-bounds): Local variable containing the bounds of the region whose emphasis markers are currently unhidden. (org-auto-emphasis--get-prop-as-list): Helper function that returns Org Auto Emphasis properties as a list. (org-auto-emphasis--post-command-hook): Function added to `post-command-hook' that rehides emphasis markers for the previous region and unhides emphasis marks for the current region. (org-auto-emphasis-mode): Toggles Org Auto Emphasis mode. Can be added to `org-mode-hook' to be enabled for all org-mode files. This code was adapted from prettify-symbols-mode in prog-mode.el --- lisp/org.el | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 7ff7ec685..870c5c958 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -3644,6 +3644,19 @@ following symbols: :type 'boolean :safe #'booleanp) +(defcustom org-auto-emphasis-unhide-at-point nil + "If non-nil, show the unhide the emphasis markers for the region when point is on it. +If set to the symbol `right-edge', also unhide the emphasis +markers if point is immediately after the emphasized region. The +emphasis markers will be rehidden as soon as point moves away +from the region. If set to nil, the emphasis markers remain +hidden even when point is in the region." + :version "25.1" + :type '(choice (const :tag "Never unhide emphasis markers" nil) + (const :tag "Unhide emphasis markers when point is inside" t) + (const :tag "Unhide emphasis markers when point is inside or at right edge" right-edge)) + :group 'org-appearance) + (defcustom org-hide-macro-markers nil "Non-nil mean font-lock should hide the brackets marking macro calls." :group 'org-appearance @@ -5056,12 +5069,77 @@ stacked delimiters is N. Escaping delimiters is not possible." '(font-lock-multiline t org-emphasis t)) (when (and org-hide-emphasis-markers (not (org-at-comment-p))) - (add-text-properties (match-end 4) (match-beginning 5) - '(invisible org-link)) - (add-text-properties (match-beginning 3) (match-end 3) - '(invisible org-link))) + (let ((s1 (match-beginning 3)) + (e1 (match-end 3)) + (s2 (match-end 4)) + (e2 (match-beginning 5))) + (add-text-properties s2 e2 '(invisible org-link)) + (add-text-properties s1 e1 '(invisible org-link)) + (add-text-properties s1 e2 + `(org-emph-start ,s1 org-emph-end ,e2)))) (throw :exit t)))))))) +(defvar-local org-auto-emphasis--current-region-bounds nil) + +(defun org-auto-emphasis--get-prop-as-list (prop) + "Helper function to get org-auto-emphasis properties as a list. +If `org-auto-emphasis-unhide-at-point' is set to `t' then return +the text property PROP at point in a list. If +`org-auto-emphasis-unhide-at-point' is set to `right-edge', the +also include the text property PROP at point-1 unless we are at +the beginning of the buffer." + (remove nil + (list (get-text-property (point) prop) + (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge) + (not (bobp))) + (get-text-property (1- (point)) prop))))) + +(defun org-auto-emphasis--post-command-hook () + ;; Rehide emphasis markers for the previous region. + (when (and org-auto-emphasis--current-region-bounds + (or (< (point) (car org-auto-emphasis--current-region-bounds)) + (> (point) (cadr org-auto-emphasis--current-region-bounds)) + (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge)) + (= (point) (cadr org-auto-emphasis--current-region-bounds))))) + (apply #'font-lock-flush org-auto-emphasis--current-region-bounds) + (setq org-auto-emphasis--current-region-bounds nil)) + ;; Unhide emphasis markers for the current region. + (when-let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start)) + (e (org-auto-emphasis--get-prop-as-list 'org-emph-end)) + (s (apply #'min s)) + (e (apply #'max e))) + (with-silent-modifications + (setq org-auto-emphasis--current-region-bounds (list s e)) + (remove-text-properties s (1+ s) '(invisible org-link)) + (remove-text-properties (1- e) e '(invisible org-link))))) + +(define-minor-mode org-auto-emphasis-mode + "Toggle Org Auto Emphasis mode. +This mode, when enabled, unhides emphasis markers for the region +at point, depending on the value of +`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG, +enable Org Auto Emphasis mode if ARG is positive, and disable it +otherwise. If called from Lisp, enable the mode if ARG is +omitted or nil. + +To enable this in all org-mode files, add the following line to init.el: + + (add-hook 'org-mode #'org-auto-emphasis-mode) +" + :init-value nil + (if org-auto-emphasis-mode + ;; Turn on + (progn + (setq-local font-lock-extra-managed-props + (append font-lock-extra-managed-props + '(org-emph-start org-emph-end))) + (when org-auto-emphasis-unhide-at-point + (add-hook 'post-command-hook + #'org-auto-emphasis--post-command-hook nil t)) + (font-lock-flush)) + ;; Turn off + (remove-hook 'post-command-hook #'org-auto-emphasis--post-command-hook t))) + (defun org-emphasize (&optional char) "Insert or change an emphasis, i.e. a font like bold or italic. If there is an active region, change that region to a new emphasis. @@ -20482,16 +20560,15 @@ With ARG, repeats or can move backward if negative." (beginning-of-line)) (_ nil))) (cl-incf arg)) - (while (and (> arg 0) (re-search-forward regexp nil t)) + (while (and (> arg 0) (re-search-forward regexp nil :move)) (pcase (get-char-property-and-overlay (point) 'invisible) (`(outline . ,o) (goto-char (overlay-end o)) - (skip-chars-forward " \t\n") - (end-of-line)) + (end-of-line 2)) (_ (end-of-line))) (cl-decf arg)) - (if (> arg 0) (goto-char (point-max)) (beginning-of-line)))) + (when (/= arg initial-arg) (beginning-of-line)))) (defun org-previous-visible-heading (arg) "Move to the previous visible heading. @@ -20830,11 +20907,10 @@ ones already marked." (set-mark (save-excursion (goto-char (mark)) - (goto-char (org-element-property :end (org-element-at-point))) - (point))) + (goto-char (org-element-property :end (org-element-at-point))))) (let ((element (org-element-at-point))) (end-of-line) - (push-mark (min (point-max) (org-element-property :end element)) t t) + (push-mark (org-element-property :end element) t t) (goto-char (org-element-property :begin element)))))) (defun org-narrow-to-element () -- 2.17.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-01 15:33 ` Shankar Rao @ 2020-06-22 5:40 ` Kyle Meyer 2020-06-22 11:25 ` Gustavo Barros 0 siblings, 1 reply; 16+ messages in thread From: Kyle Meyer @ 2020-06-22 5:40 UTC (permalink / raw) To: Shankar Rao; +Cc: emacs-orgmode Thanks for the patch, and sorry for the slow reply. Shankar Rao writes: > Sorry, I've never submitted a patch before. Looking through this mailing > list, I see that you're supposed to attach the .patch file to the e-mail, > so here it is. Inline is fine as well, though it can take a little more work on the sender's end to make sure that the patch doesn't get mangled by their mail client and that the commit message is formatted correctly. > This patch adds a minor mode that makes emphasis markers be automatically > unhidden when the point is inside the region of emphasis and then the > markers are rehidden when the point is moved elsewhere. I posted this on > /r/orgmode on reddit ( > https://www.reddit.com/r/orgmode/comments/gss1g4/update_i_made_my_own_sbrorgemphasizemode_that/), > and people there suggested that I submit this here as a patch. I don't prefer my emphasis markers hidden (i.e. I leave org-hide-emphasis-markers at nil), so perhaps I'm not the best to judge, but that does sound like a nice feature. I'm hoping others will try this out and give their thoughts. > On Mon, Jun 1, 2020 at 4:14 PM Shankar Rao <shankar.rao@gmail.com> wrote: [...] >> >> This code was adapted from prettify-symbols-mode in prog-mode.el >> >> I have not yet signed the papers assigning copyright to the FSF. I sent a >> request for the papers to assign@gnu.org, but have not yet received a >> response. Are you still waiting for a response? > Subject: [PATCH] Add mode for automatically unhiding emphasis markers in the > current region [...] > lisp/org.el | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 87 insertions(+), 11 deletions(-) > > diff --git a/lisp/org.el b/lisp/org.el > index 7ff7ec685..870c5c958 100644 Note that this no longer applies to the current master due to a conflict with b68090e0b (2020-06-04). I applied this to b68090e0b^ to try this out, and it seems to work as advertised. Here are some comments from an initial read-through. > --- a/lisp/org.el > +++ b/lisp/org.el > @@ -3644,6 +3644,19 @@ following symbols: > :type 'boolean > :safe #'booleanp) > > +(defcustom org-auto-emphasis-unhide-at-point nil > + "If non-nil, show the unhide the emphasis markers for the region when point is on it. s/show the// ? Also, I find using "region" here (and elsewhere) a little confusing. Perhaps something like "unhide the emphasis markers for the text at point" instead? > +If set to the symbol `right-edge', also unhide the emphasis > +markers if point is immediately after the emphasized region. The > +emphasis markers will be rehidden as soon as point moves away > +from the region. If set to nil, the emphasis markers remain > +hidden even when point is in the region." > + :version "25.1" This can instead be :package-version '(Org . "9.5") Emacs can then use customize-package-emacs-version-alist to map to the Emacs version. (The next release will be v9.4, but we're in a feature freeze at the moment.) > + :type '(choice (const :tag "Never unhide emphasis markers" nil) Hmm, I don't see the point of having a nil value. That already seems covered by toggling org-auto-emphasis-mode on and off. I also wonder whether we can get away with not having an option here at all. Is one of the below values more likely to be the predominant preference? > + (const :tag "Unhide emphasis markers when point is inside" t) > + (const :tag "Unhide emphasis markers when point is inside or at right edge" right-edge)) IMO these descriptions could be more concise but as clear by dropping "emphasis markers" from the t and right-edge items. > +(defvar-local org-auto-emphasis--current-region-bounds nil) > + > +(defun org-auto-emphasis--get-prop-as-list (prop) > + "Helper function to get org-auto-emphasis properties as a list. > +If `org-auto-emphasis-unhide-at-point' is set to `t' then return convention nit: Drop quotes from t. > +(defun org-auto-emphasis--post-command-hook () > + ;; Rehide emphasis markers for the previous region. > + (when (and org-auto-emphasis--current-region-bounds > + (or (< (point) (car org-auto-emphasis--current-region-bounds)) > + (> (point) (cadr org-auto-emphasis--current-region-bounds)) > + (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge)) > + (= (point) (cadr org-auto-emphasis--current-region-bounds))))) > + (apply #'font-lock-flush org-auto-emphasis--current-region-bounds) > + (setq org-auto-emphasis--current-region-bounds nil)) > + ;; Unhide emphasis markers for the current region. > + (when-let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start)) Our minimum supported Emacs version is 24.3, so we can't rely on when-let and friends being available. > +(define-minor-mode org-auto-emphasis-mode > + "Toggle Org Auto Emphasis mode. > +This mode, when enabled, unhides emphasis markers for the region > +at point, depending on the value of > +`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG, > +enable Org Auto Emphasis mode if ARG is positive, and disable it > +otherwise. If called from Lisp, enable the mode if ARG is > +omitted or nil. > + > +To enable this in all org-mode files, add the following line to init.el: nit: s/org-mode/Org/ > + > + (add-hook 'org-mode #'org-auto-emphasis-mode) You should protect the apostrophes as \\=' so that they aren't rendered according to text-quoting-style. > (defun org-emphasize (&optional char) > "Insert or change an emphasis, i.e. a font like bold or italic. > If there is an active region, change that region to a new emphasis. > @@ -20482,16 +20560,15 @@ With ARG, repeats or can move backward if negative." > (beginning-of-line)) > (_ nil))) > (cl-incf arg)) > - (while (and (> arg 0) (re-search-forward regexp nil t)) > + (while (and (> arg 0) (re-search-forward regexp nil :move)) > (pcase (get-char-property-and-overlay (point) 'invisible) > (`(outline . ,o) > (goto-char (overlay-end o)) > - (skip-chars-forward " \t\n") > - (end-of-line)) > + (end-of-line 2)) > (_ > (end-of-line))) > (cl-decf arg)) > - (if (> arg 0) (goto-char (point-max)) (beginning-of-line)))) > + (when (/= arg initial-arg) (beginning-of-line)))) Can you explain why this change to org-next-visible-heading and... > > (defun org-previous-visible-heading (arg) > "Move to the previous visible heading. > @@ -20830,11 +20907,10 @@ ones already marked." > (set-mark > (save-excursion > (goto-char (mark)) > - (goto-char (org-element-property :end (org-element-at-point))) > - (point))) > + (goto-char (org-element-property :end (org-element-at-point))))) > (let ((element (org-element-at-point))) > (end-of-line) > - (push-mark (min (point-max) (org-element-property :end element)) t t) > + (push-mark (org-element-property :end element) t t) > (goto-char (org-element-property :begin element)))))) ... this change to org-mark-element are related/needed? ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-22 5:40 ` Kyle Meyer @ 2020-06-22 11:25 ` Gustavo Barros 2020-06-23 0:07 ` Kyle Meyer 0 siblings, 1 reply; 16+ messages in thread From: Gustavo Barros @ 2020-06-22 11:25 UTC (permalink / raw) To: Kyle Meyer; +Cc: emacs-orgmode, Shankar Rao Hi Kyle, Hi Shankar, On Mon, 22 Jun 2020 at 05:40, Kyle Meyer <kyle@kyleam.com> wrote: > Shankar Rao writes: > >> This patch adds a minor mode that makes emphasis markers be automatically >> unhidden when the point is inside the region of emphasis and then the >> markers are rehidden when the point is moved elsewhere. I posted this on >> /r/orgmode on reddit ( >> https://www.reddit.com/r/orgmode/comments/gss1g4/update_i_made_my_own_sbrorgemphasizemode_that/), >> and people there suggested that I submit this here as a patch. > > I don't prefer my emphasis markers hidden (i.e. I leave > org-hide-emphasis-markers at nil), so perhaps I'm not the best to judge, > but that does sound like a nice feature. > > I'm hoping others will try this out and give their thoughts. Just an user here, but I'd like to leave my +1 to this proposed feature. I did use org-hide-emphasis-markers in the past and I liked it, but eventually dropped it because of the inconveniences of editing at the border of an emphasized region. This proposed feature eliminates the "which side of the invisible character are we?" ambiguity, so I repute it very nice indeed. I would certainly appreciate the inclusion of such a feature and, since I've been around, I've seen folks demanding something of the sort (memory here, no hard data). Indeed, I was one of the people at Reddit who suggested Shankar submitted this to the list. I did (lightly) test the code as posted on Reddit, and liked what I saw. I tried a number of cases I could think of: multiple lines, nested emphasis markers etc. As far as I tried, it did work as advertised. I also did report a corner case I found: > The only edge case I found, which in no way mars the absolute coolness > of this, is when you are actually inserting the emphasis marker. For > example, if you type *word*. Right after you type the last "*" the > emphasis will be hidden, even though the point position would have it to > be shown. Same thing if you select word and "C-c C-x C-f *". You have to > actually move point, for the mode to work in this situation. Shankar replied me this behavior is the same in prettify-symbols-mode, on which the code is based. I do not use prettify-symbols-mode myself, but did play with it a little because of this, and could not infer a regularity, so I must trust Shankar's point here. And it is indeed just a corner situation, which has no further implication I can conceive, and which does not diminish the usefulness of the feature. I can add another thought on the matter. While prettify-symbols is a mode, org-hide-emphasis-markers is an option/variable. So I wonder if the feature would fit better the current state of things in Org as either another option/defcustom or by simply expanding the range of possible values for org-hide-emphasis-markers (e.g. t, nil, not-at-point, not-at-point-right-edge). But this is just a thought, I'd be happy to see this feature be included either way. So, thanks Shankar for proposing the patch, and thanks Kyle for reviewing it. HTH. Best, Gustavo. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-22 11:25 ` Gustavo Barros @ 2020-06-23 0:07 ` Kyle Meyer 2020-06-24 12:53 ` Shankar Rao 0 siblings, 1 reply; 16+ messages in thread From: Kyle Meyer @ 2020-06-23 0:07 UTC (permalink / raw) To: Gustavo Barros; +Cc: emacs-orgmode, Shankar Rao Gustavo Barros writes: > Just an user here, but I'd like to leave my +1 to this proposed feature. > [...] Thanks. That's very useful feedback. > I can add another thought on the matter. While prettify-symbols is a > mode, org-hide-emphasis-markers is an option/variable. So I wonder if > the feature would fit better the current state of things in Org as > either another option/defcustom or by simply expanding the range of > possible values for org-hide-emphasis-markers (e.g. t, nil, > not-at-point, not-at-point-right-edge). But this is just a thought, I'd > be happy to see this feature be included either way. Hmm, yeah, that's worth thinking about. I mentioned eliminating the org-auto-emphasis-unhide-at-point option, but I didn't consider doing it by absorbing the values into org-hide-emphasis-markers and dropping the mode. Given what org-auto-emphasis-mode does underneath, though, it does fit quite neatly into a minor mode toggle. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-23 0:07 ` Kyle Meyer @ 2020-06-24 12:53 ` Shankar Rao 2020-06-24 13:49 ` Gustavo Barros 0 siblings, 1 reply; 16+ messages in thread From: Shankar Rao @ 2020-06-24 12:53 UTC (permalink / raw) To: Kyle Meyer; +Cc: emacs-orgmode, Gustavo Barros [-- Attachment #1.1: Type: text/plain, Size: 9320 bytes --] Kyle, Gustavo, Thank you both for your detailed feedback. Attached is a new version of the patch that incorporates most of your suggestions. >> I have not yet signed the papers assigning copyright to the FSF. I sent > a > >> request for the papers to assign@gnu.org, but have not yet received a > >> response. > > Are you still waiting for a response? > I received an assignment form from the FSF and I just now signed it and sent it back to them. > + :type '(choice (const :tag "Never unhide emphasis markers" nil) > > Hmm, I don't see the point of having a nil value. That already seems > covered by toggling org-auto-emphasis-mode on and off. > > I also wonder whether we can get away with not having an option here at > all. Is one of the below values more likely to be the predominant > preference? > This mimics the behavior of prettify-symbols-mode. org-auto-emphasis-unhide-at-point and org-auto-emphasis-mode correspond to prettify-symbols-unprettify-at-point and global-prettify-symbols-mode, respectively. So in the same way, one could enable prettify-symbols-mode globally with (global-prettify-symbols-mode +1) and also have (setq prettify-symbols-unprettify-at-point nil), which would effectively still keep it disabled. I'm amenable to simplifying or eliminating the option entirely. In my use I find the 'right-edge setting to be more useful that the t setting, but the behavior for t might be more intuitive to users. If I had to pick one option, I would choose 'right-edge. > I can add another thought on the matter. While prettify-symbols is a > > mode, org-hide-emphasis-markers is an option/variable. So I wonder if > > the feature would fit better the current state of things in Org as > > either another option/defcustom or by simply expanding the range of > > possible values for org-hide-emphasis-markers (e.g. t, nil, > > not-at-point, not-at-point-right-edge). But this is just a thought, I'd > > be happy to see this feature be included either way. > > Hmm, yeah, that's worth thinking about. I mentioned eliminating the > org-auto-emphasis-unhide-at-point option, but I didn't consider doing it > by absorbing the values into org-hide-emphasis-markers and dropping the > mode. Given what org-auto-emphasis-mode does underneath, though, it > does fit quite neatly into a minor mode toggle. > I agree that adding this functionality as additional options to org-hide-emphasis-markers would be more intuitive and elegant for users, as they wouldn't have to perform (add-hook 'org-mode #'org-auto-emphasis-mode) in order to enable this mode. I didn't implement it this way first because I wanted to make the simplest, least disruptive way possible, and secondly because I didn't quite know how to implement it :-). As you can see in the patch, besides the additional functions and variables, my code only modifies one preexisting org function, replacing four lines with my new eight lines. To implement this functionality in the way Gustavo suggests, we would have to for all users add org-auto-emphasis--post-command-hook to post-command-hook, and modify it so that it only operates when org-hide-emphasis-markers is 'not-at-point or 'not-at-point-right-edge. I can try to implement this if you think it would be a good idea, but I have one concern. Even if a user is not interested in org-auto-emphasis-mode, this implementation would add a small amount of code to post-command-hook, so would have the effect of slightly slowing down their system. Shankar On Tue, Jun 23, 2020 at 2:07 AM Kyle Meyer <kyle@kyleam.com> wrote: > Gustavo Barros writes: > > > Just an user here, but I'd like to leave my +1 to this proposed feature. > > [...] > > Thanks. That's very useful feedback. > > > I can add another thought on the matter. While prettify-symbols is a > > mode, org-hide-emphasis-markers is an option/variable. So I wonder if > > the feature would fit better the current state of things in Org as > > either another option/defcustom or by simply expanding the range of > > possible values for org-hide-emphasis-markers (e.g. t, nil, > > not-at-point, not-at-point-right-edge). But this is just a thought, I'd > > be happy to see this feature be included either way. > > Hmm, yeah, that's worth thinking about. I mentioned eliminating the > org-auto-emphasis-unhide-at-point option, but I didn't consider doing it > by absorbing the values into org-hide-emphasis-markers and dropping the > mode. Given what org-auto-emphasis-mode does underneath, though, it > does fit quite neatly into a minor mode toggle. > --- lisp/org.el | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index 4d46b4173..8bab33ec0 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -3644,6 +3644,19 @@ following symbols: :type 'boolean :safe #'booleanp) +(defcustom org-auto-emphasis-unhide-at-point nil + "If non-nil, unhide the emphasis markers for the text at point. +If set to the symbol `right-edge', also unhide the emphasis +markers if point is immediately after the emphasized text. The +emphasis markers will be rehidden as soon as point moves away +from the emphasized text. If set to nil, the emphasis markers +always remain hidden." + :package-version '(Org . "9.5") + :type '(choice (const :tag "Never unhide emphasis markers" nil) + (const :tag "Unhide when point is inside" t) + (const :tag "Unhide when point is inside or at right edge" right-edge)) + :group 'org-appearance) + (defcustom org-hide-macro-markers nil "Non-nil mean font-lock should hide the brackets marking macro calls." :group 'org-appearance @@ -5055,12 +5068,78 @@ stacked delimiters is N. Escaping delimiters is not possible." '(font-lock-multiline t org-emphasis t)) (when (and org-hide-emphasis-markers (not (org-at-comment-p))) - (add-text-properties (match-end 4) (match-beginning 5) - '(invisible org-link)) - (add-text-properties (match-beginning 3) (match-end 3) - '(invisible org-link))) + (let ((s1 (match-beginning 3)) + (e1 (match-end 3)) + (s2 (match-end 4)) + (e2 (match-beginning 5))) + (add-text-properties s2 e2 '(invisible org-link)) + (add-text-properties s1 e1 '(invisible org-link)) + (add-text-properties s1 e2 + `(org-emph-start ,s1 org-emph-end ,e2)))) (throw :exit t)))))))) +(defvar-local org-auto-emphasis--current-region-bounds nil) + +(defun org-auto-emphasis--get-prop-as-list (prop) + "Helper function to get org-auto-emphasis properties as a list. +If `org-auto-emphasis-unhide-at-point' is set to t, then return +the text property PROP at point in a list. If +`org-auto-emphasis-unhide-at-point' is set to `right-edge', the +also include the text property PROP at point-1 unless we are at +the beginning of the buffer." + (remove nil + (list (get-text-property (point) prop) + (when (and (eq org-auto-emphasis-unhide-at-point 'right-edge) + (not (bobp))) + (get-text-property (1- (point)) prop))))) + +(defun org-auto-emphasis--post-command-hook () + ;; Rehide emphasis markers for the previous region. + (when (and org-auto-emphasis--current-region-bounds + (or (< (point) (car org-auto-emphasis--current-region-bounds)) + (> (point) (cadr org-auto-emphasis--current-region-bounds)) + (and (not (eq org-auto-emphasis-unhide-at-point 'right-edge)) + (= (point) (cadr org-auto-emphasis--current-region-bounds))))) + (apply #'font-lock-flush org-auto-emphasis--current-region-bounds) + (setq org-auto-emphasis--current-region-bounds nil)) + ;; Unhide emphasis markers for the current region. + (let* ((s (org-auto-emphasis--get-prop-as-list 'org-emph-start)) + (e (and s (org-auto-emphasis--get-prop-as-list 'org-emph-end))) + (s (and e (apply #'min s))) + (e (and s (apply #'max e)))) + (when e + (with-silent-modifications + (setq org-auto-emphasis--current-region-bounds (list s e)) + (remove-text-properties s (1+ s) '(invisible org-link)) + (remove-text-properties (1- e) e '(invisible org-link)))))) + +(define-minor-mode org-auto-emphasis-mode + "Toggle Org Auto Emphasis mode. +This mode, when enabled, unhides emphasis markers for the text +at point, depending on the value of +`org-auto-emphasis-unhide-at-point'. With a prefix argument ARG, +enable Org Auto Emphasis mode if ARG is positive, and disable it +otherwise. If called from Lisp, enable the mode if ARG is +omitted or nil. + +To enable this in all Org files, add the following line to init.el: + + (add-hook \\='org-mode #\\='org-auto-emphasis-mode) +" + :init-value nil + (if org-auto-emphasis-mode + ;; Turn on + (progn + (setq-local font-lock-extra-managed-props + (append font-lock-extra-managed-props + '(org-emph-start org-emph-end))) + (when org-auto-emphasis-unhide-at-point + (add-hook 'post-command-hook + #'org-auto-emphasis--post-command-hook nil t)) + (font-lock-flush)) + ;; Turn off + (remove-hook 'post-command-hook #'org-auto-emphasis--post-command-hook t))) + (defun org-emphasize (&optional char) "Insert or change an emphasis, i.e. a font like bold or italic. If there is an active region, change that region to a new emphasis. -- 2.17.1 [-- Attachment #1.2: Type: text/html, Size: 11499 bytes --] [-- Attachment #2: 0001-Add-mode-for-automatically-unhiding-emphasis-markers.patch --] [-- Type: application/x-patch, Size: 6102 bytes --] ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-24 12:53 ` Shankar Rao @ 2020-06-24 13:49 ` Gustavo Barros 2020-06-24 15:46 ` Nicolas Goaziou 0 siblings, 1 reply; 16+ messages in thread From: Gustavo Barros @ 2020-06-24 13:49 UTC (permalink / raw) To: Shankar Rao; +Cc: emacs-orgmode Hi Shankar, Detailed comments are up for Kyle, or someone more qualified than myself, but I leave one further comment regarding the suggestion I had made. On Wed, 24 Jun 2020 at 09:53, Shankar Rao <shankar.rao@gmail.com> wrote: > I agree that adding this functionality as additional options to > org-hide-emphasis-markers would be more intuitive and elegant for > users, as > they wouldn't have to perform (add-hook 'org-mode > #'org-auto-emphasis-mode) in order to enable this mode. I didn't > implement > it this way first because I wanted to make the simplest, least > disruptive > way possible, and secondly because I didn't quite know how to > implement it > :-). As you can see in the patch, besides the additional functions and > variables, my code only modifies one preexisting org function, > replacing > four lines with my new eight lines. > > To implement this functionality in the way Gustavo suggests, we would > have > to for all users add org-auto-emphasis--post-command-hook to > post-command-hook, and modify it so that it only operates when > org-hide-emphasis-markers is 'not-at-point or > 'not-at-point-right-edge. I > can try to implement this if you think it would be a good idea, but I > have > one concern. Even if a user is not interested in > org-auto-emphasis-mode, > this implementation would add a small amount of code to > post-command-hook, > so would have the effect of slightly slowing down their system. You have a good point here. When I made the suggestion I was naively thinking the featured could be plugged/hooked somewhere in Org, when fontification is done. But that's not really true, as the feature requires being run every time the point moves too. So, as far as I can tell, it seems using post-command-hook is unavoidable, and if so, you are right in not wanting to add some load to it for everyone, regardless of whether they want this feature or not. You and Kyle have me convinced here. And thanks again! Best, Gustavo. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-24 13:49 ` Gustavo Barros @ 2020-06-24 15:46 ` Nicolas Goaziou 2020-06-24 16:34 ` Shankar Rao 2020-06-24 17:27 ` Gustavo Barros 0 siblings, 2 replies; 16+ messages in thread From: Nicolas Goaziou @ 2020-06-24 15:46 UTC (permalink / raw) To: Gustavo Barros; +Cc: emacs-orgmode, Shankar Rao Hello, Gustavo Barros <gusbrs.2016@gmail.com> writes: > You have a good point here. When I made the suggestion I was naively > thinking the featured could be plugged/hooked somewhere in Org, when > fontification is done. But that's not really true, as the feature > requires being run every time the point moves too. So, as far as > I can tell, it seems using post-command-hook is unavoidable, and if > so, you are right in not wanting to add some load to it for everyone, > regardless of whether they want this feature or not. You and Kyle > have me convinced here. Sorry for being late to the party, but, IMO, this doesn't sound like a right approach to the problem of invisible emphasis markers. A user choosing to hide emphasis markers should not need to—or even be given the opportunity to—display them in order to edit them efficiently. I think we should upgrade `org-emphasize' command instead, so it handles both marker visibility states in a DWIM, or in a word processor, fashion. Indeed, since emphasis markers of a given type cannot be nested in Org, the WIM part is usually easy to guess, according to the context, i.e., the syntax at point, and the region. I have some draft lying somewhere in that direction. WDYT? Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-24 15:46 ` Nicolas Goaziou @ 2020-06-24 16:34 ` Shankar Rao 2020-06-26 7:32 ` Nicolas Goaziou 2020-06-24 17:27 ` Gustavo Barros 1 sibling, 1 reply; 16+ messages in thread From: Shankar Rao @ 2020-06-24 16:34 UTC (permalink / raw) To: Gustavo Barros, Shankar Rao, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 735 bytes --] > Sorry for being late to the party, but, IMO, this doesn't sound like > a right approach to the problem of invisible emphasis markers. A user > choosing to hide emphasis markers should not need to—or even be given > the opportunity to—display them in order to edit them efficiently. > I agree that if org-emphasize handled marker visibility states in a DWIM fashion, then a user should not need to display them, but why do you believe they shouldn't have the opportunity, especially given that this is the exact behavior of prettify-symbols-mode? Could you walk me through, in your proposed DWIM system, how a user should be able to remove or change emphasis markers after they are rendered and hidden? Shankar [-- Attachment #2: Type: text/html, Size: 1005 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-24 16:34 ` Shankar Rao @ 2020-06-26 7:32 ` Nicolas Goaziou 2020-07-03 15:19 ` Shankar Rao 0 siblings, 1 reply; 16+ messages in thread From: Nicolas Goaziou @ 2020-06-26 7:32 UTC (permalink / raw) To: Shankar Rao; +Cc: emacs-orgmode, Gustavo Barros Hello, Shankar Rao <shankar.rao@gmail.com> writes: > I agree that if org-emphasize handled marker visibility states in a DWIM > fashion, then a user should not need to display them, but why do you > believe they shouldn't have the opportunity, especially given that this is > the exact behavior of prettify-symbols-mode? I wrote my message in a hurry. Let me clarify it. I'm only talking about built-in tooling. I don't mind if a user have the feature you're proposing, of course, as it is not wrong per se. However, I believe that's not the best solution for the problem we're trying to solve. I think there's an opportunity to provide something smarter, and less intrusive, to handle emphasis, which doesn't involve messing with `post-command-hook'. > Could you walk me through, in your proposed DWIM system, how a user should > be able to remove or change emphasis markers after they are rendered and > hidden? Like in a word processor, you don't need to see the markers to operate on them. I don't think the usual "toggle" model is appropriate, however. I suggest to use two commands: one for deleting the markers around point or within active region, and one for inserting markers or extending existing ones. Allow me to polish up my draft a bit, so we can compare the benefits of each system. Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-26 7:32 ` Nicolas Goaziou @ 2020-07-03 15:19 ` Shankar Rao 2020-07-05 10:50 ` Nicolas Goaziou 0 siblings, 1 reply; 16+ messages in thread From: Shankar Rao @ 2020-07-03 15:19 UTC (permalink / raw) To: Shankar Rao, Gustavo Barros, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 1990 bytes --] Hi, I wrote my message in a hurry. Let me clarify it. > > I'm only talking about built-in tooling. I don't mind if a user have the > feature you're proposing, of course, as it is not wrong per se. > > However, I believe that's not the best solution for the problem we're > trying to solve. I think there's an opportunity to provide something > smarter, and less intrusive, to handle emphasis, which doesn't involve > messing with `post-command-hook'. > I agree with you that my solution is somewhat intrusive. Ideally, I would have preferred that my solution could leverage advice functions or some Org hook, so that I wouldn't have to modify org.el, but it doesn't seem like there is a straightforward way to do that. The modification of `post-command-hook', similar to one used for `prettify-symbols-mode', only occurs if `org-auto-emphasis-mode' is active > Like in a word processor, you don't need to see the markers to operate > on them. I don't think the usual "toggle" model is appropriate, however. > I suggest to use two commands: one for deleting the markers around point > or within active region, and one for inserting markers or extending > existing ones. > So in your system, in order to interact with emphasis markers, the user would have to learn two different commands? That doesn't seem to be in line with the dwim philosophy used in modern emacs packages. In my opinion, one of the strengths of Org is that the interface is multimodal. One can (in principle) edit documents in much the same way as word processors and rich text editors. However since everything underneath is implemented with just text, one can also directly access and manipulate this text. The ability to switch between these two modalities is extremely powerful and is what sets Org apart from other document editing systems. > Allow me to polish up my draft a bit, so we can compare the benefits of > each system. > I look forward to seeing your proposed system more concretely. Shankar Rao [-- Attachment #2: Type: text/html, Size: 2739 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-07-03 15:19 ` Shankar Rao @ 2020-07-05 10:50 ` Nicolas Goaziou 2020-07-05 20:49 ` Gustavo Barros 2020-07-07 15:57 ` Shankar Rao 0 siblings, 2 replies; 16+ messages in thread From: Nicolas Goaziou @ 2020-07-05 10:50 UTC (permalink / raw) To: Shankar Rao; +Cc: emacs-orgmode, Gustavo Barros Hello, Shankar Rao <shankar.rao@gmail.com> writes: > I agree with you that my solution is somewhat intrusive. Ideally, I would > have preferred that my solution could leverage advice functions or some Org > hook, so that I wouldn't have to modify org.el, but it doesn't seem like > there is a straightforward way to do that. The modification of > `post-command-hook', similar to one used for `prettify-symbols-mode', only > occurs if `org-auto-emphasis-mode' is active The problem is not your implementation, really. It's just that I don't think it should be the _built-in_ way to solve emphasis management. IOW, we shouldn't need to activate a minor mode to make that management tolerable in the first place. However, I agree that it makes senses as an extension, in the same vein as `org-fragtog` for LaTeX fragments. > So in your system, in order to interact with emphasis markers, the user > would have to learn two different commands? That doesn't seem to be in line > with the dwim philosophy used in modern emacs packages. Two different commands? Bah! The change I suggest introduces 7 new commands and 12 new bindings! :) Yet, I claim it is still (somewhat) intuitive. > In my opinion, one of the strengths of Org is that the interface is > multimodal. One can (in principle) edit documents in much the same way as > word processors and rich text editors. However since everything underneath > is implemented with just text, one can also directly access and manipulate > this text. The ability to switch between these two modalities is extremely > powerful and is what sets Org apart from other document editing > systems. You can always toggle `visible-mode' for that. But, really, I think an option like `org-hide-emphasis-markers' is a one-off toggle. Having to, in a way, switch regularly between two values is sub-optimal. > I look forward to seeing your proposed system more concretely. Here it is. The main command is `org-emphasis'. It emphasizes the minimal possible area around point, or region. If there's already an emphasis object of the desired type around point or region, it extends it forward instead. With a prefix argument, it removes the emphasis. Interactively, the command asks for the type of emphasis to use, but I suggest to use dedicated commands instead. Thus, I added a key-binding for each of the six emphasis types. For example, for bold, use `M-o *' or `M-o M-*' There are equivalent commands for underline (`M-o _` or `M-o M-_'), and so on. Note there, even though I polished it, there are probably some glitches left, but it works well enough to give an idea. Tests are missing, too. Please evaluate the following code to try it. --8<---------------cut here---------------start------------->8--- (defun org--emphasis-flatten-region (begin end parent) "Find minimal region around BEGIN and END with boundaries at the same level. PARENT is the parent element containing both BEGIN and END. Return a list (B E CONTEXT) where B and E are, respectively, the start and the end of the smallest region containing BEGIN and END, but with a guaranteed common parent object or element CONTEXT." (let ((context-beg (org-with-point-at begin (org-element-context parent)))) ;; Find common container. (when (/= begin end) (let ((context-end (org-with-point-at end (org-element-context parent)))) (while (>= end (org-element-property :end context-beg)) (setq begin (org-element-property :begin context-beg)) (setq context-beg (org-element-property :parent context-beg))) (while (< begin (org-element-property :begin context-end)) (goto-char (org-element-property :end context-end)) (skip-chars-backward " \n\t") (setq end (point)) (setq context-end (org-element-property :parent context-end))))) ;; Make sure that we do not end up with one boundary inside the ;; common context, and the other boundary outside of it. Also move ;; out of objects that cannot contain emphasis (e.g., bold). (when (or (not (memq 'bold (org-element-restriction context-beg))) (< begin (org-element-property :contents-begin context-beg)) (> end (org-element-property :contents-end context-beg))) (setq begin (org-element-property :begin context-beg)) (goto-char (org-element-property :end context-beg)) (skip-chars-backward " \n\t") (setq end (point))) ;; Return value. (list begin end context-beg))) (defun org--emphasis-extend-region (begin end parent type) "Return smallest area extending emphasis between BEGIN and END. PARENT is an element, as returned by `org-element-at-point'. The function assumes PARENT contents include both BEGIN and END positions. TYPE is emphasis type being extended, as a symbol `bold', `code', `italic', `strike-through', `underline', and `verbatim'. Return nil if there is no possible location for the emphasis markup. Otherwise, return (A . B) where A and B are buffer positions where emphasis markers can be inserted." (org-with-wide-buffer ;; Skip any white space so that the command marks the following ;; word, à la `mark-word'. (let ((limit (org-element-property :contents-end parent))) (goto-char begin) (skip-chars-forward " \t\n" limit) (setq begin (and (> limit (point)) (point)))) ;; At the end of the element, there is nothing to emphasize, so ;; bail out. (when begin (goto-char end) (skip-chars-backward " \t\n" begin) (setq end (max begin (point))) (pcase (org--emphasis-flatten-region begin end parent) (`(,new-begin ,new-end ,context) ;; Special case: when there's an emphasis object of the ;; desired type around the area we're interested in, drop the ;; area and extend the object instead. (let ((emphasis (org-element-lineage context (list type) t))) (when emphasis (setq context (org-element-property :parent emphasis)) (setq new-begin (org-element-property :begin emphasis)) ;; Force extending after the object only, if possible. (setq new-end (and (< (org-element-property :end emphasis) (org-with-point-at (org-element-property :contents-end context) (skip-chars-backward " \t\n") (point))) (1+ (org-element-property :end emphasis)))) (setq begin 0) (setq end new-end))) (when (= begin new-begin) ;; Find an acceptable BEGIN position for the opening ;; emphasis marker. It must be located after an appropriate ;; prefix, but not before a white space. We repeatedly try ;; to find such a location. (let* ((limit (org-element-property :contents-begin context)) (prefix-re "-\"'({[:space:]") (non-prefix-re (concat "^" prefix-re))) (goto-char new-begin) (skip-chars-backward non-prefix-re limit) (while (eq ?\s (char-syntax (char-after))) ;invalid border (skip-chars-backward prefix-re limit) (skip-chars-backward non-prefix-re limit))) (setq new-begin (point))) (when (and new-end (= end new-end)) ;; Find an acceptable END position for the closing emphasis ;; marker. It must be located between a non-space character ;; and an appropriate suffix. We look for the next position ;; before the suffix, and check if there is no space behind. ;; Rinse and repeat. (let* ((limit (org-element-property :contents-end context)) (suffix-re "-[:space:]!\"',.:;?)}\\[") (non-suffix-re (concat "^" suffix-re))) (goto-char new-end) (skip-chars-forward non-suffix-re limit) (while (eq ?\s (char-syntax (char-before))) ;invalid border (skip-chars-forward suffix-re limit) (skip-chars-forward non-suffix-re limit))) (setq new-end (point))) ;; Return value. (and new-begin new-end (cons new-begin new-end))) (other (error "Invalid return value for `org--emphasis-flatten-region': %S" other)))))) (defun org--emphasis-clean-markup (type beg end) "Remove all emphasis of type TYPE between BEG and END. TYPE is a symbol among `bold', `code', `italic', `strike-through', `underline', and `verbatim'. The function assumes BEG and END both belong to the same element." (save-restriction (narrow-to-region beg end) (save-excursion ;; Remove markup in reverse order so object boundaries are still ;; accurate after each buffer modification. (dolist (o (reverse (org-element-map (org-element-parse-buffer) type #'identity))) (goto-char (org-element-property :end o)) (skip-chars-backward " \t") (delete-char -1) (goto-char (org-element-property :begin o)) (delete-char 1))))) (defun org--emphasis-container (begin end) "Return element around BEGIN and END possibly containing emphasis. Return nil if there is no such element." (org-with-point-at begin (let ((element (org-element-at-point))) (pcase (org-element-type element) ;; XXX: Item's tag and headline title can contain emphasis. ;; However, other places in these elements cannot. If BEGIN ;; and END are located appropriately, return a fake element ;; limiting contents to the tag or the title. ((or `headline `inlinetask `item) (when (and (or (org-match-line org-complex-heading-regexp) (org-match-line org-list-full-item-re)) (org-string-nw-p (match-string 4)) (org-pos-in-match-range begin 4) (org-pos-in-match-range end 4)) (let ((new (org-element-copy element))) (org-element-put-property new :contents-begin (match-beginning 4)) (goto-char (match-end 4)) (skip-chars-backward " \t") (org-element-put-property new :contents-end (point)) new))) (type (and (memq type org-element-object-containers) (>= begin (org-element-property :contents-begin element)) (<= end (org-element-property :contents-end element)) element)))))) (defun org-emphasis (&optional arg type) "Apply or remove emphasis at point, or in region. Emphasize minimal area around region or point. If the area is already emphasized, extend it forward. In that case, point is left within the emphasis. When called with an universal prefix argument, remove emphasis around and within region instead. When called interactively, ask for the type of emphasis to apply or remove. When optional argument TYPE is provided, use that emphasis type instead." (interactive "P") ;; Make sure to consider the next non-white character (or end of ;; line, since we don't want to move out of the current element). (let* ((region? (org-region-active-p)) (region-start (and region? (region-beginning))) (region-end (and region? (region-end))) (begin (progn (goto-char (or region-start (point))) (skip-chars-forward " \t") (point))) (end (max begin (or region-end (point)))) (parent (org--emphasis-container begin end))) (unless parent (user-error "Cannot emphasize contents here")) ;; Now proceed according to ARG. (let* ((type (pcase (or type (read-char "Choose emphasis [*~/+_=]: ")) ((or ?* `bold) 'bold) ((or ?~ `code) 'code) ((or ?/ `italic) 'italic) ((or ?+ `strike-through) 'strike-through) ((or ?_ `underline) 'underline) ((or ?= `verbatim) 'verbatim) (answer (user-error "Unknown markup type: %S" answer)))) (markup (pcase type (`bold ?*) (`code ?~) (`italic ?/) (`strike-through ?+) (`underline ?_) (_ ?=)))) (pcase arg ;; No argument: insert emphasis markers. (`nil (pcase (org--emphasis-extend-region begin end parent type) (`nil (user-error (if (org-element-lineage (org-element-context parent) (list type) t) "Cannot extend emphasis further" "Nothing to emphasize in the region"))) (`(,begin . ,end) (if (and (or (< begin (point-min)) (> end (point-max))) (not (yes-or-no-p "Insert markers outside visible part \ of buffer? "))) (message "Emphasis markup insertion aborted") ;; First delete all markup, then insert new one. The ;; first action modifies buffer, so we store insertion ;; location in markers. ;; ;; Also, pay attention to the final position, which ;; should always end within new markers. (let ((begin-marker (copy-marker begin)) (end-marker (copy-marker end)) (origin (point-marker))) (org--emphasis-clean-markup type begin end) (org-with-point-at origin (goto-char end-marker) (insert markup) (goto-char begin-marker) (insert-before-markers markup)) (set-marker begin-marker nil) (set-marker end-marker nil) (set-marker origin nil)))) (value (error "Invalid return value %S" value)))) ;; Non-nil argument: remove emphasis markers. (_ (pcase (org--emphasis-flatten-region begin end parent) (`(,begin ,end ,context) (let ((emphasis (org-element-lineage context (list type) t))) (if (not emphasis) (org--emphasis-clean-markup type begin end) ;; We're already within emphasis object of the desired ;; type: delete it. (org-with-point-at (org-element-property :end emphasis) (skip-chars-backward " \t") (delete-char -1)) (org-with-point-at (org-element-property :begin emphasis) (delete-char 1))))) (other (error "Unknown return value for `org--emphasis-flatten-region': %S" other)))))))) (defun org-emphasis-bold (&optional arg) "Emphasize area around point or region with bold markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'bold)) (defun org-emphasis-code (&optional arg) "Emphasize area around point or region with code markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'code)) (defun org-emphasis-italic (&optional arg) "Emphasize area around point or region with italic markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'italic)) (defun org-emphasis-strike-through (&optional arg) "Emphasize area around point or region with strike-through markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'strike-through)) (defun org-emphasis-underline (&optional arg) "Emphasize area around point or region with underline markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'underline)) (defun org-emphasis-verbatim (&optional arg) "Emphasize area around point or region with verbatim markup. When optional argument ARG is non-nil, remove such markup instead." (interactive "P") (org-emphasis arg 'verbatim)) ;;; Suggested bindings (org-defkey org-mode-map (kbd "M-o *") 'org-emphasis-bold) (org-defkey org-mode-map (kbd "M-o M-*") 'org-emphasis-bold) (org-defkey org-mode-map (kbd "M-o ~") 'org-emphasis-code) (org-defkey org-mode-map (kbd "M-o M-~") 'org-emphasis-code) (org-defkey org-mode-map (kbd "M-o /") 'org-emphasis-italic) (org-defkey org-mode-map (kbd "M-o M-/") 'org-emphasis-italic) (org-defkey org-mode-map (kbd "M-o +") 'org-emphasis-strike-through) (org-defkey org-mode-map (kbd "M-o M-+") 'org-emphasis-strike-through) (org-defkey org-mode-map (kbd "M-o _") 'org-emphasis-underline) (org-defkey org-mode-map (kbd "M-o M-_") 'org-emphasis-underline) (org-defkey org-mode-map (kbd "M-o =") 'org-emphasis-verbatim) (org-defkey org-mode-map (kbd "M-o M-=") 'org-emphasis-verbatim) --8<---------------cut here---------------end--------------->8--- Regards, -- Nicolas Goaziou ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-07-05 10:50 ` Nicolas Goaziou @ 2020-07-05 20:49 ` Gustavo Barros 2020-07-06 14:01 ` Gustavo Barros 2020-07-07 15:57 ` Shankar Rao 1 sibling, 1 reply; 16+ messages in thread From: Gustavo Barros @ 2020-07-05 20:49 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: emacs-orgmode, Shankar Rao Hi Nicolas, Hi All, On Sun, 05 Jul 2020 at 07:50, Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote: > The problem is not your implementation, really. It's just that I don't > think it should be the _built-in_ way to solve emphasis > management. IOW, > we shouldn't need to activate a minor mode to make that management > tolerable in the first place. > > However, I agree that it makes senses as an extension, in the same > vein > as `org-fragtog` for LaTeX fragments. [...] > But, really, I think an option like `org-hide-emphasis-markers' is > a one-off toggle. Having to, in a way, switch regularly between two > values is sub-optimal. I don't think I have anything to add to the previous discussion on this matter, and I know you took it into consideration. Also, I'm well aware that sometimes a user interested in a feature lacks a more general perspective a maintainer has. So I take your position here stems from one such general design choices, and I understand and respect it. > Here it is. > > The main command is `org-emphasis'. It emphasizes the minimal possible > area around point, or region. If there's already an emphasis object of > the desired type around point or region, it extends it forward > instead. > With a prefix argument, it removes the emphasis. > > Interactively, the command asks for the type of emphasis to use, but > I suggest to use dedicated commands instead. Thus, I added a > key-binding > for each of the six emphasis types. For example, for bold, use > > `M-o *' or `M-o M-*' > > There are equivalent commands for underline (`M-o _` or `M-o M-_'), > and > so on. > > Note there, even though I polished it, there are probably some > glitches > left, but it works well enough to give an idea. Tests are missing, > too. > > Please evaluate the following code to try it. This is really, really nice. Certainly a major improvement in the way `org-emphasize' works. I specially like you've chosen to make it act on the element around point, that you added the possibility of increasing this scope with repetition, and that you made the functions commands we can bind. If I may, I'd like to add comments and report tests, for your consideration, in the spirit of trying to help you polish the approach. One low hanging fruit, which you probably have already considered, is to use a transient keymap to ease the repetition of the emphasis commands. So that we could type `M-o * * * *' to emphasize four words, instead of `M-o * M-o * M-o * M-o *'. Even better if in this keymap we could call a command, bound e.g. to `-', to go back one step in case we have gone too far in the repetition. This is interesting in itself, but specially so given a number of the markers are shift-keys, which means the first and the second part of the bindings use different modifiers, making the repetition quite "athletic" (I suppose we could use "M-O", but still). A second thing is regarding the removal of the markers. I think there is space to simplify this further and make it even more convenient. As things are, we have six different bindings to remove an emphasis marker around point. Of course, when adding emphasis, we have to specify which one we want, but when removing it, the markers are already there and we know what is the emphasis around point, and can go with a single command, e.g. `org-remove-emphasis', and a single binding, e.g. `M-o r/M-r', without the cognitive load of having to identify visually which is the marker, to call the correct command to remove it. The only case not covered by this would be if we have nested emphasis of different types and want to remove the outer one. I'd say this is rare enough to leave uncovered in exchange for the simplification of 6 to 1 commands for emphasis removal. True, this seventh command could just be added, and leave the current six as they are, but I do have a suggestion for another use of the prefix, which see. (Perhaps an argument similar to the one being made here for removal could be made for extending emphasis, but I'm not sure if with the same relevance). Still regarding emphasis removal, I see two things one might want when "removing" emphasis: one is to remove the whole emphasis around point, the other is to remove part of an existing emphasized region, doing the analogous of what your six emphasis commands do, but removing emphasis one word at a time. If this distinction is deemed useful and worth implementing, how about `org-remove-emphasis' with no prefix doing the first, and with prefix doing the second? A third thing I think is worth considering is the direction of extension, given that `org-emphasize' also works by extending an existing emphasized region. Two things here: should one be able to control the direction the expansion occurs? what should be the preferred (or only) expansion direction? I'd say the first one would be really nice, and I'd suggest using the prefix to the six emphasis commands to achieve it ("prefix changes the default direction"). As to the second, I'd go for preferring a backwards expansion, rather than a forwards one. My reasoning here is that one would be adding emphasis either while skimming/navigating through an existing document, in which case one has more freedom in point placement, or when one is typing, in which case moving point implies that we must get back to where we were before continuing typing. So for this "while typing" situation a backward expansion would be much more useful, while for the case of "adding emphasis to existing text" the direction would be less important. I take that's the reason `flyspell' has `flyspell-auto-correct-previous-word' while it does not have a "next" equivalent, and why `flyspell-correct' (the package) defaults to correcting the previous misspelling. A fourth issue is point placement after the emphasis is added. `org-emphasis' takes a stance here and places point within the emphasis. I do agree with this option, but it is still true that sometimes, one might want or need otherwise. This, of course, gets more interesting when `org-hide-emphasis-markers' is t. And I actually think this issue is still more general. One thing is to "add emphasis markers to existing text", another is "adding text around existing emphasis markers". The first one is superbly dealt with by this implementation of `org-emphasize', the second one, as far as I can see, not equally so. Finally, as I took it for a spin, I might as well report some cases which called my attention. I know you said this isn't ready yet, but I hope it is still useful. In the examples, '|' represents point, and '·' space. 1) When point is at the right-edge of a word, the emphasis command will either emphasize the following word, if there is one before eol, or error with "Nothing to emphasize in the region" even though there is no active region. If there is only whitespace between point and eol the emphasis command will issue the same error and move point to eol. Illustrations: Starting from: #+begin_src org foo|·bar #+end_src `M-o *' results in: #+begin_src org foo·*|bar* #+end_src (note point has moved) Starting from: #+begin_src org foo·bar| #+end_src `M-o *' errors with "Nothing to emphasize in the region". Starting from: #+begin_src org foo·bar|··· #+end_src `M-o *' errors with "Nothing to emphasize in the region" and moves point to: #+begin_src org foo·bar···| #+end_src I suggest it would make sense, when at a word right boundary, to emphasize the immediately preceding word rather than the next one. Though this is probably somewhat a matter of preference, I'd argue it is more intuitive. On the other hand, the last case, where the command issues an error, does not apply emphasis and moves point, is clearly unexpected behavior (it should at least not move point). 2) When point is within whitespace, with no "word" at point, it still emphasizes the next word, if there is one. Illustration: Starting from: #+begin_src org foo·|·bar #+end_src `M-o *' results in: #+begin_src org foo··*|bar* #+end_src (note point has moved) I would expect to get instead: #+begin_src org foo·*|*·bar #+end_src Starting from an empty line (or a "whitespace only" line): #+begin_src org | #+end_src We get error "Cannot emphasize contents here". But why not? #+begin_src org *|* #+end_src And be able to insert some content "to be bold". Indeed, if the right boundary logic above is used, and this within whitespace one is also used, then point never needs to move when applying emphasis "around point", which seems sensible to me. (I haven't given proper thought on what to do with point/region when region is active though.) Also, as far as I can tell, it would also never fall back to "Nothing to emphasize in the region", which indeed is somewhat strange when no region is active. The general idea is, if no "minimal area around region or point" can be identified, place the markers around point, instead of returning error. That said, I reiterate I really consider this revamping of `org-emphasize' a major improvement, and a very welcome one. And I thank you very much for that. My comments here are just offered for your consideration and use as you see fit, in the hope they might be useful. And I'm looking forward to see this reach distribution. Best, Gustavo. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-07-05 20:49 ` Gustavo Barros @ 2020-07-06 14:01 ` Gustavo Barros 0 siblings, 0 replies; 16+ messages in thread From: Gustavo Barros @ 2020-07-06 14:01 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: emacs-orgmode, Shankar Rao Hi Nicolas, Hi All, On Sun, 05 Jul 2020 at 17:49, Gustavo Barros <gusbrs.2016@gmail.com> wrote: > A fourth issue is point placement after the emphasis is > added. `org-emphasis' > takes a stance here and places point within the emphasis. I do agree > with this > option, but it is still true that sometimes, one might want or need > otherwise. > This, of course, gets more interesting when > `org-hide-emphasis-markers' is t. > And I actually think this issue is still more general. One thing is > to "add > emphasis markers to existing text", another is "adding text around > existing > emphasis markers". The first one is superbly dealt with by this > implementation of `org-emphasize', the second one, as far as I can > see, not > equally so. After sleeping over this problem, I think I had an interesting idea to allow some control of point position in an intuitive fashion. I thus submit it to the list. Consider the following suggested behavior for `org-emphasize': i) anything in the direction opposite to the emphasis expansion direction is ignored, regardless of whether point is at a word boundary or not on that side (this corresponds to the current implementation, but goes against my initial suggestion of considering the right boundary of a word as "part" of the previous word); ii) point never moves (and this is different from the current implementation). Simple, clear cut rules. And they would make it possible to control whether point is placed within or outside the emphasis markers by manipulating point position wrt whitespace /before/ calling `org-emphasize'. So, taking the current forward expansion direction, if we wanted to emphasize the following word, we would have: i) if the point is placed before whitespace preceding the following word, point will be left where is is, which will result to be outside the emphasis markers; ii) if point is within a word (which includes the left boundary) point will end inside the markers; it also hasn't moved, just the marker was applied before it. Some examples, again assuming forward expansion: #+begin_src org foo|·bar foo·|bar foo·b|ar foo·bar| #+end_src for `M-o *', the results would be: #+begin_src org foo|·*bar* foo·*|bar* foo·*b|ar* foo·bar| #+end_src Assuming a backwards expansion direction was to exist (and the more I think of this, the more I lean towards preferring this as the default), we could do the following. I'm typing something: #+begin_src org foo·bar| #+end_src But then I decide to emphasize "bar", and only "bar". I could go with `SPC M-o *' to get: #+begin_src org foo·*bar*·| #+end_src And be able to just keep on typing: #+begin_src org foo·*bar*·baz| #+end_src I wouldn't say this goes all the way to solve the "adding text around existing emphasis markers" problem. But, as far as my scrutiny went, I do think it goes quite a stretch. And it is quite simple, which should make for "intuitive" hopefully. WDYT? Best, Gustavo. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-07-05 10:50 ` Nicolas Goaziou 2020-07-05 20:49 ` Gustavo Barros @ 2020-07-07 15:57 ` Shankar Rao 1 sibling, 0 replies; 16+ messages in thread From: Shankar Rao @ 2020-07-07 15:57 UTC (permalink / raw) To: Shankar Rao, Gustavo Barros, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 5898 bytes --] Thank you for your hard work on this. It's definitely easier to compare two concrete blocks of code rather than abstract ideas. > I agree with you that my solution is somewhat intrusive. Ideally, I would > > have preferred that my solution could leverage advice functions or some > Org > > hook, so that I wouldn't have to modify org.el, but it doesn't seem like > > there is a straightforward way to do that. The modification of > > `post-command-hook', similar to one used for `prettify-symbols-mode', > only > > occurs if `org-auto-emphasis-mode' is active > > The problem is not your implementation, really. It's just that I don't > think it should be the _built-in_ way to solve emphasis management. IOW, > we shouldn't need to activate a minor mode to make that management > tolerable in the first place. > > However, I agree that it makes senses as an extension, in the same vein > as `org-fragtog` for LaTeX fragments. > That's a fair point. As I said, I modified `org-do-emphasis-faces' in org.el only because I couldn't find a less intrusive way of achieving the functionality I was looking for. Is there a way to make `org-auto-emphasis-mode' an extension that leaves org.el unmodified? > > So in your system, in order to interact with emphasis markers, the user > > would have to learn two different commands? That doesn't seem to be in > line > > with the dwim philosophy used in modern emacs packages. > > Two different commands? Bah! The change I suggest introduces 7 new > commands and 12 new bindings! :) > > Yet, I claim it is still (somewhat) intuitive. > I agree that your change is reasonably intuitive. I find it quite elegant that you appropriated the M-o binding (which by default runs the `facemenu-set-*' commands) in orgmode, and that the modifier keys (*,/,_,~,=,+) map to text emphasis markers. But while I find your change easy to understand, I find it a bit unwieldy to use. I discuss this further below. > > In my opinion, one of the strengths of Org is that the interface is > > multimodal. One can (in principle) edit documents in much the same way as > > word processors and rich text editors. However since everything > underneath > > is implemented with just text, one can also directly access and > manipulate > > this text. The ability to switch between these two modalities is > extremely > > powerful and is what sets Org apart from other document editing > > systems. > > You can always toggle `visible-mode' for that. > > But, really, I think an option like `org-hide-emphasis-markers' is > a one-off toggle. Having to, in a way, switch regularly between two > values is sub-optimal. > I completely agree that toggling on and off *all* emphasis markers is suboptimal. In fact, before I developed this `org-auto-emphasis-mode', my previous solution was to toggle the emphasis marker at point. Please refer to this reddit post ( https://www.reddit.com/r/orgmode/comments/grh423/is_it_possible_to_make_orghideemphasismarkers_and/). Coincidentally, I bound this function to M-o as well. > Here it is. > > The main command is `org-emphasis'. It emphasizes the minimal possible > area around point, or region. If there's already an emphasis object of > the desired type around point or region, it extends it forward instead. > With a prefix argument, it removes the emphasis. > > Interactively, the command asks for the type of emphasis to use, but > I suggest to use dedicated commands instead. Thus, I added a key-binding > for each of the six emphasis types. For example, for bold, use > > `M-o *' or `M-o M-*' > > There are equivalent commands for underline (`M-o _` or `M-o M-_'), and > so on. > I tested out your commands and I find your `org-emphasis' to indeed be an improvement over `org-emphasize'. Since the two commands are so similar, I would recommend refining this and having it be a replacement for `org-emphasize'. Here are my comments. - I like that, in the absence of a region, `org-emphasis' emphasizes the area around the point. This improves upon `org-emphasize', which inserts a pair of emphasis markers at point. - I find the behavior of repeated invocations to expand the area of emphasis to be useful, but strange. I don't know of any other commands that expand the area of some property with repeated invocations (except for `expand-region', which is designed to do that explicitly). To me, it would be both more straightforward to expand or contract the region (e.g., using C-right or C-left) and then apply emphasis using M-o. - I find it unwieldy that to unemphasize, you must use both the prefix command and remember which marker you chose (e.g. to unbold you must do C-u M-o *). Prefix commands are usually reserved for special modifications of commands, and I think unemphasizing is sufficiently common that it shouldn't be relegated to this space. In word processors like MS Word, unemphasizing is implemented by repeatedly invoking the keyboard command (e.g, C-b on plain text bolds it and C-b on bolded text unbolds it). Since Org doesn't properly render nested emphasis markers, I believe that it would be more intuitive if unemphasizing was implemented via repeated invocation (i.e., M-o * on already bolded text) toggle tht emphasis. - I like Gustavo's idea of using a transient keymap to implement expansion. In fact, if you implemented it that way, you could use the transient keymap for expanding the area of emphasis and reserve repeated invocation for toggling the emphasis - I also agree with Gustavo that there should be a single command to remove all emphasis at point/region. Similar to how `org-emphasize' does it, I suggest that you could use M-o SPC for this. - I believe that these adding/removing emphasis should not move the point. I'm glad that I've been able to contribute to this discussion, and I hope we can reach some consensus for improving emphasis editing in Org! Shankar [-- Attachment #2: Type: text/html, Size: 7500 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] Add mode for automatically unhiding emphasis markers in the current region 2020-06-24 15:46 ` Nicolas Goaziou 2020-06-24 16:34 ` Shankar Rao @ 2020-06-24 17:27 ` Gustavo Barros 1 sibling, 0 replies; 16+ messages in thread From: Gustavo Barros @ 2020-06-24 17:27 UTC (permalink / raw) To: Nicolas Goaziou; +Cc: emacs-orgmode, Shankar Rao Hi Nicolas, On Wed, 24 Jun 2020 at 12:46, Nicolas Goaziou <mail@nicolasgoaziou.fr> wrote: > Hello, > > Gustavo Barros <gusbrs.2016@gmail.com> writes: > >> You have a good point here. When I made the suggestion I was naively >> thinking the featured could be plugged/hooked somewhere in Org, when >> fontification is done. But that's not really true, as the feature >> requires being run every time the point moves too. So, as far as >> I can tell, it seems using post-command-hook is unavoidable, and if >> so, you are right in not wanting to add some load to it for everyone, >> regardless of whether they want this feature or not. You and Kyle >> have me convinced here. > > Sorry for being late to the party, but, IMO, this doesn't sound like > a right approach to the problem of invisible emphasis markers. A user > choosing to hide emphasis markers should not need to—or even be given > the opportunity to—display them in order to edit them efficiently. > I do agree with what you said, as you have stated it: It'd be good if the user of `org-hide-emphasis-markers' didn't need to display the invisible character to edit them efficiently. And it is true that I argued in favor of this proposed patch giving the related editing inconveniences as a main point. But the feature is the equivalent of `prettify-symbols-unprettify-at-point' for `org-hide-emphasis-markers' and it does have an appeal in itself, for the visual cue it offers, besides the editing improvement, which is a byproduct. I like `org-hide-emphasis-markers', but if I was not "given the opportunity to display them" or if I could not edit them directly even if invisible, as a word processor does, I would probably not consider ever hiding them in the first place. > I think we should upgrade `org-emphasize' command instead, so it > handles > both marker visibility states in a DWIM, or in a word processor, > fashion. Indeed, since emphasis markers of a given type cannot be > nested > in Org, the WIM part is usually easy to guess, according to the > context, > i.e., the syntax at point, and the region. I have some draft lying > somewhere in that direction. > > WDYT? I think that it would be great independently of the proposed patch. Indeed, that would be very useful including for users which set `org-hide-emphasis-markers' to nil. On the other hand, even with a more capable dwim `org-empasize', I'm pretty sure many users will still add emphasis markers by directly typing them, even if occasionally, or they will delete them inadvertently if invisible, in which case, the proposed patch remains very useful for this reason too. If I may, `TeX-font' in AUCTeX would be my dream `org-emphasize'. Two things it does that `org-emphasize' doesn't (as far as I know of): i) when there is no region selected, and point is within a font macro, it operates on the imediate enclosing font macro, not requiring region selection, so that we can change the font macro by calling `TeX-font' with a prefix, or remove the font macro with "C-c C-f C-d"; ii) `LaTeX-font-list' is customizable, allowing for better key bindings; it's easier to type "b" than "*", "s" than "+" etc., anyway, it gives choice. Again, just an user here, just offering a data point. (And I was quoted ;-). Best, Gustavo. ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2020-07-07 16:01 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-06-01 14:14 [PATCH] Add mode for automatically unhiding emphasis markers in the current region Shankar Rao 2020-06-01 15:33 ` Shankar Rao 2020-06-22 5:40 ` Kyle Meyer 2020-06-22 11:25 ` Gustavo Barros 2020-06-23 0:07 ` Kyle Meyer 2020-06-24 12:53 ` Shankar Rao 2020-06-24 13:49 ` Gustavo Barros 2020-06-24 15:46 ` Nicolas Goaziou 2020-06-24 16:34 ` Shankar Rao 2020-06-26 7:32 ` Nicolas Goaziou 2020-07-03 15:19 ` Shankar Rao 2020-07-05 10:50 ` Nicolas Goaziou 2020-07-05 20:49 ` Gustavo Barros 2020-07-06 14:01 ` Gustavo Barros 2020-07-07 15:57 ` Shankar Rao 2020-06-24 17:27 ` Gustavo Barros
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).