Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evil/Vim's $ command and end-of-line behavior #2525

Closed
darkfeline opened this issue Aug 3, 2015 · 32 comments
Closed

Evil/Vim's $ command and end-of-line behavior #2525

darkfeline opened this issue Aug 3, 2015 · 32 comments

Comments

@darkfeline
Copy link
Contributor

I noticed recently that Spacemacs now allows the cursor to move "beyond" the end of the line, which Vim/vi does not traditionally allow. I think this change is great because some Emacs functionality assumes the ability to do so, such as eval-last-sexp.

However, I'm not entirely sure if the $ command should move beyond the end of the line or to the final character in the line. Currently, it does the former, but coming from Vim I am used to the latter. In particular, with the former, $i and $a both do the same thing, appending to the end of the line, but with the latter, there's the option of doing $i to insert before the last character in the line. However, the former is useful in conjunction with, e.g., eval-last-sexp. Perhaps $ should work like in Vim and a new g$ command for moving beyond the end of a line?

I'm interested in hearing what other users think about this.

@syl20bnr
Copy link
Owner

syl20bnr commented Aug 3, 2015

That's a very tricky situation. I see no satisfying solution, even a blend of the two behaviors is not ideal.
Let hear what people have to say about it and I'll tell what I think about this case afterwards.

@TheBB
Copy link
Collaborator

TheBB commented Aug 3, 2015

This implements @darkfeline's g$ idea. I'll take it for a test drive and report back in a few days.

Vim and Evil have separate motions for beginning of line, too: ^ moves to the first non-blank character and 0 moves to column zero, so I would say separating end of line and last nonblank character isn't too controversial, even though it's only really useful (outside of this issue) for people with lots of trailing whitespace.

(evil-define-motion evil-last-non-blank (count)
  "Move the cursor to the last non-blank character
on the current line. If COUNT is given, move COUNT - 1
lines downward first."
  :type inclusive
  (evil-end-of-line count)
  (re-search-backward "^\\|[^[:space:]]")
  (setq evil-this-type (if (eolp) 'exclusive 'inclusive)))
