Reputation: 954
I come upon one scenario when editing a file in vim and I still haven't found a way to do it quickly in vim way. When editing a call of a function, I offently put my arguments in a wrong order.
anyFunction(arg2, arg1)
When arriving on this situation, I have to find arg2 / delete it / append it before the ')' / deal with the ', ' / etc.
Isn't it a better way to this task quickly ? I am open to any idea (macro/ shortcut / plugin) even if I'd rather have a 'vim only' way of doing this
Upvotes: 4
Views: 5380
Reputation:
Similar to what Peter Rincker suggested (Argumentative), sideways also does what you describe.
Upvotes: 1
Reputation: 45177
I actually made a plugin to deal with a exact situation called argumentative.vim. (Sorry for the plug.)
Argumentative.vim provides the following mappings:
[,
and ],
motions which will go to the previous or next argument<,
and >,
to shift an argument left or righti,
and a,
argument text objects. e.g. da,
, ci,
or yi,
So with this plugin you move to the argument in question and then do a <,
or >,
as many times as needed. It can also take a count e.g. 2>,
.
If you have Tim Pope's excellent repeat.vim plugin installed <,
and >,
become repeatable with the .
command.
Upvotes: 4
Reputation: 5041
put this mapping in your _vimrc.
" gw : Swap word with next word
nmap <silent> gw :s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l>
then in normal mode with the cursor anywhere in arg1 type gw to swap parameters
anyFunction(arg1, arg2)
Explanation:-
arg1 the separator (here a comma) and arg2 are put into regexp memories 1 2 3
the substitute reverses them to 3 2 1
Control-O return to last position
Control-L redraw the screen
Note that the separator is any non-alphanumeric character or string e,g whitespace
Upvotes: 3
Reputation: 172778
You need two things:
Upvotes: 4
Reputation: 8905
This is a perfect use for a regular expression search and replace.
You want to find "anyFunction(", then swap anything up to the ',' with anything from the ',' to the ')'. This is fairly straightforward, using [^,]*
for "anything up to the ','" and [^)]*
for "anything up to the ')'". Use \(...\)
to capture each thing, and \1
, \2
to refer to those things in the replacement:
:s#anyFunction(\s*\([^,]*\),\s*\([^)]*\)#anyFunction(\2, \1#g
Note how I use \s*
to allow any whitespace between the "anyFunction(" and the first thing, and also between the ',' and the second thing.
If you want this to be able to span multiple lines, you can use \_s
instead of \s
, and capture the whitespace if you want to maintain the multi-line format:
:s#anyFunction(\(\_s*\)\([^,]*\),\(\_s*\)\([^)]*\)#anyFunction(\1\4,\3\2#g
There is also a multi-line variant of [...]
collections, for example \_[^,]
meaning "anything (even a new line) except for a ',' " which you could use in the pattern if your use case demands it.
For details, consult the help topics for: /\s
, /\_s
, /\1
, /\(
, and /[
.
If you want a more general-purpose mapping to use at every location, you can use the cursor position in your regular expression, rather than keying off the function name. The cursor position in a regular expression is matched using \%#
as demonstrated here: http://vim.wikia.com/wiki/Exchanging_adjacent_words
Upvotes: 1
Reputation: 195289
I would recommend a plugin: vim-exchange for that:
https://github.com/tommcdo/vim-exchange
Upvotes: 2