emacs-tree-sitter / elisp-tree-sitter

Emacs Lisp bindings for tree-sitter
https://emacs-tree-sitter.github.io
MIT License
816 stars 73 forks source link

[C/C++] Incorrect Highlighting When Using Macros: Teach Tree Sitter To Ignore Them #219

Open Jacobfaib opened 2 years ago

Jacobfaib commented 2 years ago

TL;DR: Macros break highlighting. How can I make tree-sitter-hl ignore (some of) them? Does not necessarily have to be fancy, can be as simple as a user-set regex or list.


A common idiom in C and C++ is to use macro definitions to hide otherwise unsavory build-details such as __attribute__s and extern declarations:

// foo.h
#define PUBLIC_VISIBILITY __attribute__((visibility("default")))
#define PUBLIC_API extern PUBLIC_VISIBILITY

PUBLIC_API int foo();
class PUBLIC_VISIBILITY bar;

The problem is that using these makes the syntax highlighting break. For example:

Without Macro (correct ✅) With Macro (incorrect ❌)
image image

It is probably impossible/unreasonable for tree-sitter to determine that an identifier is a macro, so is there a way to simply discard certain idenfiers from the AST?

I searched https://emacs-tree-sitter.github.io/syntax-highlighting/customization/ for a way to do this, but the examples listed show only how to extend highlighting. Furthermore even if one could craft a suitable query I don't think it would work since the underlying issue is that the AST is ill-formed to begin with.

theHamsta commented 2 years ago

Tree-sitter allows to skip certain ranges during parsing (set_included_ranges). This would require some kind of pre-scanning of the text and everything time a range has changed.