-
-
Save jdtsmith/55e6a660dd4c0779a600ac81bf9bfc23 to your computer and use it in GitHub Desktop.
(defun my/org-toggle-emphasis (type) | |
"Toggle org emphasis TYPE (a character) at point." | |
(cl-labels ((in-emph (re) | |
"See if in org emphasis given by RE." | |
(and (org-in-regexp re 2) | |
(>= (point) (match-beginning 3)) | |
(<= (point) (match-end 4)))) | |
(de-emphasize () | |
"Remove most recently matched org emphasis markers." | |
(save-excursion | |
(replace-match "" nil nil nil 3) | |
(delete-region (match-end 4) (1+ (match-end 4)))))) | |
(let* ((res (vector org-emph-re org-verbatim-re)) | |
(idx (cl-case type (?/ 0) (?* 0) (?_ 0) (?+ 0) (?= 1) (?~ 1))) | |
(re (aref res idx)) | |
(other-re (aref res (- 1 idx))) | |
(type-re (string-replace (if (= idx 1) "=~" "*/_+") | |
(char-to-string type) re)) | |
add-bounds offset is-word) | |
(save-match-data | |
(if (region-active-p) | |
(if (in-emph type-re) (de-emphasize) (org-emphasize type)) | |
(if (eq (char-before) type) (backward-char)) | |
(if (in-emph type-re) ;nothing marked, in emph text? | |
(de-emphasize) | |
(setq add-bounds ; check other flavors | |
(if (or (in-emph re) (in-emph other-re)) | |
(cons (match-beginning 4) (match-end 4)) | |
(setq is-word t) | |
(bounds-of-thing-at-point 'symbol)))) | |
(if add-bounds | |
(let ((off (- (point) (car add-bounds))) | |
(at-end (= (point) (cdr add-bounds)))) | |
(set-mark (car add-bounds)) | |
(goto-char (cdr add-bounds)) | |
(org-emphasize type) ;deletes marked region! | |
(unless is-word ; delete extra spaces | |
(goto-char (car add-bounds)) | |
(when (eq (char-after) ?\s) (delete-char 1)) | |
(goto-char (+ 2 (cdr add-bounds))) | |
(when (eq (char-after) ?\s) (delete-char 1))) | |
(goto-char (+ (car add-bounds) off | |
(cond ((= off 0) 0) (at-end 2) (t 1))))) | |
(if is-word (org-emphasize type)))))))) |
May consider using (bounds-of-thing-at-point 'symbol) instead of 'word, so works on hyphenated words and vari-abl-es.
Thanks! I had in fact wanted this, and reached for current-word
, which does the right thing, but that returns the word and not its bounds. Even considered submitting a patch for current-word-bounds
.
Also, have you seen this snippet for insert-pair
Nope, I hadn't seen that interesting approach, thanks. I tend to just use s-e
when at a blank to get a ~~
with point between. That's what the final (if is-word (org-emphasize type))
does. I.e. it was a word, but we didn't find one, so just emphasize "nothing".
Just tweaked to correctly de-emphasize right after an emphasized word *word*[s-b] -> word
, and to leave point outside the word if point is on the boundary to begin with.
I had in fact wanted this, and reached for current-word, which does the right thing
Interesting, I thought current-word
'word
etc. all used the same underlying syntax tables to define a word. Guess not! Thanks for that.
Great! Thanks for sharing, as always. Hope feedback is welcome.
May consider using
(bounds-of-thing-at-point 'symbol)
instead of'word
, so works on hyphenated words andvari-abl-es
.Also, have you seen this snippet for
insert-pair
that has been floating around for a while? Can include the extra chars with:Or if calling
insert-pair
direct, something like this for insert or delete is similar (obviously not as complete, i.e. determining if region-active-p) for your idea: