emacs-ess / ESS

Emacs Speaks Statistics: ESS
https://ess.r-project.org/
GNU General Public License v3.0
626 stars 161 forks source link

Smart `ess-cycle-assign` #948

Open basille opened 5 years ago

basille commented 5 years ago

I very much like the recent function ess-cycle-assign, which I now use routinely. However, I wished it was a bit smarter in detecting the context:

1. Spaces before the operator. For instance, typing:

bla␣█

I would expect the function to return:

bla␣<-␣█

and not:

bla␣␣<-␣█

I see this has been discussed in the commit for ess-cycle-assign. Since it would not be desirable for all users, maybe that could be customizable with something like ess-cycle-assign-remove-trailing-space.

2. Detect if assignment operator is already there, and reformat it. For instance, with:

bla<-bli

and the cursor anywhere on <-, I would like the function to return:

bla␣<-␣bli

3. Detect if assignment operator is already there, and cycle through the list of operators — this would come after the previous behavior: if the operator is properly formatted (with space around), if I have this:

bla␣<-␣█

I would expect the function to start cycling, instead of returning:

bla␣<-␣␣<-␣█

and only start cycling on the second… This behavior should also work in full statement like:

bla␣<-␣bli

in which case it should immediately start cycling if the operator is properly formated.

4. To make if fully flexible, the list of operators itself could be customizable. For instance, I rarely use <<- and ->>, so I would happy to cycle between <-, = and ->. Some people may only need <- and =, in which case they could simply bind ess-insert-assign to = and press twice. However, most of the points above could also apply to ess-insert-assign.

jabranham commented 5 years ago
  1. Spaces before the operator.

I agree with you here. It could be nice if this function cleaned up spaces before (and after) the assignment operator

  1. Detect if assignment operator is already there, and reformat it.

This might be outside the scope of this function.

  1. Detect if assignment operator is already there, and cycle through the list of operators

Makes sense to me.

  1. To make if fully flexible, the list of operators itself could be customizable

This is already the case. You can change ess-assign-list to be whatever you want.

basille commented 5 years ago

Thanks @jabranham for looking at it! I'd be happy to help if I can — mostly testing as I really have no practical knowledge of Lisp…

This said, I think 1) and 2) are related, aren't they? If the function checks and cleans spaces when inserting the operator, it could just as well reformat an existing one properly, right? In a way, I would find it slightly inconsistent to do 1) and 3), but not 2)… (everything being customizable, so people having a different approach of spacing could still use it as they wish).

I didn't know about ess-assign-list! This is pretty awesome! I'm now thinking of adding the pipe there!