jdtsmith / indent-bars

Fast, configurable indentation guide-bars for Emacs
GNU General Public License v3.0
335 stars 13 forks source link

indent-bars-mode conflicting with prism-whitespace-mode #61

Closed shipmints closed 4 days ago

shipmints commented 5 days ago

I haven't done an analysis to see what it's stuck doing but it shouldn't take 15 seconds to disable it for a single buffer. I will try to reproduce in emacs -Q. For what it's worth, indent-bars-mode on MacOS without stipple support and char-mode enabled, works in elisp buffers but not in python buffers. Perhaps whatever is interfering with it is what is causing the issue. No backtrace or any clues.

shipmints commented 5 days ago

If I disable prism-whitespace-mode, indent-bars works and disabling is faster. There's some negative interaction between these packages. I don't know if Adam @alphapapa is using both modes (yet!) but it is worth looking into. prism and indent-bars work fine together in elisp buffers.

jdtsmith commented 5 days ago

It should be instantaneous to enable/disable. Is emacs responsive during this 15s? Is this happening even without treesit? Certainly should work in Python buffers; that's where I use it most.

Check Messages to see if there are any vague font-lock errors reported when you have prism on? I'm not sure how/why prism would interfere with indent-bars, since it appears to style text only (parens, blocks, etc.), and this mode only styles spaces and tabs at the beginning of lines. Now, if it overwrites 'face or display over full blocks of text in a jit-lock function of its own, and comes later than indent-bars, it will overwrite the bars. For fixing that, it might work to enable indent-bars last in your mode hook. The same thing happens with e.g. Python multi-line strings, but indent-bars runs after font-lock when needed, and so overcomes that.

shipmints commented 5 days ago

