Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs C mode - how do you syntax highlight hex numbers?

One thing that has bugged me about Emacs since I switched to it is that I can only get it to syntax highlight decimal numbers correctly in C code. For example, these numbers are highlighted correctly:

1234
1234l
1234.5f

However these numbers are NOT highlighted correctly:

0x1234  // x is different colour
0xabcd  // no hex digits are coloured
019     // invalid digit 9 is coloured like it is correct

Is it possible to have Emacs colour every character in these numbers the same? Even better if invalid numbers (like 019 or 0x0g) can be coloured differently to make them stand out.

like image 487
Malvineous Avatar asked Jan 14 '12 04:01

Malvineous


2 Answers

Thanks for the pointer Mischa Arefiev, it got me looking in the right places. This is what I have come up with, and it covers all of my original requirements. The only limitation I'm aware of right now is that it will highlight an invalid number suffix as if it were correct (e.g. "123ulu")

(add-hook 'c-mode-common-hook (lambda ()
    (font-lock-add-keywords nil '(

        ; Valid hex number (will highlight invalid suffix though)
        ("\\b0x[[:xdigit:]]+[uUlL]*\\b" . font-lock-string-face)

        ; Invalid hex number
        ("\\b0x\\(\\w\\|\\.\\)+\\b" . font-lock-warning-face)

        ; Valid floating point number.
        ("\\(\\b[0-9]+\\|\\)\\(\\.\\)\\([0-9]+\\(e[-]?[0-9]+\\)?\\([lL]?\\|[dD]?[fF]?\\)\\)\\b" (1 font-lock-string-face) (3 font-lock-string-face))

        ; Invalid floating point number.  Must be before valid decimal.
        ("\\b[0-9].*?\\..+?\\b" . font-lock-warning-face)

        ; Valid decimal number.  Must be before octal regexes otherwise 0 and 0l
        ; will be highlighted as errors.  Will highlight invalid suffix though.
        ("\\b\\(\\(0\\|[1-9][0-9]*\\)[uUlL]*\\)\\b" 1 font-lock-string-face)

        ; Valid octal number
        ("\\b0[0-7]+[uUlL]*\\b" . font-lock-string-face)

        ; Floating point number with no digits after the period.  This must be
        ; after the invalid numbers, otherwise it will "steal" some invalid
        ; numbers and highlight them as valid.
        ("\\b\\([0-9]+\\)\\." (1 font-lock-string-face))

        ; Invalid number.  Must be last so it only highlights anything not
        ; matched above.
        ("\\b[0-9]\\(\\w\\|\\.\\)+?\\b" . font-lock-warning-face)
    ))
))

Any suggestions/optimisations/fixes welcome!

EDIT: Stopped it from highlighting numbers within comments.

like image 166
Malvineous Avatar answered Oct 05 '22 02:10

Malvineous


Perhaps this will work:

  (font-lock-add-keywords
   'c-mode
   '(("0x\\([0-9a-fA-F]+\\)" . font-lock-builtin-face)))
like image 38
Mischa Arefiev Avatar answered Oct 05 '22 02:10

Mischa Arefiev