Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace to end of text-object

Tags:

vim

In Vim, I keep finding myself desiring a keystroke to rewrite the rest of some parameter list. For example, in the following Python function:

def myfun(a, b=12, c=(1,2,3), d=15):
    pass

I wish to replace the c=(1,2,3), d=15 with e=12. The keystroke ci( allows me to replace everything inside the entire parameter list, but I find that I often want to retain some prefix of the Vim text-object. In general, I'd assume this keystroke I'm searching for would be useful in the context of replacing final parameters of function calls as well as definitions.

A desirable answer to this question would apply to quoted strings, [] blocks and other text objects too. Note that I understand all about text-objects as answered in "How to select between brackets (or quotes or ...) in Vim?".

Both @pb2q and @romainl give good search shortcuts, but they require me to visually find the end of the enclosing block to devise a search which is unambiguous in terms of any other garbage which is in the block (e.g. think nested function calls). In particular, I often find myself wanting this when I have nested parenthesis inside the parenthesis set I want to manipulate. The answer I really want is analogous to ci) or ca) which is entirely conceptually based on the nearest enclosing bracketing ) and deals entirely gracefully with other nested ) blocks.

like image 980
jbmohler Avatar asked Jul 26 '12 16:07

jbmohler


3 Answers

There are a bunch of commands starting with ] that go to the end of some kind of structure, and respect nesting. ]) to go to the end of a parenthesized block, ]} to go to the end of a braced block, ]/ to go to the end of a C comment (/*...*/ style). Use [ in place of ] to go to the beginning instead of the end.

So to do the replacement of your c=(1,2,3), d=15 type c]).

The complete list of these commands is listed under :help various-motions. Unfortunately there isn't one for blocks delimited by brackets, because [[ and ]] already had a different meaning in classical vi, and vim has defined ][ and [] to fit nicely with those.

like image 91
Alan Curry Avatar answered Sep 22 '22 02:09

Alan Curry


Create a map with this

mavi)o`a
  • Mark the current position a
  • visually select inside () to select the full set of characters inside the () that you are in
  • go to the other end of the highlighted text :h v_o for more info
  • move to the previously marked position

Now you can perform an operation such as c or d...

Edit: I still like @Alan-Curry's solution best because the key sequence is short. However this technique has the benefit of also working with ].

I also discovered a simplification for my solution:

vi)o``

`` jumps to the last position. So you don't need to create a mark.

like image 39
darcyparker Avatar answered Sep 26 '22 02:09

darcyparker


If you don't mind using a plugin, I believe vim-ninja-feet does exactly what you are looking for.

  • c]i) will change the rest of the parameter list,
  • d[i" will delete backwards to the beginning of a quote, and
  • z]i] will put you in insert mode at the end of a [] block.
like image 27
pagrick Avatar answered Sep 25 '22 02:09

pagrick