File size: 2,045 Bytes
50fe3c9 | 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 | import { Vim } from "@replit/codemirror-vim";
import { type EditorView, ViewPlugin } from "@codemirror/view";
import type { Extension } from "@codemirror/state";
export type VimHandlers = { save: () => void; close: () => void };
const handlers = new WeakMap<EditorView, VimHandlers>();
/** A CodeMirror extension that binds :w / :q handlers to this view. */
export function vimHandlersExtension(getHandlers: () => VimHandlers): Extension {
return ViewPlugin.define((view) => {
handlers.set(view, getHandlers());
return {
update() {
// Keep handlers fresh in case the closure captured stale refs.
handlers.set(view, getHandlers());
},
destroy() {
handlers.delete(view);
},
};
});
}
let initialized = false;
export function initVimGlobals(): void {
if (initialized) return;
initialized = true;
type CmAdapter = { cm6?: EditorView };
const getView = (cm: CmAdapter) => cm.cm6;
Vim.defineEx("write", "w", (cm: CmAdapter) => {
const view = getView(cm);
if (view) handlers.get(view)?.save();
});
Vim.defineEx("quit", "q", (cm: CmAdapter) => {
const view = getView(cm);
if (view) handlers.get(view)?.close();
});
Vim.defineEx("wq", "wq", (cm: CmAdapter) => {
const view = getView(cm);
if (!view) return;
const h = handlers.get(view);
h?.save();
h?.close();
});
Vim.defineEx("xit", "x", (cm: CmAdapter) => {
const view = getView(cm);
if (!view) return;
const h = handlers.get(view);
h?.save();
h?.close();
});
// Arrow keys are forwarded by the plugin to the editor scope handlers,
// which breaks operator-pending (d<Up>) and counts (15<Up>). Remap to
// hjkl so they stay inside the vim state machine.
Vim.map("<Up>", "k", "normal");
Vim.map("<Down>", "j", "normal");
Vim.map("<Left>", "h", "normal");
Vim.map("<Right>", "l", "normal");
Vim.map("<Up>", "k", "visual");
Vim.map("<Down>", "j", "visual");
Vim.map("<Left>", "h", "visual");
Vim.map("<Right>", "l", "visual");
}
|