1

I am writing a feature that changes the displaying of certain words as is done in texinfo-mode, where greek syntax \alpha is displayed as the actual greek symbol α. The implementation uses prettify-symbols-mode.

Have seen that texinfo-mode uses ("\\alpha" . ?α). Not sure about the purpose of ?, and whether I would need to employ the ? for my word replacement feature.

A problem that I have encountered is that when the word little gets displayed as the two-letter word ll, both letters get inserted at the same point, such that the user only sees a single letter l.

    (defvar wrepl
      '(
         ("all" . "l")     ("as" . "as")      ("can" . "k")
         ("do" . "do")     ("for" . "f")      ("in" . "n")
         ("is" . "s")      ("it" . "t")       ("know" . "no")
         ("like" . "lk")   ("little" . "ll")  ("more" . "mo")
         ("some" . "so")   ("than" . "n")     ("that" . "ta")
         ("there" . "tr")  ("this" . "th")    ("time" . "ti")
         ("to" . "to")     ("we" . "w")       ("well" . "l")
         ("will" . "l")    ("work" . "wk")    ("you" . "u")
      "Replacements for specific words.")
6
  • How are you planning to use it?
    – NickD
    Apr 19, 2022 at 22:15
  • The plan is to use prettify-symbols.
    – Dilna
    Apr 19, 2022 at 22:16
  • ? is emacs lisp syntax for characters. See the elisp manual.
    – NickD
    Apr 19, 2022 at 22:17
  • Please add all explanatory stuff to the question: it has to stand on its own even if the comments disappear.
    – NickD
    Apr 19, 2022 at 22:18
  • It is still unclear what you are trying to do and, more importantly, why. Among other things, it is unclear whether you want text to be replaced, in which case prettify-symbols is the wrong tool, or you want overlays to change the appearance of the unchanged text, in which case prettify-symbols may be appropriate. Please give real-world usage before-and-after examples. Apr 20, 2022 at 8:16

1 Answer 1

3

As commented below already, I am not aware of any feature that provides this functionality out of the box. However, while looking at prettify-symbols-mode to look for an alternative, it looked like adapting it to achieve what you ask for, would not be so much work.

So here is the code for steno-mode, an adaption of prettify-symbols-mode that uses the display text property instead of the compose text property:

(setq steno-list '(("all" . "l")     ("as" . "as")      ("can" . "k")
                  ("do" . "do")     ("for" . "f")      ("in" . "n")
                  ("is" . "s")      ("it" . "t")       ("know" . "no")
                  ("like" . "lk")   ("little" . "ll")  ("more" . "mo")
                  ("some" . "so")   ("than" . "n")     ("that" . "ta")
                  ("there" . "tr")  ("this" . "th")    ("time" . "ti")
                  ("to" . "to")     ("we" . "w")       ("well" . "l")
                  ("will" . "l")    ("work" . "wk")    ("you" . "u")))


;; adapted from `prettify-symbols--compose-symbol'
(defun steno--display-symbol (alist)
  "Add paired string as display property to relevant regions"
  ;; Check that the chars should really be composed into a symbol.
  (let ((start (match-beginning 0))
        (end (match-end 0))
        (match (match-string 0)))
    (if (and (not (equal prettify-symbols--current-symbol-bounds (list start end)))
             (funcall prettify-symbols-compose-predicate start end match))
        (with-silent-modifications
          (add-text-properties
           start end
           `(steno-start ,start steno-end ,end display ,(cdr (assoc match alist)))))
      (remove-list-of-text-properties start end
                                      '(steno-start
                                        steno-end
                                        display))))
  ;; Return nil because we're not adding any face property.
  nil)

(defun steno--make-keywords ()
  (interactive)
  `((,(regexp-opt (mapcar 'car steno-list) t)
     (0 (steno--display-symbol ',steno-list)))))

(defvar-local steno--keywords nil)

(define-minor-mode steno-mode
  "Toggle Steno mode.

When Steno mode and font-locking are enabled, symbols are
prettified according to the rules in
`steno-alist' (which see), which are locally defined
by major modes supporting prettifying. To add further
customizations for a given major mode, you can modify
`steno-alist' thus:

  (add-hook \\='emacs-lisp-mode-hook
            (lambda ()
              (push \\='(\"<=\" . ?≤) steno-alist)))

You can enable this mode locally in desired buffers, or use
`global-steno-mode' to enable it for all modes that
support it."
  :init-value nil
  (when steno--keywords
    (font-lock-remove-keywords nil steno--keywords)
    (setq steno--keywords nil))
  (if steno-mode
      ;; Turn on
      (when (setq steno--keywords (steno--make-keywords))
        (font-lock-add-keywords nil steno--keywords)
        (when prettify-symbols-unprettify-at-point
          (add-hook 'post-command-hook
                    #'prettify-symbols--post-command-hook nil t))
        (font-lock-flush))
    ;; Turn off
    (remove-hook 'post-command-hook #'prettify-symbols--post-command-hook t)
    (with-silent-modifications
      (remove-text-properties (point-min) (point-max) '(display nil)))))

Use it like how you would use prettify-symbols-mode.

I am not sure what the remaining prettify-symbols... functions are doing, but from the comments in the code it seems that they are required. Therefore, I have left them in to be safe.

4
  • Is it correct syntax to use ("like" . "lk") without employing ? as in ("like" . ?"lk") ?
    – Dilna
    Apr 21, 2022 at 6:37
  • would I need to set prettify-symbols-compose-predicate?
    – Dilna
    Apr 21, 2022 at 6:44
  • I would say, just try my answer (open a buffer with some example text and apply the command), and you will find out the answers to these questions. You can read about cases when prettify-symbols-compose-predicate is needed here. So my answer only works when you are using/writing the words as separate entities (i.e. without surrounding them with double quotes) and as long as they are not part of comments. Apr 21, 2022 at 8:39
  • I did not get notified about your updates to the question. Indeed, it looks like prettify-symbols-mode can only be used to replace 'patterns' by a (compositions of) single character(s). I could not find anything that provides your desired functionality. I guess you have two alternatives: either modify the prettify-symbols-mode to use text-properties instead of compose-region (see here. Or if you only use short texts, then simply hack something using replace-regexp. Apr 30, 2022 at 8:09

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.