justinbarclay / parinfer-rust-mode

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

Smart mode prevents deleting whitespace if parentheses would change #27

Open andreyorst opened 4 years ago

andreyorst commented 4 years ago

This is a minor inconvenience. Here's an example.

Imagine you've written the let block, and you've just finished writing the expression:

(let ((first-binfing (some-expression with args)|)))

(| represents the point)

Now you want to add second binding. You press enter, and Emacs sets the indentation for you:

image

Oops. You've forgot to escape the binding list, and Emacs thinks that you want to add another form to first binding list. So naturally you simply delete the whitespace with backspace:

image

Uh oh. Parinfer smart mode prevents me from escaping the block. Deleting with backspace doesn't work anymore.

Now I have to press left arrow or C-b:

image

And now you finally can type (:

image

Other parinfer implementations allow deleting and escaping current block. Im not sure if this is a Parinfer rust thing or in your Elisp code.

Again this is not a serious issue, but rather a minor inconvenience.

justinbarclay commented 4 years ago

Sorry for the delay, gmail decided to put my github notifications into spam 🤷‍♀️.

This is mostly linked to parinfer-rust because it can reposition the cursor. I also verified that this behavior is part of the parinfer spec. With this demo set to smart mode it exhibits the same behavior as you've described.

However, I have checked out atom-parinfer and it does follow the behavior you've described.

I think this could be a worthy enhancement

andreyorst commented 3 years ago

I guess this function, when bound to "<backspace>" solves this just fine:

(defun backspace-or-delete-indentation ()
  (interactive)
  (let ((old (point))
        (new (save-excursion
               (back-to-indentation)
               (point))))
    (if (eq old new)
        (delete-indentation)
      (delete-backward-char 1))))

Do you think if your plugin should bind it by default?

EDIT: Ugh, after thinking a bit more, it will not allow to move blocks to top level, so

justinbarclay commented 3 years ago

Hmm from looking at other packages like parinfer for vscode, it seems they set an argument, force-balance, to true when calling into parinfer-rust. One that I never implemented when I was working on the interface for the rust plugin. This is something I plan to work on over my Christmas holiday.

Thanks for continuing to think about this problem and I am sorry I haven't been able to put more time into fixing it.

andreyorst commented 3 years ago

Thanks for continuing to think about this problem and I am sorry I haven't been able to put more time into fixing it.

No worries! I'm currently not using Parinfer as of this moment, mostly because of https://github.com/eraserhd/parinfer-rust/issues/92 -- at work it generates a lot of noise in merge requests or requires me to do a lot of cleanup before pushing, but I'm planning to come back when behavior would be more transparent or when I'll make sure that every project I work on is correctly formatted all the time :)