digitallyserviced/semanticolor

string.quoted suppert in tree-sitter

Closed this issue · 5 comments

Hi thanks for making semanticolor,

in the tree-sitter update, it looks like "text" is blank when scopeName is "string.quoted",

if (utils.isTreeSitter(grammar)) {
  semanticolorGrammar.idForScope = function (scopeName, text) {
  if (scopeName.includes("string") {
    console.log(text) // text is empty
  }
  // ...
}

is this a known limitation for tree-sitter?

In short, yes.

Fetching the text from TreeSitter has a performance cost, and the grammar checks for the scope at basically every level of the document, from the full text of the whole thing down to individual tokens/words. In order to reduce the performance penalty as much as possible, when I added the text to the call in the grammar to support Semanticolor, I set it up to do so only for leaf nodes (individual words/tokens).

Generally the text isn’t needed for strings as they tend to always be set to the same color. Are you trying to set up a configuration that needs different colors for each string constant?

thanks for the quick reply,

oh okay that makes sense, yes am using custom state management relying on typed strings, similar to:

const myScore = getState({ type: "gameStats", prop: "myScore" })

where having the myScore variable and string match colors had been useful.

also have no current issues with textmate aside from code-folding, although had switched to be future-proof

as a small sidenote, noticed other keywords (maybe nested-properties?) became uncolored in treesitter until "source" was set to colored and guessing that's for a simmilar reason,

In terms of workarounds am assuming

  • continue using textmate (no problem for now)
  • potentially increase the amount of text atom sends with tree-sitter (sounding unlikely due to performance)
  • fork atom with that custom change
  • fork semanticolor with a custom way to re-parse only strings (not sure if possible/feasable)

Or create constants for your string values?

const types = {
  gameStats = "gameStats",
  //...
};
const props = {
  myScore = "myScore",
  //...
};

const myScore = getState({ type: types.gameStats, prop: props.myScore });

As for re-parsing only strings, you'd have to run it outside the grammar process after all the scopes are determined for the document. At that point you wouldn't be able to change the scopes, but you could do something like the plugins do that highlight things (to colorize hex colors, for example). I haven't looked into it but it should be possible.

thanks for the tips and example, that's good to know a custom plugin solution may still be possible later

thanks for the suggestion , I've implemented a version of manual string coloring here if anyone's interested in doing the same https://github.com/HugoMcPhee/semanticolor-icons/blob/master/lib/semanticolor.js