0

Prettify seems to work well with languages like matlab or python by ignoring things like addition (+) or multiplication (*) when directly next to the symbol. I'd like to add things like underscore (_) to that ignore list, but I can't seem to find out where.

Python-mode seems to automatically do this, but it's not always active, so I imagine it must be stored in some kind of list. I imagine it has something to do with: How to prettify symbols inside comments?, but I can't seem to figure it out.

How do I go about doing this?

strange
  • 71
  • 6

1 Answers1

1

The symbol boundaries are controlled through the function registered at the variable prettify-symbols-compose-predicate.

That function is prettify-symbols-default-compose-p by default. If that function returns non-nil the symbol that starts at START, ends at END, and has match-string MATCH is accepted for prettification.

Citation from prog-mode.el:

(defun prettify-symbols-default-compose-p (start end _match)
  "Return true iff the symbol MATCH should be composed.
The symbol starts at position START and ends at position END.
This is the default for `prettify-symbols-compose-predicate'
which is suitable for most programming languages such as C or Lisp."
  ;; Check that the chars should really be composed into a symbol.
  (let* ((syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_))
                           '(?w ?_) '(?. ?\\)))
         (syntaxes-end (if (memq (char-syntax (char-before end)) '(?w ?_))
                           '(?w ?_) '(?. ?\\))))
    (not (or (memq (char-syntax (or (char-before start) ?\s)) syntaxes-beg)
             (memq (char-syntax (or (char-after end) ?\s)) syntaxes-end)
             (nth 8 (syntax-ppss))))))

As one sees the predicate is syntax controlled. If the syntax at the beginning of the symbol is "word" or "symbol" then the character before may not be of syntax "word" or "symbol". Futhermore the match may not be within a comment or string.

I would recommend to not change the syntax of any characters like _. That has too many side-effects since the syntax-table is used in many other places.

You can roll your own predicate for prettify-symbols-compose-predicate.

For an instance you could additionally explicitly allow _ before start and after end.

(defun my-prettify-symbols-compose-p (start end _match)
  "Return true iff the symbol MATCH should be composed.
The symbol starts at position START and ends at position END.
This is the default for `prettify-symbols-compose-predicate'
which is suitable for most programming languages such as C or Lisp."
  ;; Check that the chars should really be composed into a symbol.
  (let* ((syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_))
                           '(?w ?_) '(?. ?\\)))
         (syntaxes-end (if (memq (char-syntax (char-before end)) '(?w ?_))
                           '(?w ?_) '(?. ?\\))))
    (not (or (and
               (null (memq (char-before start) '(?_)))
               (memq (char-syntax (or (char-before start) ?\s)) syntaxes-beg))
             (and
               (null (memq (char-after end) '(?_)))
               (memq (char-syntax (or (char-after end) ?\s)) syntaxes-end))
             (nth 8 (syntax-ppss))))))

Don't forget to register my-prettify-symbols-compose-p at prettify-symbols-compose-predicate within the hook of the major mode where it is required, i.e.:

(add-hook 'my-major-mode-hook (lambda ()
                                 (setq prettify-symbols-compose-predicate #'my-prettify-symbols-compose-p)))
Tobias
  • 32,569
  • 1
  • 34
  • 75
  • Thanks for the explanation! I had trouble making heads or tails of some of that code and would most likely have broken something. – strange Mar 28 '19 at 08:41