Skip to main content

hjkl_engine/
lib.rs

1//! Vim-mode editor engine built on top of [`hjkl_buffer`].
2//!
3//! Exposes an [`Editor`] you can drop into a ratatui layout, a command
4//! grammar that covers the bulk of vim's normal / insert / visual /
5//! visual-line / visual-block modes, text-object operators, dot-repeat,
6//! and ex-command handling (`:s/foo/bar/g`, `:w`, `:q`, `:noh`, ...).
7//! Rendering goes through `hjkl_buffer::BufferView`; selection / gutter
8//! highlights are painted in the same single-pass as text.
9//!
10//! Imported wholesale from sqeel-vim with full git history. The trait
11//! extraction (Selection / SelectionSet / Buffer + Host sub-traits per
12//! [`SPEC.md`][spec]) lands progressively under [`crate::types`]. Pre-1.0
13//! churn — the public surface may change in patch bumps.
14//!
15//! [spec]: https://github.com/kryptic-sh/hjkl/blob/main/crates/hjkl-engine/SPEC.md
16//!
17//! The legacy public surface is intentionally narrow:
18//!
19//! - [`Editor`] — the editor widget.
20//! - [`KeybindingMode`] / [`VimMode`] — mode enums used by host apps.
21//! - [`ex::run`] / [`ex::ExEffect`] — drive ex-mode commands.
22
23mod editor;
24mod input;
25mod registers;
26pub mod types;
27mod vim;
28
29pub use editor::{Editor, LspIntent};
30pub use input::{Input, Key};
31pub use registers::{Registers, Slot};
32
33// Internal vim FSM entry points — promoted to pub so ex commands
34// (which now live in `hjkl-editor`) can reach them across the crate
35// boundary. Sealed at 0.1.0 trait extraction.
36pub use types::{
37    Attrs, BufferId, Color, CursorShape, Edit as EditOp, EngineError, Highlight, HighlightKind,
38    Host, Input as PlannedInput, Mode, Modifiers, MouseEvent, MouseKind, Options, Pos, Selection,
39    SelectionKind, SelectionSet, SpecialKey, Style, Viewport as PlannedViewport,
40};
41pub use vim::SearchPrompt;
42#[doc(hidden)]
43pub use vim::{do_redo, do_undo};
44
45/// Which keyboard discipline the editor uses. Currently vim-only, but
46/// kept as an enum so future emacs / plain bindings can slot in without
47/// touching the public signature.
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
49pub enum KeybindingMode {
50    #[default]
51    Vim,
52}
53
54#[cfg(feature = "serde")]
55impl serde::Serialize for KeybindingMode {
56    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
57        s.serialize_str("vim")
58    }
59}
60
61#[cfg(feature = "serde")]
62impl<'de> serde::Deserialize<'de> for KeybindingMode {
63    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
64        let _ = String::deserialize(d)?;
65        Ok(KeybindingMode::Vim)
66    }
67}
68
69/// Coarse vim-mode a host app can display in its status line.
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
71pub enum VimMode {
72    #[default]
73    Normal,
74    Insert,
75    Visual,
76    VisualLine,
77    VisualBlock,
78}