fxbois / web-mode

web template editing mode for emacs
https://web-mode.org
GNU General Public License v3.0
1.63k stars 262 forks source link

Proposal for a web-minor-mode #1218

Closed bigodel closed 2 years ago

bigodel commented 2 years ago

hi! i'd like to propose implementing a web-minor-mode, similar to what js2-mode does with its js2-minor-mode. the rationale behind it would be that for some cases, such as when editing JSX or TSX files, it would be desirable to use the major mode as a js-mode or typescript-mode derived mode in order to enable tree-sitter on it, making use of tree-sitter objects and syntax highlighting, while at the same time having the facilities to jump and edit tags and attributes and possibly using web-mode's indentation.

i tried setting tree-sitter on a web-mode buffer as well, and i think that would work instead of the minor mode -- even though i still think that the minor mode could be valuable -- but it fails to ultimately highlight the buffer using tree-sitter-hl-mode. i tried the following (this requires that both tree-sitter and tree-sitter-langs are installed).

(add-to-list 'tree-sitter-major-mode-language-alist '(web-mode . tsx))
(tree-sitter-require 'tsx)
(tree-sitter-mode t)
(tree-sitter-hl-mode t)

on a TSX buffer with web-mode as a major mode (also with a derived mode typescript-tsx-mode, derived from web-mode, and on JSX buffers in both cases as well, "pure" web-mode and a derived mode), but it fails with

Debugger entered--Lisp error: (wrong-number-of-arguments #<subr quote> 0)
  quote()
  font-lock-eval-keywords(quote)
  tree-sitter-hl--minimize-font-lock-keywords()
  #<subr tree-sitter-hl--setup>()
  apply(#<subr tree-sitter-hl--setup> nil)
  tree-sitter-hl--setup()
  tree-sitter-hl-mode()

which is, as the stacktrace points out, happening when tree-sitter-hl-mode tries to load font-lock-defaults, which is set to '('(web-mode-fontify) t) on web-mode buffers -- i think this is a typo, btw. that second quote before (web-mode-fontify) shouldn't be here, should it?. and i also tried setting it to ((web-mode-fontify) t) but it also fails with wrong number of arguments, because font-lock is trying to call it with no arguments (don't really know how it all works, tbh), but it expects a single argument.

i managed to get a hacky ad hoc web-minor-mode working on Emacs 28.0.90. it loads web-mode without calling its hooks, and then loads the previous major-mode back, retaining most of web-mode's bindings on the minor mode

fxbois commented 2 years ago

@bigodel thank you for this

bigodel commented 2 years ago

@bigodel thank you for this

you're very much welcome! web-mode is amazing and it think it'd be even more amazingier if we could use part of its features outside of it. i haven't submitted a PR for this because i didn't manage to understand what and which parts of web-mode.el could and should be loaded on a minor mode, though. so i did the hacky solution of just loading it and reloading the previous mode again, which seems to be working fine for navigation and most of the editing features. i think that indentation could also be handled by this proposed minor mode, but maybe as an user option (TSX with tree-sitter won't indent the HTML-like tags or its attributes correctly, and we still don't have a working tree-sitter-indent, but i give it a couple of months until we have something in that space).