โหลดไฟล์ใน VIM โดยอัตโนมัติทันทีที่มีการเปลี่ยนแปลงบนดิสก์


33

สมมติว่าไฟล์ไม่มีการเปลี่ยนแปลงที่ไม่ได้บันทึกในบัฟเฟอร์ VIM ฉันต้องการให้โหลดซ้ำโดยอัตโนมัติหากไฟล์เปลี่ยนแปลงบนดิสก์ กรณีการใช้งานบ่อยที่สุดคือเมื่อฉันอัปเดตสำเนาการทำงานที่ไฟล์นั้นอยู่

ฉันจะบรรลุสิ่งนี้ได้อย่างไร


ฉันคิดว่านี่คือสิ่งที่คุณหมายถึง แต่กรณีการใช้งานเฉพาะของฉันคือเมื่อฉันตรวจสอบสาขา git ที่แตกต่างกันหรือกระทำฉันต้องการเป็นกลุ่มเพื่อโหลดไฟล์
นาธานลอง

คำตอบ:


32

ใน~/.vimrc:

set autoread

9
โดยทั่วไปautoreadจะเรียกใช้หลังจากเรียกใช้คำสั่งภายนอกเท่านั้น คำตอบนี้ให้รายละเอียดการแก้ปัญหา
Tom Hale

ไม่สามารถใช้งานได้ตามลิงก์ @TomHale เพื่อรับคำตอบโดยละเอียด
JonnyRaa

11

นี่คือสิ่งที่ได้ผลสำหรับฉัน

set autoread                                                                                                                                                                                    
au CursorHold * checktime  

บรรทัดแรกนั้นยังไม่เพียงพอ คุณสามารถใส่ในคุณ.vimrc

เครดิตไปยังพานไห่กวง


ไม่จำเป็นต้องใช้ autocmd - การตรวจสอบเวลาควรทำงานภายในเวลาเดียวกันกับที่เกิดเหตุการณ์ CursorHold ขึ้นมา พูดอีกอย่างก็คือคุณกำลังทำให้ Vim ทำ checktime ครั้งที่สอง
Heptite

สำหรับฉันมันเป็นสิ่งจำเป็น ทางออกที่ดีที่สุดที่ฉันได้พบหลังจากการวิจัยมากมาย @Heptite คุณมีบทและข้อสำหรับยืนยันของคุณหรือไม่
Tom Hale

1
@ TomHale ฉันได้ตรวจสอบ Vim docs แล้วและไม่ได้พูดอย่างชัดเจนเท่าที่ฉันจะบอกได้ แต่ " :help timestamp" ดูเหมือนจะระบุว่าฉันเป็นคนที่มีข้อผิดพลาดและ Vim นั้นทำการตรวจสอบเหตุการณ์เฉพาะเท่านั้น ดังนั้น autocmd อาจจำเป็นต้องทำให้ตรวจสอบบ่อยขึ้น
Heptite

5

Autoread ทำงานไม่ถูกต้อง งานต่อไปนี้สำหรับฉัน:

คุณจำเป็นต้องติดตั้งสคริปต์จากที่นี่

ฉันได้ผลลัพธ์ที่ดีที่สุดโดยการเรียกใช้ฟังก์ชันการตั้งค่าโดยตรงเช่นนั้น

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

เหตุผลนี้คือฉันต้องการเรียกใช้การตั้งค่า ipython / screen / vim

คุณสามารถแปลงให้เป็นมุมมองรุ่นปรับปรุงได้อย่างง่ายดาย

สคริปต์กระบวนการ

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
หากคุณกำลังใช้ vim GUIs อย่างใดอย่างหนึ่งเช่น gVim หรือ MacVim คำสั่ง autoread จะรวมเข้ากับส่วนที่เหลือของสภาพแวดล้อม เช่นการแก้ไขไฟล์ในโปรแกรมอื่นโปรแกรมแก้ไขอื่นหรือจากแหล่งควบคุมจากนั้นการสลับกลับไปเป็นกลุ่มจะทำการอัปเดตไฟล์ที่อัพเดตโดยอัตโนมัติ ปัญหาน่าจะเป็นไปได้อย่างไรกับการรวมกันของเวอร์ชันเทอร์มินัลของ vim เวอร์ชันเทอร์มินัลไม่สามารถบอกได้เมื่อคุณสลับระหว่างโปรแกรมทั้งใน GUI หรือใช้เทอร์มินัลมัลติเพล็กเซอร์เช่น tmux ดังนั้นจึงไม่สามารถทำการทดสอบอัตโนมัติในเวลาที่เกี่ยวข้อง มันจะดีถ้าเป็นกลุ่มจะสมัครสมาชิกเหตุการณ์ระบบไฟล์ที่เกี่ยวข้อง
bames53

3

ปลั๊กอินvim-autoreadทำงานให้ฉันแล้ว:

