vim.wasm: vim ported ไปยัง webassembly โครงการนี้เป็นส้อมทดลองของ VIM Editor โดย @RHYSD เพื่อรวบรวมลงใน WebAssembly โดยใช้ Emscripten และ Binaryen VIM ทำงานบนเว็บและโต้ตอบกับเธรดหลักผ่าน SharedArrayBuffer
เป้าหมายของโครงการนี้คือการเรียกใช้ VIM Editor บนเบราว์เซอร์โดยไม่สูญเสียฟังก์ชันการทำงานที่ทรงพลังของ Vim โดยการรวบรวมแหล่งข้อมูล VIM C ลงใน webAssembly

การใช้งาน
:write เฉพาะไฟล์เขียนบนหน่วยความจำ ดาวน์โหลดบัฟเฟอร์ปัจจุบันโดย :export หรือไฟล์เฉพาะโดย :export {file}"* ได้รับการสนับสนุนตัวอย่างเช่นวางข้อความคลิปบอร์ดระบบเพื่อ vim ด้วย "*p หรือ :put * และคัดลอกข้อความใน vim ไปยังคลิปบอร์ดระบบด้วย "*y หรือ :yank * ถ้าคุณต้องการซิง :set clipboard=unnamed คลิปบอร์ดของ Vim กับคลิปบอร์ดระบบ~/.vim จะถูกเก็บไว้อย่างต่อเนื่องใน DB ที่จัดทำดัชนี โปรดเขียนการกำหนดค่าที่คุณชื่นชอบใน ~/.vim/vimrc (ไม่ใช่ ~/.vimrc )file={filepath}={url} ดึงไฟล์จาก {url} ถึง {filepath} สามารถเปิดไฟล์ระยะไกลโดยพลการ (ดูแลเกี่ยวกับ CORS):!/path/to/file.js ประเมินรหัส JavaScript ในเบราว์เซอร์ :!% ประเมินบัฟเฟอร์ปัจจุบัน:e tutorarg= พารามิเตอร์การสืบค้น (เช่น ?arg=~%2f.vim%2fvimrc&arg=hello.txt ) เพื่อเพิ่มอาร์กิวเมนต์บรรทัดคำสั่ง vimสังเกต
SharedArrayBuffer และ Atomics บน Firefox หรือ Safari ต้องใช้ธงฟีเจอร์ ( javascript.options.shared_memory สำหรับ Firefox) ในตอนนี้keydown โปรดปิดการใช้งานส่วนขยายเบราว์เซอร์ของคุณซึ่งสกัดกั้นเหตุการณ์สำคัญ (โหมดไม่ระบุตัวตนจะดีที่สุด):quit แต่มันไม่ได้ปิดแท็บเบราว์เซอร์ โปรดปิดด้วยตนเอง :) โครงการนี้ได้รับการบรรจุเป็น vim-wasm NPM Pacakge ที่จะใช้ในเว็บแอปพลิเคชันได้อย่างง่ายดาย โปรดอ่านเอกสารสำหรับรายละเอียดเพิ่มเติม
เวอร์ชัน VIM พอร์ตปัจจุบันคือ 8.2.0055 พร้อมชุดคุณสมบัติ 'ปกติ' และ 'เล็ก' โปรดตรวจสอบ Changelog สำหรับประวัติอัปเดต
โครงการต่อไปนี้เกี่ยวข้องกับแพ็คเกจ NPM นี้และอาจเหมาะสำหรับกรณีการใช้งานของคุณ

