Cập nhật 2015-06-25 :
- Tôi đã loại bỏ phương pháp "shell", vì nó quá rối loạn. Nó dừng chế độ chèn và để lại quá trình zombie. Nhìn vào lịch sử sửa đổi của bài viết này là bạn thực sự muốn xem nó.
- Tôi đã tạo một plugin từ đây: auto_autoread.vim . Hiện tại, nó thực sự giống như mã bên dưới, nhưng tôi khuyên bạn nên sử dụng plugin vì điều này có khả năng nhận được cập nhật.
Không gì autoread
làm gì?
Để trả lời câu hỏi này, trước tiên chúng ta phải hiểu autoread
tùy chọn này làm gì và quan trọng hơn là những gì nó không làm.
Thật không may :help 'autoread'
, không có nhiều thông tin về điều này, nó chỉ nói rằng "một tệp đã được phát hiện đã bị thay đổi bên ngoài Vim" . Làm thế nào để Vim phát hiện ra rằng một tập tin được thay đổi? Trên một số hành động nhất định, Vim kiểm tra thời gian sửa đổi của tệp.
Khi nào:
:checktime
Được sử dụng;
- một bộ đệm được nhập vào;
:diffupdate
Được sử dụng;
:e
được cấp cho một tệp đã có bộ đệm;
- thực hiện một lệnh bên ngoài với
!
;
- trở về nền trước (
^Z
, fg
chỉ khi vỏ có kiểm soát công việc);
đối với gVim, điều này cũng được thực hiện khi:
- đóng menu "nhấp chuột phải" (bằng cách chọn một cái gì đó, hoặc chỉ bằng cách đóng nó);
- trọng tâm được thay đổi (đây là những gì bạn đã nhận thấy);
- đóng hộp thoại trình duyệt tệp bật lên nếu bạn sử dụng "tệp -> mở", "tệp -> lưu dưới dạng" từ menu (cũng như một số nơi khác).
Tôi đã thu thập thông tin này từ nguồn Vim bằng cách định vị tất cả các cuộc gọi đến
buf_check_timestamp()
, các check_timestamps()
chức năng và vị trí
need_check_timestamps
được đặt TRUE
.
Tôi có thể đã bỏ lỡ một số sự kiện, nhưng điều quan trọng cần nhớ là Vim chỉ kiểm tra xem tệp có bị sửa đổi trong một tập hợp rất hạn chế của xơ gan hay không . Nó chắc chắn không "thăm dò" tệp cho các thay đổi trong n giây, về cơ bản là những gì bạn đang theo đuổi.
Vì vậy, cho mục đích của bạn, set autoread
là không đủ.
Sử dụng Python
Điều này lên lịch một luồng Python để chạy trong nền, nó sẽ chạy
:checktime
mỗi n giây. Nếu autoread
được bật , điều này sẽ tải lại bộ đệm từ đĩa, nếu không nó sẽ chỉ cảnh báo.
Điều này đòi hỏi Vim có +python
hoặc +python3
trong :version
. Nó nên hoạt động trên tất cả các nền tảng (bao gồm cả Windows).
fun! AutoreadPython()
python << EOF
import time, vim
try: import thread
except ImportError: import _thread as thread # Py3
def autoread():
vim.command('checktime') # Run the 'checktime' command
vim.command('redraw') # Actually update the display
def autoread_loop():
while True:
time.sleep(1)
autoread()
thread.start_new_thread(autoread_loop, ())
EOF
endfun
Bạn có thể bắt đầu điều này bằng cách sử dụng :call AutoreadPython()
; tất nhiên bạn có thể làm điều này trong một autocmd; ví dụ:
autocmd *.c call AutoreadPython()
Lời bạt
Thực tế có nhiều phương thức hơn, ví dụ bạn có thể sử dụng một công cụ như
entr
hoặc Python inotify
hoặc gamin
mô-đun để theo dõi tệp để thay đổi, :checktime
cũng kiểm tra tất cả các bộ đệm nếu nó không đưa ra bất kỳ đối số nào, điều này có thể được cải thiện bằng cách chỉ kiểm tra một bộ đệm hoặc một tập tin nhất định
Tuy nhiên, câu trả lời này đã khá dài :-) Phương pháp này (hy vọng!) Hoạt động tốt cho hầu hết các kịch bản hoặc có thể dễ dàng thích ứng với kịch bản của bạn.
Tái bút Tôi cũng đã thử sử dụng Ruby, nhưng tiếc là các chủ đề của Ruby (không sử dụng Thread
) không chạy trong nền như Python, vì vậy tôi không thể làm cho nó hoạt động (mặc dù có một cách khác?)
CursorHold
sự kiện này? Nếu Vim không có tiêu điểm, nó sẽ kích hoạt cứ sau n giây.