feat: add file editor vim mode (#1437)

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Champii
2026-06-08 19:10:32 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent d9b9b56599
commit f45fe05f33
18 changed files with 197 additions and 17 deletions
@@ -0,0 +1,52 @@
import type { Extension } from '@codemirror/state';
import type { EditorView, Panel } from '@codemirror/view';
import { drawSelection, showPanel } from '@codemirror/view';
import { getCM, vim } from '@replit/codemirror-vim';
type VimStatusPlugin = {
updateStatus: () => void;
};
const isVimStatusPlugin = (value: unknown): value is VimStatusPlugin => {
return (
value !== null
&& typeof value === 'object'
&& 'updateStatus' in value
&& typeof value.updateStatus === 'function'
);
};
const bottomVimStatusPanel = (view: EditorView): Panel => {
const dom = document.createElement('div');
dom.className = 'cm-vim-panel';
const cm = getCM(view);
if (!cm) {
return { top: false, dom };
}
cm.state.statusbar = dom;
const vimPlugin: unknown = cm.state.vimPlugin;
// The Vim package exposes only a top status panel; reuse its updater with a bottom panel.
if (isVimStatusPlugin(vimPlugin)) {
vimPlugin.updateStatus();
}
return {
top: false,
dom,
destroy() {
if (cm.state.statusbar === dom) {
cm.state.statusbar = null;
}
},
};
};
export function createVimModeExtensions(enabled: boolean | undefined): Extension[] {
if (!enabled) {
return [];
}
return [vim(), showPanel.of(bottomVimStatusPanel), drawSelection()];
}