Skip to main content

hjkl_editor/
lib.rs

1//! # hjkl-editor
2//!
3//! Front door for the hjkl modal editor stack. Re-exports the working
4//! parts of [`hjkl_engine`] and [`hjkl_buffer`] under a curated
5//! namespace so downstream consumers (sqeel, buffr, hjkl binary) add
6//! one dependency instead of three and don't need to know the
7//! crate-split.
8//!
9//! Two layers ride alongside each other during the 0.0.x churn:
10//!
11//! - **Legacy surface** (today's runtime): the [`runtime`] module
12//!   re-exports the existing [`Editor`], [`KeybindingMode`], [`VimMode`],
13//!   [`Input`], [`Key`], [`SearchPrompt`], [`Registers`], [`Slot`], and
14//!   [`LspIntent`]. This is what sqeel-tui consumes today.
15//! - **Planned surface** (0.1.0 SPEC): the [`spec`] module re-exports
16//!   the additive types from [`hjkl_engine::types`] —
17//!   [`spec::Pos`], [`spec::Selection`], [`spec::SelectionSet`],
18//!   [`spec::Edit`], [`spec::Mode`], [`spec::Style`], [`spec::Highlight`],
19//!   [`spec::Options`], [`spec::Input`], [`spec::Host`], [`spec::EngineError`].
20//!   Trait extraction will rewire the runtime onto these — once it
21//!   ships, [`runtime`] becomes a thin compat layer.
22//!
23//! ## Usage
24//!
25//! ```no_run
26//! use hjkl_editor::buffer;
27//! use hjkl_editor::runtime::{DefaultHost, Editor, Options};
28//!
29//! let mut editor = Editor::new(buffer::Buffer::new(), DefaultHost::new(), Options::default());
30//! editor.set_content("hello world");
31//! ```
32//!
33//! Buffer and rope helpers are re-exported at the [`buffer`] module,
34//! mirroring the [`hjkl_buffer`] surface.
35//!
36//! [`Editor`]: hjkl_engine::Editor
37//! [`KeybindingMode`]: hjkl_engine::KeybindingMode
38//! [`VimMode`]: hjkl_engine::VimMode
39//! [`Input`]: hjkl_engine::Input
40//! [`Key`]: hjkl_engine::Key
41//! [`SearchPrompt`]: hjkl_engine::SearchPrompt
42//! [`Registers`]: hjkl_engine::Registers
43//! [`Slot`]: hjkl_engine::Slot
44//! [`LspIntent`]: hjkl_engine::LspIntent
45#![forbid(unsafe_code)]
46
47// Ex command driver — relocated from hjkl-engine in 0.0.5. Lives here
48// because ex commands operate over the public Editor surface; engine
49// stays focused on the FSM core.
50mod ex;
51
52pub mod buffer {
53    //! Re-export of [`hjkl_buffer`]'s public surface.
54
55    pub use hjkl_buffer::{
56        Buffer, BufferView, Edit, Fold, Gutter, MotionKind, Position, RowSpan, Selection, Sign,
57        Span, StyleResolver, Viewport, Wrap,
58    };
59}
60
61pub mod runtime {
62    //! Legacy runtime surface — the working sqeel-vim port.
63    //!
64    //! These types drive editing today. The trait extraction lands a
65    //! generic `Editor<B: Buffer, H: Host>` into [`crate::spec`] that
66    //! eventually replaces this surface; pre-1.0 churn means the swap
67    //! can land on a patch bump.
68
69    pub use hjkl_engine::types::{DefaultHost, Options};
70    pub use hjkl_engine::{
71        Editor, Input, Key, KeybindingMode, LspIntent, Registers, SearchPrompt, Slot, VimMode,
72    };
73    pub mod ex {
74        //! Ex command driver — `:s/pat/.../`, `:w`, `:q`, etc.
75        //!
76        //! Lives in this crate (relocated from hjkl-engine in 0.0.5).
77        pub use crate::ex::*;
78    }
79}
80
81pub mod spec {
82    //! Engine trait surface re-exported for consumers.
83    //!
84    //! All types are additive — they coexist with [`crate::runtime`]
85    //! during the churn phase. Trait impls are forthcoming; today the
86    //! types support host-side prep (e.g., buffr-modal's `BuffrHost`).
87
88    pub use hjkl_engine::types::{
89        Attrs, Buffer, BufferEdit, BufferId, Color, Cursor, CursorShape, Edit, EngineError, FoldOp,
90        FoldProvider, Highlight, HighlightKind, Host, Input, Mode, Modifiers, MouseEvent,
91        MouseKind, NoopFoldProvider, Options, Pos, Query, Search, Selection, SelectionKind,
92        SelectionSet, SpecialKey, Style, Viewport,
93    };
94    pub use hjkl_engine::{BufferFoldProvider, BufferFoldProviderMut};
95}
96
97#[cfg(test)]
98mod tests {
99    use super::*;
100
101    #[test]
102    fn editor_constructs() {
103        let _ = runtime::Editor::new(
104            buffer::Buffer::new(),
105            runtime::DefaultHost::new(),
106            runtime::Options::default(),
107        );
108    }
109
110    #[test]
111    fn buffer_constructs() {
112        let _ = buffer::Buffer::from_str("hello\nworld");
113    }
114
115    #[test]
116    fn spec_options_default() {
117        let opts = spec::Options::default();
118        assert_eq!(opts.tabstop, 4);
119    }
120
121    #[test]
122    fn spec_selection_set_default() {
123        let set = spec::SelectionSet::default();
124        assert_eq!(set.items.len(), 1);
125    }
126}