2015-07-11 14 views
7

Ich habe Inhalt in einer Variablen (out) gespeichert, die ich durch den aktuellen Puffer ersetzen möchte. Ich mache es zur Zeit so (vereinfachte Version):Verhindern, dass der Cursor nach unten springt, wenn der Puffer ersetzt wird

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

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

jedoch setline() hier verursacht Langsamkeit auf einigen Maschinen und https://github.com/fatih/vim-go/issues/459. Ich habe es selbst profiliert, aber für mich war Setline kein Problem. Wie auch immer, ich brauche eine Lösung, die schneller ist. Also habe ich mir mehrere andere Lösungen ausgedacht.

Erste ist, der den Ausgang in ein Register setzt, löscht alle Zeilen und legt sie dann zurück:

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

Zweite Lösung wäre mit append() (die zuvor in verwendet wurde vim-go https://github.com/fatih/vim-go/commit/99a1732e40e3f064300d544eebd4153dbc3c60c7):

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

Sie beide Arbeit! Beide verursachen aber auch einen Nebeneffekt, den ich immer noch nicht lösen konnte und der auch im Titel steht. Das Problem wird wie folgt beschrieben:

Wenn ein Puffer in einer anderen Ansicht (etwa neben nächsten) geöffnet ist, und wir eine der beiden oben genannten Lösungen nennen, es bricht den Cursor von die andere Ansicht und springt auf der Boden

ist hier ein GIF zeigt es besser (wenn ich :w eines der Verfahren genannt oben nennen wird): http://d.pr/i/1buDZ

gibt es eine Möglichkeit, den Inhalt eines Puffers zu ersetzen, die schnell ist und bricht das Layout nicht? Oder wie kann ich es mit einem der oben genannten Verfahren verhindern?

Danke.

Antwort

0

Haben Sie versucht winsaveview() und winrestview()?

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

aber ich weiß nicht, etwas über Einfügen von Text in einem schnelleren Weg

+0

Ja, ich benutze sie bereits, aber sie haben keinen Einfluss auf die beiden oben genannten Optionen. Hier ist, wie ich es benutze: https://github.com/fatih/vim-go/blob/master/autoload/go/fmt.vim#L58 Auch gibt es kein Problem mit dem aktuellen Puffer/Sicht, das Problem ist, es ist Auswirkungen auf die andere Windows-Cursor-Position, wo ich keine Kontrolle habe. –

+0

Hoppla, das habe ich über dein Thema vermisst: "in * einer anderen Ansicht *", sorry – yolenoyer

+0

Yeah, schau auch mal auf das GIF, ich habe es auch in Aktion gezeigt :) –

0

Versuchen Sie, den redraw Befehl.

Ich habe ähnliche Probleme mit seltsamen Verzögerungen ein paar Mal konfrontiert, wo Profiling nichts Verdächtiges zeigt. Aber der redraw Befehl löste es in den meisten Fällen und es stört das Fensterlayout nicht (das letzte Mal fand ich dieses Problem in vim-addon-qf-layout plugin).

Wenn das Problem weiterhin auftritt, können Sie versuchen, den folgenden Ansatz zu verwenden, der sich geringfügig von Ihrem ersten Beispiel unterscheidet. Ich habe using it for quite some time without any delays gewesen:

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

Leider funktioniert beides nicht. Die Verwendung von 'redraw' verhindert nicht, dass die zweite Ansicht geändert wird. Die andere Änderung bringt den gesamten Puffer durcheinander, da er den Inhalt nicht vollständig ersetzt. Stattdessen "präsidiert" es es immer noch. –

0

Was ist das? Es speichert die Ansicht für jedes Fenster mit dem geöffneten aktuellen Puffer und stellt anschließend alle Ansichten nach den Änderungen wieder her. Es scheint für mich zu funktionieren.

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 
Verwandte Themen