Tự động tải lại một tệp trong VIM ngay khi thay đổi trên đĩa


32

Giả sử rằng một tệp không có các thay đổi chưa được lưu trong bộ đệm VIM, tôi muốn nó tự động tải lại nếu tệp thay đổi trên đĩa. Trường hợp sử dụng thường xuyên nhất cho trường hợp này là khi tôi cập nhật bản sao làm việc trong đó tệp nằm trong đó.

Làm thế nào tôi có thể đạt được điều này?


Tôi nghĩ đây là ý của bạn, nhưng trường hợp sử dụng cụ thể của tôi là khi tôi kiểm tra một nhánh git hoặc cam kết khác, tôi muốn vim tải lại tệp.
Nathan Long

Câu trả lời:


32

Trong của bạn ~/.vimrc:

set autoread

9
Nói chung autoreadsẽ chỉ kích hoạt sau khi thực hiện một lệnh bên ngoài. Câu trả lời này chi tiết các giải pháp.
Tom Hale

Điều này không hoạt động Theo liên kết @TomHale để có câu trả lời chi tiết
JonnyRaa

11

Đây là những gì làm việc cho tôi

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

Dòng đầu tiên không đủ. Bạn có thể đặt vào bạn.vimrc

tín dụng cho Phan Hải Quang


Autocmd không cần thiết - thời gian kiểm tra được cho là chạy nội bộ cùng lúc với sự kiện CthonHold được kích hoạt. Nói cách khác, bạn chỉ đang khiến Vim thực hiện lần kiểm tra thứ hai.
Heptite

Đối với tôi nó là cần thiết. Giải pháp tốt nhất tôi đã tìm thấy sau rất nhiều nghiên cứu. @Heptite, bạn có chương và câu cho khẳng định của bạn không?
Tom Hale

1
@TomHale Tôi đã xem xét các tài liệu Vim và nó không nói rõ ràng, theo như tôi có thể nói, nhưng " :help timestamp" dường như cho thấy tôi là người có lỗi và Vim chỉ thực hiện kiểm tra các sự kiện cụ thể, vì vậy autocmd có thể cần thiết để khiến nó kiểm tra thường xuyên hơn.
Heptite

5

Autoread không hoạt động chính xác. Các công việc sau đây cho tôi:

Trước tiên bạn cần cài đặt tập lệnh từ đây .

Tôi đã nhận được kết quả tốt nhất bằng cách gọi trực tiếp chức năng thiết lập, như vậy.

let autoreadargs={'autoread':1} 
execute WatchForChanges("*",autoreadargs) 

Lý do cho điều này, là tôi muốn chạy một thiết lập ipython / screen / vim.

Bạn có thể dễ dàng chuyển đổi nó thành một phiên bản nâng cao của chế độ xem.

kịch bản quá trình ..

mkdir -p ~/bin
cat <<`OUT` > ~/bin/vimviewer
#!/usr/bin/env sh
exec vim -n --cmd "source /home/bryan/.vim/.vimrc.watchforchanges | let autoreadargs={'autoread':1} | execute WatchForChanges('*',autoreadargs)" $@
`OUT`

chmod 755 ~/bin/vimviewer
vimview test.txt

1
Nếu bạn đang sử dụng một trong các GUI vim như gVim hoặc MacVim thì lệnh autoread sẽ tích hợp tốt với phần còn lại của môi trường. Ví dụ: chỉnh sửa tệp trong một số chương trình khác, trình chỉnh sửa khác hoặc từ kiểm soát nguồn, sau đó chuyển trở lại vim sẽ tự động đọc các tệp đã cập nhật. Vấn đề dường như là cách tích hợp phiên bản đầu cuối của vim. Phiên bản đầu cuối không thể biết khi nào bạn chuyển đổi giữa các chương trình trong GUI hoặc sử dụng bộ ghép kênh đầu cuối như tmux, do đó, nó không thể tự động đọc vào những thời điểm thích hợp. Sẽ thật tuyệt nếu vim chỉ đăng ký vào các sự kiện hệ thống tệp có liên quan.
bames53

