zellidev0
zellidev0

Reputation: 151

How to multiline replace different characters in vim

i have this code snippet. I want to replace all the empty spaces with one space. In IntelliJ i would simply multi-cursor, jump to the -- use option + shift + left arrow then right arrow to select all the spaces and type a space which replaces them.

I'm new to vim and haven't found any solution that achieves this.

vim.opt.showmode = false                      -- we don't need to see things like -- INSERT -- anymore
vim.opt.showtabline = 2                       -- always show tabs
vim.opt.smartcase = true                      -- smart case
vim.opt.splitbelow = true                     -- force all horizontal splits to go below current window
vim.opt.splitright = true                     -- force all vertical splits to go to the right of current window
vim.opt.swapfile = false                      -- creates a swapfile
vim.opt.termguicolors = true                  -- set term gui colors (most terminals support this)
vim.opt.timeoutlen = 1000                     -- time to wait for a mapped sequence to complete (in milliseconds)
vim.opt.undofile = true                       -- enable persistent undo
vim.opt.writebackup = false                   -- if a file is being edited by another program (or was written to file while editing with another program), it 

Thanks.

Upvotes: 0

Views: 166

Answers (1)

romainl
romainl

Reputation: 196566

In my semi-fresh install of Intellij IDEA CE, the correct sequence would be:

<place cursor>
<option><option>
<down>
<down>
<down>
<down>
<down>
<down>
<down>
<down>
<down>
<option-shift-left>
<(option-shift-)right>
<space>
<escape>

In Vim, you could simply use a multi-cursor plugin, there are a few, or do it…

With a substitution:

vip
:'<,'>s/ \{2,}/ /<CR>

where…

  • vip visually select the current "paragraph", see :help v and :help text-objects.
  • '<,'> is the :help :range of lines on which to execute the following command. You can indicate a range explicitly or implicitly, by selecting the range of lines before entering command-line mode. This is what we did, here, and Vim inserted the corresponding range automatically: '<,'>.
  • s/ \{2,}/ / is the substitution
  • \{2,} matches 2 consecutive spaces or more.
  • is, well… a single space.
  • And <CR> is the Enter key.

With the "dot formula":

/ \{2,}<CR>
cgn<space>
.
.
.
.
.
.
.
.
.

where…

  • / \{2,}<CR> searches for the next sequence of 2 or more spaces. In this case, we are just setting the stage for the next commands.
  • cgn<space> replaces the current or next search match with a <space>, see :help c and :help gn.
  • The nine . repeat the previous command nine times, see :help ..

FWIW, I have a custom mapping that makes it possible to use a count before .:

nnoremap . :<C-u>execute "norm! " . repeat(".", v:count1)<CR>

which shortens the command above quite a bit at the cost of counting the lines so YMMV:

/ \{2,}<CR>
cgn<space>
9.

Philosophical considerations:

  • In a way, the "dot formula" is the opposite of multi-cursors: in one case you place the cursor n times and then perform the edit, while in the other you perform the edit and repeat it n times.
  • Competent vimmers use search a lot for navigation and regular expressions tend to become a second nature. It feels weird at first to be so literal and deliberate about your edits, especially after decades of meaningless <down>s and <left>s, but it eventually grows on you.
  • I would naturally go for the substitution.

Upvotes: 2

Related Questions