vim.wasm:VIM移植到WebAssembly该项目是@RHYSD的VIM编辑器实验叉,可将其编译为使用Emscripten和Binaryen的WebAssembly。 VIM在Web Worker上运行,并通过SharedArrayBuffer与主线程进行交互。
该项目的目的是在浏览器上运行VIM编辑器,而不会通过将VIM C源编译到WebAssembly中而丢失VIM强大的功能。

用法
:write仅在内存上写入文件。下载当前缓冲区:export或特定文件:export {file} 。"*p "*y "* :yank * :put * :set clipboard=unnamed~/.vim目录下的文件持续存储在索引DB中。请在~/.vim/vimrc (非~/.vimrc )中写出您喜欢的配置。file={filepath}={url}将文件从{url}获取到{filepath} 。可以打开任意远程文件(关心CORS)。:!/path/to/file.js在浏览器中评估JavaScript代码。 :!%评估当前缓冲区。:e tutor 。arg=查询vim (例如?arg=~%2f.vim%2fvimrc&arg=hello.txt注意
SharedArrayBuffer和Atomics 。在Firefox或Safari上,必须暂时启用功能标志( javascript.options.shared_memory )。keydown事件中获取密钥输入。请禁用您的浏览器扩展名截取关键事件(隐身模式将是最好的)。:quit ,但不会关闭浏览器选项卡。请手动关闭它:)该项目被包装为vim-wasm NPM PACAKGE,可轻松在Web应用程序中使用。请阅读文档以获取更多详细信息。
当前的移植VIM版本为8.2.0055,具有“正常”和“小”功能集。请检查变更记录以获取更新历史记录。
以下项目与此NPM软件包有关,可能更适合您的用例。

在Worker线程中,VIM通过编译为WASM运行。打开页面时,将工作线程从主线程中产生为专用的Web Worker。
假设您用键盘输入一些东西。浏览器将其作为keydown事件中的KeyboardEvent视为。主线程中的JavaScript捕获事件,并将键盘信息存储到共享内存缓冲区中。
缓冲区与工作线程共享。 VIM等待并通过通过JavaScript的Atomics API对共享内存缓冲区进行轮询来获取键盘信息。当在缓冲区中找到密钥信息时,它会加载信息并计算关键序列。通过JS到WASM API得益于Emscripten,该序列被添加到WASM中VIM的输入缓冲区中。
输入缓冲区中的序列由Core Editor Logic(更新缓冲区,屏幕,...)处理。由于更新,某些绘制事件发生了,例如绘制文本,绘制式,滚动区域,...
由于Emscripten的JS至C API,这些抽奖活动将从WASM中的WARSM中发送给JavaScript。考虑到设备像素比和<canvas/> api,如何计算事件,这些计算出的渲染事件将通过postMessage()传递的消息传递到主线程。
主线程JavaScript接收并招募这些渲染事件。在动画框架上,它将它们渲染为<canvas/> 。
最后,您可以在页面中看到渲染的屏幕。

