Open yuhan0 opened 5 years ago
Note that this is slightly different from #300, because it can often be ambiguous where closing parens should go:
;; unbalanced
(defn foo
[bar {:a 1 baz (quux))
;;============================
;; a few possible "solutions"
(defn foo
[bar {:a 1 baz (quux)}])
(defn foo
[bar {:a 1} baz] (quux))
(defn foo
[bar] {:a 1} baz (quux))
So an automatic function to close all parens won't be sufficient - the user should be able to navigate to each point and insert them manually.
The logic here is actually cheating a bit. We never even check if the buffer is unbalanced, we just assume it is and prevent the user from inserting the closing delimiter.
This can be improved for sure, it sounds like a nice challenge. The main issue here, as always, is performance. Since we don't keep any state sometimes this might require a re-parse of the entire buffer and that can blow up.
As a shitty solution I can offer you to use C-q
with which you can insert anything and smartparens will ignore all the checks.
Yeah, I've been using the C-q
workaround so far, or r
from evil normal state, but it's definitely not optimal in terms of editing flow.
I would be glad to try helping with this, any pointers on where/how to start tackling it? I tried briefly to read through the relevant portions of the code but the API seems quite complicated.
I think that sp-skip-closing-pair
is the place.
Now that I think about it more... it might be possible to do this somehow because we actually do the parse anyway to determine the point out of which we want to jump out. So the data is in a sense computed but then thrown away because on failure the parser just returns nil
and not, for example, the furthest opening delim which caused the failure to match. With this information we could determine if we are over- or under- balanced, and in the under- case allow the insertion.
The two situations are:
(foo bar | ;; under-balanced, allow insertion
(foo bar) | ;; over-balanced, do not allow insertion.
The buffer actually parsed would be (foo bar )
or (foo bar ))
(i.e. we temporarily insert the delimiter).
So at least this simple case should be quite easy to implement. As for inserting </div>
or something similar, I'm not so sure.
Expected behavior
With
smartparens-strict-mode
enabled, I occasionally run into situations where the buffer is in an unbalanced state with missing closing delimiters.It would be nice to "correct" the situation by simply typing the closing parens in the appropriate places, like a regular editor would let you do.
Actual behavior
Nothing is inserted, the expressions remain unbalanced with the message printed:
This can be quite frustrating - after all the intention is to insert a balanced closing delimiter, and strict mode should be smart enough to detect that and allow the "correction" to go through.
It would be even better if Smartparens could detect the closest unbalanced opening and automatically insert the corresponding closing pair, e.g. allowing the user to type an easy-to-reach closing pair such as
]
to insert#-}
or</div>
or\end{section}
Steps to reproduce the problem
(foo bar
)
Environment & version information
In recent enough
smartparens
you can callM-x sp-describe-system
to generate this report. Please fill manually what we could not detect automatically. Edit the output as you see fit to protect your privacy.smartparens
version: 20190103.2309major-mode
:python-mode
M-x emacs-version
): GNU Emacs 27.0.50 (build 1, x86_64-apple-darwin17.6.0, NS appkit-1561.40 Version 10.13.5 (Build 17F77)) of 2018-07-08