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

Using as motion #7

Open
moll opened this issue Jan 21, 2014 · 15 comments
Open

Using as motion #7

moll opened this issue Jan 21, 2014 · 15 comments

Comments

@moll
Copy link

moll commented Jan 21, 2014

Hey,

Thanks for writing plugins with tests!

Any idea how to use Sideways's argument text objects as Vim motions? So instead of deleting or changing the argument you're on, you'd be able to say "delete the next two arguments"? I'm getting quite tired of counting commas manually and doing d2f,. :)

@AndrewRadev
Copy link
Owner

Good point. I've created a new branch called textobj-with-count. In it, you should be able to say, for example, 2daa or d2aa and this would delete the next 2 arguments. I haven't implemented looping, so in this case:

def foo(one, two, three):
    pass

If the cursor is on two, and you type 5daa, you're going to be left with:

def foo(one):
    pass

I figured looping would complicate things, both implementation-wise and conceptually.

Could you try out the branch, see what bugs you can find?

@moll
Copy link
Author

moll commented Jan 27, 2014

Sweet! Thanks, I'll give it a go soon!

I was also thinking, how about mimicking how d) and d( work instead? And perhaps providing plugs so one could remap () motions for programming files (I'm talking about d), the sentence, not da)). That would allow deleting arguments both ways, with count, without having to mess with any looping. There's already :SidewaysJumpLeft/Right. Can that be reused for that?

Implementing deleting in terms of a directional motion would then free up d2aa for deleting nested arguments from inside instead. Something where you could replace the whole bar() call in foo(1, bar(2, 3, 4), 5) when on 3. Currently you'd have to do da)db or if the argument happens to be something more complex, like 42 + bar(2, 3, 4), bang db multiple times.

@AndrewRadev
Copy link
Owner

I think :SidewaysJump could probably be used for deleting left and right, yes. I'll just have to turn it into a proper plugin mapping and see how I can handle counts. I'll try to work on that this weekend.

Regarding "nested" arguments, I'm not so sure. The example you gave could be deleted by jumping back to the bar and then performing a daa. Right now, I don't think I have the machinery to figure out the levels of nesting, either. It may be possible, but I'd have to think about it. It does seem like something of an edge case, though (you'd rarely have more than 2 levels, and you could go to the actual function name to treat it as a single argument).

@moll
Copy link
Author

moll commented Jan 28, 2014

Cool, if you get SidewaysJump working, you might want to remove the count-for-deleting-next arguments after that.

Yep, moving to bar in the above example is an option, but that'll require quite a lot of manual navigating. Most other text objects do support numbers for selecting consecutive outer blocks, hence my suggestion that daa should, too. See d2a) etc.

@AndrewRadev
Copy link
Owner

Didn't manage to work that weekend, other things came up.

I put some time into it today and I think I'm going to have to do a little bit of refactoring to get this feature done in a nice way. I'll try to devote some time to it the upcoming weekend, let's hope I have more success this time :).

Regarding the d2a) idea, I completely agree that it would make sense, I'm simply not sure if it would be reasonably easy to implement. Right now, the plugin puts effort into finding the nearest "argument list" it could find and focuses on that. The only way I can think of implementing the "nested" functionality would be to move back one character from the first column of the parsed match and try again. And so on, until the given number of counts. I'll think more about it once I've done the restructuring I have in mind.

@moll
Copy link
Author

moll commented Feb 12, 2014

Cool. No hurry.

Another idea I had about implementation is that could you reuse Vim's built-in (or syntax-based etc.) text-block-objects? I've recently found myself quite often trying to cia inside a function call that is spread between lines. In JavaScript that'd be something like (with the cursor on the opening {):

foo(1, 2, {
  bar: 1337
})