ในเธรดคนงาน VIM กำลังทำงานโดยรวบรวมเป็น WASM เธรดคนงานถูกวางไข่เป็นผู้ทำงานบนเว็บเฉพาะจากเธรดหลักเมื่อเปิดหน้า
สมมติว่าคุณป้อนบางอย่างด้วยแป้นพิมพ์ เบราว์เซอร์ใช้เป็น KeyboardEvent ในเหตุการณ์ keydown JavaScript ในเธรดหลักจะจับเหตุการณ์และจัดเก็บข้อมูล Keydown ไปยังบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน
บัฟเฟอร์ถูกแชร์กับเธรดคนงาน Vim Waits และได้รับข้อมูล Keydown โดยการสำรวจบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกันผ่าน Atomics API ของ JavaScript เมื่อพบข้อมูลคีย์ในบัฟเฟอร์จะโหลดข้อมูลและคำนวณลำดับคีย์ ผ่าน JS ถึง WASM API ด้วย emscripten ลำดับจะถูกเพิ่มเข้าไปในบัฟเฟอร์อินพุตของ VIM ใน WASM
ลำดับในบัฟเฟอร์อินพุตถูกประมวลผลโดย Core Editor Logic (Update Buffer, Screen, ... ) เนื่องจากการอัปเดตเหตุการณ์การวาดบางอย่างเกิดขึ้นเช่นการวาดข้อความวาด rects, พื้นที่เลื่อน, ...
เหตุการณ์การวาดเหล่านี้จะถูกส่งไปยัง JavaScript ในเธรดคนงานจาก WASM ขอบคุณ JS ของ Emscripten ถึง C API พิจารณาอัตราส่วนพิกเซลอุปกรณ์และ <canvas/> API วิธีการคำนวณเหตุการณ์ที่คำนวณได้และเหตุการณ์การเรนเดอร์ที่คำนวณได้เหล่านี้จะถูกส่งผ่านจากเธรดคนงานไปยังเธรดหลักผ่านข้อความที่ส่งผ่านด้วย postMessage()
กระทู้หลัก JavaScript ได้รับและ enqueues เหตุการณ์การเรนเดอร์เหล่านี้ ในกรอบแอนิเมชั่นมันทำให้พวกเขาเป็น <canvas/>
ในที่สุดคุณสามารถดูหน้าจอแสดงผลในหน้า

