Search and Replace with incremented values in Vim

前端 未结 5 529
北恋
北恋 2021-01-31 03:57

Lets say I wrote a simple CSS rule like this:

.star_10 {
  background: url(stars.png) no-repeat 0 0;
}

And I need 10, so I copied it 9 times.

5条回答
  •  情歌与酒
    2021-01-31 04:45

    I needed this solution but also with leading zero support. My use of the original question is more like Example 1 than what Example 2 (this was the original example).

    I created a function called SearchIncr() (search, replace, and increment).

    There are four required arguments: target_string, replacement_string, start_value, increment_value. There are also two optional arguments: leading_zeros, position

    leading_zeros is a positive integer value, and position is 'before' or 'after'. See example 2.


    Example 1

    :'<,'>call SearchIncr("0 0","new",1,5,8)
    

    If the file looks like this:

    what 0 0 post
    areu 0 0 post
    doin 0 0 post
    

    You will then get:

    what new00000001 post
    areu new00000006 post
    doin new00000011 post
    

    Example 2

    :'<,'>call SearchIncr("0;","px;",-18,-18,0,'after')
    

    If the file looks like this:

    .star_10 {
      background: url(stars.png) no-repeat 0 0;
    }
    .star_10 {
      background: url(stars.png) no-repeat 0 0;
    }
    .star_10 {
      background: url(stars.png) no-repeat 0 0;
    }
    

    You will then get:

    .star_10 {
      background: url(stars.png) no-repeat 0 -18px;
    }
    .star_10 {
      background: url(stars.png) no-repeat 0 -36px;
    }
    .star_10 {
      background: url(stars.png) no-repeat 0 -54px;
    }
    

    The vimscript is here:

    " place functions here
    function! SearchIncr(a1,a2,a3,a4,...) 
      " patn, repl, start, increment
      let target = a:a1
      let repl = a:a2
      let startval = a:a3
      let increment = a:a4
    
      " 1st optional argument handles leading zeros
      " process optional leading zero
      if a:0 >= 1
        let leadingz = a:1
      else
        " default to 0
        let leadingz = 0
      endif
    
      " 2nd optional argument handles if target string goes before or after
      " default is before
      if a:0 == 2
        " ideally set to 'after'
        let repl_pos = a:2 
      else
        let repl_pos = 'before'
      endif
    
      " inits
      let l:incr = startval - increment
      let lnum = a:firstline
    
      " cycle though selection
      while lnum <= a:lastline
    
        " the FORMATTING string
        if repl_pos == 'before'
          let l:incrstring = '\=printf(''%s%0'. leadingz . 'd'',repl,l:incr)'
        elseif repl_pos == 'after'
          let l:incrstring = '\=printf(''%0'. leadingz . 'd%s'',l:incr,repl)'
        else
          "default to no leading zero and before placement
          let l:incrstring = '\=printf(''%s%0d'',repl,l:incr)'
        endif
    
        " only increment counter when target matches
        if match(getline(lnum),target) > 0
          let l:incr = l:incr + increment
        endif
    
        " the search and replace
        call setline(lnum,substitute(getline(lnum),target,
        \ l:incrstring,'g'))
    
        let lnum = lnum + 1
      endwhile
    endfunction
    

    Any comments to improve on the above would be greatly appreciated!

提交回复
热议问题