Files
openidea/src/features/vim/mode.ts
T
l0ng-ai 7146779f6c feat(vim): Built-in Vim mode modelled on IdeaVim (#55)
Built-in Vim emulation on @replit/codemirror-vim (approved dependency), modelled on IdeaVim: `vim.toggle` (Tools › Vim, status widget, Settings › Editor › Vim), mode widget (NORMAL / INSERT / VISUAL / V-LINE / V-BLOCK / REPLACE), IdeaVim-style shortcut conflict handlers (Vim / IDE per key) through a generic `registerKeyClaim()` in the keymap dispatcher, Escape closing popups first, a safe subset of ~/.openideavimrc / ~/.ideavimrc (set, map variants, mapleader, :action / <Action>()), Ex commands :w :wa :q :qa :wq :x :action. Covers file editors, diff editable side and merge result via a new `embeddedEditorExtensions` extension point.

Verified in the app on macOS: motions/operators, i/Esc/V mode widget, :w saves, Ctrl+R redoes in Vim without running Run, toggling off restores plain editing. Not verified on Windows/Linux.

Fixes #27

https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 11:43:37 +08:00

18 lines
703 B
TypeScript

/** The Vim mode of the focused (or last focused) Vim editor, for the status bar widget. */
import { create } from "zustand";
export interface VimModeState {
/** codemirror-vim's mode: `normal`, `insert`, `visual`, `replace`. */
mode: string;
/** Visual sub-mode. */
sub: "linewise" | "blockwise" | null;
}
export const useVimMode = create<VimModeState>(() => ({ mode: "normal", sub: null }));
/** IdeaVim's widget text: NORMAL, INSERT, VISUAL, V-LINE, V-BLOCK, REPLACE. */
export function modeLabel({ mode, sub }: VimModeState): string {
if (mode === "visual") return sub === "linewise" ? "V-LINE" : sub === "blockwise" ? "V-BLOCK" : "VISUAL";
return (mode || "normal").toUpperCase();
}