WebAssembly Frontend สำหรับ VIM ถูกนำมาใช้เป็นส่วนหน้า GUI ใหม่ของ VIM เช่น GUI อื่น ๆ เช่น GTK Frontend แหล่ง C ถูกรวบรวมไว้ในไฟล์ LLVM BitCode แต่ละไฟล์จากนั้นเชื่อมโยงกับไฟล์ bitcode หนึ่งไฟล์ vim.bc โดย emcc ในที่สุด emcc จะรวบรวม vim.bc เป็น vim.wasm binary โดยใช้ binaryen และสร้างรันไทม์ HTML/JavaScript
ความแตกต่างที่ฉันเผชิญในตอนแรกคือการขาดห้องสมุดเทอร์มินัลเช่น ncurses ฉันแก้ไข configure สคริปต์เพื่อละเว้นการตรวจสอบไลบรารีเทอร์มินัล มันก็โอเคตั้งแต่ Frontend GUI สำหรับ WASM มักจะใช้แทน CUI Frontend ฉันต้องการวิธีแก้ปัญหามากมายเพื่อผ่าน configure ค่าการตรวจสอบ
Emscripten ให้สภาพแวดล้อมที่มีลักษณะเหมือน Unix ดังนั้น os_unix.c สามารถรองรับ WASM ได้ อย่างไรก็ตามคุณสมบัติบางอย่างไม่ได้รับการสนับสนุนโดย emscripten ฉันเพิ่ม #ifdef FEAT_GUI_WASM GUARDS เพื่อปิดการใช้งานคุณสมบัติที่ไม่สามารถรองรับได้โดย WASM (IE fork (2) การสนับสนุนการสนับสนุน PTY ตัวจัดการสัญญาณเป็น stubbed ... ฯลฯ )
ฉันสร้าง gui_wasm.c การอ้างอิงอย่างหนัก gui_mac.c และ gui_w32.c Event Loop ( gui_mch_update() และ gui_mch_wait_for_chars() ) ถูกนำไปใช้กับการรอการปิดกั้น และเหตุการณ์การเรนเดอร์ UI เกือบทั้งหมดจะถูกส่งผ่านไปยังเลเยอร์ JavaScript โดยการเรียกใช้ฟังก์ชัน JavaScript จาก C ขอบคุณ Emscripten
แหล่ง C ถูกรวบรวม (ด้วยการเพิ่มประสิทธิภาพหลายอย่าง) ลงใน LLVM BitCode พร้อมเสียงดังก้องซึ่งรวมเข้ากับ Emscripten จากนั้นไฟล์ BitCode ทั้งหมด ( .o ) จะเชื่อมโยงกับไฟล์ bitcode หนึ่งไฟล์ vim.bc พร้อม llvm-link linker (รวมเข้ากับ emscripten)
และฉันสร้างรันไทม์ JavaScript ใน TypeScript เพื่อวาดเหตุการณ์การเรนเดอร์ที่ส่งจาก C. JavaScript Runtime ถูกแยกออกเป็นสองส่วน เธรดหลักและด้ายคนงาน wasm/main.ts สำหรับเธรดหลัก มันเริ่มต้น vim ในเธรดคนงานและวาดหน้าจอ VIM ไปยัง <canvas> รับเหตุการณ์การวาดจาก VIM wasm/runtime.ts และ wasm/pre.ts สำหรับเธรดคนงาน พวกเขาเขียนโดยใช้ emscripten API
emcc (คอมไพเลอร์ C ของ Emscripten) รวบรวม vim.bc และ runtime.js เป็น vim.wasm , vim.js และ vim.data พร้อมไฟล์ vim runtime ที่โหลดไว้ล่วงหน้า (เช่น colorscheme) โดยใช้ binaryen ไฟล์รันไทม์ถูกโหลดบนระบบไฟล์เสมือนจริงที่ให้ไว้ในเบราว์เซอร์โดย Emscripten ที่นี่ไฟล์เหล่านี้รวบรวมไว้สำหรับเธรดคนงาน wasm/main.js เริ่มต้นการโหลด Web Worker โดย vim.js
ในที่สุดฉันก็สร้าง wasm/index.html ขนาดเล็กซึ่งมี <canvas/> เพื่อแสดงหน้าจอ vim และโหลด wasm/main.js
ตอนนี้โฮสติ้ง wasm/index.html ด้วยเว็บเซิร์ฟเวอร์และเข้าถึงได้ด้วยเบราว์เซอร์จะเปิด VIM มันใช้งานได้
sleep() บน JavaScript ส่วนที่ยากที่สุดสำหรับการพอร์ตนี้คือวิธีการใช้การปิดกั้นการรอ (มักจะทำด้วย sleep() )
เนื่องจากการปิดกั้นเธรดหลักบนหน้าเว็บหมายถึงการปิดกั้นการโต้ตอบของผู้ใช้จึงเป็นสิ่งต้องห้ามโดยทั่วไป การดำเนินการเกือบทั้งหมดที่ใช้เวลาจะถูกนำไปใช้เป็น API แบบอะซิงโครนัสใน JavaScript WASM ทำงานบนเธรดหลักไม่สามารถบล็อกเธรดยกเว้นการวนรอบที่ไม่ว่าง
แต่โปรแกรม C ใช้ฟังก์ชั่น sleep() อย่างไม่เป็นทางการดังนั้นจึงเป็นปัญหาเมื่อพอร์ตโปรแกรม Frontend GUI ของ VIM คาดว่าจะรอการป้อนข้อมูลผู้ใช้ด้วยการรอการปิดกั้น
Emscripten ให้วิธีแก้ปัญหาสำหรับปัญหานี้ Emterpreter ด้วย emterpreter, emscripten ให้ (pseudo) ฟังก์ชั่นการรอการปิดกั้นเช่น emscripten_sleep() เมื่อใช้ในฟังก์ชัน C emcc จะรวบรวมฟังก์ชั่นลงในรหัสไบต์ Emterpreter แทน WASM และที่รันไทม์รหัสไบต์จะทำงานบนล่าม (บน WASM) เมื่อล่ามถึงจุดเรียก emscripten_sleep() มันจะระงับการดำเนินการรหัสไบต์และตั้งค่าตัวจับเวลา (พร้อมฟังก์ชัน setTimeout JS) หลังจากหมดเวลาล่ามจะดำเนินการต่อสถานะและดำเนินการต่อไป
ด้วยกลไกนี้การรอแบบอะซิงโครนัสของ JavaScript จะดูราวกับว่าการรอซิงโครนัสจาก C World ตอนแรกฉันใช้ Emterpreter และใช้งานได้ อย่างไรก็ตามมีหลายประเด็น
ฉันมองหาทางเลือกและพบ Atomics.wait() Atomics.wait() เป็นฟังก์ชั่นดั้งเดิมแบบซิงโครนัสระดับต่ำ มันรอจนกว่าจะมีการอัปเดตไบต์เฉพาะในบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน มัน ปิดกั้นรอ แน่นอนว่ามันไม่สามารถใช้ได้ในเธรดหลัก จะต้องใช้กับเธรดคนงาน
ฉันย้ายฐานรหัส WASM ไปยัง Web Worker ที่ทำงานบนเธรด Worker แม้ว่าการเรนเดอร์ <canvas/> ยังคงทำในเธรดหลัก

