From: Simon Pugnet <simon@polaris64.net>
To: Emacs developers <emacs-devel@gnu.org>
Subject: Tree sitter: issue embedding HTML, CSS, JavaScript within a new php-ts-mode
Date: Thu, 09 Feb 2023 12:45:19 +0000 [thread overview]
Message-ID: <87o7q3ngu8.fsf@polaris64.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 4063 bytes --]
Dear Emacs maintainers,
I have recently started work on a PHP tree sitter major mode. Things
are going well so far, however I'm having trouble with embedding
multiple languages in the PHP buffer.
In case you're not familiar with PHP, here's a quick example (I'm
using org-mode mark-up in this message which hopefully will help): -
#+begin_src php
<html lang="en-gb">
<head>
<style type="text/css">
body {
background: url("/background.png");
color: #ff0000;
}
</style>
</head>
<body>
<?php
$a = [1, 2, "3", 4.5];
if (is_array($a)) {
echo "$a is an array";
} else {
echo "$a is not an array";
}
?>
<div id="my-div">
<h1>This is a test</h1>
</div>
<script type="text/javascript">
const div = document.getElementById('my-div');
// This is a JS comment
/* This too */
console.log("my-div is:", div);
</script>
<?php // Some more PHP here ?>
</body>
</html>
#+end_src
As you can see, PHP code is usually encapsulated within a HTML
document, with PHP code enclosed within ~<?php ... ?>~ blocks.
The first block of HTML from the beginning of the buffer to the first
~<?php~ is enclosed within a ~(program (text))~ node. The second
(after ~?>~ and before the second ~<?php~) is enclosed within a
~(text_interpolation (text))~ node. I have therefore defined the
following ~treesit-range-settings~ in my major mode: -
#+begin_src emacs-lisp
(setq-local treesit-range-settings
(treesit-range-rules
:embed 'html
:host 'php
'((program (text) @capture)
(text_interpolation (text) @capture))))
#+end_src
This seems to work however when I evaluate ~(treesit-language-at
(point))~ anywhere in this buffer I get ='html= in response. This is
of course expected within a HTML region, but not within a PHP region.
Despite this, the font-locking I have defined for PHP appears to work
correctly. I have also defined a custom face and applied it via
font-locking to the above two nodes to confirm that those regions are
indeed enclosed as expected and they are.
My hope eventually is to use the following ~treesit-range-settings~: -
#+begin_src emacs-lisp
(setq-local treesit-range-settings
(treesit-range-rules
:embed 'html
:host 'php
'((program (text) @capture)
(text_interpolation (text) @capture))
:embed 'css
:host 'html
'((style_element (raw_text) @capture))
:embed 'typescript
:host 'html
'((script_element (raw_text) @capture))))
#+end_src
As well as defining these rules, I require =css-mode= and
=typescript-ts-mode= and append their own font-locking rules to my
own. My hope is that this will allow CSS and JavaScript embedded
within HTML regions to be font-locked according to those separate
major modes too. This appears to work for simple files but does not
work reliably for more complex files. Also when using the above I get
='typescript= whenever I evaluate ~(treesit-language-at (point))~. I'm
not sure if this is just a bug with the language grammars that I'm
using or if perhaps because I'm not using the treesit library
correctly. Because of the issue with ~treesit-language-at~ above I'm
concerned that it's the latter.
So my questions are: -
1. Based on my rules for embedding ='html= within ='php= above, should
I expect ~(treesit-language-at (point))~ to return ='php= when the
point is within a PHP region?
2. Is my goal of embedding HTML within PHP, then embedding CSS and
JavaScript/TypeScript within HTML feasible and if so am I going about
this in the right way?
Thank you in advance for your help and thank you for all of your work
on Emacs and the tree sitter integration.
Kind regards,
--
Simon Pugnet
https://www.polaris64.net/
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 861 bytes --]
next reply other threads:[~2023-02-09 12:45 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-09 12:45 Simon Pugnet [this message]
2023-02-10 5:45 ` Tree sitter: issue embedding HTML, CSS, JavaScript within a new php-ts-mode Yuan Fu
2023-02-10 11:40 ` Simon Pugnet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o7q3ngu8.fsf@polaris64.net \
--to=simon@polaris64.net \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).