onivim / libvim

libvim: The core Vim editing engine as a minimal C library
https://v2.onivim.io
MIT License
692 stars 34 forks source link

WebAssembly build #258

Open easbar opened 3 years ago

easbar commented 3 years ago

Can you give some advice how to compile libvim to WebAssembly? its mentioned in the README.md but I could not find any instructions how this is done.

I do not know the esy tool very well, but I think I was able to build the library under linux using this script in src/build (running it from src):

# build in this folder
cur__install=my_build_wasm
# the lib folder is not created by the makefile for some reason -> created it manually
mkdir -p $cur__install/lib
emconfigure ./configure --disable-selinux CFLAGS=-fPIC
emmake make installlibvim DESTDIR=$cur__install

There were some failing checks though (not sure if this is the problem):

checking --with-tlib argument... empty: automatic terminal library selection
checking for tgetent in -ltinfo... no
checking for tgetent in -lncurses... no
checking for tgetent in -ltermlib... no
checking for tgetent in -ltermcap... no
checking for tgetent in -lcurses... no
no terminal library found
checking for tgetent()... configure: error: NOT FOUND!
      You need to install a terminal library; for example ncurses.
      Or specify the name of the library with --with-tlib.

Anyway I got a libvim.a file and tried compiling this code:

#include <stdio.h>
#include "libvim.h"

void sayHello() {
        printf("hello\n");
}

int main(int argc, char** argv) {
        vimInit(argc, argv);
        sayHello();
}

using this command:

emcc -Iinclude -Iinclude/proto -DHAVE_CONFIG_H -fPIC main.c lib/libvim.a -o index.html

But then I got this error:

wasm-ld: error: unknown file type: libvim.o

This works fine using gcc:

# after running the same build script but with configure/make instead of emconfigure/emmake
gcc -Iinclude -Iinclude/proto -DHAVE_CONFIG_H main.c lib/libvim.a -lSM -lICE -lXt -lX11 -lXdmcp -lm -ltinfo -lnsl -ldl

Any idea what could be wrong? Did you have success using this library with WebAssembly yet? If so it would be great if you could add some directions how.

elebeaup commented 3 years ago

Emscripten does not seem to support ncurses. But, libvim is not responsible for rendering the user interface. So, I think we can skip this check.

After some tweaks, I succeeded in compiling libvim to WebAssembly. I tested part of the API (motion, update buffer callback, get vim mode, input and key press,...) and it works.

I have a question about the cursor position. @bryphe In oni2, how is the cursor position handled after a vim motion? Do you check after each keyboard event if the cursor position has changed? In the API, I cannot find any callback about the cursor position that would be triggered after a vim motion (w, h, j, gg,...)

bryphe commented 3 years ago

After some tweaks, I succeeded in compiling libvim to WebAssembly. I tested part of the API (motion, update buffer callback, get vim mode, input and key press,...) and it works.

@elebeaup - very exciting! Thanks for exploring this and sharing what you've done so far. Would be interested to see it in action

In oni2, how is the cursor position handled after a vim motion? Do you check after each keyboard event if the cursor position has changed? In the API, I cannot find any callback about the cursor position that would be triggered after a vim motion (w, h, j, gg,...)

Good question - you're exactly right in terms of the strategy Onivim 2 uses: we get the cursor position with vimCursorGetLine/vimCursorGetColumn after running libvim's vimKey/vimExecute/vimCommand.

titanous commented 3 years ago

I played around with this a bit in December. I ended up ripping out some terminal-related stuff in order to get it to build. This is what I ended up with: https://github.com/titanous/libvim/commit/ffdb7d9ad6e22f0152b39aacffc23e261456c874

I haven't had time to fully test/integrate and clean this up, but I wanted to checkpoint here in case someone else got to it first.

elebeaup commented 3 years ago

You can find my work in progress here : elebeaup@9aff8976cd0b338945feeaefce0526d33c9243e0.

Compiling

$ emconfigure ./configure
$ emmake make libvim.js

Testing

$ cd wasm
$ npm install
$ npm test