VIM的WebAssembly前端与其他GUI(例如GTK Frontend)一样,是VIM的新GUI前端。 c源被编译到每个LLVM比特代码文件,然后将它们链接到一个emcc文件vim.bc emcc最终将使用二进制将vim.bc编译为vim.wasm二进制,并生成HTML/JavaScript运行时。
我最初面临的差异是缺乏终端库,例如ncurses。我修改了configure脚本以忽略终端库检查。没关系,因为WASM的GUI前端总是使用而不是CUI前端。我需要许多解决方法来传递configure检查。
Emscripten提供类似Unix的环境。因此, os_unix.c可以支持WASM。但是,Emscripten不支持某些功能。我添加了许多#ifdef FEAT_GUI_WASM guards,以禁用WASM(即fork (2)支持,PTY支持,信号处理程序的固定功能,...等等)。
我创建了gui_wasm.c大量参考gui_mac.c和gui_w32.c 。事件循环( gui_mch_update()和gui_mch_wait_for_chars() )仅通过阻止等待来实现。而且,几乎所有的UI渲染事件都将通过Emscripten调用C的JavaScript函数传递给JavaScript层。
C源(具有许多优化)与clang的LLVM比特码合并到Emscripten。然后,所有比特代码文件( .o )都链接到带有llvm-link Linker(也集成到EMScripten)的一个BitCode文件vim.bc
我在打字稿中创建了JavaScript运行时,以绘制C. JavaScript运行时发送的渲染事件分为两个部分;主线程和工人线程。 wasm/main.ts用于主线程。它在Worker线程中启动VIM,并将VIM屏幕绘制为<canvas>从VIM接收绘制事件。 wasm/runtime.ts和wasm/pre.ts用于工作线程。它们是使用Emscripten API编写的。
emcc (Emscripten的C编译器)使用Binaryen编译了带有预加载的VIM Runtime Files(IE Colorscheme)的vim.wasm , vim.js和vim.data中的vim.bc和runtime.js 。运行时文件被加载在Emscripten在浏览器上提供的虚拟文件系统上。在这里,这些文件是用于工作线程的。 wasm/main.js启动了一个专用的Web Worker加载vim.js
最后,我创建了一个小的wasm/index.html ,其中包含<canvas/>以渲染vim屏幕并加载wasm/main.js 。
现在,使用Web服务器托管wasm/index.html并使用浏览器打开VIM访问它。有用。
sleep()此移植最困难的部分是如何实现阻止等待(通常使用sleep()完成)。
由于在网页上阻止主线程意味着阻止用户交互,因此基本上禁止它。几乎所有花费时间的操作在JavaScript中都实现为异步API。在主线程上运行的WASM不能阻止线程,除了繁忙的循环。
但是C程序随便使用sleep()函数,因此移植程序时是一个问题。 VIM的GUI前端也有望通过阻止等待等待用户输入。
Emscripten为此问题提供解决方法,EmterPreter。使用EmterPreter,Emscripten提供(伪)阻止等待功能,例如emscripten_sleep() 。当它们用于C函数时, emcc将函数编译为EmterPreter字节代码而不是WASM。在运行时,字节代码是在解释器上运行的(在WASM上)。当解释器在调用emscripten_sleep()点到达时,它暂停字节代码执行并设置计时器(带有setTimeout JS函数)。时间到期后,口译员恢复状态并继续执行。
通过这种机制,JavaScript的异步等待看起来好像来自C World的同步等待。起初,我使用了Emterpreter,并且起作用。但是,有几个问题。
我寻找了一个替代品和发现的Atomics.wait() 。 Atomics.wait()是低级同步原始函数。它等到共享内存缓冲区中的特定字节更新。它正在阻止等待。当然,它在主线程上不可用。它必须在工作线程上使用。
我将WASM代码基库移至Web Worker上在Worker线程上运行的Web Worker,尽管渲染<canvas/>仍在主线程中完成。

