~glacambre/firenvim

ref: 1317fa8380df811a0a97ff9f805b5e523b7a37cd firenvim/src/Neovim.ts -rw-r--r-- 2.7 KiB
1317fa83glacambre Add build instructions to README.md, add LICENSE.md 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { onRedraw } from "./Redraw";
import { Stdin } from "./Stdin";
import { Stdout } from "./Stdout";

export async function neovim(element: HTMLPreElement, selector: string) {
    let stdin: Stdin;
    let stdout: Stdout;
    let reqId = 0;
    const requests = new Map<number, { resolve: any, reject: any }>();
    const highlights: HighlightArray = [{ background: "#FFFFFF", foreground: "#000000" }];
    const grids: any[] = [];

    const port = browser.runtime.connect();
    stdin = new Stdin(port);
    stdout = new Stdout(port);

    const request = (api: string, args: any[]) => {
        return new Promise((resolve, reject) => {
            reqId += 1;
            const r = requests.get(reqId);
            if (r) {
                console.error(`reqId ${reqId} already taken!`);
            }
            requests.set(reqId, {resolve, reject});
            stdin.write(reqId, api, args);
        });
    };
    stdout.addListener("request", (id: any, name: any, args: any) => {
        console.log("received request", id, name, args);
    });
    stdout.addListener("response", (id: any, error: any, result: any) => {
        const r = requests.get(id);
        if (!r) {
            // This can't happen and yet it sometimes does, possibly due to a firefox bug
            console.error(`Received answer to ${id} but no handler found!`);
        } else {
            requests.delete(id);
            if (error) {
                r.reject(error);
            } else {
                r.resolve(result);
            }
        }
    });
    stdout.addListener("notification", async (name: string, args: any[]) => {
        switch (name) {
            case "redraw":
                onRedraw(args, element, grids, highlights);
                break;
            case "firenvim_bufwrite":
                browser.runtime.sendMessage({
                    args: {
                        args: [selector, args[0].text.join("\n")],
                        function: "setElementContent",
                    },
                    function: "messageOwnTab",
                });
                break;
            default:
                console.log(`Unhandled notification '${name}':`, args);
                break;
        }
    });

    const { 0: channel, 1: apiInfo } = (await request("nvim_get_api_info", [])) as INvimApiInfo;
    return apiInfo.functions
        .filter(f => f.deprecated_since === undefined)
        .reduce((acc, cur) => {
            let name = cur.name;
            if (name.startsWith("nvim_")) {
                name = name.slice(5);
            }
            acc[name] = (...args: any[]) => request(cur.name, args);
            return acc;
        }, {} as {[k: string]: (...args: any[]) => any});
}