Option to auto re-indentation
Yevgnen opened this issue · 12 comments
Given
(bind-keys ("C-+" . change-number-at-point)
| ("C-c C-o" . browse-url-at-point)
("C-|" . aj-toggle-fold))
can we add an option to get
(bind-keys ("C-+" . change-number-at-point)
|("C-|" . aj-toggle-fold))
instead of
(bind-keys ("C-+" . change-number-at-point)
|("C-|" . aj-toggle-fold))
after two puni-kill-line
calls like smartparens
?
Not sure if this is a major mode specific issue, but the same 'issue' happens in python-mode
. Sometimes I just want to really kill a line.
def test():
| a = 1
a += 1
return a
def test():
|a += 1
return a
Thanks.
Well, to me this behavior brings more help than trouble. Think about this:
(progn |(a...)
(b...)
(c...))
;; Call `puni-kill-line` twice
(progn |(b...)
(c...))
If (b...)
is a multi-line form, you can then mark the sexp after point and re-indent it.
If we don't re-indent after killing a line, you'll have:
(progn |(a...)
(b...)
(c...))
;; Call `puni-kill-line` twice
(progn | (b...)
(c...))
Now you have to delete those spaces between the point and (b...)
.
I'm very used to this and if I do want to kill a whole line, from the beginning, I move my point to the indentation, then kill the line. I have a custom command bind to C-a
:
(defun toki-beginning-of-line ()
"A smarter version of `beginning-of-line'.
Jump to the beginning of current line, or if the point is already
there, move to the first non-whitespace character in current
line."
(interactive)
(if (and (bolp) (not (puni--line-empty-p)))
(skip-chars-forward "[:blank:]")
(beginning-of-line)))
In your example, I would do this:
(bind-keys ("C-+" . change-number-at-point)
| ("C-c C-o" . browse-url-at-point)
("C-|" . aj-toggle-fold))
;; Call `toki-beginning-of-line`
(bind-keys ("C-+" . change-number-at-point)
|("C-c C-o" . browse-url-at-point)
("C-|" . aj-toggle-fold))
;; Call `puni-kill-line` twice
(bind-keys ("C-+" . change-number-at-point)
|("C-|" . aj-toggle-fold))
Does this make sense?
Hi, thanks for your reply. I'm not sure if I fully understand your statement.
If we don't re-indent after killing a line
I do want re-indentation.
For these examples,
def test():
|a += 1
return a
and
(bind-keys ("C-+" . change-number-at-point)
|("C-|" . aj-toggle-fold))
I need to re-indent manually by TAB
or indent-region
which is I'm trying to avoid. (I consider they are unindented because if they are not, a subsequent call to indent-region
should not change them.)
if I do want to kill a whole line, from the beginning, I move my point to the indentation, then kill the line.
I also use mwim for moving between bol
and indentation. But if without auto re-indentation, I just need to re-train my muscle memory :)
@Yevgnen I'm not sure if auto-reindentation is in the scope of puni (or if it should be in its scope). But I'm happily using aggressive-indent-mode together with puni to have that feature, and not just in lisp but all prog-mode buffers where emacs knows indentation rules.
@tsdh Hi, thanks for your suggestion. I just try aggressive-indent-mode
. It does re-indent the line after double kills. But I see there's delay of the re-indentation even I've set aggressive-indent-sit-for-time
to zero. Also, it seems too aggressive for me in other scenarios :)
I'm not sure if auto-reindentation is in the scope of puni (or if it should be in its scope).
Yes...Maybe I should just advise the commands to re-indent instead of adding an option.
If we don't re-indent after killing a line
I do want re-indentation.
Sorry I didn't put it clearly. What Puni does is: when you call puni-kill-line
, it calculates the current indentation, then do the kill. Then, if the next line is brought to the current line, it drags the first non-blank char of that line to the current indentation.
I call this "re-indentation" but actually it's not the same as what we may usually mean by "re-indentation" (say, pressing TAB
).
Since you put the cursor at the beginning of the line, kill the line itself, then kill the newline character, the indentation is zero when you do the second kill, that causes your problem.
The remedy is:
- set
kill-whole-line
tot
(so you kill the line and the newline char at the same time). - or move to the indentation first, then do the kill.
The problem of not doing the "re-indentation" is shown in the example I gave:
(progn |(a...)
(b...)
(c...))
;; Call `puni-kill-line` twice
(progn | (b...)
(c...))
You could try this by calling the built-in kill-line
twice.
I am not opposed to adding a user option, but we have to think about how to deal with the above situation.
Hi, thanks for the clarification.
I didn't know about the kill-whole-line
variable. It works pretty well when one do really want to kill the line without subsequent insertions. Otherwise, one will still have to bring the cursor back to indentation and open a new line.
In my option, puni-kill-line
is more like kill-sexp
than kill-line
in some situations (although it could indeed kill both things). So I expected the following result like before I tried
(progn |(a...)
(b...)
(c...))
;; Call `puni-kill-line`, just like `kill-sexp` or `sp-kill-sexp`
(progn |
(b...)
(c...))
;; One more `puni-kill-line`
(progn |
(c...))
But I agree that the current double puni-kill-line
is convenient for the above example.
I've fixed the initial example with C-k
with the following advice:
(define-advice puni-kill-line (:before (&rest _))
"Go back to indentation before killing the line if it makes sense to."
(when (looking-back "^[[:space:]]*")
(back-to-indentation)))
@andreyorst I tried this advice and it feels really good ;) Can I use your code and make it a user option?
@andreyorst I tried this advice and it feels really good ;) Can I use your code and make it a user option?
sure!
@AmaiKinono actually, I've changed the advice a bit:
(define-advice puni-kill-line (:before (&rest _))
"Go back to indentation before killing the line if it makes sense to."
(when (looking-back "^[[:space:]]*")
(if (bound-and-true-p indent-line-function)
(funcall indent-line-function)
(back-to-indentation))))
I've redesigned the behavior to (hopefully) make everyone happy. Feel free to reopen this if you still find it inconvenient.
@AmaiKinono Now, when I kill-line in a message-mode buffer, the formerly next line becomes the current one (as it should be) but also gets indented.
Oh, also reproducible with text-mode or fundamental-mode. I have a buffer with this text.
|This is a sentence. This is another one. Together, we are the whole
paragraph. This is a sentence. This is another one. Together, we are the
whole paragraph. This is a sentence. This is another one. Together, we are
the whole paragraph. This is a sentence. This is another one. Together, we
are the whole paragraph.
The |
represents point. I hit C-k
twice (puni-kill-line
). I end up with this:
|paragraph. This is a sentence. This is another one. Together, we are the
whole paragraph. This is a sentence. This is another one. Together, we are
the whole paragraph. This is a sentence. This is another one. Together, we
are the whole paragraph.
Also puni-kill-line
at the end of the buffer repeatedly inserts more spaces.
I guess that's not what's intended. I don't have the ability to re-open this issue.