Open bpstahlman opened 7 years ago
@bpstahlman C-f seems to be the only way, but you can bind (kbd "\"") to lispy-doublequote if you want " to terminate.
I have a slightly related question: How to delete an empty string?
I would expect DEL and C-d, but they go in and out of quotes without deleting anything. Even M-x lispy-splice removes parentheses instead of quotes. Maybe I'm lacking creativity, but tell me how to delete an empty string?
@Somelauw With point inside the empty string, DEL moves point just to the right of the empty string (just past the closing "
). From that position, a subsequent DEL will delete the entire string.
@bpstahlman thanks, there is a difference between lispy-delete-backward and lispy-backward-delete and I was using the latter instead of the former.
I see that I can hit C-f in this situation. Is that the recommended way?
Yes, that's what I do. Using lispy-alt-line
, which I bind to RET in my own config also works to escape strings.
@Somelauw When inside a string, delete it:
@abo-abo Ok. Thanks. I wasn't aware of lispy-alt-line
as it doesn't appear in the documentation. Just found it in lispy.el. Fwiw, I would say that in the case of strings (unlike lists), needing to "escape from" the sexp is much more common than needing to nest a pair of delimiters within it, to the point that most users would probably be fine with doing something extra to get the nesting behavior if it meant they could simply hit "
in the common case to escape from the string. Even more significant than the extra keystroke is the violation of the "principle of least surprise," which can be especially problematic for new users. (My son was thrown by the same thing when he started using lispy a few days ago... ;-) But perhaps backwards-compatibility is the issue...
@bpstahlman I've just gone to binding \" to nil in lispy-mode-map, and letting smartparens take care of that pair.
@abo-abo What is the rationale for having to call lispy-delete or lispy-delete-backward twice to delete empty strings? You can already lispy-alt-line or C-f/b to move out of the empty string.
The way deleting empty lists works from within is inconsistent as well. From (|), lispy-delete-backward will kill the pair, but lispy-delete will first move point out of pair and require another keypress.
What is the rationale for having to call lispy-delete or lispy-delete-backward twice to delete empty strings?
I'll give an example. In this case, it's correct to delete at once with C-d, since the cursor is before an atom (it's like you press C-d on one char):
|"test"
But what about C-d in this case:
"test|"
It feels unnatural for C-d to delete backwards. So the first C-d will move out backwards, to reduce the deletion to the natural case. Works exactly the same way with lists.
I think the consistency could be improved.
You are correct that C-d from the following states are equivalent:
(test|)
"test|"
But here:
(|test)
lispy-delete-backward will remove the entire sexp immediately, and I find this intuitive, because in the following, backspace will kill the pair (but, another inconsistency, C-d won't).
(|)
If it feels unnatural to kill a whole atom when deleting from within, that's ok, but I think the behavior when backspacing or C-d from within an empty list or string should always be just to kill the pair.
I think this could be accounted for with a variable `lispy-delete-atom-from-within'. When true, C-d from any of the following:
(|)
(foo|)
"|"
"foo|"
or backspace from one of the following:
(|)
(|fooo)
"|"
"|bar"
Will always just kill the whole thing.
Thoughts? If you think this is ok but don't want to spend time on it, I could make a PR
Thoughts? If you think this is ok but don't want to spend time on it, I could make a PR
sounds good.
I think it may make more sense to rename the variable to something like lispy-delete-string-or-sexp-from-within
or lispy-delete-entire-from-within
since "atom" only describes the string part.
I guess string-or-sexp is most descriptive
@noctuid I agree. @sooheon Either string-or-sexp
or plain sexp
is fine with me.
Stupid question, I'm not all too well versed in Emacs, how do I bind " to nil in the lispy-mode-map? Doing (define-key lispy-mode-map (kbd "\"") nil)
doesn't do anything.
@sondr3
(define-key lispy-mode-map-lispy (kbd "\"") nil)
Thanks you @abo-abo, that worked 😄
I believe this issue could be closed unless there's an intention to make lispy-doublequote
the default behavior for "
which I think fits more naturally according to what the main point of the issue was. It would be even better if this function would actually insert a \"\"
if we are not at the end of the string instead of a single \"
but that's a minor nitpick, (define-key lispy-mode-map-lispy (kbd "\"") 'lispy-doublequote)
is enough for me.
When I hit
"
to enter a quoted string, Lispy inserts a pair of quotes and leaves point between them to allow me to enter the text of the string. This feels natural and is pretty much the way lisp editors generally work (and the way paren pairs work even in Lispy). When I've finished entering the string, however, there doesn't appear to be a natural way to terminate the string and move on to insert the next sexp. Initially, I would hit"
, expecting point to move past the closing quote, but this resulted in a pair of escaped quotes being inserted in the string. I can imagine that there are situations in which you'd want a pair of escaped quotes inside the string, but this is a much less common use case than the one in which you simply want to hit"
to terminate the string. I see that I can hitC-f
in this situation. Is that the recommended way? Is the reason for not making the "move past terminating quote" functionality the default that this would force the "insert pair of escaped quotes" functionality to be moved to something likelispy-quotes
with a negative arg (since positive arg is already used to unquote a string)?