VIM使用Atomics.wait()通过观看共享内存缓冲区来等待用户输入。当关键事件发生时,主线程将关键事件数据存储到共享内存缓冲区中,并通知Atomics.notify()出现新的密钥事件。 Worker线程检测缓冲区是否通过Atomics.wait()更新,并从缓冲区加载关键事件数据。 VIM从数据中计算一个密钥序列,并将其添加到输入缓冲区中。最终,VIM处理事件,并通过JavaScript将DRAW事件发送到主线程。
作为奖励,不再阻止用户互动,因为几乎所有逻辑(包括整个VIM)都在工作线程中运行。
请确保安装了Emscripten(我使用的1.38.37)和二进制(我使用的V84)。如果您使用MACOS,则可以使用brew install emscripten binaryen安装它们。
请使用build.sh脚本黑客入侵此项目。克隆此存储库后,只需运行./build.sh即可。它在wasm/ Directory中构建了vim.wasm。它需要时间,并且CPU电源很多。
最终,使用Web服务器(例如python -m http.server 1234托管wasm/直接在localhost上。访问localhost:1234?debug将通过调试日志开始VIM。请注意,由于启用了许多调试功能,因此它比发行版本要慢得多。有关更多详细信息,请阅读WASM/readme.md。
请注意,该存储库的wasm分支经常合并最新的VIM/VIM主分支。如果您想入侵此项目,请确保创建自己的分支机构并通过git merge将wasm分支合并到您的分支机构中。
sleep() 。默认情况下,Emscripten将sleep()编译成一个繁忙的循环。因此,vim.wasm使用的EmterPreter提供了emscripten_sleep() 。一些白名单的功能由EmterPreter运行。但是此功能不是那么稳定。它使构建的二进制文件更大,并且编译更长。string参数不起作用。SharedArrayBuffer被禁用。这可以通过异步固定。这项工作正在进行中,并在PR#35进行了跟踪。 开发是在GitHub项目中管理的。
<canvas/>在工作线程中该项目受到Lu Wang的令人印象深刻的VIM.JS的启发。
此存储库中的所有其他文件均在与VIM(VIM许可证)相同的许可下获得许可。请参阅:help license以获取更多详细信息。
原始Readme正在关注。

有关此读数的翻译,请参阅结尾。
VIM是Good Old Unix编辑器VI的大大改进版本。添加了许多新功能:多级撤消,语法突出显示,命令行历史记录,在线帮助,拼写检查,文件名完成,块操作,脚本语言等。还有一个图形用户界面(GUI)。尽管如此,维持VI兼容性,那些“手指”的VI的人会感到宾至如归。有关VI的差异,请参见runtime/doc/vi_diff.txt 。
该编辑器对于编辑程序和其他纯文本文件非常有用。所有命令均以普通键盘字符给出,因此那些可以用十个手指打字的人可以很快工作。此外,功能键可以由用户映射到命令,并且可以使用鼠标。
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文件附带运行时档案。它包括在运行时使用的文档,语法文件和其他文件。要运行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文件。
VIM导师是初学者一小时的培训课程。通常,它可以作为vimtutor开始。请参阅:help tutor以获取更多信息。
最好的是使用:help 。如果您还没有可执行文件,请读取runtime/doc/help.txt 。它包含其他文档文件的指针。用户手册读起来像一本书,建议学习使用VIM。请参阅:help user-manual 。
VIM是慈善软件。您可以随意使用并复制它,但鼓励您捐款以帮助乌干达的孤儿。请阅读文件runtime/doc/uganda.txt以获取详细信息(DO :help uganda内部的VIM)。
许可证的摘要:使用或分发未修改的VIM副本没有任何限制。 VIM的一部分也可以分发,但必须始终包括许可文本。对于修改版本,适用一些限制。该许可证兼容GPL,您可以将VIM与GPL库编译并分发。
修复错误并添加新功能需要大量时间和精力。要表示您对工作的赞赏,并激励Bram和其他人继续研究VIM,请发送捐款。
由于Bram又回到了有偿工作,因此资金现在将用于帮助乌干达的儿童。请参阅runtime/doc/uganda.txt 。但与此同时,捐赠增加了布拉姆继续在VIM上工作的动机!
有关VIM网站上有关赞助外观的最新信息:http://www.vim.org/sponsor/
如果您想帮助使VIM更好,请参阅contruting.md文件。
有关VIM的最新消息可以在VIM主页上找到:http://www.vim.org/
如果有问题,请查看VIM文档或提示:http://www.vim.org/docs.php http://vim.wikia.com/wiki/wiki/wiki/vim_tips_wiki
如果您仍然有问题或任何其他问题,请使用其中一个邮件列表与VIM用户和开发人员讨论:http://www.vim.org/maillist.php
如果没有其他作用,请直接报告错误:bram moolenaar [email protected]
将任何其他评论,补丁,鲜花和建议发送到:bram moolenaar [email protected]
这是VIM:VI:VI改进的8.2版的README.md 。
韩国人