How can I 'change in number' or 'change in digits' in Vim

1.5k Views Asked by At

I'm regularly editing CSS in Vim and need to change a value like:

width: 300px;

to something else like:

width: 178px;

Normally what I do is navigate to the 3 in 300 and type cw to change the word. But if I do this I have to type the px bit again. Is there a short and quick way to say change in digits.

In my searching I've discovered Ctrl-a and Ctrl-x to increment and decrement numbers in this situation. Is there an equivalent for being able to retype the number?

I should clarify that the ideal solution would require the fewest keystrokes at time of operation and support modifications to different length numbers. Like if I wanted to change 300px to 17px.

5

There are 5 best solutions below

4
On BEST ANSWER

Here is in, a custom text-object that lets you act on numerical values (including floats):

" custom text-object for numerical values
function! Numbers()
    call search('\d\([^0-9\.]\|$\)', 'cW')
    normal v
    call search('\(^\|[^0-9\.]\d\)', 'becW')
endfunction
xnoremap in :<C-u>call Numbers()<CR>
onoremap in :normal vin<CR>

The actual search is performed in a function to avoid clobbering the search register and search highlighting.

You can add that text-object to your vimrc "as is" and use it like other text-objects:

vin
cin
yin
din

demo

--- edit ---

This new version:

  • doesn't mess with search highlighting (good),
  • doesn't mess with the search register (good),
  • respects BOL and EOL (good),
  • works with floats (good).

Comments welcome.

--- edit ---

0
On

My favorite way is to use visual mode, so I would navigate to the 3, then use either 2 spaces (or any other motion command) to navigate to the end of the part I wanted to change. Once I have highlighted the part I want to change, just type s178 to substitute the chars "178" for whatever is highlighted.

3
On

If you just want to change the 300 to 178 on that line do:

:s/300/178/ RETURN

It will do a find->replace on the current line

To do it globally, do:

:%s/300/178/g RETURN

0
On

I don't know of a "change in digits" command, but you can use t, which is like f but goes to the character before what you are searching for; that is, if you type tp, it will move the cursor to the character just before "p" in your line. Combining it with c, if your cursor is on the 3, ctp178 Esc will replace 300 with 178.

Alternatively, you can use 3s to substitute the next three characters: 3s178 Esc. This is easy when the string being replaced is easy to scan for length. And if your replacement text is the same length as the text being replaced, you can just use R to replace: R178 Esc.

0
On

You can use the text object proposed by romainl, or, alternatively, rely on existing ones: