2017-02-26 27 views
3

;默認行爲是重複在同一方向上的最後f/F/t/T搜索,而在相反的方向移動,。當他們到達他們各自方向的最後一次搜索時,繼續按下它們會導致無操作。我怎樣才能讓它們繞回來,以便在向前和向後循環中搜索?例如。Vim的 - 讓分號週期

fb一個並[b]ÇFOO酒吧巴茲

; ABC FOO並[b] AR巴茲

; ABC FOO酒吧並[b] AZ

;一個並[b]ÇFOO酒吧巴茲

另外,我也會很高興的一個版本,開始向另一個方向移動,一旦它達到最後,例如

fb一個並[b]ÇFOO酒吧巴茲

; ABC FOO並[b] AR巴茲

; ABC FOO酒吧並[b] AZ

; ABC FOO並[b] AR巴茲

+0

您可以執行與http://stackoverflow.com/a/25072966/1890567類似的操作,該操作使用內置搜索,然後將其限制爲當前行。該n/N將包裝在當前行上。 – FDinoff

回答

2

起初,我認爲這很容易。原來不是。你必須基本上重新實施每個組合fFtT;,,以及許多邊緣情況。這最終是32行vimscript。那就是:

function! RepeatFind(reverse) 
    let l:dict = getcharsearch() 

    if a:reverse == l:dict['forward'] 
    let l:text = getline('.')[:col('.') - 2] 
    if l:dict['until'] 
     let l:text = l:text[:-2] 
    endif 
    else 
    let l:text = getline('.')[col('.'):] 
    if l:dict['until'] 
     let l:text = l:text[1:] 
    endif 
    endif 

    if index(split(l:text, '.\zs'), l:dict['char']) != -1 
    exe 'normal! '.(a:reverse ? ',' : ';') 
    else 
    if !a:reverse && l:dict['forward'] 
     normal 0; 
    elseif !a:reverse && !l:dict['forward'] 
     normal! $; 
    elseif a:reverse && l:dict['forward'] 
     normal! $, 
    elseif a:reverse && !l:dict['forward'] 
     normal! 0, 
    endif 
    endif 
endfunction 

nnoremap ; :<C-u>call RepeatFind(0)<cr> 
nnoremap , :<C-u>call RepeatFind(1)<cr> 

一個困難來自於大寫字母變體和,是雙negatable,工作向前發展。這就是16-28行的原因,對所有可能的組合進行了硬編碼。

另外,我也很樂意與開始在另一個方向移動,一旦打到最後

這可能不會是很難實現的,因爲關於過去的信息版本搜索,當前方向等已經被存儲。但它帶來了一些有趣的角落案例。例如,如果您使用;直到切換到後退,然後按,會發生什麼情況。如果這種嘗試繼續前進,然後倒退?

+0

哇,謝謝你爲此付出的所有努力。 – Kvass

+1

你知道搜索功能嗎?我想如果你使用了這個,很多這個可以簡化。你也可以使用'getcharsearch()'來找出搜索方向和最後搜索到的字符。 – FDinoff

+0

@FDinoff哦,哇,我根本不知道。這非常有用,謝謝你讓我知道! – DJMcMayhem