all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Yuan Fu <casouri@gmail.com>
To: Perry Smith <pedz@easesoftware.com>
Cc: emacs-devel <emacs-devel@gnu.org>
Subject: Re: Foo.html.erb -- major mode
Date: Tue, 13 Dec 2022 23:48:26 -0800	[thread overview]
Message-ID: <4AB94890-7028-49CE-9069-2AE274F9CFDA@gmail.com> (raw)
In-Reply-To: <479CD2BE-EFB5-426C-9C60-D22DBB75745D@easesoftware.com>

[-- Attachment #1: Type: text/plain, Size: 413 bytes --]

> 
> Also, I’ve bumped into the Info page about using Tree Sitter for multi language modes.  Is there an example of a mode that uses multiple languages that I can look at for ideas?

I’ve written a tiny html mode to make sure the multi language APIs make sense. Hopefully I’ll find time to expand it a bit and add a tree-sitter HTML mode. (If you are interested in doing it, please go ahead.)

Yuan


[-- Attachment #2: veb-mode.el --]
[-- Type: application/octet-stream, Size: 2659 bytes --]

;;; veb-mode.el --- HTML mode  -*- lexical-binding: t; -*-

;; Author: Yuan Fu <casouri@gmail.com>

;;; Commentary:

;;; Code:

(require 'treesit)
(require 'js)
(require 'css-mode)

(defvar veb-mode--font-lock-settings
  (append
   (treesit-font-lock-rules

    :feature 'html-tag
    :language 'html
    '((tag_name) @font-lock-comment-face)

    :feature 'html-tag-error
    :language 'html
    '((erroneous_end_tag_name) @error)

    :feature 'html-meta
    :language 'html
    '((doctype) @font-lock-comment-face)

    :feature 'html-comment
    :language 'html
    '((comment) @font-lock-comment-face)

    :feature 'html-attribute
    :language 'html
    '((attribute_name) @font-lock-comment-face)

    :feature 'css-selector
    :language 'css
    '((class_selector) @css-selector)

    :feature 'css-property
    :language 'css
    '((property_name) @css-property)

    :feature 'css-comment
    :language 'css
    '((comment) @font-lock-comment-face))

   (mapcar (lambda (rule)
             (list (nth 0 rule)
                   (nth 1 rule)
                   (intern (format "js-%s" (nth 2 rule)))
                   (nth 3 rule)))
           js--treesit-font-lock-settings)))

(defvar veb-mode--range-settings
  (treesit-range-rules
   :embed 'javascript
   :host 'html
   '((script_element (raw_text) @cap))

   :embed 'css
   :host 'html
   '((style_element (raw_text) @cap))))

(defun veb-mode--language-at (pos)
  (let ((node (treesit-node-at pos 'html)))
    (pcase (treesit-node-type (treesit-node-parent node))
      ("script_element" 'javascript)
      ("style_element" 'css)
      (_ 'html))))

(define-derived-mode veb-mode prog-mode "Veb"
  "A mode for HTML + CSS + Javascript."
  (cond
   ((treesit-ready-p '(html css javascript))
    (treesit-parser-create 'javascript)
    (treesit-parser-create 'css)
    (treesit-parser-create 'html)

    (setq-local treesit-font-lock-settings veb-mode--font-lock-settings)
    (setq-local treesit-font-lock-feature-list
                '((html-tag html-comment html-tag-error)
                  ( html-attribute
                    css-comment css-property css-selector
                    js-comment js-string js-declaration
                    js-string js-keyword js-identifier js-expression
                    js-constant)
                  (js-property js-pattern js-jsx)))
    (setq-local treesit-range-settings veb-mode--range-settings)
    (setq-local treesit-language-at-point-function
                #'veb-mode--language-at)

    (treesit-major-mode-setup))))

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.html\\'" . veb-mode))

(provide 'veb-mode)

;;; veb-mode.el ends here

  parent reply	other threads:[~2022-12-14  7:48 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-13 15:26 Foo.html.erb -- major mode Perry Smith
2022-12-13 16:29 ` Dmitry Gutov
2022-12-13 22:56   ` chad
2022-12-14  7:48 ` Yuan Fu [this message]
2022-12-14  8:08 ` Theodor Thornhill
2022-12-15 15:08 ` Dmitry Gutov

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

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4AB94890-7028-49CE-9069-2AE274F9CFDA@gmail.com \
    --to=casouri@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=pedz@easesoftware.com \
    /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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.