mickeynp / combobulate

Structured Editing and Navigation in Emacs with Tree-Sitter
GNU General Public License v3.0
911 stars 53 forks source link

Permit query builder on unsupported languages? #73

Closed danderson closed 7 months ago

danderson commented 9 months ago

I'm writing a new major mode, using your article as a reference. Thank you for writing it, and for Mastering Emacs!

The article rightly states that having Combobulate's interactive query builder is a godsend when getting to grips with tree-sitter and working out font locking rules. However, at present, the query builder refuses to run at all on unsupported languages, even if the buffer has tree-sitter parsers available.

While the really civilized features of this package require explicit per-language work, interactive tree querying appears to work reasonably without full combobulate support, and is invaluable when first feeling your way around a language to write its font locking rules.

Would you have any interest in letting combobulate-query run on any tree-sitter enabled buffer, albeit with warnings and lesser functionality for unsupported languages? I've hacked up my own emacs appropriately, but it seems potentially nice to have more generally.

For reference, this is how I rudely persuaded the query builder to run in my nascent major mode:

(defun combobulate-templ-setup ())
(defconst combobulate-rules-templ '())
(defconst combobulate-rules-templ-inverted '())
(add-to-list 'combobulate-setup-functions-alist '(templ . combobulate-templ-setup))
mickeynp commented 9 months ago

Hi Dan,

Thanks for your feedback!

So what you need to do is very simple. (I've reworked it to make it even simpler in a branch due to hit later this week, though.)

  1. Open build-relationships.py.
  2. Amend the dictionary at the top so i downloads the grammar files from the tree-sitter grammar source.
  3. Run build-relationships.py with Python 3.11+. (Updated version coming out soon has a Dockerfile to help with this.)
  4. You should now have the new rules.

From that point on, provided your grammar is installed properly so Emacs can load it, and if combobulate-rules is rebuilt with your grammar json file, you can now use the query builder.

Can you tell me the other problems you ran into in more detail?

mickeynp commented 9 months ago

Oh, I should add: you can invoke combobulate-query-builder from anywhere. It'll ask you for a parser to use, and that feature should work without the rest of combobulate.

danderson commented 9 months ago

(it's Dave, yes the username is confusing and historical, sorry)

Hmm, I'm now not sure what I was doing that made the query builder fail to load. combobulate-mode refused to work due to lack of support, as expected. combobulate-query was also refusing to load the builder, but I think that was user error: I was invoking it on a buffer with no tree-sitter parsers created, prior to bootstrapping the major mode. Doing that results in Wrong type argument: treesit-parser-p, nil. Now that I have a partial mode set up that creates the parsers, combobulate-query and combobulate-query-builder both work happily in the absence of full combobulate support.

I think I was expecting to be prompted with a list of all parsers available to emacs, and for the query builder to create the parser as needed. However, rooting around the treesit elisp APIs, I don't see any way to list all available parsers based on a filesystem trawl, so the only prompt you could offer is "enter a freeform language name and I'll try to treesit-parser-create for you". Alternatively, swapping the nil argument error for some words about me having to create a parser first would have sorted me out.

Assuming you're okay with integrating niche grammars into combobulate, once your rework has landed I'll gladly send a PR for the grammar I'm adding. It's for https://templ.guide, a superset grammar of Go that provides JSX-like functionality (and so leads to interesting nested-languages challenges when writing the major mode! It's been interesting). That said, I also understand if you'd rather focus effort on the important modes first!

danderson commented 9 months ago

Aha, got it to break again after clearing out all my development cruft from my emacs instance. On a language that has no combobulate support, combobulate-query-builder fails after selecting the language you want to query on, with Symbol's value as variable is void: combobulate-rules-<LANG>, where <LANG> is the selected tree-sitter language.

To get the query builder to run, I has to setq both the rules and inverted rules variable to an empty list, as in the original post in the issue.

mickeynp commented 9 months ago

Hi Dave! Sorry about the name mismatch :)

I've pushed a bunch of stuff -- most of it unrelated to this, but it's got some tweaks and fixes around the query builder -- to the development branch.

It includes a number of changes to the build-relationships tool (namely, grammars to get are now specced in sources.ini) and it'll auto-generate a list of known rules, so the query builder should now ask you.

From that point on, you should be able to use the query builder without the rest of Combobulate. I'll work on improving the documentation for this, of course.

(You'll also have proper code completion once the rules are created by the build tool.)

mickeynp commented 7 months ago

This is now easily possible in master.