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) lands
12//! progressively under [`crate::types`]. Pre-1.0 churn — the public surface
13//! may change in patch bumps. See [docs.rs](https://docs.rs/hjkl-engine) for
14//! the canonical API reference.
15//!
16//! The legacy public surface is intentionally narrow:
17//!
18//! - [`Editor`] — the editor widget.
19//! - [`KeybindingMode`] / [`VimMode`] — mode enums used by host apps.
20//! - [`ex::run`] / [`ex::ExEffect`] — drive ex-mode commands.
21
22mod buf_helpers;
23mod buffer_impl;
24mod editor;
25mod input;
26pub mod keymap_motion;
27pub mod motions;
28mod registers;
29pub mod search;
30pub mod substitute;
31pub mod types;
32mod viewport_math;
33mod vim;
34
35#[cfg(feature = "crossterm")]
36pub use crossterm::event::KeyEvent;
37#[cfg(feature = "crossterm")]
38pub use editor::crossterm_to_input;
39pub use editor::{Editor, LspIntent, StepBookkeeping};
40pub use input::{Input, Key, decode_macro, from_planned as decode_planned_input};
41pub use registers::{Registers, Slot};
42
43pub use buffer_impl::{BufferFoldProvider, BufferFoldProviderMut};
44pub use keymap_motion::MotionKind;
45pub use substitute::{
46    SubstError, SubstFlags, SubstituteCmd, SubstituteOutcome, apply_substitute, parse_substitute,
47};
48pub use types::{
49    Attrs, Buffer, BufferEdit, BufferId, Color, ContentEdit, Cursor, CursorShape, DefaultHost,
50    Edit, EditorSnapshot, EngineError, FoldOp, FoldProvider, Highlight, HighlightKind, Host,
51    Input as PlannedInput, Mode, Modifiers, MouseEvent, MouseKind, NoopFoldProvider, OptionValue,
52    Options, Pos, Query, RenderFrame, Search, Selection, SelectionKind, SelectionSet, SnapshotMode,
53    SpecialKey, Style, Viewport, WrapMode,
54};
55pub use vim::{
56    InsertDir, InsertEntry, InsertReason, InsertSession, LastChange, LastVisual, Motion, Operator,
57    Pending, RangeKind, ScrollDir, SearchPrompt, op_is_change, parse_motion,
58};
59
60/// The FSM-internal mode discriminator used by `Editor::fsm_mode()` and
61/// `Editor::set_fsm_mode()`. Re-exported as `FsmMode` to avoid clashing with
62/// the `types::Mode` buffer-side enum that is already exported as `Mode`.
63///
64/// Used by `hjkl-vim::normal` and `hjkl-vim::dispatch_input` for mode
65/// comparisons.
66pub use vim::Mode as FsmMode;
67
68// 0.0.32 dropped the `#[deprecated]` re-export aliases introduced at
69// 0.0.31 (`SpecBuffer`, `SpecBufferEdit`, `EditOp`, `PlannedViewport`).
70// Consumers must use the canonical names: `Buffer`, `BufferEdit`,
71// `Edit`, `Viewport`.
72
73/// Which keyboard discipline the editor uses. Currently vim-only, but
74/// kept as an enum so future emacs / plain bindings can slot in without
75/// touching the public signature.
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
77pub enum KeybindingMode {
78    #[default]
79    Vim,
80}
81
82#[cfg(feature = "serde")]
83impl serde::Serialize for KeybindingMode {
84    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
85        s.serialize_str("vim")
86    }
87}
88
89#[cfg(feature = "serde")]
90impl<'de> serde::Deserialize<'de> for KeybindingMode {
91    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
92        let _ = String::deserialize(d)?;
93        Ok(KeybindingMode::Vim)
94    }
95}
96
97/// Coarse vim-mode a host app can display in its status line.
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
99pub enum VimMode {
100    #[default]
101    Normal,
102    Insert,
103    Visual,
104    VisualLine,
105    VisualBlock,
106}