10

Update, Emacs 28 supports f-stings


Python 3.6 supports F strings, eg:

So:

print(f'Test {} me!'.format(2 + 2))

Can be written as:

print(f'Test {2 + 2} me!')

Which print's Test 4 me, Is there a way to adjust emacs syntax highlighting so the text between the {...} shows using regular code syntax-highlighting (instead of the same highlighting as a string).

ideasman42
  • 8,375
  • 1
  • 28
  • 105

3 Answers3

6

FWIW, I just pushed support for "proper" highlighting of f-strings in Emacs's master branch, so it will be available in Emacs-28 when that gets released (and is available in GNU ELPA's python package as of version 0.27, for older Emacsen).

Stefan
  • 26,154
  • 3
  • 46
  • 84
2

The mentioned bug thread provides a workaround hack, which works on some simple cases. I extended that hack a bit, to better address my use cases:

(defconst brace-regexp
  "[^{]{[^{}]*}")
(defconst python-f-string-regexp
  "f\\('.*?[^\\]'\\|\".*?[^\\]\"\\)")
(defun python-f-string-font-lock-find (limit)
  (while (re-search-forward python-f-string-regexp limit t)
    (put-text-property (match-beginning 0) (match-end 0)
                       'face 'font-lock-string-face)
    (let ((start (match-beginning 0)))
      (while (re-search-backward brace-regexp start t)
        (put-text-property (1+ (match-beginning 0)) (match-end 0)
                           'face 'font-lock-type-face))))
  nil)
(with-eval-after-load 'python
  (font-lock-add-keywords
   'python-mode
   `((python-f-string-font-lock-find))
   'append))

Good stuff:

  • Only applied on f-strings, not on string literals. This is the main feature, it prevents real bugs by capturing visually when I forget to add the f.
  • works with (almost) arbitrary expressions within the {}
  • {{ does not trigger highlighting Bad stuff:
  • still hacky, I'm not elisp literate
  • if the expression within {} contains a }, then expression highlight will be cut off there
  • expressions within {} get all the same colour (I arbitrarily picked the 'type' face because it contrasts well with strings on my system)
Muihlinn
  • 2,576
  • 1
  • 14
  • 22
0

Try https://github.com/karlotness/tree-sitter.el , works perfectly for me.

;; Core APIs.
(straight-register-package
 '(tsc :host github
       :repo "ubolonton/emacs-tree-sitter"
       :files ("core/*.el")))

;; Base framework, syntax highlighting.
(use-package tree-sitter
  :straight (:host github
                   :repo "ubolonton/emacs-tree-sitter"
                   :files ("lisp/*.el"))
  :diminish (tree-sitter-mode)
  :hook ((after-init . global-tree-sitter-mode)
         (tree-sitter-after-on . tree-sitter-hl-mode)))

;; Language bundle.
(use-package tree-sitter-langs
  :straight (:host github
                   :repo "ubolonton/emacs-tree-sitter"
                   :files ("langs/*.el" "langs/queries"))
  :demand t
  :after tree-sitter)
Saddle Point
  • 481
  • 7
  • 23