2015-07-11 26 views
7

Ho contenuto memorizzato in una variabile (out) che voglio sostituire con il buffer corrente. Attualmente sto facendo in questo modo (versione semplificata):Previene il salto del cursore verso il basso quando viene sostituito il buffer

let splitted = split(out, '\n') 
if line('$') > len(splitted) 
    execute len(splitted) .',$delete' 
endif 
call setline(1, splitted) 

(dettagliata: https://github.com/fatih/vim-go/blob/master/autoload/go/fmt.vim#L130)

Tuttavia setline() qui provoca lentezza su alcune macchine e https://github.com/fatih/vim-go/issues/459. L'ho realizzato io stesso ma per me il setline non era un problema. Ad ogni modo, ho bisogno di una soluzione che sia più veloce. Quindi ho trovato diverse altre soluzioni.

primo è, che mette l'uscita di un registro, elimina tutte le righe e poi lo rimette:

let @a = out 
% delete _ 
put! a 
$ delete _ 

Seconda soluzione sarebbe utilizzando append() (che è stato usato in precedenza in vim-go https://github.com/fatih/vim-go/commit/99a1732e40e3f064300d544eebd4153dbc3c60c7):

let splitted = split(out, '\n') 
%delete _ 
call append(0, splitted) 
$delete _ 

Essi sia lavoro! Tuttavia entrambi causano anche un effetto collaterale che non riesco ancora a risolvere ed è anche scritto nel titolo. Il problema è descritto come:

Se un buffer viene aperto in un'altra vista (per esempio vicino al seguente), e chiamiamo una delle due soluzioni sopra, rompe il cursore del l'altra vista e salta fondo

Qui è un GIF che mostra meglio (ogni volta chiamo :w una delle procedure sopra è chiamato): http://d.pr/i/1buDZ

c'è un modo, per sostituire il contenuto di un buffer, che è veloce e non rompe il layout? O come posso prevenirlo con una delle procedure sopra?

Grazie.

risposta

0

Hai provato winsaveview() e winrestview()?

:let old_view=winsaveview() 
:% delete _ 
:put! =out 
:$ delete _ 
:call winrestview(old_view) 

Comunque non so niente di incollare il testo in modo più rapido

+0

Sì, li sto già utilizzando, ma non influiscono sulle due opzioni precedenti. Ecco come lo uso: https://github.com/fatih/vim-go/blob/master/autoload/go/fmt.vim#L58 Inoltre non c'è alcun problema con il buffer/vista attuale, il problema è che è influisce sull'altra posizione del cursore di Windows, in cui non ho alcun controllo. –

+0

Oops, ho perso questo problema: "in * un'altra vista *", spiacente – yolenoyer

+0

Sì, anche per favore guarda la GIF, l'ho mostrato anche in azione :) –

0

Provare a utilizzare il comando redraw.

Ho affrontato problemi simili di strani ritardi alcune volte, in cui la profilazione non mostra nulla di sospetto. Ma il comando redraw l'ha risolto nella maggior parte dei casi e non interrompe il layout della finestra (l'ultima volta che ho trovato questo problema era in vim-addon-qf-layout plugin).

Se il problema si verifica ancora, provare a utilizzare il seguente approccio, leggermente diverso dal primo esempio; Sono stato using it for quite some time without any delays:

function! s:setCurrentLine(content) 
    silent put =a:content 
    " delete original line 
    silent '[-1delete _ 
endfunction 
+0

Sfortunatamente, entrambi si avvicinano non funziona. L'uso di 'ridisegna', tuttavia, non impedisce la modifica della seconda vista. L'altra modifica incasina l'intero buffer in quanto non sostituisce completamente il contenuto. Invece continua a "esserlo". –

0

Che dire di questo? Salva la vista per ogni finestra con il buffer corrente aperto all'interno, quindi ripristina tutte le viste dopo le modifiche. Sembra funzionare per me.

function! BufListSave() 
    let cur_buf = winbufnr(0) 
    let cur_tab = tabpagenr() 
    let buflist = [] 
    for i in range(tabpagenr('$')) 
     let tab_array = [] 
     let tab_buflist = tabpagebuflist(i+1) 
     for j in range(len(tab_buflist)) 
      if tab_buflist[j] == cur_buf 
       exe "tabn ".(i+1) 
       let cur_win = winnr() 
       exe (j+1)."wincmd w" 
       call add(tab_array, {"win":j+1, "view":winsaveview()}) 
       exe cur_win."wincmd w" 
      endif 
     endfor 
     call add(buflist, tab_array) 
    endfor 
    exe "tabn ".cur_tab 
    return buflist 
endfunction 


function! BufListRest(buflist) 
    let cur_tab = tabpagenr() 
    for i in range(len(a:buflist)) 
     let tab_array = a:buflist[i] 
     if len(tab_array) == 0 
      continue 
     endif 
     exe "tabn ".(i+1) 
     let cur_win = winnr() 
     for wi in tab_array 
      exe "".wi['win']."wincmd w" 
      call winrestview(wi['view']) 
     endfor 
     exe cur_win."wincmd w" 
    endfor 
    exe "tabn ".cur_tab 
endfunction 


function! Do_It() 
    let buf_list = BufListSave() 
    %delete _ 
    put! =out 
    $delete _ 
    call BufListRest(buf_list) 
endfunction 


function! Do_It_Silently() 
    silent call Do_It() 
endfunction