2017-09-15 153 views
1

我目前正在編寫一個替代函數,我通常需要在vim中進行編程。vim:轉義替換字符串(vimscript)

我已經寫過的函數看起來像這樣,並且對於搜索和替換內部沒有任何特殊字符的字符串基本上可以運行。我已經意識到要自動逃避「/」。我的問題是,我怎麼有這樣自動適應所有的escape()函數在該行

execute ':silent :argdo %s/' . escape(searchPattern, '/') . '/' . escape(replacePattern, '/') . '/ge' 

有轉義將被轉義字符的?

" MAIN FUNCTION 
" inspired by http://vimcasts.org/episodes/project-wide-find-and-replace/ 
function! SubstituteProjectwide(searchInput) 
    :set hidden 
    let cwd = getcwd() 
    let filename=expand('%:p') 
    call inputsave() 
    let searchPattern = input('Search for: ', a:searchInput) 
    let replacePattern = input('Replace "' . searchPattern . '" with: ') 
    let filePattern = input('Filepattern: ', cwd . '/**/*.*') 
    call inputrestore() 
    execute ':silent :args ' . filePattern 
    execute ':silent :vimgrep /' . searchPattern . '/g ##' 
    execute ':silent :Qargs' 
    execute ':silent :argdo %s/' . escape(searchPattern, '/\') . '/' . escape(replacePattern, '/\') . '/ge' 
    execute ':silent :edit ' . filename 
    echo 'Replaced "' . searchPattern . '" with "' . replacePattern . '" in ' . filePattern 
endfunction 

" VISUAL ENTRYPOINT WITH SELECTED TEXT 
function! SubstituteProjectwideVisual() 
    let v = @* 
    call SubstituteProjectwide(GetVisualSelectedText()) 
endfunction 
:vnoremap <F6> :call SubstituteProjectwideVisual()<cr> 

" NORMAL ENTRYPOINT WIHT WORD UNDER CURSOR 
function! SubstituteProjectwideNormal() 
    let wordUnderCursor = expand("<cword>") 
    call SubsituteProjectwide(wordUnderCursor) 
endfunction 
:nnoremap <F6> :call SubstituteProjectwideNormal()<cr> 

" GETTING THE FILES WICH CONTAIN SEARCH PATTERN 
" copied from http://vimcasts.org/episodes/project-wide-find-and-replace/ 
command! -nargs=0 -bar Qargs execute 'args' QuickfixFilenames() 
function! QuickfixFilenames() 
    let buffer_numbers = {} 
    for quickfix_item in getqflist() 
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr']) 
    endfor 
    return join(map(values(buffer_numbers), 'fnameescape(v:val)')) 
endfunction 

" GETTING THE CURRENT VISUAL SELECTION 
" copied from: https://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript 
function! GetVisualSelectedText() 
    let [line_start, column_start] = getpos("'<")[1:2] 
    let [line_end, column_end] = getpos("'>")[1:2] 
    let lines = getline(line_start, line_end) 
    if len(lines) == 0 
    return '' 
    endif 
    let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)] 
    let lines[0] = lines[0][column_start - 1:] 
    return join(lines, "\n") 
endfunction 

UPDATE

我設法逃脫衆多人物像

escape(searchPattern, '/\') . '/' . escape(replacePattern, '/\') 

但是我怎麼知道我必須逃離這角色的列表中,當它基本上是可能的,每一個字符可以在搜索和替換字符串?

回答

1

要執行字面取代,指定 「非常-nomagic」(:help /\V),和逃脫分離器(/)和在源\

如果設置了'magic'選項,則在替換中,&~也必須轉義。 (\V已經不在這裏工作。)

execute ':silent :argdo %s/\V' . escape(searchPattern, '/\') . '/' . escape(replacePattern, '/\' . (&magic ? '&~' : '')) . '/ge' 

斷行(如果可能)必須從^M改爲\n

execute ':silent :argdo %s/\V' . substitute(escape(searchPattern, '/\'),"\n",'\\n','ge') . '/' . escape(replacePattern, '/\' . (&magic ? '&~' : '')) . '/ge' 
+0

似乎運行。我必須用一些更復雜的搜索條件來測試它 – divramod

+0

@divramod請記住,您還需要轉義'&'和'〜',至少在替換模式中。在@ ingo-karkat的答案中查看最後一行的結尾。 –

1

這並不完全回答你的問題,但是是另一種方式看着你想解決的問題。我並不完全遵循:args設置爲您做的事情,因爲quickfix在:vimgrep之後提供了所有您需要的信息。

我有這個在我的vimrc:

nnoremap <F3> :vimgrep // $PROJECT_ROOT_DIR/src/**/*.{cpp,h,c,inl,msg}<C-Left><C-Left><Right> 

顯然,您要自定義的搜索路徑,因爲這樣的重點就在以上五個文件擴展名在每次都配置一個特定的文件層次我推出Vim ...

無論如何,一旦你有了這個,:cr確保你在開始,然後做搜索&取代你想要的宏裏面。如果你想,你可以在前幾個測試中進行測試,但是...

qbq清除'b'寄存器。

qa開始錄製的「一個」宏觀」

:%s/this/that/g啓動宏和替代‘說’的‘本’。(按回車鍵)

:w|cnf寫文件,去到下一個(按回車鍵)

q停止記錄的「a」宏。

然後[email protected]@bq將運行宏一次,將其保存在@b。然後只需運行 (類型)@b一次,直到它完成它會繼續自稱。