lil' vi help ...

heusserm on 2003-11-04T14:27:48

I've got a program that looks something like this:

#Begin code $sth->bind_param(1, 'blahblah'); $sth->bind_param(2, $somevar); #End Code

I want to change it to this:

#Begin code $sth->bind_param(1, $somevar); $sth->bind_param(2, 'blahblah'); #End Code

Here's how I would do it in VI:

Go to the 1. Type 'I' (Insert Mode), change it to 2. Go to the 2, change it to 1. Type 'ESC'

Do to the first line. Press DD (Delete). Arrow down. Press P (Paste). Arrow up, and DD the blank line inserted. Arrow down, press I (Insert), backspace, hit return, then fix the indenting on the next line.

I'm 100% convinced this is a silly, inefficient way to type. Yes, it beats the heck out of some GUI Windows-like text editor, but still, it should be faster. I just don't know enought about VI (or vim) yet.

Ideas are welcome.


Do it in Perl

petdance on 2003-11-04T14:48:13

Write a Perl program with a specific heuristic to take care of it. Something like:
  • Read in all the lines of the file
  • Walk thru the lines finding the one with bind parm 1. That's line $x.
  • Make sure that $line[$x+1] is bind parm 2, or else die because your heuristic isn't right.
  • @line[$x,$x+1] = @line[$x+1,$x];
  • $line[$x] =~ s/2/1/;
  • $line[$x+1] =~ s/1/2/;
Or thereabouts. Seems to me that you don't need to switch the parms, but rather switch their bind numbers.

It's a quick throwaway tool, but that's OK that you're going to throw it away. Better yet, keep it in some CVS project (we call ours "lab") that acts as a junk drawer, so you have it later on if you need to do something similar in the future.

Re:Do it in Perl

prakash on 2003-11-05T22:32:50

For a quick throaway tools, one can't beat perl one-liners. Here's one using the regex approach:

perl -0777 pi.bak -e 's/\(1, ([^\)]+)\)(.*?)\(2, ([^\)]+)\)/(1, $3)$2(2, $1)/gs' file.pl

Disclaimer: Not tested extensively.

/prakash

here's some small improvements

jmm on 2003-11-04T14:51:34

There is some improvement to be made.
/2CR         # (CR is return) search for the 2 (or some other way to get there)
r1kr2        # change 2->1, up, change 1->2
ddp          # delete 1'st line, append 1'st line after 2'nd
The "r" is useful to change one character ("R" will overwrite a bunch of chars, it's like insert mode but overwrites).

The "ddp" switches the current line with the next. It is a variant on the very useful (especially for dyslexics) "xp" which swaps the current char with the next.

Actually, though, I would normally just swap the second args, instead of swapping the first args and then swapping the lines. Go to the 2'nd arg on the 1'st line (/\$CR), delete it (de), down to the start of the 2'nd arg on the 2'nd line (j), prepend the deleted arg (P), back to the start of the 2'nd 2'nd arg (l), delete it (dt'), up to the 2'nd arg pos in the 1'st line (kh), prepend it back (P).

vi is like perl

jmm on 2003-11-04T15:01:09

I found one aspect of vi that prepared me well for Larry's view of perl (that writing pidgin perl is a great way to start and should be tolerated, nay encouraged).

I found that my initial use of vi was adequate, but that every 6 months or a year I would read through the vi manual and pick a few more useful idioms and add them to the set that I knew well enough to use without thinking. After a few years of this, my vi repertoire was large enough that most of the new idioms I tried to learn were not useful often enough - by the next time I had a good reason to use one of them, I had forgotten it - so that I wasn't learning much more. So I dropped it down to every few years I would reread the manual (like when a new vi-lookalike comes along - like vim).

vim: C-A C-X

rafael on 2003-11-04T15:35:15

With vim, where the C-A and C-X commands are available to increment and decrement numbers, I'll probably be doing (without thinking much), from the 1st line :
<C-A>ddpk<C-X>

Re:vim: C-A C-X

prakash on 2003-11-05T22:42:01

Hmm. I didn't know about these. Learnt something new.

Also, to make it even easier, a temporary binding can be created using map.

:map <C-Q>  <C-A>ddpk<C-X>

Of course, a better (preferably unused) key may be used in place of

<C-Q>
I just chose that as it is rarely used, I think.

/prakash

Finally, something I know...

Buck on 2003-11-04T19:45:24

  1. Move the cursor to the space after the comma in the param list.
  2. Press "r[Enter]"; replaces the space with a newline.
  3. Do the same on the other line.
  4. Now, move to the line that has the second arg from the first line.
  5. Press "ddp"; moves it after the former second line.
  6. Go down one line to the second argument from the second line.
  7. Press "ddkkP"; moves it after the first line.
  8. Go up to the first line.
  9. Press "J" to join the two lines into one putting a space between the two pieces.
  10. Go down to the next line, and do it again.

Mind you, this only works because except for the args themselves, both lines end the same. Otherwise, I'd just do a cut and paste on the args themselves ("2dw" and "3dw" as appropriate)