3

I've been able to partially modify how emacs highlights syntax of python files. For example I find highlighting the definition of variable to be disturbing and I've done this

'(font-lock-constant-face ((t (:foreground "#2aa198" :weight normal))))
 '(font-lock-keyword-face ((t (:foreground "#859900" :weight normal))))
 '(font-lock-variable-name-face ((t (:foreground "#839496")))))

But I'd also like imports to be highlighted with different color, stop highlighting "sys.exit()" as a constant etc, treat print as a builtin function, not as keyword etc. So I need to change how emacs parses python code. In vim you can do this by creating a custom syntax file and placing it in special folder, how to do the same for emacs?

from abc import ABC
print('some')
map(int, ('1',))
int('1')


@cached
def name(a, abc='abc'):
    pass

name(1, abc='bca')

enter image description here

The right one is how I want syntax highlighting to look and the left one is emacs.

7
  • 1
    If you only want to change the appearance of a particular face, then place your cursor on the text with the undesirable color and type M-x customize-face. If you want to change how Emacs identifies a particular section of code within a python file to highlight, then please edit your question with a minimal example that we can all copy to our own computer to duplicate what you see, and also specify how you wish to change the default behavior. E.g., maybe you want to create your own face and use that instead of the default face, or maybe you want something not to be highlighted, or maybe ...
    – lawlist
    Commented Mar 15, 2017 at 5:04
  • You write your own major mode and place it into load-path, so not that different from Vim.
    – wasamasa
    Commented Mar 15, 2017 at 7:34
  • @lawlist Okay, I've added screenshot and code example Commented Mar 16, 2017 at 21:32
  • @wasamasa yeah, very helpful [sarcasm]. What I expect is link to the tutorial on how to write custom parser/syntax highlighter Commented Mar 16, 2017 at 21:34
  • Stackexchange strongly discourages link-only answers and prefers self-contained answers which is sort of difficult to do for this case. You'll have to read the manual and study existing code.
    – wasamasa
    Commented Mar 16, 2017 at 21:53

1 Answer 1

4

In Emacs, syntax highlighting is performed using the module font-lock. It highlights a buffer in two phases:

  • The syntactic phase, where comments and strings are highlighted.
  • The keyword phase, where everything else is highlighted.

The rules for the keywords phase is stored in the variable font-lock-keywords. The variable accepts a complex data structure. It is fully described in it's doc string. However, the text is very complex, and it might take some time to let everything sink in -- I've been trying to understand it for the past 20 years ;-)

A keyword can either be based on a regexp or lisp code.

You can add font-lock keywords using font-lock-add-keywords and remove old ones using font-lock-remove-keywords. They take two arguments, a major mode and a list of new keywords. Instead of a major mode, you can pass nil, which makes them act on the current buffer. I would recommend you to use the latter method, as it would allow you to try out keyword variants until you are satisfied -- just kill the current buffer and reopen the file.

In your case, you will need to find the font-lock keywords that doesn't work as you want (e.g. how it highlights the @ sign, and how it decides which color a builtin function like print) and modify those.

The view and understand existing keywords, I would like to recommend my package Font Lock Studio. It's an interactive debugger for font-lock keywords, where you can step one part of the font-lock highlighting machinery at a time.

2
  • On Emacs 24.5.1, I haven't got the font-lock-add-keywords nor the font-lock-remove-keywords commands, but they are mentioned in the font-lock-keywords doc string. Any idea why they are not available?
    – Giuseppe
    Commented Aug 22, 2017 at 9:36
  • They are not commands, they are Emacs Lisp functions. Typically, they are placed in an init file (or in a stand-alone package). Commented Aug 22, 2017 at 9:43

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.