vim.wasm: vim porting ke WebAssembly Proyek ini adalah garpu eksperimental editor VIM oleh @rhysd untuk mengkompilasinya menjadi WebAssembly menggunakan Emscripten dan Binaryen. VIM berjalan pada pekerja web dan berinteraksi dengan utas utama melalui SharedArrayBuffer .
Tujuan dari proyek ini adalah menjalankan editor VIM di browser tanpa kehilangan fungsionalitas VIM yang kuat dengan menyusun sumber Vim C menjadi WebAssembly.

PENGGUNAAN
:write hanya menulis file di memori. Unduh buffer saat ini oleh :export atau file tertentu oleh :export {file} ."* didukung. Misalnya, Tempel Teks Sistem Clipboard untuk Vim dengan "*p atau :put * , dan salin teks di vim ke System Clipboard dengan "*y atau :yank * . Jika Anda ingin menyinkronkan clipboard VIM dengan System Clipboard , :set clipboard=unnamed harus berfungsi seperti VIM normal.~/.vim secara terus -menerus disimpan dalam DB yang diindeks. Harap tulis konfigurasi favorit Anda di ~/.vim/vimrc (bukan ~/.vimrc ).file={filepath}={url} mengambil file dari {url} ke {filepath} . File jarak jauh yang sewenang -wenang dapat dibuka (Peduli Tentang COR).:!/path/to/file.js mengevaluasi kode JavaScript di browser. :!% Mengevaluasi buffer saat ini.:e tutor .arg= parameter kueri (misalnya ?arg=~%2f.vim%2fvimrc&arg=hello.txt ) untuk menambahkan argumen baris perintah vim .MELIHAT
SharedArrayBuffer dan Atomics . Di Firefox atau Safari, bendera fitur ( javascript.options.shared_memory for firefox) harus diaktifkan untuk saat ini.keydown DOM. Harap nonaktifkan ekstensi browser Anda yang mencegat peristiwa kunci (mode penyamaran akan menjadi yang terbaik).:quit , tetapi tidak menutup tab browser. Harap tutup secara manual :) Proyek ini dikemas sebagai vim-wasm NPM Pacakge untuk digunakan dalam aplikasi web dengan mudah. Harap baca dokumentasi untuk detail lebih lanjut.
Versi VIM porting saat ini adalah 8.2.0055 dengan set fitur 'normal' dan 'kecil'. Silakan periksa Changelog untuk riwayat pembaruan.
Proyek berikut terkait dengan paket NPM ini dan mungkin lebih cocok untuk kasus penggunaan Anda.

Di utas pekerja, VIM berjalan dengan dikompilasi ke Wasm. Utas pekerja ditelusuri sebagai pekerja web khusus dari utas utama saat membuka halaman.
Katakanlah Anda memasukkan sesuatu dengan keyboard. Browser menganggapnya sebagai KeyboardEvent pada acara keydown . JavaScript di utas utama menangkap acara dan menyimpan informasi keydown ke buffer memori bersama.
Buffer dibagikan dengan utas pekerja. Vim menunggu dan mendapatkan informasi keydown dengan melakukan polling buffer memori bersama melalui API Atomics Javascript. Ketika informasi kunci ditemukan di buffer, ia memuat informasi dan menghitung urutan kunci. Via JS ke WASM API berkat Emscripten, urutan ditambahkan ke buffer input VIM di Wasm.
Urutan dalam input buffer diproses oleh Core Editor Logic (pembaruan buffer, layar, ...). Karena pembaruan, beberapa peristiwa menggambar terjadi seperti menggambar teks, menggambar rects, daerah gulir, ...
Acara undian ini dikirim ke JavaScript di utas pekerja dari Wasm berkat JS ke C API Emscripten. Mempertimbangkan rasio piksel perangkat dan <canvas/> API, cara membuat acara dihitung dan acara rendering yang dihitung ini ditularkan dari utas pekerja ke utas utama melalui pesan yang lewat dengan postMessage() .
Utas utama JavaScript menerima dan enqueues acara rendering ini. Pada bingkai animasi, itu membuat mereka ke <canvas/> .
Akhirnya Anda dapat melihat layar yang diberikan di halaman.

