Как определить, какой буфер был изменен внешне с помощью gVim?

320
ysap

Я использую следующую автокоманду Vim в моем .gvimrcфайле:

augroup MyAuGroup autocmd MyAuGroup FileChangedShell * call FileChanedEvent_BuffUpdate() augroup END  function FileChanedEvent_BuffUpdate() let MyBn = bufname("%") let MyStr = "Warning: File \"".MyBn."\" has changed since editing started\nSee \":help W11\" for more info." let MyTest = confirm(MyStr, "&OK\n&Load File", 2, "W") if MyTest == 2 edit else endif endfunction 

с намерением заменить поведение gVim по умолчанию при внешнем изменении файла (см. этот вопрос ). Однако если открыто несколько окон с несколькими буферами, editкоманда работает с последним активным окном, а не с окном, содержащим буфер, который был изменен.

Как я могу определить, какой буфер вызвал FileChangedShellсобытие, и применить editк нему буфер?

1

2 ответа на вопрос

4
Ingo Karkat

От :help FileChangedShell:

NOTE: When this autocommand is executed, the current buffer "%" may be different from the buffer that was changed "<afile>". 

Вам нужно найти окно, в котором редактируется соответствующий файл. Для этого номер буфера (in <abuf>) еще проще:

let winNr = bufwinnr(0 + expand('<abuf>')) execute winNr . 'wincmd w' edit 

То же самое относится и к имени буфера; замещать

let MyBn = bufname("%") 

с

let MyBn = expand('<afile>') 
Я использовал `edit MyBn` вместо команды` edit`. Но при выборе кнопки «загрузить файл» я получаю ошибку «E811», и буфер не обновляется. Я думаю, что мой альтернативный ответ является более прямым. ysap 10 лет назад 0
Интересно, почему есть разница между двумя формами `edit`. Версия `edit` (без аргументов) работает, когда последним активным буфером был тот, в котором был измененный файл. ysap 10 лет назад 0
пробовал также `редактировать `но получил тот же ответ ysap 10 лет назад 0
Вам необходимо выполнить `edit 'edit' fnameescape (MyBn)`, но я вижу, что вы нашли более простую альтернативу. Ingo Karkat 10 лет назад 0
К сожалению, этот вариант тоже не работает. ysap 10 лет назад 0
0
ysap

Благодаря ответу @ IngoKarkat. Я нашел альтернативное решение. Заменить ifблок в функции:

 if MyTest == 2 let v:fcs_choice = "reload" else let v:fcs_choice = "" endif 

Это, кажется, делает трюк.