georgewfraser/vscode-tree-sitter

[JavaScript] Highlight function parameters

dimaMachina opened this issue · 6 comments

Hi George, can you update your extension to solve this problem ? 🙏microsoft/vscode#69824
Thanks

Highlighting parameters differently is definitely possible, though I'm not 100% sure what color would be appropriate. Right now we're using the scope "variable" for fields, but it should probably be:

  • Types: entity.name.type
  • Function declarations: entity.name.function
  • Parameters: variable
  • Fields: [something else]
  • Globals, everything else: nothing / white

Sadly, I don't think this is fixable with the tree sitter since its a context-free parser 😕(see https://tree-sitter.github.io/tree-sitter/creating-parsers#understanding-the-problem).

We can ask the expert @maxbrunsfeld though.
Hey @maxbrunsfeld

function(aParameter) {
     let notAParameter = 10
     print(aParameter)
     print(notAParameter)
}

is it possible for the both of the aParameter's to have the same (parameter) tag, but for the notAParameter to have the general/variable tag?

I don't think this is fixable with the tree sitter since its a context-free parser

Identifying function parameters isn't the responsibility of the parser. That's a separate layer of analysis that you'd have to perform based on the syntax tree.

It's definitely doable; we actually do this today our new Tree-sitter-based syntax highlighting system (built for a different GitHub project, not Atom). It's not really documented yet, but it works:

Screen Shot 2019-06-03 at 1 55 36 PM

Here's the PR that introduces the capability: tree-sitter/tree-sitter#331. It's implemented in a Rust crate called tree-sitter-highlight, which is designed for highlighting entire documents. It doesn't yet have features for dealing with incremental highlighting of mutable documents in text editors.

I haven't thought about how to do this local variable tracking efficiently in a Text editor context like Atom or VSCode. I think it would be very complicated to keep track of things incrementally, the way that Tree-sitter updates the parse tree incrementally.

Instead, you'd probably just want to do it for an entire function in a deferred fashion (like when the user stops typing for 100 milliseconds or something like that).

Thanks, that was an awesome response, I didn't think about using the tree sitter in that way before. This opens up opportunities to solve other hard problems like user defined c macros. They'd be a lot easier since they're often not scoped at all, and can't be overridden.

If I end up adding support for lazy highlighting of context-sensitive language concepts I'll make a generic library for it and let you know.

Yes, I am already doing something along these lines in Go to color local variables differently than top-level variables, and to color mutable locals differently than immutable locals:

export function colorGo(root: Parser.SyntaxNode, visibleRanges: {start: number, end: number}[]) {

I'd love to see this implemented. Highlighted parameters are something I got accustomed to back when I was using Sublime, where they're quite common in function declarations (but disregarded in function bodies). Monokai-ish color schemes like orange italics, as far as styling goes, and the traditional TextMate scope is variable.parameter.

VSCode w/ Tree Sitter

Screen Shot 1

Sublime w/ TextMate

Screen Shot

ETA: There's an Atom package called language-rust-treesitter that adds parameter highlighting to Rust (and does a pretty snazzy job with the language overall).