From: Shankar Rao <shankar.rao@gmail.com>
To: emacs-orgmode@gnu.org
Subject: [PATCH] Add mode for automatically unhiding emphasis markers in the current region
Date: Mon, 1 Jun 2020 16:14:17 +0200 [thread overview]
Message-ID: <CAGEgU=j+UJoWwoRKChkVxN5dmwbD4YaNTWdLS6Qgj57osZLRJA@mail.gmail.com> (raw)
[-- 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 --]
next reply other threads:[~2020-06-01 14:26 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-01 14:14 Shankar Rao [this message]
2020-06-01 15:33 ` [PATCH] Add mode for automatically unhiding emphasis markers in the current region 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAGEgU=j+UJoWwoRKChkVxN5dmwbD4YaNTWdLS6Qgj57osZLRJA@mail.gmail.com' \
--to=shankar.rao@gmail.com \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).