How to search and replace globally, starting from the cursor position and wrapping around the end of file, in a single command invocation in Vim?

前端 未结 6 1322
攒了一身酷
攒了一身酷 2020-12-22 18:42

When I search with the / Normal-mode command:

/\\vSEARCHTERM

Vim starts the search from the cursor position and continues downwa

6条回答
  •  清酒与你
    2020-12-22 19:07

    Here’s something very rough that addresses the concerns about wrapping the search around with the two-step approach (:,$s/BEFORE/AFTER/gc|1,''-&&) or with an intermediate “Continue at beginning of file?”-prompt approach:

    " Define a mapping that calls a command.
    nnoremap e :Substitute/\v<=expand('')>//
    
    " And that command calls a script-local function.
    command! -nargs=1 Substitute call s:Substitute()
    
    function! s:Substitute(patterns)
      if getregtype('s') != ''
        let l:register = getreg('s')
      endif
      normal! qs
      redir => l:replacements
      try
        execute ',$s' . a:patterns . 'gce#'
      catch /^Vim:Interrupt$/
        return
      finally
        normal! q
        let l:transcript = getreg('s')
        if exists('l:register')
          call setreg('s', l:register)
        endif
      endtry
      redir END
    
      if len(l:replacements) > 0
        " At least one instance of pattern was found.
        let l:last = strpart(l:transcript, len(l:transcript) - 1)
        " Note: type the literal  (^[) here with :
        if l:last ==# 'l' || l:last ==# 'q' || l:last ==# '^['
          " User bailed.
          return
        endif
      endif
    
      " Loop around to top of file and continue.
      " Avoid unwanted "Backwards range given, OK to swap (y/n)?" messages.
      if line("''") > 1
        1,''-&&"
      endif
    endfunction
    

    This function uses a couple of hacks to check whether we should wrap around to the top:

    • No wrapping if user pressed L, Q, or Esc, any of which indicate a desire to abort.
    • Detect that final key press by recording a macro into the s register and inspecting last character of it.
    • Avoid overwriting an existing macro by saving/restoring the s register.
    • If you are already recording a macro when using the command, all bets are off.
    • Tries to do the right thing with interrupts.
    • Avoids “backwards range” warnings with an explicit guard.

提交回复
热议问题