Frontend WebAssembly untuk VIM diimplementasikan sebagai frontend GUI baru VIM seperti GUI lainnya seperti GTK Frontend. Sumber C dikompilasi untuk setiap file bitcode LLVM dan kemudian ditautkan ke satu file bitcode vim.bc oleh emcc . emcc akhirnya akan mengkompilasi vim.bc menjadi vim.wasm biner menggunakan biner dan menghasilkan runtime html/javascript.
Perbedaan yang saya hadapi pada awalnya adalah kurangnya perpustakaan terminal seperti Ncurses. Saya memodifikasi skrip configure untuk mengabaikan pemeriksaan perpustakaan terminal. Tidak apa -apa karena GUI Frontend for Wasm selalu digunakan sebagai pengganti CUI Frontend. Saya membutuhkan banyak solusi untuk melewati cek configure .
Emscripten menyediakan lingkungan seperti Unix. Jadi os_unix.c dapat mendukung Wasm. Namun, beberapa fitur tidak didukung oleh Emscripten. Saya menambahkan banyak penjaga #ifdef FEAT_GUI_WASM untuk menonaktifkan fitur yang tidak dapat didukung oleh Wasm (yaitu dukungan fork (2) dukungan, dukungan PTY, penangan sinyal dibungkus, ... dll).
Saya membuat gui_wasm.c sangat merujuk gui_mac.c dan gui_w32.c . Loop Acara ( gui_mch_update() dan gui_mch_wait_for_chars() ) hanya diimplementasikan dengan pemblokiran tunggu. Dan hampir semua acara rendering UI diteruskan ke lapisan JavaScript dengan memanggil fungsi JavaScript dari C berkat Emscripten.
Sumber C dikompilasi (dengan banyak optimisasi) ke dalam bitcode LLVM dengan dentang yang terintegrasi ke Emscripten. Maka semua file bitcode ( .o ) ditautkan ke satu file bitcode vim.bc dengan llvm-link linker (juga terintegrasi ke emscripten).
Dan saya membuat runtime JavaScript di TypeScript untuk menggambar acara rendering yang dikirim dari C. Javascript Runtime dipisahkan menjadi dua bagian; utas utama dan utas pekerja. wasm/main.ts adalah untuk utas utama. Ini dimulai vim di utas pekerja dan menggambar layar VIM ke <canvas> menerima acara undian dari VIM. wasm/runtime.ts dan wasm/pre.ts adalah untuk utas pekerja. Mereka ditulis menggunakan Emscripten API.
emcc (kompiler C Emscripten) mengkompilasi vim.bc dan runtime.js menjadi vim.wasm , vim.js dan vim.data dengan file runtime vim yang dimuat sebelumnya (yaitu colorscheme) menggunakan biner. File runtime dimuat pada sistem file virtual yang disediakan di browser oleh Emscripten. Di sini, file -file ini dikompilasi untuk utas pekerja. wasm/main.js memulai pekerja web khusus yang memuat vim.js
Akhirnya, saya membuat wasm/index.html kecil yang berisi <canvas/> untuk membuat layar vim dan memuat wasm/main.js .
Sekarang hosting wasm/index.html dengan server web dan mengaksesnya dengan browser membuka vim. Itu berhasil.
sleep() di javascript Bagian tersulit untuk porting ini adalah cara menerapkan pemblokiran tunggu (biasanya dilakukan dengan sleep() ).
Karena memblokir utas utama pada halaman web berarti memblokir interaksi pengguna, pada dasarnya dilarang. Hampir semua operasi mengambil waktu diimplementasikan sebagai API asinkron di JavaScript. Wasm yang berjalan di utas utama tidak dapat memblokir utas kecuali untuk loop sibuk.
Tetapi program C dengan santai menggunakan fungsi sleep() sehingga menjadi masalah saat porting program. Frontend GUI VIM juga diharapkan menunggu input pengguna dengan memblokir tunggu.
Emscripten memberikan solusi untuk masalah ini, Emterpreter. Dengan Emterpreter, Emscripten menyediakan (pseudo) yang memblokir fungsi tunggu seperti emscripten_sleep() . Ketika mereka digunakan dalam fungsi C, emcc mengkompilasi fungsi ke dalam kode byte emterpreter, bukannya WASM. Dan saat runtime, kode byte dijalankan pada penerjemah (pada WASM). Ketika penerjemah mencapai pada titik yang memanggil emscripten_sleep() , ia menangguhkan eksekusi kode byte dan mengatur timer (dengan fungsi setTimeout JS). Setelah waktu berakhir, penerjemah melanjutkan keadaan dan melanjutkan eksekusi.
Dengan mekanisme ini, penantian asinkron Javascript tampak seolah -olah menunggu sinkron dari C World. Awalnya saya menggunakan Emterpreter dan itu berhasil. Namun, ada beberapa masalah.
Saya mencari alternatif dan menemukan Atomics.wait() . Atomics.wait() adalah fungsi primitif sinkron tingkat rendah. Menunggu sampai byte spesifik dalam buffer memori bersama diperbarui. Itu memblokir menunggu . Tentu saja tidak tersedia di utas utama. Itu harus digunakan pada utas pekerja.
Saya memindahkan basis kode WASM ke pekerja web yang berjalan di utas pekerja, meskipun rendering <canvas/> masih dilakukan di utas utama.