3

Plugin vim-autoread đã làm việc cho tôi cho đến nay:

vim-autoread

Tự động khiến vim tải lại các tệp đã được ghi trên đĩa nhưng không được sửa đổi trong bộ đệm kể từ lần ghi cuối cùng từ vim. Điều này cho phép một tệp mở trong vim được chỉnh sửa bằng ứng dụng khác và được lưu. Khi quay lại vim, miễn là bạn chưa sửa đổi tệp kể từ lần thay đổi cuối cùng, tệp sẽ được cập nhật tự động để phản ánh các thay đổi được thực hiện trên đĩa, như thể bạn đã nhấn: e thủ công.


Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ đánh giá
Burgi

@Burgi Tôi đã thêm mô tả plugin giải thích cách giải quyết vấn đề.
Wojtek Kruszewski

Tôi đã thử nó nhưng tôi phải gõ một lệnh điều hướng (như j) để xem cập nhật hiệu quả. Tôi đã tạo ra một vấn đề ở đây về điều này: github.com/djoshea/vim-autoread/issues/3
Martin Delille

3

từ câu trả lời này (tham khảo câu trả lời của PhanHaiQuang và nhận xét của @flukus)

Người ta có thể chạy oneliner này từ ex (whithin vim) khi cần (hoặc đặt từng lệnh trong vimrc, khi tệp log được mở.)

:set autoread | au CursorHold * checktime | call feedkeys("lh")

Giải thích:
- autoread : đọc tệp khi thay đổi từ bên ngoài (nhưng nó không hoạt động, không có bộ đếm thời gian bên trong hoặc một cái gì đó tương tự. Nó sẽ chỉ đọc tệp khi vim thực hiện một hành động, như một lệnh trong ex :!
- CoderHold * thời gian kiểm tra : khi con trỏ không di chuyển theo thời gian được chỉ định trong 'updatetime' (tức là 4000 milis giây theo mặc định), thời gian kiểm tra sẽ được thực hiện, kiểm tra các thay đổi từ bên ngoài tệp
- gọi feedkey ("lh") : con trỏ được di chuyển một lần, phải và quay lại bên trái. và sau đó không có gì xảy ra (... điều đó có nghĩa là CthonHold được kích hoạt, có nghĩa là chúng ta có một vòng lặp )


lhkhông làm gì cả, nếu con trỏ ở vị trí cuối cùng trên dòng, lhsẽ thay đổi vị trí của nó.
Mahmoud Al-Qudsi

Chính xác, đó là điểm. Tệp được tải lại với mức tối thiểu của sự tương tác hoặc thay đổi đối với tệp. Bạn có thể nhảy đến dòng cuối cùng hoặc đầu tiên nếu bạn muốn (chỉ cần thay thế lh bằng gg hoặc G), nhưng mục tiêu ở đây, chỉ là tải lại tệp trong vim, và đó là những gì được thực hiện bởi lớp lót này, không có gì hơn. Bạn thích làm gì ở đây?
eli

@ MahmoudAl-Qudsi ... nghĩa, rằng "lh" chỉ kích hoạt CursorHold - hành động (tôi đã đề cập rằng trong Giải thích), sau đó một lần nữa gây nên autoread
eli

1

Có một số plugin được liệt kê ở đây có thể hoạt động tùy thuộc vào phiên bản Vim của bạn.

Một cách tiếp cận khác là định kỳ gửi checktimelệnh tới vim từ một quy trình bên ngoài. Đây là tập lệnh ShellJS để làm điều này (yêu cầu shelljs-plugin-sleep, NeoVim và nvr)

while (true) {
  sleep(15);
  var servernames = exec('nvr --serverlist').trim().split('\n');
  if (!servernames.length || !servernames[0]) {
    continue;
  }
  servernames.forEach(
    (sn) => exec(`nvr -c "checktime" --servername ${sn}`) );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.