1

I want to replace words like 1st with 1^{st} and 102nd with 102^{nd} while typing in emacs. Basically I want to replace things that match this:

"\([0-9]+\)\(st\|nd\|rd\|th\)"

with this \1^{\2} as I type.

It seems like an abbrev might work for this, but it does not appear you can put a regexp as the name.

The best I have come up with is

(defun org-ordinal-expansion ()
  (interactive)
  (and (= ?w (char-syntax (char-before)))
       (save-excursion
         (and (skip-syntax-backward "w")
          (let (case-fold-search)
        (looking-at "\\([0-9]+\\)\\(st\\|nd\\|rd\\|th\\)"))
          (replace-match "\\1^{\\2}")))))

(define-minor-mode ordinal-mode
  "Toggle `ordinal-mode'.  Converst 1st to 1^{st} as you type."
  :init-value nil
  :lighter (" om")
  (if ordinal-mode
      (add-hook 'post-self-insert-hook #'org-ordinal-expansion nil 'local)
    (remove-hook 'post-self-insert-hook #'org-ordinal-expansion 'local)))

Is there some more elegant way to achieve this that doesn't rely on the post-self-insert-hook?

4
  • Not more elegant but another way to do what you want might be to add a function that does the conversion to write-file-functions so that it happens every time you save the file. At least then you'd be to use a single regexp search and replace.
    – stevoooo
    Apr 10, 2017 at 19:03
  • That could also be done in a before-save-hook. I really want it to work as I type though. I guess even an abbrev basically has to do the check I do above, so it probably isn't too far off. Apr 10, 2017 at 22:15
  • @JohnKitchin The code above works well for me. Are you stick with it or is there any improved version?
    – azzamsa
    Feb 2, 2021 at 1:57
  • I don’t have a better version. Now I might use yasnippet perhaps, although that still requires a trigger key. Feb 2, 2021 at 18:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.