justinbarclay / parinfer-rust-mode

Simplifying how you write Lisp
https://shaunlebron.github.io/parinfer/
GNU General Public License v3.0
227 stars 16 forks source link

Strange behavior in some Elisp files #91

Closed abougouffa closed 3 months ago

abougouffa commented 3 months ago

When editing some Elisp files (like this one), I get a strange and annoying behavior where, on every edit, Emacs freezes for a moment and the buffer scrolls to the end.

I've enabled parinfer-rust-toggle-debug and you can find the debug logs attached. It seems to be a kind of an infinite loop.

parinfer-rust-debug.txt

Screencast_20240517_172654.webm

justinbarclay commented 3 months ago

That does look frustrating and not something that came up in my testing, so thank you for reporting this.

I think (remove-hook 'parinfer-rust-mode-hook 'parinfer-rust--auto-apply-fast-mode) should fix your issue, though on a 2000 line files, parinfer will also feel pretty sluggish IME.

If this resolves the issue for you, please let me know.

abougouffa commented 3 months ago

Hi @justinbarclay ,

Thanks for the reply,

The snippet worked, there is no more jumping. However, editing still very slow, especially on big files. I'm using parinfer-rust-mode for several years now, and it is the first time I'm facing a problem in big files! So I guess this should be a bug of some sort and not an actual limitation of parinfer.

I've also noticed a problem when trying to undo changes using vundo, at some time I get a problem from track-changes which is used only by parinfer-rust-mode. However, I'm not able to reproduce this behavior right now.

justinbarclay commented 3 months ago

The snippet worked, there is no more jumping.

Great, I'll probably disable this snippet in an update this weekend.

I'm using parinfer-rust-mode for several years now, and it is the first time I'm facing a problem in big files!

That's weird because I've always experienced slowness with buffer > 1000 lines.

You could try using v0.8.8, which was the last tag before I changed strategies for how I communicated with parinfer-rust. Or v0.8.7, which is the last tag before I changed the change tracking library. If those don't work, I'm curious what version you were on where it was running quickly because I haven't changed anything that should affect performance in a long time.

I've also noticed a problem when trying to undo changes using vundo, at some time I get a problem from track-changes which is used only by parinfer-rust-mode

Yeah... I've found implementing things for track-changes difficult to get right. I thought I ironed out most of the bugs but I'll see if I can trigger anything with undo/vundo. Thanks for letting me know.

abougouffa commented 3 months ago

Hi again @justinbarclay,

Thank you for your reply!

That's weird because I've always experienced https://github.com/justinbarclay/parinfer-rust-mode/issues/38 with buffer > 1000 lines.

Yes, I confirm, just I feel like it is a bit slower now. Maybe it is just a matter of perception!

I'm curious what version you were on where it was running quickly because I haven't changed anything that should affect performance in a long time.

I'm on the latest version d3bfb2745cc0858e2741dc2a2f00a86f456656ec (installed from MELPA) with parinfer-rust-emacs v0.4.6.

There is another issue when I open Elisp files. I hook parinfer-rust-mode to emacs-lisp-mode-hook, and sometimes, even though parinfer is enabled (parinfer-rust-mode evaluates to t), I see no effect on parenthesis when editing. I will see if I can find a minimal snippet that reproduces this behavior.

Edit

Here is an example that sometimes happens when trying to make any changes, here, I'm trying to enter a character in the file, which doesn't work and produce this error:

Debugger entered--Lisp error: (error "Unregistering a non-registered tracker: nil")
  error("Unregistering a non-registered tracker: %S" nil)
  track-changes-unregister(nil)
  parinfer-rust--check-for-issues()
  newline(nil 1)
  funcall-interactively(newline nil 1)
  command-execute(newline)
justinbarclay commented 3 months ago

All right, sorry for the delay. I just made a slew of changes, one of which is that parinfer-rust--auto-apply-fast-mode is no longer set by default. However, I have worked hard to improve the characteristics of the fast buffer-replace strategy. Now, there is only a slight stutter in the buffer when you first start editing a buffer where pixel-scroll-precision-mode is enabled.