I remember the argtextobj plugin I used used to behave like that. But it came with its own problems (which I don't remember. :P).

@AndrewRadev
Copy link
Owner

I can't really imagine how this would be implemented generically and reliably. I'll take a look at the source code of argtextobj for ideas, but I don't think I'll be implementing multi-line argument lists. If nothing else, this particular example can easily be operated on with a i{/a{ textobject. Though I understand that intuition would push towards using the "argument" object for this as well...

More to the point, I've just pushed an implementation of counts that affect "outer" textobjects, the d2a( that we discussed. I still haven't implemented counts in the directions, though. I guess I need to make the "jump" commands into mappings.

One thing that might be weird is that the "jump" motions should also wrap around the list, which may be surprising if you use a motion with a count that's too large. For instance, if you have 3 items to the right and you jump 5 times, you'll loop around from the other side. But I guess this is still okay, users simply need to mind the counts.

I'm also starting to think it would make a lot of sense to create some default mappings right about now. Do you have any ideas for good ones? As I see it now, there are 5 motions:

  • jump left/right
  • swap left/right
  • text object

ia/aa might make sense as a default for the argument list, but what about the others? I currently use s< and s> for swapping (which is a no-go due to the s), but I don't really use anything for jumping.

@AndrewRadev
Copy link
Owner

I think I've gotten the motions working, though I'm not sure they're very useful the way they are now... The problem is that the motions go to the beginning of the arguments, not to the ends. Which makes a lot of sense if you're just jumping around, but not so much when you're performing a d or c motion.

The built-in w motion has the same problem. The mapping dw, if it worked correctly, would delete up to the next word. There's some special handling for it so that it deletes to the end of the current word instead.

The only thing I can imagine is providing two sets of motions, a w motion and a e motion that go to the beginning and end of an argument respectively.

For now, could you exercise these motions, let me know what you think? I would also appreciate your thoughts on my previous question regarding default mappings.

@AndrewRadev
Copy link
Owner

Did you get around to experimenting with the motions? What do you think about the w/e problem?

@moll
Copy link
Author

moll commented Apr 13, 2014

Hey,

Thanks for all the work on this! Sorry, haven't yet had the opportunity to delve head first into tweaking Vim again. I'll do so and then get back to you. :)

@AndrewRadev
Copy link
Owner

No worries, just wanted to throw a bump in there, keep the issue alive :).

@moll
Copy link
Author

moll commented May 17, 2014

Hey again,

Yeah, I'm for for having a as the argument motion. For the jumps and sideways moves I'd have to say let them be unset by default. I don't know about you, but I've got way too many plugins all competing for mappings by default. :) I picked g<-g> for Sideways.vim because I don't use g<, but others might choose differently. For jumping I'll be picking ( and ) in programming files, because there the default sentence jumping is seldom useful.

Is the textobj with count branch still the one with the code you suggested I look at? Mind rebasing it ontop of your latest changes? :) Thank you!

@AndrewRadev
Copy link
Owner

I've rebased the textobj-with-count branch on top of master and force-pushed. You make a good point about the default mappings. I'm still thinking of putting some <leader> maps at least, just to make testing easier, but I don't know.

Do you have any thoughts on:

The problem is that the motions go to the beginning of the arguments, not to the ends. Which makes a lot of sense if you're just jumping around, but not so much when you're performing a d or c motion.

The built-in w motion has the same problem. The mapping dw, if it worked correctly, would delete up to the next word. There's some special handling for it so that it deletes to the end of the current word instead.

The only thing I can imagine is providing two sets of motions, a w motion and a e motion that go to the beginning and end of an argument respectively.

@moll
Copy link
Author

moll commented May 18, 2014

Thank you again! I'll check the branch out and then think it over about the start-end issue. ;-)

You mean for automated testing? Add your default maps to your test's vimrc. :-)

@pag
Copy link

pag commented Dec 20, 2018

Is this going to make it into the main branch? I map SidewaysRight to a multi character key so typing it every time is annoying, and neither number repeats (e.g. "5") nor dot repeats (i.e. ".") work with this plugin.

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

No branches or pull requests

3 participants