VIM menggunakan Atomics.wait() untuk input pengguna yang menunggu dengan menonton buffer memori bersama. Ketika peristiwa utama terjadi, utas utama menyimpan data acara utama ke buffer memori bersama dan memberi tahu bahwa acara kunci baru datang dengan Atomics.notify() . Thread pekerja mendeteksi bahwa buffer diperbarui oleh Atomics.wait() dan memuat data acara utama dari buffer. VIM menghitung urutan kunci dari data dan menambahkannya ke buffer input. Akhirnya Vim menangani acara dan mengirim acara menggambar ke utas utama melalui JavaScript.
Sebagai bonus, interaksi pengguna tidak lagi dicegah karena hampir semua logika termasuk seluruh vim dijalankan di utas pekerja.
Pastikan Emscripten (saya menggunakan 1.38.37) dan Binaryen (saya menggunakan V84) diinstal. Jika Anda menggunakan macOS, mereka dapat diinstal dengan brew install emscripten binaryen .
Silakan gunakan skrip build.sh untuk meretas proyek ini. Tepat setelah mengkloning repositori ini, cukup jalankan ./build.sh . Itu membangun vim.wasm di wasm/ Direktori. Butuh waktu dan daya CPU banyak.
Akhirnya host wasm/ langsung di localhost dengan server web seperti python -m http.server 1234 . Mengakses ke localhost:1234?debug akan memulai vim dengan log debug. Perhatikan bahwa itu jauh lebih lambat dari rilis build karena banyak fitur debug diaktifkan. Harap baca Wasm/Readme.md untuk lebih jelasnya.
Harap dicatat bahwa cabang wasm Repositori ini sering menggabungkan cabang master VIM/VIM terbaru. Jika Anda ingin meretas proyek ini, harap pastikan untuk membuat cabang Anda sendiri dan menggabungkan cabang wasm ke cabang Anda dengan git merge .
sleep() . Secara default, Emscripten mengkompilasi sleep() menjadi lingkaran yang sibuk. Jadi vim.wasm menggunakan emterpreter yang menyediakan emscripten_sleep() . Beberapa fungsi daftar putih dijalankan dengan Emterpreter. Tetapi fitur ini tidak begitu stabil. Itu membuat binari yang dibangun lebih besar dan kompilasi lebih lama.string tidak berfungsi.SharedArrayBuffer dinonaktifkan karena kerentanan keamanan Specter. Ini dapat diperbaiki dengan asyncify. Pekerjaan sedang berlangsung dan dilacak di PR #35. Pengembangan dikelola dalam proyek GitHub.
<canvas/> di utas pekerja menggunakan kanvas offscreenProyek ini sangat terinspirasi oleh proyek yang mengesankan Vim.js oleh Lu Wang.
Semua file tambahan dalam repositori ini dilisensikan dengan lisensi yang sama dengan VIM (lisensi VIM). Silakan lihat :help license untuk detail lebih lanjut.
Readme asli sedang mengikuti.