VIM ใช้ Atomics.wait() สำหรับการรอการป้อนข้อมูลผู้ใช้โดยดูบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกัน เมื่อเหตุการณ์สำคัญเกิดขึ้นเธรดหลักจะจัดเก็บข้อมูลเหตุการณ์สำคัญไปยังบัฟเฟอร์หน่วยความจำที่ใช้ร่วมกันและแจ้งว่าเหตุการณ์คีย์ใหม่มาโดย Atomics.notify() เธรดคนงานตรวจพบว่าบัฟเฟอร์ได้รับการอัปเดตโดย Atomics.wait() และโหลดข้อมูลเหตุการณ์สำคัญจากบัฟเฟอร์ VIM คำนวณลำดับคีย์จากข้อมูลและเพิ่มลงในบัฟเฟอร์อินพุต ในที่สุด Vim จัดการเหตุการณ์และส่งเหตุการณ์การวาดไปยังเธรดหลักผ่าน JavaScript
เป็นโบนัสการโต้ตอบของผู้ใช้จะไม่ถูกป้องกันอีกต่อไปเนื่องจากตรรกะเกือบทั้งหมดรวมถึง VIM ทั้งหมดจะทำงานในเธรดคนงาน
โปรดตรวจสอบให้แน่ใจว่า emscripten (ฉันใช้ 1.38.37) และ Binaryen (ฉันใช้ V84) ติดตั้ง หากคุณใช้ MacOS สามารถติดตั้งด้วย brew install emscripten binaryen
โปรดใช้ build.sh Script เพื่อแฮ็กโครงการนี้ หลังจากโคลนที่เก็บนี้เพียงแค่เรียกใช้ ./build.sh มันสร้าง vim.wasm ใน wasm/ directory ต้องใช้เวลาและพลังงานซีพียูมาก
ในที่สุดโฮสต์ wasm/ โดยตรงบน localhost ด้วยเว็บเซิร์ฟเวอร์เช่น python -m http.server 1234 การเข้าถึง localhost:1234?debug จะเริ่มต้นด้วยบันทึกการดีบัก โปรดทราบว่ามันช้ากว่าการเปิดตัวมากเนื่องจากเปิดใช้งานคุณสมบัติการดีบักจำนวนมาก โปรดอ่าน wasm/readme.md สำหรับรายละเอียดเพิ่มเติม
โปรดทราบว่าสาขา wasm ของที่เก็บนี้มักจะรวมสาขา VIM/VIM Master ล่าสุด หากคุณต้องการแฮ็คโครงการนี้โปรดสร้างสาขาของคุณเองและผสานสาขา wasm ลงในสาขาของคุณโดย git merge
sleep() โดยค่าเริ่มต้น Emscripten จะรวบรวม sleep() เป็นวงที่ไม่ว่าง ดังนั้น vim.wasm ใช้ emterpreter ซึ่งให้ emscripten_sleep() ฟังก์ชั่น Whitelisted บางอย่างทำงานด้วย Emterpreter แต่คุณสมบัตินี้ไม่เสถียร มันทำให้ไบนารีในตัวมีขนาดใหญ่ขึ้นและรวบรวมได้นานขึ้นstring ไม่ทำงานSharedArrayBuffer ถูกปิดใช้งานเนื่องจากช่องโหว่ด้านความปลอดภัยของปีศาจ สิ่งนี้สามารถแก้ไขได้ด้วย asyncify งานกำลังดำเนินการและติดตามที่ PR #35 การพัฒนาได้รับการจัดการในโครงการ GitHub
<canvas/> ในเธรดคนงานโดยใช้ผืนผ้าใบนอกจอโครงการนี้ได้รับแรงบันดาลใจอย่างมากจากโครงการที่น่าประทับใจ VIM.JS โดย Lu Wang
ไฟล์เพิ่มเติมทั้งหมดในที่เก็บนี้ได้รับอนุญาตภายใต้ใบอนุญาตเดียวกับ VIM (VIM LICENITH) โปรดดู :help license สำหรับรายละเอียดเพิ่มเติม
readme ดั้งเดิมกำลังติดตาม

