tree-sitter / tree-sitter-haskell

Haskell grammar for tree-sitter.
MIT License
155 stars 36 forks source link

Syntax Highlighting in Escaped String Literals #42

Closed jpe90 closed 3 years ago

jpe90 commented 3 years ago

Hello,

Is it possible to highlight escaped string literals? Here's how they look currently in neovim w/ TS highlighting enabled:

126541203-798eb22d-9b86-499a-ac8f-24f9c1883594

Vs other editors with highlighted escaped literals:

126541129-226640dd-27a0-4fa8-aacc-acdf30c066cf

tek commented 3 years ago

in general, you can use injections to defer to a different grammar, by putting this into $VIMCONFIG/queries/haskell/injections.scm:

(string) @grammar-with-escape-highlights

And I can look into parsing strings directly in the grammar.

tek commented 3 years ago

so, the other grammar would need to be specifically parsing only the string

jpe90 commented 3 years ago

Got it working after I realized you didn't mean to literally add @grammar-with-escape-highlights, LOL. Thank you!!

tek commented 3 years ago

oh really, which grammar did you use?

jpe90 commented 3 years ago

I just tried a couple at random and went with Rust because it picked up \" and \n without giving me problems in the project I'm working on

tek commented 3 years ago

oh heh. you could create a minimal grammar that only parses strings tho

jpe90 commented 3 years ago

I'm not really familiar with treesitter internals (or parsing in general really) to know how to go about that.. would reading https://tree-sitter.github.io/tree-sitter/creating-parsers get me started, or is there other documentation you would also recommend?

tek commented 3 years ago

I did a similar thing for quasiquotes here: https://github.com/tek/vim-bundle-conf/tree/master/tree-sitter/exon

it's bare bones, you'll just have to modify grammar.js, it should be fairly intuitive, using that page you linked.

then you'll have to add it in you vim config in a plugin/foo.vim:

lua <<EOF
local parser_config = require "nvim-treesitter.parsers".get_parser_configs()
parser_config.string_grammar_name = {
  install_info = {
    url = "/path/to/string/grammar/",
    files = {"src/parser.c"}
  }
}
EOF

and you can refer to it in an injection with @string_grammar_name after :TSInstall string_grammar_name

jpe90 commented 3 years ago

Thank you, that example was very helpful. I ended up giving it a shot. I set up a minimal grammar named "porcupine" which only parses strings into two nodes, "string_fragment" or "escape_sequence". I inject it into haskell with (string) @porcupine in injections.scm, it installs successfully with :TSInstall porcupine and is applied in the right places when I look at a source file with TSPlayground:

escape_sequence

string_fragment

However I can't seem to get the capture groups set up for them. In the minimal grammar, I have a queries/highlights.scm containing:

(string_fragment) @string
(escape_sequence) @escape

and a corresponding "escape" custom capture group set up in my vim config.

But those don't seem to get picked up:

no_captures_found

I'm sure I'm missing something on how capture groups work, so I'll try to figure it out, but let me know if anything obvious jumps out that I'm missing.

tek commented 3 years ago

by "in the minimal grammar", do you mean that the highlights file is in the porcupine/queries directory? because that won't get picked up by nvim I think.

jpe90 commented 3 years ago

Yeah, I had tried adding those highlights in the haskell queries directory in the fork of nvim-treesitter that my config is hooked up to and treesitter exploded with an error referencing an "invalid node". If I included a porcupine highlight group it got picked up, though. Anyways I should probably find time to figure out how tree-sitter actually works before trying to hack something together :^) my attempt is here

tek commented 3 years ago

well, for nvim, you have to put all the queries and injections into the nvim config. so either your nvim-treesitter fork or your local ~/.config/nvim. and the injection has to be in queries/haskell/injections.scm, while the highlighting for porcupine has to be in queries/porcupine/highlights.scm.

tek commented 3 years ago

@jpe90 can this be closed?

jpe90 commented 3 years ago

Sure, thanks for trying to help.

tek commented 3 years ago

@jpe90 oh, were you no able to implement your goal?

jpe90 commented 3 years ago

No, I got stuck getting highlights/injections recognized and felt a little out of my depth. I wanted to make more of an effort to understand how they work before I kept bugging for help. I'll give it another shot when I'm feeling brave :^)

tek commented 3 years ago

gotcha, feel free to continue here when you need more input!