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
/**
 * Shared utilities — Glide config
 *
 * Glide configs can't import runtime code between files (only type
 * imports, which are stripped), and each included file gets its own
 * global scope. Shared state goes through `glide.g`, which crosses
 * include boundaries; types are added with `declare global`. Keys
 * under `glide.g["dev.kejadlen"]` are this dotfiles repo's own
 * namespace (reverse-DNS, so glide's own GlideGlobals state can never
 * collide — it already uses `mapleader` there).
 */

glide.styles.add(`
  .glide-notification {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    z-index: 2147483646;
    background: var(--glide-cmdl-bg);
    color: var(--glide-cmdl-fg);
    border: 1px solid hsla(0, 0%, 100%, 0.1);
    border-radius: 4px;
    box-shadow: 0 -8px 32px hsla(0, 0%, 0%, 0.4);
    font-family: var(--glide-cmdl-font-family);
    font-size: var(--glide-cmdl-font-size);
    line-height: var(--glide-cmdl-line-height);
    padding: 0.75rem 1rem;
    max-width: 600px;
    word-break: break-all;
  }
`);

declare global {
  interface DevKejadlen {
    /** Show a transient notification overlay in the browser UI. */
    notify(text: string): void;
    /** Add a browser.* listener that removes itself after :config_reload; defined in glide.ts. */
    listen<T extends (...args: any[]) => any, P extends unknown[]>(
      event: { addListener(callback: T, ...params: P): void; removeListener(callback: T): void },
      listener: T,
      ...params: P
    ): void;
  }

  interface GlideGlobals {
    "dev.kejadlen"?: DevKejadlen;
  }
}

// Keymap and excmd callbacks run in the main process, where `document`
// is the browser UI itself; `DOM` is main-process-only by design.
glide.g["dev.kejadlen"]!.notify = (text: string): void => {
  const el = DOM.create_element("div", { className: "glide-notification", textContent: text });
  document.documentElement.appendChild(el);
  setTimeout(() => el.remove(), 2000);
};