0

I'm trying to write a function that replaces text in all buffers. So I call Ack to search all the matches and next step I want to set into Quickfix command line this code

:QuickFixDoAll %s/foo/boo/gc

Seems like I can only call 'exec' function which runs this command immediately and there is no ablility to edit it or cancel at all

I also tried "input" function to read user input but got this error at runtime

not an editor command

Any ideas?

.vimrc:

function! ReplaceInFiles(o, n)                                                                                                       
    exec "Ack '" . a:o . "'"
    exec "QuickFixDoAll %s/" . a:o . "/" . a:n . "/gc"
endfunction

" QuickFixDoAll
function! QuickFixDoAll(command)
    if empty(getqflist())
        return
    endif
    let s:prev_val = ""
    for d in getqflist()
        let s:curr_val = bufname(d.bufnr)
        if (s:curr_val != s:prev_val)
            exec "edit " . s:curr_val
            exec a:command
        endif
        let s:prev_val = s:curr_val
    endfor
    exec "quit"
endfunction
command! -nargs=+ QuickFixDoAll call QuickFixDoAll(<f-args>)
2
  • Is that QuickFixDoAll command from you (then show the source code behind it)? So you want to edit / remove some quickfix matches, and then replace the remaining ones, right? I don't fully get the actual problem you're struggling with. Commented Nov 7, 2015 at 21:13
  • Added the source code... I want to edit not matches but this command ":QuickFixDoAll %s/foo/boo/gc" before execute it. Actually i want to change last argument to execute replacement with or without confirmation Commented Nov 7, 2015 at 21:53

2 Answers 2

1

Using input()

This queries both values interactively:

function! ReplaceInFiles()                                                                                                       
    let l:o = input('search? ')
    let l:n = input('replace? ')
    exec "Ack '" . l:o . "'"
    exec "QuickFixDoAll %s/" . l:o . "/" . l:n . "/gc"
endfunction
nnoremap <Leader>r :call ReplaceInFiles()<CR>

Incomplete mapping

nnoremap <Leader>r :let o = ''<Bar>exec "Ack '" . o . "'"<Bar>exec "QuickFixDoAll %s/" . o . "//gc"<Home><Right><Right><Right><Right><Right><Right><Right><Right><Right>

This one puts the cursor on the right spot for the search. As this value is used twice (Ack and QuickFixDoAll), it is assigned to a variable. After that, move to the end of the command and fill in the replacement in between the //gc.

Custom parsing

The most comfortable option would be a custom command :AckAndSubstAll/search/replacement/. For that, you'd need to parse the two parts in the custom command (like :s does). You could do that with matchstr(), or use ingo#cmdargs#substitute#Parse() from my ingo-library plugin.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, now with "input" function anything works great. Anyway, i didn't use all the features you provided but added "input('additional params? (q=quit) ')" right after ack invoke
Great! Yes, there are many possible variations. If that solves your problem, please accept the answer by clicking on the outlined arrow next to it.
0

First use vim-qargs to copy all files from the quickfix window into Vim's arglist by calling :Qargs.

Then run your replace on all arguments in the arglist by doing :argdo %s/search/replace/gc

1 Comment

There is a cdo command built into vim 7.4.858. Which runs a command for every line in the quick fix list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.