Skip to content

T-FG8R-editor-settings-toolbar-and-vim

State: planning/proposed · Impact: medium · Complexity: medium

The markdown editor has no vim mode, and every MdSurface mount hardcodes its toolbar as toolbar="fixed" rather than reading a user preference. This task makes both a real settings choice — a vim extension slot in the CodeMirror engine, and one editor settings section every markdown and code surface reads from — so a user picks modal editing and toolbar visibility once.

LocationRole today
packages/ts/obsidian-editor/src/extensions.tsCompiles the fixed extension stack (plugins, keymaps, theme); no vim extension slot
packages/ts/obsidian-editor/package.jsonDependency list; no @replit/codemirror-vim
packages/ts/markdown-ui/app/components/MdSurface.vue#toolbartoolbar?: boolean | 'fixed' prop, default false; no vim prop
solutions/determined/experiences/notes/app/components/NotesNoteView.vueMounts MdSurface with toolbar="fixed" hardcoded
solutions/determined/experiences/agent-pants/app/components/ApNewComponentWizard.vueMounts MdSurface with toolbar="fixed" hardcoded
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/index.vueSame
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/notes/[...path].vueSame
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/plugins/[...path].vueSame
packages/ts/app-frame/app/plugins/settings.client.tsRegisters the shell’s own sections (shell.general zod, shell.appearance/icons/effects component-based) through registerSettings
packages/ts/app-frame/app/composables/useSettingsSection.tsDeclarative/zod settings persistence keyed by namespace; fires the settings:saved hook on save
solutions/augmented/apps/vimit_prototype/app/components/VimEditor/VimEditor.vuePrototype CM6 + vim integration; comments the ordering rule “key filter MUST come before vim()“

An editor zod settings section (vimMode: boolean, showToolbar: boolean), default vimMode: false / showToolbar: true, registered through registerSettings following settings.client.ts’s pattern. @replit/codemirror-vim ^6.3.0 is an opt-in extension in obsidian-editor’s stack, installed ahead of the editor’s own keymaps — the vimit_prototype’s ordering note generalizes to: vim must sit before any keymap it needs to intercept. The same slot exists in code-editor-package. Every MdSurface mount binds toolbar and a new vim prop from useSettingsSection('editor') instead of the toolbar="fixed" literal. A status-bar indicator shows the active vim mode when enabled.

  1. Add @replit/codemirror-vim ^6.3.0 to packages/ts/obsidian-editor/package.json.
  2. In extensions.ts, add vim?: boolean to ObsidianEditorOptions and, when set, prepend vim() to the returned extension array ahead of the keymap.of([...pluginKeys, ...structuralKeymap, ...]) block.
  3. Add the matching vim slot to code-editor-package (depends on T-MVW5-code-editor-package existing).
  4. Register an editor zod settings section (vimMode, showToolbar) via registerSettings, following settings.client.ts’s shell.general pattern.
  5. Add a vim prop to MdSurface.vue alongside the existing toolbar prop, threaded to obsidianEditorExtensions.
  6. Bind toolbar and vim on all five toolbar="fixed" mounts (NotesNoteView.vue and the four agent-pants mounts) to useSettingsSection('editor') instead of the literal.
  7. Add a status-bar mode indicator (normal/insert/visual) that reads vim state when vimMode is on.
  8. Cover the toggle and a vim smoke test (enter insert mode, type, escape) in the playground or an experience e2e spec.
AreaNote
packages/ts/obsidian-editor/package.jsonAdd @replit/codemirror-vim
packages/ts/obsidian-editor/src/extensions.tsPrepend vim() extension when enabled
packages/ts/obsidian-editor/src/types.tsvim?: boolean on ObsidianEditorOptions
packages/ts/markdown-ui/app/components/MdSurface.vuevim prop, status-bar mode indicator
packages/ts/app-frame/app/plugins/settings.client.tsRegister the editor zod section
solutions/determined/experiences/notes/app/components/NotesNoteView.vueBind toolbar/vim from useSettingsSection('editor')
solutions/determined/experiences/agent-pants/app/components/ApNewComponentWizard.vueSame
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/index.vueSame
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/notes/[...path].vueSame
solutions/determined/experiences/agent-pants/app/pages/apps/agent-pants/plugins/[...path].vueSame
  • AC-1: Toggling showToolbar off in Settings hides MdSurface’s toolbar on all five mounts without a page reload.
  • AC-2: Toggling vimMode on enables normal/insert/visual modal editing; a test drives Escape, i and a motion, and asserts the resulting buffer.
  • AC-3: The vim extension installs ahead of the editor’s own keymaps, verified by a test that a vim-mapped key is not swallowed by a plugin chord.
  • AC-4: A status-bar indicator shows the current vim mode when vimMode is on and is absent when it is off.
  • AC-5: code-editor-package’s vim slot compiles and has at least one passing test.
  • Vim key-filtering or an allowlist (vimit_prototype’s allowedKeys); this task ships plain vim, not a restricted subset.
  • An ex-command surface (:w, :q) beyond what @replit/codemirror-vim provides.
  • Creating code-editor-package itself (T-MVW5-code-editor-package); this task only adds a vim slot once that package exists.

From the user’s Agent Manager planning request (2026-09-07), grouped with tables, styling and mermaid as the markdown-ecosystem stage. M-BMFD’s Stage 6 row cites the vimit_prototype ordering note directly; the CodeMirror-6 editor engine (confirmed in the plan’s direct-answers section — there is no ProseMirror anywhere in the repo) is why vim support and the future code editor share one extension.

T-MVW5-code-editor-package


← Back to Tasks