2015-07-11 2 views
7

У меня есть содержимое, хранящееся в переменной (out), которую я хочу заменить текущим буфером. В настоящее время я делаю это так (упрощенный вариант):Запретить курсор прыгать снизу при замене буфера

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

(Детальнее: https://github.com/fatih/vim-go/blob/master/autoload/go/fmt.vim#L130)

Однако setline() здесь приводит к медлительности на некоторых машинах и https://github.com/fatih/vim-go/issues/459. Я сам профилировал его, но для меня сеттинга не было проблемой. Во всяком случае, мне нужно решение, которое быстрее. Поэтому я придумал несколько других решений.

Первый из них, который помещает выходные данные в регистр, удаляет все строки, а затем помещает его обратно:

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

Второе решение будет использовать append() (который ранее был использован в VIM-идут https://github.com/fatih/vim-go/commit/99a1732e40e3f064300d544eebd4153dbc3c60c7):

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

Они как работа! Однако оба они также вызывают побочный эффект, который я все еще не могу решить, а также написано в названии. Проблема описана как:

Если буфер открыт в другой точке зрения (скажем, рядом с другой), и мы называем один из двух решений выше, он ломает курсор другой вид и переходит к нижний

Вот GIF, показывая, что лучше (всякий раз, когда я называю :w одну из процедур выше называется): http://d.pr/i/1buDZ

есть ли способ, чтобы заменить содержимое буфера, который быстро и не нарушает макет? Или как я могу предотвратить это с помощью одной из вышеперечисленных процедур?

Спасибо.

ответ

0

Вы попробовали winsaveview() и winrestview()?

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

Однако я ничего наклеивать текст не знать быстрый способ

+0

Да, я уже использую их, но они не влияют на два варианта выше. Вот как я его использую: https://github.com/fatih/vim-go/blob/master/autoload/go/fmt.vim#L58 Также нет проблем с текущим буфером/представлением, проблема в том, что это влияя на другую позицию курсора Windows, где у меня нет никакого контроля. –

+0

К сожалению, я пропустил это о вашей проблеме: «в * другом виде *», извините – yolenoyer

+0

Да, пожалуйста, смотрите GIF, я тоже показал его в действии :) –

0

Попробуйте использовать команду redraw.

Я сталкивался с аналогичными проблемами странных задержек несколько раз, когда профилирование не показывает ничего подозрительного. Но команда redraw решила ее в большинстве случаев и не нарушила макет окна (последний раз, когда я нашел эту проблему в vim-addon-qf-layout plugin).

Если проблема все еще происходит, вы можете попробовать использовать следующий подход, который немного отличается от вашего первого примера; Я был using it for quite some time without any delays:

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

К сожалению, оба подхода не работают. Использование 'redraw', по-прежнему не препятствует изменению второго вида. Другое изменение испортит весь буфер, поскольку он не полностью заменяет содержимое. Вместо этого он все еще «предает» его. –

0

Как насчет этого? Он сохраняет представление для каждого окна с текущим буфером, открытым внутри, а затем восстанавливает все представления после изменений. Кажется, это работает для меня.

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 

 Смежные вопросы

  • Нет связанных вопросов^_^