Untuk terjemahan readme ini lihat akhir.
Vim adalah versi yang sangat ditingkatkan dari editor UNIX lama yang baik VI. Banyak fitur baru telah ditambahkan: multi-level Undo, Sintaks Sorot, riwayat baris perintah, bantuan online, pemeriksaan ejaan, penyelesaian nama file, operasi blok, bahasa skrip, dll. Ada juga antarmuka pengguna grafis (GUI) yang tersedia. Namun, kompatibilitas VI dipertahankan, mereka yang memiliki VI "di jari" akan terasa di rumah. Lihat runtime/doc/vi_diff.txt untuk perbedaan dengan VI.
Editor ini sangat berguna untuk mengedit program dan file teks biasa lainnya. Semua perintah diberikan dengan karakter keyboard normal, sehingga mereka yang dapat mengetik dengan sepuluh jari dapat bekerja sangat cepat. Selain itu, tombol fungsi dapat dipetakan ke perintah oleh pengguna, dan mouse dapat digunakan.
VIM berjalan di bawah MS-Windows (NT, 2000, XP, Vista, 7, 8, 10), Macintosh, VMS dan hampir semua rasa UNIX. Porting ke sistem lain seharusnya tidak terlalu sulit. Versi yang lebih lama dari VIM dijalankan pada MS-DOS, MS-Windows 95/98/ME, Amiga Dos, Atari Mint, BeOS, RISC OS dan OS/2. Ini tidak lagi dipertahankan.
Anda sering dapat menggunakan manajer paket favorit Anda untuk menginstal VIM. Di Mac dan Linux versi kecil VIM sudah diinstal sebelumnya, Anda masih perlu menginstal VIM jika Anda ingin lebih banyak fitur.
Ada distribusi terpisah untuk UNIX, PC, Amiga dan beberapa sistem lainnya. File README.md ini dilengkapi dengan arsip runtime. Ini termasuk dokumentasi, file sintaks dan file lain yang digunakan saat runtime. Untuk menjalankan vim, Anda harus mendapatkan salah satu arsip biner atau arsip sumber. Yang mana yang Anda butuhkan tergantung pada sistem yang ingin Anda jalankan dan apakah Anda mau atau harus mengkompilasinya sendiri. Periksa http://www.vim.org/download.php untuk ikhtisar distribusi yang tersedia saat ini.
Beberapa tempat populer untuk mendapatkan vim terbaru:
Jika Anda memperoleh distribusi biner, Anda tidak perlu mengkompilasi vim. Jika Anda memperoleh distribusi sumber, semua barang untuk mengkompilasi VIM ada di direktori src . Lihat src/INSTALL untuk instruksi.
Lihat salah satu file ini untuk instruksi khusus sistem. Baik di direktori readMedir (di repositori) atau direktori teratas (jika Anda membongkar arsip):
README_ami.txt Amiga
README_unix.txt Unix
README_dos.txt MS-DOS and MS-Windows
README_mac.txt Macintosh
README_vms.txt VMS
Ada file README_*.txt lainnya, tergantung pada distribusi yang Anda gunakan.
Vim Tutor adalah kursus pelatihan satu jam untuk pemula. Seringkali bisa dimulai sebagai vimtutor . Lihat :help tutor untuk informasi lebih lanjut.
Yang terbaik adalah menggunakan :help di vim. Jika Anda belum dapat dieksekusi, baca runtime/doc/help.txt . Ini berisi petunjuk ke file dokumentasi lainnya. Manual pengguna dibaca seperti buku dan disarankan untuk belajar menggunakan VIM. Lihat :help user-manual .
Vim adalah Charityware. Anda dapat menggunakan dan menyalinnya sebanyak yang Anda suka, tetapi Anda didorong untuk memberikan sumbangan untuk membantu anak yatim di Uganda. Silakan baca file runtime/doc/uganda.txt untuk detailnya (lakukan :help uganda di dalam vim).
Ringkasan Lisensi: Tidak ada batasan untuk menggunakan atau mendistribusikan salinan VIM yang tidak dimodifikasi. Bagian VIM juga dapat didistribusikan, tetapi teks lisensi harus selalu dimasukkan. Untuk versi yang dimodifikasi, beberapa pembatasan berlaku. Lisensi kompatibel dengan GPL, Anda dapat mengkompilasi VIM dengan pustaka GPL dan mendistribusikannya.
Memperbaiki bug dan menambahkan fitur baru membutuhkan banyak waktu dan upaya. Untuk menunjukkan penghargaan Anda untuk pekerjaan dan memotivasi Bram dan orang lain untuk terus bekerja di VIM, silakan kirim sumbangan.
Karena Bram kembali ke pekerjaan berbayar, uang sekarang akan digunakan untuk membantu anak -anak di Uganda. Lihat runtime/doc/uganda.txt . Tetapi pada saat yang sama sumbangan meningkatkan motivasi Bram untuk terus bekerja di VIM!
Untuk informasi terbaru tentang tampilan sponsor di situs web VIM: http://www.vim.org/sponsor/
Jika Anda ingin membantu membuat VIM lebih baik, lihat file Contributing.md.
Berita terbaru tentang vim dapat ditemukan di halaman beranda VIM: http://www.vim.org/
Jika Anda memiliki masalah, lihat dokumentasi atau tips VIM: http://www.vim.org/docs.php http://vim.wikia.com/wiki/vim_tips_wiki
Jika Anda masih memiliki masalah atau pertanyaan lain, gunakan salah satu milis untuk membahasnya dengan pengguna dan pengembang vim: http://www.vim.org/mAillist.php
Jika tidak ada lagi yang berhasil, laporkan bug secara langsung: Bram moolenaar [email protected]
Kirim komentar, tambalan, bunga, dan saran lainnya ke: Bram moolenaar [email protected]
Ini adalah README.md untuk versi 8.2 dari vim: vi ditingkatkan.
Korea