Which you can see here:

There is another issue when I open Elisp files. I hook parinfer-rust-mode to emacs-lisp-mode-hook, and sometimes, even though parinfer is enabled (parinfer-rust-mode evaluates to t), I see no effect on parenthesis when editing. I will see if I can find a minimal snippet that reproduces this behavior.

I noticed a bug where if a buffer was in a modified state before parinfer-rust-mode was enabled, it sometimes didn't fully activate. I've resolved that, so hopefully, this was the same issue you were experiencing.

Here is an example that sometimes happens when trying to make any changes, here, I'm trying to enter a character in the file, which doesn't work and produce this error:

Even in all my testing this week, I never encountered this issue, but I have played around with the machinery for parinfer-rust--check-for-issues, so with any luck, the changes I made helped here.

abougouffa commented 3 months ago

Thank you very much for your responsiveness @justinbarclay

I will update my Parinfer installation and test it. Thanks again!

justinbarclay commented 3 months ago

Awesome, I hope it at least alleviates some of the bugs 😅.

justinbarclay commented 3 months ago

Hey, I'm just looking to follow up. I'm wondering if parinfer has been behaving better for you

abougouffa commented 3 months ago

Hi @justinbarclay ,

Yes, I've been hacking with Elisp these days and I see that most of the issues have gone. Only some issues related to track-changes persist (mainly, when trying to vundo a non linear undo tree, buffers corresponding to some states popup randomly).

justinbarclay commented 3 months ago

Thanks for the clarification. I've moved this to issue #94, making it easier to find if others encounter it. Unfortunately, I don't have a good idea of a fix for this bug yet. My cursory glance at the issue suggests that it's happening because Vundo is making the buffer read-only for some amount of time. If that's the case, it violates a constraint of parinfer as well, as it can run anytime the buffer changes.

Maybe a solution would be for vundo to provide a hook for users to disable some minor modes when vundo is invoked in a buffer? Then it's up to the user to set up parinfer-rust-mode to disable and enable at the appropriate times? vundo-enter-hook vundo-exit-hook

justinbarclay commented 3 months ago

@abougouffa So I dug into a little bit vundo a little bit today and I think this might help solve your issue.

(use-package parinfer-rust-mode
  ;; ...
  :config
  (add-hook 'vundo-pre-enter-hook (lambda () (parinfer-rust-mode 0) nil t))
  (add-hook 'vundo-post-exit-hook (lambda () (parinfer-rust-mode 1) nil t)))
abougouffa commented 3 months ago

Thank you so much @justinbarclay

Yep, that's what I did in my config, here is my snippet in case anyone faces the same issue:

;; HACK: Disable `parinfer-rust-mode' on some commands.
(defvar-local +parinfer-rust--was-enabled-p nil)

(defun +parinfer-rust--restore (&rest _)
  (when +parinfer-rust--was-enabled-p
    (setq +parinfer-rust--was-enabled-p nil)
    (parinfer-rust-mode 1)))

(defun +parinfer-rust--disable (&rest _)
  (setq +parinfer-rust--was-enabled-p (bound-and-true-p parinfer-rust-mode))
  (when +parinfer-rust--was-enabled-p
    (parinfer-rust-mode -1)))

;; Fix the issue of `vundo` (related to `track-changes`) when exploring the undo tree
(with-eval-after-load 'vundo
  (add-hook 'vundo-pre-enter-hook #'+parinfer-rust--disable)
  (add-hook 'vundo-post-exit-hook #'+parinfer-rust--restore))

Edit 2

It seems to be a problem in my original tweak above, I was testing on a removed variable parinfer-rust-enabled in the +parinfer-rust--disable function, causing it to not disable the mode correctly. The hack above works fine now!

~Edit 1~

~Disabling parinfer-rust-mode don't solve the track-changes issue, the annoying message keeps showing and opens another window with the same buffer~

image