More clues. This is indent-bars ts support disabled, prism-whitespace-mode, debug on error, on in a python buffer and manual M-x indent-bars-mode toggle off. Could be a red herring.

  scan-sexps(45204 1)
  forward-sexp(1)
  python-nav--lisp-forward-sexp(1)
  python-nav--forward-sexp(1 nil nil)
  python-nav-forward-sexp(1)
  forward-sexp(1)
  prism-match-whitespace(59284)
  font-lock-fontify-keywords-region(1 59284 nil)
  font-lock-default-fontify-region(1 59284 nil)
  font-lock-fontify-region(1 59284)
  #f(compiled-function (fun) #<bytecode -0x157012a4e8839783>)(font-lock-fontify-region)
  run-hook-wrapped(#f(compiled-function (fun) #<bytecode -0x157012a4e8839783>) font-lock-fontify-region)
  jit-lock--run-functions(1 59284)
  jit-lock-fontify-now(1 59284)
  font-lock-ensure()
  indent-bars-teardown()
  (if indent-bars-mode (if (and (daemonp) (not (frame-parameter nil 'client))) (add-hook 'after-make-frame-functions #'indent-bars-setup-and-remove nil t) (indent-bars-setup)) (indent-bars-teardown))
  (let ((last-message (current-message))) (setq indent-bars-mode (cond ((eq arg 'toggle) (not indent-bars-mode)) ((and (numberp arg) (< arg 1)) nil) (t t))) (if (boundp 'local-minor-modes) (progn (setq local-minor-modes (delq 'indent-bars-mode local-minor-modes)) (if indent-bars-mode (progn (setq local-minor-modes (cons 'indent-bars-mode local-minor-modes)))))) (if indent-bars-mode (if (and (daemonp) (not (frame-parameter nil 'client))) (add-hook 'after-make-frame-functions #'indent-bars-setup-and-remove nil t) (indent-bars-setup)) (indent-bars-teardown)) (run-hooks 'indent-bars-mode-hook (if indent-bars-mode 'indent-bars-mode-on-hook 'indent-bars-mode-off-hook)) (if (called-interactively-p 'any) (progn nil (if (and (current-message) (not (equal last-message (current-message)))) nil (let ((local " in current buffer")) (message "%s %sabled%s" "Indent-Bars mode" (if indent-bars-mode "en" "dis") local))))))
  indent-bars-mode(toggle)
  funcall-interactively(indent-bars-mode toggle)
  #<subr call-interactively>(indent-bars-mode record nil)
  apply(#<subr call-interactively> (indent-bars-mode record nil))
  (let* ((bufferlo--anywhere-old-read-buffer-function (if bufferlo--anywhere-nested bufferlo--anywhere-old-read-buffer-function read-buffer-function)) (bufferlo--anywhere-nested t) (read-buffer-function #'(lambda (prompt &optional def require-match predicate) (let ((read-buffer-function bufferlo--anywhere-old-read-buffer-function)) (read-buffer prompt def require-match #'...))))) (apply oldfn (list function record-flags keys)))
  (if (or bufferlo--anywhere-tmp-enabled (and (not bufferlo--anywhere-tmp-disabled) (xor (eq bufferlo-anywhere-filter-type 'exclude) (cond ((eq bufferlo-anywhere-filter t) t) ((listp bufferlo-anywhere-filter) (memq function bufferlo-anywhere-filter)) ((functionp bufferlo-anywhere-filter) (funcall bufferlo-anywhere-filter function)))))) (let* ((bufferlo--anywhere-old-read-buffer-function (if bufferlo--anywhere-nested bufferlo--anywhere-old-read-buffer-function read-buffer-function)) (bufferlo--anywhere-nested t) (read-buffer-function #'(lambda (prompt &optional def require-match predicate) (let (...) (read-buffer prompt def require-match ...))))) (apply oldfn (list function record-flags keys))) (let ((read-buffer-function (if bufferlo--anywhere-nested bufferlo--anywhere-old-read-buffer-function read-buffer-function))) (apply oldfn (list function record-flags keys))))
  bufferlo--interactive-advice(#<subr call-interactively> indent-bars-mode record nil)
  apply(bufferlo--interactive-advice #<subr call-interactively> (indent-bars-mode record nil))
  call-interactively(indent-bars-mode record nil)
  command-execute(indent-bars-mode record)
  execute-extended-command(nil "indent-bars-mode" "indent-bars")
  funcall-interactively(execute-extended-command nil "indent-bars-mode" "indent-bars")
jdtsmith commented 5 days ago

What was the error? This seems to happening in prism code.

If you just M-: (font-lock-ensure) in a buffer with prism-mode enabled (leaving indent-bars out of it), does that cause a similar error/slowdown?

shipmints commented 5 days ago

Font lock is broken with the file I was trying to edit. I guess I should report this to the bug list. The "That:" in the multi-line comment screws it up. I haven't tried without treesit. I'll do that now. Edit: font-lock works fine without treesit. This could be the cause of some issues. What do you think?

#!/usr/bin/env python

def foo:
    pass

class bar:
    def func:
        """
        This: is a comment.
        That: is a comment.
        """
        if True:
            pass

def baz:
    if True:
        if True:
            if True:
                print('True')
image
shipmints commented 5 days ago

I updated my grammars. Will monitor. It surprises me (I'm new-ish to treesitter) that any program that python3 can run is not considered acceptable and that the grammar writers/font-lock writers have an opinion about what well-formed programs might be that differs from the compiler/interpreter platform itself.

I also can't understand why they don't build version numbers into the grammars to interrogate along with compiler traces. How the heck do they enjoy supporting the ecosystem. I feel for Joao, too, the LSP world seems the same.

jdtsmith commented 5 days ago

If you haven't updated python-mode.el in a while, you might. Its sexp navigation was hanging on partially open multi-line strings. If font-lock hangs up it might be the cause. This file works fine for me in python-ts-mode:

image

Not sure why treesitter grammars are not versioned, but it's a pain.

alphapapa commented 5 days ago

FWIW, I use prism-whitespace-mode with Python buffers (not using Tree-Sitter), and it works fine. Also, I've been using prism-whitespace-mode with indent-bars-mode in a large YAML buffer, and it works fine.

So I doubt the problem is prism-whitespace-mode; if there is a bug in it (which isn't impossible), it should probably manifest without indent-bars-mode being involved.

jdtsmith commented 4 days ago

@shipmints I think if a bug or package incompatibility remains here you need to put some work into isolating it, starting with emacs -Q. Let me know.

jdtsmith commented 4 days ago

Other reports indicate there is no conflict between the 2 packages, so this must be an issue specific to your config. Can re-open if not.