Categories: Kali Linux

Vim Wasm – Vim Editor Ported To WebAssembly

Vim Wasm project is running Vim editor on browser by compiling Vim C sources into WebAssembly.

Notices

  1. Please access from a desktop browser (Chrome/Firefox/Safari/Edge). Safari seems the best on macOS.
  2. Please avoid slow networks. Your browser will fetch total of around 1MB files.
  3. vim.wasm takes key inputs from DOM keydown event. Please disable your browser extensions which affect key inputs (incognito mode would be the best).
  4. This project is very early phase of experiment. Currently only tiny features are supported. More features will be implemented (please see TODO section). And you may notice soon on trying it… it’s buggy 🙂
  5. If inputting something does not change anything, please try to click somewhere in the page. Vim may have lost the focus.
  6. You can try vimtutor by :e tutor.

Also Read GitMiner – Tool For Advanced Mining For Content On Github

How Vim Wasm Works

Build Process

 

WebAssembly frontend for Vim is implemented as a new GUI frontend. C sources are compiled to each LLVM bitcode files and then they are linked to one bitcode file vim.bc by emcc. emcc finally compiles the vim.bc into vim.wasm binary using binaryen and generates HTML/JavaScript runtime.

The difference I faced at first was the lack of terminal library such as ncurses. I modified configure script to ignore the terminal library check. It’s OK since GUI frontend for Wasm is always used instead of CUI frontend. I needed many workarounds to pass configure checks.

emscripten provides Unix-like environment. So os_unix.c can support Wasm. However, some features are not supported by emscripten. I added many #ifdef FEAT_GUI_WASM guards to disable features which cannot be supported by Wasm (i.e. fork (2) support, PTY support, signal handlers are stubbed, …etc).

I created gui_wasm.c heavily referencing gui_mac.c and gui_w32.c. Event loop (gui_mch_update() and gui_mch_wait_for_chars()) is simply implemented with sleep(). And almost all UI rendering events arer passed to JavaScript layer by calling JavaScript functions from C thanks to emscripten.

C sources are compiled (with many optimizations) into LLVM bitcode with Clang which is integrated to emscripten. Then all bitcode files (.o) are linked to one bitcode file vim.bc with llvm-link linker (also integrated to emscripten).

Finally I created JavaScript runtime to draw the rendering events sent from C. It is created as wasm/runtime.ts using emscripten API. It draws Vim screen to <canvas/> element with rendering events such as ‘draw text’, ‘scroll screen’, ‘set foreground color’, ‘clear rect’, …etc.

emcc (emscripten’s C compiler) compiles the vim.bc into vim.wasm, vim.js and vim.html with preloaded Vim runtime files (i.e. colorscheme) using binaryen. Runtime files are put on a virtual file system provided by emscripten on a browser.

Now hosting vim.html with a web server and accessing to it with browser opens Vim. It works.

User Interaction

User interaction is very simple. You input something with keyboard. Browser takes it as KeyboardEvent on keydown event and JavaScript runtime sends the input to Wasm thanks to emscripten’s JS to C API. Sent input is added to a buffer in C layer. It affects the editor’s state.

An editor core implemented in C calculates rendering events and sends it to JavaScript layer thanks to emscripten’s C to JS API. JavaScript runtime receives rendering events and stores them into a queue. On animation frames, it draws them to <canvas/> element in the web page.

Finally you can see the rendered results in the page.

Development

Please make sure that Emscripten and binaryen (I’m using 1.38.6) are installed. If you use macOS, they can be installed with brew install emscripten binaryen.

You can use build.sh script to hack this project. Just after cloning this repository, simply run ./build.sh and it builds vim.wasm in wasm/ directory. It takes time and CPU power a lot.

Finally host the wasm/ directly on localhost with web server such as python -m http.server 1234. Accessing to localhost:1234/vim.html will start Vim with debug build. Note that it’s much slower than release build since many debug features are enabled.

Please note that this repository’s wasm branch is frequently rebased on the latest vim/vim master branch. If you want to hack this project, please ensure to create your own branch and merge wasm branch into your branch by git merge.

Author : Bram Moolenaar

R K

Recent Posts

Kali Linux 2024.4 Released, What’s New?

Kali Linux 2024.4, the final release of 2024, brings a wide range of updates and…

3 days ago

Lifetime-Amsi-EtwPatch : Disabling PowerShell’s AMSI And ETW Protections

This Go program applies a lifetime patch to PowerShell to disable ETW (Event Tracing for…

3 days ago

GPOHunter – Active Directory Group Policy Security Analyzer

GPOHunter is a comprehensive tool designed to analyze and identify security misconfigurations in Active Directory…

5 days ago

2024 MITRE ATT&CK Evaluation Results – Cynet Became a Leader With 100% Detection & Protection

Across small-to-medium enterprises (SMEs) and managed service providers (MSPs), the top priority for cybersecurity leaders…

1 week ago

SecHub : Streamlining Security Across Software Development Lifecycles

The free and open-source security platform SecHub, provides a central API to test software with…

1 week ago

Hawker : The Comprehensive OSINT Toolkit For Cybersecurity Professionals

Don't worry if there are any bugs in the tool, we will try to fix…

1 week ago