(define-key evil-motion-state-map "g$" 'evil-end-of-line)
(define-key evil-motion-state-map "$" 'evil-last-non-blank)

TheBB added a commit to TheBB/dotfiles that referenced this issue Aug 3, 2015
TheBB added a commit to TheBB/dotfiles that referenced this issue Aug 3, 2015
@herbertjones
Copy link
Contributor

Also, the new behavior makes hitting x repeatedly at the end of a line no longer erase characters at the end of the line. Instead no action is taken.

@darkfeline
Copy link
Contributor Author

@herbertjones That's unfortunate. You can always use X instead.

@TheBB
Copy link
Collaborator

TheBB commented Aug 5, 2015

I'm unconvinced by my own suggestion, and I've reverted to standard evil behavior, as god intended. ,el suits me fine for evaling sexps at the end of a line.

@darkfeline
Copy link
Contributor Author

@TheBB "standard evil behavior" Do you mean Vim's behavior or the current behavior?

@TheBB
Copy link
Collaborator

TheBB commented Aug 5, 2015

I mean Vim's behavior, with evil-move-beyond-eol set to nil.

@xged
Copy link

xged commented Aug 7, 2015

My vote is for the original Vim's behavior of $. How many times I had to do v $ h...

@syl20bnr
Copy link
Owner

syl20bnr commented Aug 7, 2015

We should be ok if we just advice $ to go backward one character when beyond eol is allowed.

To my mind, consistency of evaluating sexp is as important as $ original behavior. A partial solution is a no go.

I'll see if I can get it upstream.

@jasminpatry
Copy link
Contributor

+1 for original vim behavior of $.

@agriffis
Copy link
Contributor

Emacs is used for lots of editing tasks besides evaling sexps, and this is a pretty major departure from vim behavior. If it's possible to make this non-default and/or restricted to modes that require it, that would make longtime vim users like me a lot happier.

@syl20bnr
Copy link
Owner

Don't worry :-)

To my mind, consistency of evaluating sexp is as important as $ original behavior. A partial solution is a no go.
I'll see if I can get it upstream.

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

here's a solution to the eval-last-sexp problem. I just tested that it works

(defun eval-end-of-sexp (arg)
  (interactive "P")
  (save-excursion
    (forward-char)
    (eval-last-sexp arg)))

@syl20bnr
Copy link
Owner

It works but this is not what needs to be fixed. The inconsistency is that in elisp the point must be on the closing parenthesis whereas in other lisps it is still the vanilla behavior where the point must be put behind. I go the vanilla behavior route which is the way I find the most natural and viable in the long run, maintenance wise.

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

but then you can't eval a sexp without a space at the end no?

@syl20bnr
Copy link
Owner

You can with evil-move-beyond-eol :-)

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

then why this 41459be?

@syl20bnr
Copy link
Owner

I'm the contributor of evil-move-beyond-eol, I enabled it in spacemacs and then people found side effects with $ and x. I have to fix those side effects upstream. In the meantime we decided to revert to nil which is what the comment says.

@syl20bnr
Copy link
Owner

Obviously both concerns are equally important but $ and x are more noticeable by users.

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

Ok, thanks.

What I was suggesting is that it seems strange to alter the behavior for one (yes important) function, when it's easy to come up with alternatives that do what you want.

@syl20bnr
Copy link
Owner

@justbur you can PR your hack in the meantime.

@syl20bnr
Copy link
Owner

@justbur what is easy ? The issue is that we cannot move the point beyond the last character in evil.

@syl20bnr
Copy link
Owner

Well we can with evil-move-beyond-eol but I will repeat myself, $ and x must be aware of this.

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

Sorry to intrude. I can adjust to whatever the default becomes and am not concerned. I was just offering a different way to approach the problem, instead of change the behavior of evil use a different but equally as functional eval function.

@syl20bnr
Copy link
Owner

But the default behavior of evil/vim is the problem :-D
In Emacs and more specifically lisps dialect the point must be behind the closing parens, in Vim you cannot move behind the last char of a line so Evil patches emacs-lisp but not the other modes to eval on the closing parens. I don't like that, and think about our editing styles and so on.
There is some limit with being Vim compatible at some point :-)

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

I agree that either option causes problems, but as far as a default is concerned I'm willing to bet that the average spacemacs user is comfortable with the vim way of doing things and doesn't do a lot of lisp coding. For the others, it's very easy to use evil-move-beyond-eol in your personal settings. Essentially, these are both muscle memory arguments. Moving away from vim's default affects everyone in every mode, while the other affects the lispers. That's how I was thinking about it at least.

@syl20bnr
Copy link
Owner

I don't know what we are arguing here, we reverted eol back to nil for the exact reason you mentioned. When we have consistent evil motion while being able to go past the last char I'll re-enable it.

As I said there is no partial solution. We have to have both.

@justbur
Copy link
Contributor

justbur commented Sep 17, 2015

I don't know either. I'll stop :-)

@syl20bnr
Copy link
Owner

So after digging evil the conclusion is: we keep the Vim behavior and we will advise the eval functions of the other lisps to be able to put the cursor on the closing parens to eval last sexp. This is the opposite solution of what I wanted.

So in Normal state the point must be on the closing parens.
In Emacs and Hybrid states the point must be behind the closing parens.

Seems consistent and should be POLA enough. The thing is to have the same behavior in any mode so we will advise all the lisp dialects to follow what is done in Evil.

@TheBB
Copy link
Collaborator

TheBB commented Sep 22, 2015

Is this still on the 0.104 milestone after 41459be?

@syl20bnr
Copy link
Owner

Not really. I guess the 0.104.0 is almost ready, I wan't to rewrite a bit the README.md to make is shorter and some pompous stuff in DOCUMENTATION.org (especially at the end).
Actually I will make a whole pass on the documentation files to tweak them.

@syl20bnr syl20bnr removed this from the release 0.104 milestone Sep 22, 2015
@syl20bnr
Copy link
Owner

I close this discussion and open a new one for the adapting clojure etc...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants