4

Here's a snippet that I'm working with (* denotes cursor location)

*"First random string"   ,"Random string I want to remove"           }
"Random string number 2" , "Another random string I want to keep"    }

To:

*"First random string"   ,                                           }
"Random string number 2" , "Another random string I want to keep"    }

The brackets are aligned neatly with each other with spaces, and I want to remove the last argument from the first array (while maintaining the easy readability of the current bracket, and comma placement.

The easy answer (the one I'm forced to do for now) would be to count the number of characters in the string and do <count>r<space> but that easily gets tedious with strings of the length I'm working with. I'm sure there's a better way to directly replace the text. I'm sure that vim has a visual replace feature but <select text>r<space> doesn't work.

  • 1
    Does fRva"R<space> not work? – Peter Rincker Mar 16 '17 at 18:00
  • @PeterRincker At least in my old vim 7.3 R is not allowed from visual mode, but that may have changed. But 3f"va" seems to be easier, so you don't have to find a char in second string that's missing in the first one. – Philippos Mar 16 '17 at 19:28
  • 1
    I'm sorry I mistyped. Use r instead of R. I have tested this on Vim 7.2 – Peter Rincker Mar 16 '17 at 19:32
  • 1
    Have you tried a macro? qqf,lvt}r<space> should do the recording and then you can go to another line and apply the macro with @q. You can find the lines with /\v.+\}. Then you can move to lines you want to replace with n and then apply the macro (with @q, as I wrote) – rbernabe Mar 16 '17 at 20:58
  • Which version of Vim? I second @PeterRincker, r<space> over a visual selection works as expected – muru Mar 17 '17 at 2:48
2

I'm confident that <select text>r<space> as you say does work. But you may be using a terminal in which the mouse selection is not passed to Vim (or Vim is not configured to understand the selection with the mouse; as in e.g. set mouse=a).

Yet, instead of selecting with the mouse I'd use f to perform the selection. In other words assuming the cursor in the first line and first column in:

"First random string"    ,"Random string I want to remove"           }
"Random string number 2" , "Another random string I want to keep"    }

I'd do f,f"vf"r 0 and I'll end with the cursor in the same position and the following text:

"First random string"    ,                                           }
"Random string number 2" , "Another random string I want to keep"    }

Explanation:

  • f, - moves to the comma in the middle
  • f" - moves to the next double quote (the next character, but use f" to account for possible spaces)
  • v - enters visual mode
  • f" - moves to the next double quote (at the other side of the string), making the visual mode select it all
  • r<space> - changes the entire visual selection to spaces
  • 0 - returns to first column

Yet, one thing I'd do would be to assign this command to a register and then reuse it, i.e.

:let @a='0f,f"vf"r 0'

And then I can use @a as a command to clean the second quoted string.

1

Selecting text then r<space> certainly works. Perhaps you are not selecting with vim itself (but for example with mouse over the terminal, which uses the terminal's "select" feature, something vim is completely unaware of).

The following vim feature may come in handy when selecting text in this situation. Say you are in a "block" of something, for example (star shows cursor location):

  • "some* string"
  • (code *in (parentheses)
  • { something (in *curly) "brackets" }

The first block is surrounded by "", the second with () and the third with {}. Let's call these delimiters <delimeter> (doesn't matter if opening or closing). The following commands help interact with these blocks:

  • <action>a<delimiter> do something with a block (including the delimiters). a as in "a block".
  • <action>i<delimiter> do something with what's inside the block (excluding the delimiters). i for "inner".

The action could be anything, like v or d.

In your case, as soon as you move the cursor inside the string you want to remove, you can do va"r<space>:

  • v: select
  • a": the string surrounding the cursor
  • r: replace with
  • <space>: space

See :help object-select for a list of these "blocks" (or objects, rather) that can be selected.


This command is wonderful, you can quickly select blocks of C code, strings, paragraphs or sentences in text. It's so wonderful, here is another demonstration:

int func(int x, int y)
{
    x = do_something_with(x);
    y = do_something_with(y); <CURSOR SOMEWHERE ON THIS LINE>
    for (int i = 0; i < x; ++i)
    {
        for (int j = 0; j < y; ++j)
        {
            c += global_array[x][y];
        }
    }
}

And you want to change it to:

int func(int x, int y)
{
    return x + y;
}

All you need to do is: vi{dO<your new code>. Neat!

0

How about using a plugin, like Align or Tabular? Take a look at the suggestion given here. There a demo shown at this link which is great for Tabular.

0

While in normal mode and the cursor is on the left from the closing brace, type the following:

mxt}vT,r<space>`x

The explanation:

mx                " Save the mark x at the curent cursor position
  t}              " Move to the right till before the first closing brace
    v             " Start visual mode per character
     T,           " Move to the left till after the first comma
       r<space>   " Replace all characters with spaces
               `x " Jump to the position of the mark x

To repeat this on a several lines:

qx                " Start recording the keystrokes to the register x
   ...            " Type the commands
       q          " Stop recording

To playback the keystrokes from the register x type @x. Now you can use @@ to repeat the last playback or . (the dot) to repeat the last action (playback counts as a single action). To view the contents of all registers use the :reg command.

http://vim.wikia.com/wiki/Using_marks
http://vim.wikia.com/wiki/VimTip144
http://vim.wikia.com/wiki/Macros

Update

Make sure you are not mixing spaces and tabs or things will get messy. If you need to replace the string with tabs, then instead of vT,r<space> type dT,4i<Tab><Esc>, where 4 is the number of tabs you need to align the brace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.