dgutov / mmm-mode

New official home for mmm-mode, fixed for Emacs >= 23
http://mmm-mode.sourceforge.net/
GNU General Public License v2.0
334 stars 32 forks source link

Indentation not working in vue-mode with recent emacs27 #99

Closed garyo closed 5 years ago

garyo commented 5 years ago

I'm using vue mode, which is based on mmm-mode for editing vue files (part HTML, part Typescript, part CSS). It's all been working fine, until a recent emacs commit: https://github.com/emacs-mirror/emacs/commit/0b3982b1a38 "lisp/emacs-lisp/syntax.el: Use syntax-ppss-table for syntax-propertize." As of that commit, indentation in typescript or javascript sub-modes of vue-mode no longer works at all.

I submitted an emacs bug on it (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37751) but they said to report it here first.

To repro, use a recent Emacs 27 build (newer than June 4, 2019) with this "test.vue" file:

<template>
<h1>hi</h1>
</template>
<script lang="ts">
import * as d3 from 'd3'
function foo() {

}
</script>

with this emacs init file (emacs -q -l init.el test.vue):

(require 'package)
(package-initialize)
(require 'use-package)
(setq use-package-verbose t
      use-package-always-ensure t)

(setq visible-bell t)
(global-font-lock-mode 0)

;;; Vue mode, based on mmm-mode -- set up for .vue files (html/css/script)
(use-package vue-mode
  :mode "\\.vue$"
  )

To see the problem, go to the blank line in function foo and type TAB. It should indent, but instead you'll be left at column 0. I note that (syntax-ppss (point)) returns an indent level of 0 on that blank line in the failing Emacs commit, where it should return 1 (and it does in the prev Emacs commit). However (parse-partial-sexp (point-min) (point)) works in both commits, so it's something about the ppss syntax tables I think.

(I created a vue-mode bug as well, https://github.com/AdamNiederer/vue-mode/issues/99, but he says Vue mode is just a pretty thin wrapper around mmm-mode. So I'm hoping you can give me a clue here.)

garyo commented 5 years ago

Aha, I have a clue. Adding this code appears to fix the problem for me:

(defun fix-mmm-syntax ()
  (save-restriction
    (setq-local syntax-ppss-table typescript-mode-syntax-table)
    ))
(add-hook 'mmm-typescript-mode-enter-hook 'fix-mmm-syntax)

Apparently each mode needs to have its syntax table set into syntax-ppss-table now.

This also works (I'm not sure I understand the details of mmm-mode so please check):

(use-package vue-mode
  :mode "\\.vue$"
  :config
  (add-to-list 'mmm-save-local-variables '(syntax-ppss-table buffer))
  )
dgutov commented 5 years ago

You seem to have missed my reply in here:

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37751#11

garyo commented 5 years ago

Ha, yes I did -- I'm going too fast. :-) Yes, that is exactly what I found too -- thank you for confirming! Much appreciated.

dgutov commented 5 years ago

Thanks for confirming, pushed!

garyo commented 5 years ago

One question -- I see that some vars are saved per buffer, and others are saved globally. I'm not sure which category this var should be in. Your commit saves it globally -- I'm not sure what the difference would be.

dgutov commented 5 years ago

Good point. The difference is minor (global means per-major-mode), but maybe per-buffer is more appropriate since that's how we're saving the local syntax-table.