diff --git a/queries/highlights.scm b/queries/highlights.scm index 3f308db0..61d889f8 100644 --- a/queries/highlights.scm +++ b/queries/highlights.scm @@ -34,9 +34,11 @@ ] @keyword ; `private`, `protected` and `public` are `Module` instance methods, not -; keywords: they can be called with arguments, passed a `def`, or shadowed. +; keywords. Bare, they parse as a plain identifier; `#is-not? local` keeps a +; local variable that shadows one of them from being highlighted as a call. ((identifier) @function.method.builtin - (#match? @function.method.builtin "^(private|protected|public)$")) + (#match? @function.method.builtin "^(private|protected|public)$") + (#is-not? local)) (constant) @constructor @@ -50,6 +52,15 @@ ((identifier) @function.method.builtin (#eq? @function.method.builtin "require")) +; The argument forms, such as `private :foo` and `private def bar; end`, have to +; come after the general call pattern above to take precedence over it. +; `!receiver` keeps an unrelated method that happens to share the name, as in +; `acl.public`, highlighted as an ordinary call. +((call + !receiver + method: (identifier) @function.method.builtin) + (#match? @function.method.builtin "^(private|protected|public)$")) + ; Function definitions (alias (identifier) @function.method) diff --git a/test/highlight/classes.rb b/test/highlight/classes.rb index 9139d903..ca34f0fd 100644 --- a/test/highlight/classes.rb +++ b/test/highlight/classes.rb @@ -29,5 +29,24 @@ def init(id) protected # ^ function.method.builtin + + private :with_symbol + # <- function.method.builtin + + private def with_def; end + # <- function.method.builtin + + def shadowed + private = 1 + # <- variable + private + # <- variable + private + end + + def unrelated(acl) + acl.public + # ^ function.method + end end # <- keyword