สำหรับการแปลของ readme นี้ดูจุดสิ้นสุด
VIM เป็นรุ่น Good Old UNIX Editor VI รุ่นปรับปรุงที่ดีขึ้นอย่างมาก มีการเพิ่มคุณสมบัติใหม่มากมาย: UNDO หลายระดับ, การไฮไลต์ไวยากรณ์, ประวัติบรรทัดคำสั่ง, วิธีใช้ออนไลน์, การตรวจสอบการสะกด, การเสร็จสิ้นชื่อไฟล์, การดำเนินการบล็อก, ภาษาสคริปต์ ฯลฯ นอกจากนี้ยังมีอินเทอร์เฟซผู้ใช้กราฟิก (GUI) ถึงกระนั้นความเข้ากันได้ของ VI ก็ยังคงอยู่ผู้ที่มี VI "ในนิ้วมือ" จะรู้สึกเหมือนอยู่บ้าน ดู runtime/doc/vi_diff.txt สำหรับความแตกต่างกับ VI
ตัวแก้ไขนี้มีประโยชน์มากสำหรับการแก้ไขโปรแกรมและไฟล์ข้อความธรรมดาอื่น ๆ คำสั่งทั้งหมดจะได้รับอักขระแป้นพิมพ์ปกติดังนั้นผู้ที่สามารถพิมพ์ด้วยสิบนิ้วสามารถทำงานได้อย่างรวดเร็ว นอกจากนี้คีย์ฟังก์ชันสามารถแมปกับคำสั่งโดยผู้ใช้และสามารถใช้เมาส์ได้
Vim ทำงานภายใต้ MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VM และเกือบทั้งหมดของ UNIX การย้ายไปยังระบบอื่น ๆ ไม่ควรยากมาก VIM รุ่นเก่าทำงานบน MS-DOS, MS-Windows 95/98/ME, Amiga Dos, Atari Mint, Beos, RISC OS และ OS/2 สิ่งเหล่านี้ไม่ได้รับการดูแลอีกต่อไป
คุณสามารถใช้แพ็คเกจตัวจัดการแพ็คเกจที่คุณชื่นชอบเพื่อติดตั้ง VIM บน Mac และ Linux มีการติดตั้ง VIM รุ่นเล็ก ๆ ไว้ล่วงหน้าคุณยังต้องติดตั้ง VIM หากคุณต้องการคุณสมบัติเพิ่มเติม
มีการแจกแจงแยกต่างหากสำหรับ UNIX, PC, AMIGA และระบบอื่น ๆ ไฟล์ README.md นี้มาพร้อมกับ Runtime Archive มันมีเอกสาร, ไฟล์ไวยากรณ์และไฟล์อื่น ๆ ที่ใช้ในรันไทม์ ในการเรียกใช้ VIM คุณต้องได้รับหนึ่งในคลังเก็บไบนารีหรือแหล่งเก็บถาวรที่มา อันไหนที่คุณต้องการขึ้นอยู่กับระบบที่คุณต้องการเรียกใช้และไม่ว่าคุณต้องการหรือต้องรวบรวมด้วยตัวเอง ตรวจสอบ http://www.vim.org/download.php สำหรับภาพรวมของการแจกแจงที่มีอยู่ในปัจจุบัน
สถานที่ยอดนิยมบางแห่งเพื่อรับ VIM ล่าสุด:
หากคุณได้รับการกระจายแบบไบนารีคุณไม่จำเป็นต้องรวบรวม VIM หากคุณได้รับการกระจายแหล่งที่มาสิ่งของทั้งหมดสำหรับการรวบรวม VIM อยู่ในไดเรกทอรี src ดู src/INSTALL สำหรับคำแนะนำ
ดูหนึ่งในไฟล์เหล่านี้สำหรับคำแนะนำเฉพาะระบบ ไม่ว่าจะในไดเรกทอรี ReadMedir (ในที่เก็บ) หรือไดเรกทอรีด้านบน (ถ้าคุณแกะไฟล์เก็บถาวร):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
มี README_*.txt ขึ้นอยู่กับการแจกแจงที่คุณใช้
TUTOR VIM เป็นหลักสูตรฝึกอบรมหนึ่งชั่วโมงสำหรับผู้เริ่มต้น บ่อยครั้งที่มันสามารถเริ่มต้นเป็น vimtutor ดู :help tutor สำหรับข้อมูลเพิ่มเติม
สิ่งที่ดีที่สุดคือใช้ :help ใน VIM หากคุณยังไม่มีการเรียกใช้งานให้อ่าน runtime/doc/help.txt มันมีพอยน์เตอร์ไปยังไฟล์เอกสารอื่น ๆ คู่มือผู้ใช้อ่านเหมือนหนังสือและแนะนำให้เรียนรู้ที่จะใช้ VIM ดู :help user-manual
Vim คือ Charityware คุณสามารถใช้และคัดลอกได้มากเท่าที่คุณต้องการ แต่คุณได้รับการสนับสนุนให้บริจาคเพื่อช่วยเหลือเด็กกำพร้าในยูกันดา โปรดอ่านไฟล์ runtime/doc/uganda.txt สำหรับรายละเอียด (ทำ :help uganda ใน VIM)
สรุปใบอนุญาต: ไม่มีข้อ จำกัด ในการใช้หรือแจกจ่ายสำเนา VIM ที่ไม่ได้แก้ไข บางส่วนของ VIM อาจมีการแจกจ่าย แต่จะต้องรวมข้อความใบอนุญาตไว้เสมอ สำหรับเวอร์ชันที่ได้รับการแก้ไขจะมีข้อ จำกัด เล็กน้อย ใบอนุญาตเข้ากันได้กับ GPL คุณอาจรวบรวม VIM ด้วยไลบรารี GPL และแจกจ่าย
การแก้ไขข้อบกพร่องและการเพิ่มคุณสมบัติใหม่ใช้เวลาและความพยายามอย่างมาก เพื่อแสดงความขอบคุณสำหรับงานและกระตุ้นให้ Bram และคนอื่น ๆ ทำงานต่อไปได้โปรดส่งเงินบริจาค
เนื่องจาก Bram กลับไปทำงานที่ได้รับค่าจ้างตอนนี้เงินจะถูกนำมาใช้เพื่อช่วยเหลือเด็ก ๆ ในยูกันดา ดู runtime/doc/uganda.txt แต่ในขณะเดียวกันการบริจาคเพิ่มแรงจูงใจของ Bram ในการทำงานกับ Vim!
สำหรับข้อมูลล่าสุดเกี่ยวกับการสนับสนุนเว็บไซต์ VIM: http://www.vim.org/sponsor/
หากคุณต้องการช่วยให้ VIM ดีขึ้นให้ดูไฟล์ที่มีส่วนร่วม
ข่าวล่าสุดเกี่ยวกับ VIM สามารถพบได้ในโฮมเพจ VIM: http://www.vim.org/
หากคุณมีปัญหาให้ดูเอกสารหรือเคล็ดลับ VIM: http://www.vim.org/docs.php http://vim.wikia.com/wiki/vim_tips_wiki
หากคุณยังคงมีปัญหาหรือคำถามอื่น ๆ ให้ใช้หนึ่งในรายชื่อผู้รับจดหมายเพื่อหารือเกี่ยวกับผู้ใช้ VIM และนักพัฒนา: http://www.vim.org/maillist.php
หากไม่มีอะไรทำงานอื่นให้รายงานข้อบกพร่องโดยตรง: Bram Moolenaar [email protected]
ส่งความคิดเห็นอื่น ๆ แพทช์ดอกไม้และคำแนะนำไปที่: Bram Moolenaar [email protected]
นี่คือ README.md สำหรับเวอร์ชัน 8.2 ของ VIM: VI ปรับปรุง
เกาหลี