เป็นกลุ่ม-AutoRead

ทำให้ vim โหลดไฟล์ที่เขียนบนดิสก์โดยอัตโนมัติ แต่ไม่แก้ไขในบัฟเฟอร์ตั้งแต่การเขียนล่าสุดจาก vim สิ่งนี้เปิดใช้งานไฟล์ที่เปิดเป็นกลุ่มที่จะแก้ไขโดยใช้แอปพลิเคชันอื่นและบันทึกไว้ เมื่อกลับไปเป็นกลุ่มตราบใดที่คุณยังไม่ได้แก้ไขไฟล์ตั้งแต่มีการเปลี่ยนแปลงครั้งล่าสุดไฟล์นั้นจะได้รับการอัปเดตโดยอัตโนมัติเพื่อแสดงการเปลี่ยนแปลงที่เกิดขึ้นบนดิสก์ราวกับว่าคุณได้กด: e ด้วยตนเอง


แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงมีการเปลี่ยนแปลง - จากการรีวิว
Burgi

@Burgi ฉันได้เพิ่มคำอธิบายปลั๊กอินที่อธิบายถึงวิธีการแก้ปัญหา
Wojtek Kruszewski

ฉันลองแล้ว แต่ฉันต้องพิมพ์คำสั่งการนำทาง (เช่นj) เพื่อดูการปรับปรุงที่มีประสิทธิภาพ ฉันสร้างปัญหาที่นี่เกี่ยวกับเรื่องนี้: github.com/djoshea/vim-autoread/issues/3
Martin Delille

3

จากคำตอบนี้(อ้างอิงจากคำตอบของPhanHaiQuangและความคิดเห็นโดย @flukus)

หนึ่งสามารถเรียกใช้ oneliner นี้จากอดีต (whithin vim) เมื่อจำเป็น (หรือใส่คำสั่งแต่ละคำสั่งใน vimrc เมื่อเปิดไฟล์บันทึก)

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

คำอธิบาย:
- autoread : อ่านไฟล์เมื่อมีการเปลี่ยนแปลงจากภายนอก (แต่มันไม่ทำงานด้วยตัวของมันเองไม่มีตัวจับเวลาภายในหรืออะไรทำนองนั้นมันจะอ่านไฟล์เมื่อ vim ทำการกระทำเช่นเดียวกับคำสั่งในอดีต:!
- CursorHold * การตรวจสอบเวลา: เมื่อเคอร์เซอร์ไม่ได้ถูกย้ายโดยผู้ใช้ตามเวลาที่ระบุใน 'updatetime' (ซึ่งเป็น 4,000 มิลลิวินาทีโดยค่าเริ่มต้น) เวลาตรวจสอบจะถูกดำเนินการซึ่งจะตรวจสอบการเปลี่ยนแปลงจากภายนอกไฟล์
- ปุ่มฟีดการโทร ("lh") : เคอร์เซอร์ถูกย้ายหนึ่งครั้งด้านขวาและด้านหลังซ้ายจากนั้นไม่มีสิ่งใดเกิดขึ้น (... ซึ่งหมายความว่า CursorHold นั้นเริ่มทำงานซึ่งหมายความว่าเรามีลูป )


lhไม่ทำอะไรเลยถ้าเคอร์เซอร์อยู่ที่ตำแหน่งสุดท้ายของบรรทัดlhจะเปลี่ยนตำแหน่งของมัน
Mahmoud Al-Qudsi

ตรงประเด็นนั่นแหละ ไฟล์จะถูกโหลดใหม่ด้วยการโต้ตอบน้อยที่สุดหรือการเปลี่ยนแปลงกับไฟล์ คุณสามารถข้ามไปยังบรรทัดสุดท้ายหรือบรรทัดแรกหากคุณต้องการ (เพียงแทนที่ lh ด้วย gg หรือ G) แต่เป้าหมายที่นี่คือการโหลดไฟล์เป็นกลุ่มและทำตามสิ่งที่ทำโดยซับนี้ไม่มีอะไรเพิ่มเติม คุณอยากทำอะไรที่นี่?
eli

@ MahmoudAl-Qudsi ... ความหมายว่า "lh" เพียงแค่เรียก CursorHold - การกระทำ (ฉันพูดถึงว่าในคำอธิบาย) ซึ่งจากนั้นอีกครั้งทริกเกอร์ autoread
eli

1

มีปลั๊กอินบางตัวที่แสดงที่นี่ซึ่งอาจใช้งานได้ขึ้นอยู่กับเวอร์ชั่นของ Vim ของคุณ

อีกวิธีหนึ่งคือการส่งchecktimeคำสั่งไปเป็นกลุ่มจากกระบวนการภายนอกเป็นระยะ นี่คือสคริปต์ ShellJS เพื่อทำสิ่งนี้ (ต้องการshelljs-plugin-sleep, NeoVim และ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}`) );
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.