pub struct Editor<B: View = View, H: Host = DefaultHost> {
pub styled_spans: Vec<Vec<(usize, usize, Style)>>,
/* private fields */
}Fields§
§styled_spans: Vec<Vec<(usize, usize, Style)>>Per-row syntax styling in engine-native form. Always present —
populated by Editor::install_syntax_spans. Ratatui hosts use
hjkl_engine_tui::EditorRatatuiExt::install_ratatui_syntax_spans.
Implementations§
Source§impl<H: Host> Editor<View, H>
impl<H: Host> Editor<View, H>
Sourcepub fn new(buffer: View, host: H, options: Options) -> Self
pub fn new(buffer: View, host: H, options: Options) -> Self
Build an Editor from a buffer, host adapter, and SPEC options.
0.1.0 (Patch C-δ): canonical, frozen constructor per SPEC §“Editor
surface”. Replaces the pre-0.1.0 Editor::new(KeybindingMode) /
with_host / with_options triad — there is no shim.
Consumers that don’t need a custom host pass
crate::types::DefaultHost::new(); consumers that don’t need
custom options pass crate::types::Options::default().
Source§impl<B: View, H: Host> Editor<B, H>
impl<B: View, H: Host> Editor<B, H>
Source§impl<H: Host> Editor<View, H>
impl<H: Host> Editor<View, H>
Sourcepub fn set_iskeyword(&mut self, spec: impl Into<String>)
pub fn set_iskeyword(&mut self, spec: impl Into<String>)
Update the active iskeyword spec for word motions
(w/b/e/ge and engine-side */# pickup). 0.0.28
hoisted iskeyword storage out of View — Editor is the
single owner now. Equivalent to assigning
settings_mut().iskeyword directly; the dedicated setter is
retained for source-compatibility with 0.0.27 callers.
Sourcepub fn emit_cursor_shape_if_changed(&mut self)
pub fn emit_cursor_shape_if_changed(&mut self)
Emit Host::emit_cursor_shape if the public mode has changed
since the last emit. Engine calls this at the end of every input
step so mode transitions surface to the host without sprinkling
the call across every vim.mode = ... site.
Sourcepub fn record_yank_to_host(&mut self, text: String)
pub fn record_yank_to_host(&mut self, text: String)
Record a yank/cut payload. Forwards the text to
crate::types::Host::write_clipboard so the platform-clipboard
integration can store or transmit it.
Sourcepub fn sticky_col(&self) -> Option<usize>
pub fn sticky_col(&self) -> Option<usize>
Vim’s sticky column (curswant). None before the first motion;
hosts shouldn’t normally need to read this directly — it’s
surfaced for migration off View::sticky_col and for
snapshot tests.
Sourcepub fn set_sticky_col(&mut self, col: Option<usize>)
pub fn set_sticky_col(&mut self, col: Option<usize>)
Replace the sticky column. Hosts should rarely touch this — motion code maintains it through the standard horizontal / vertical motion paths.
Sourcepub fn mark(&self, c: char) -> Option<(usize, usize)>
pub fn mark(&self, c: char) -> Option<(usize, usize)>
Host hook: replace the cached syntax-derived block ranges that
:foldsyntax consumes. the host calls this on every re-parse;
the cost is just a Vec swap.
Look up a named mark by character. Returns (row, col) if
set; None otherwise. Both lowercase ('a–'z) and
uppercase ('A–'Z) marks live in the same unified
Editor::marks map as of 0.0.36.
Sourcepub fn set_mark(&mut self, c: char, pos: (usize, usize))
pub fn set_mark(&mut self, c: char, pos: (usize, usize))
Set the named mark c to (row, col). Used by the FSM’s
m{a-zA-Z} keystroke and by Editor::restore_snapshot.
Sourcepub fn clear_mark(&mut self, c: char)
pub fn clear_mark(&mut self, c: char)
Remove the named mark c (no-op if unset).
Sourcepub fn global_mark(&self, c: char) -> Option<(u64, usize, usize)>
pub fn global_mark(&self, c: char) -> Option<(u64, usize, usize)>
Look up an uppercase global mark by letter. Returns
(buffer_id, row, col) if set; None otherwise.
Sourcepub fn set_global_mark(&mut self, c: char, buffer_id: u64, pos: (usize, usize))
pub fn set_global_mark(&mut self, c: char, buffer_id: u64, pos: (usize, usize))
Set an uppercase global mark c to (buffer_id, row, col).
Sourcepub fn current_buffer_id(&self) -> u64
pub fn current_buffer_id(&self) -> u64
Return the buffer_id this editor is currently attached to.
Sourcepub fn set_current_buffer_id(&mut self, id: u64)
pub fn set_current_buffer_id(&mut self, id: u64)
Update the buffer_id this editor is attached to. Called by the
app on every switch_to so global-mark sets record the correct id.
Sourcepub fn global_marks_iter(
&self,
) -> impl Iterator<Item = (char, u64, usize, usize)> + '_
pub fn global_marks_iter( &self, ) -> impl Iterator<Item = (char, u64, usize, usize)> + '_
Iterate all global marks ('A'–'Z'), yielding
(mark_char, buffer_id, row, col).
Sourcepub fn buffer_mark(&self, c: char) -> Option<(usize, usize)>
👎Deprecated since 0.0.36: use Editor::mark — lowercase + uppercase marks now live in a single map
pub fn buffer_mark(&self, c: char) -> Option<(usize, usize)>
use Editor::mark — lowercase + uppercase marks now live in a single map
Look up a buffer-local lowercase mark ('a–'z). Kept as a
thin wrapper over Editor::mark for source compatibility
with pre-0.0.36 callers; new code should call
Editor::mark directly.
Sourcepub fn pop_last_undo(&mut self) -> bool
pub fn pop_last_undo(&mut self) -> bool
Discard the most recent undo entry. Used by ex commands that
pre-emptively pushed an undo state (:s, :r) but ended up
matching nothing — popping prevents a no-op undo step from
polluting the user’s history.
Returns true if an entry was discarded.
Sourcepub fn marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
pub fn marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
Read all named marks set this session — both lowercase
('a–'z) and uppercase ('A–'Z). Iteration is
deterministic (BTreeMap-ordered) so snapshot / :marks
output is stable.
Sourcepub fn buffer_marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
👎Deprecated since 0.0.36: use Editor::marks — lowercase + uppercase marks now live in a single map
pub fn buffer_marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
use Editor::marks — lowercase + uppercase marks now live in a single map
Read all buffer-local lowercase marks. Kept for source
compatibility with pre-0.0.36 callers (e.g. :marks ex
command); new code should use Editor::marks which
iterates the unified map.
Sourcepub fn last_edit_pos(&self) -> Option<(usize, usize)>
pub fn last_edit_pos(&self) -> Option<(usize, usize)>
Position of the last edit (where . would replay). None if
no edit has happened yet in this session.
Sourcepub fn file_marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
pub fn file_marks(&self) -> impl Iterator<Item = (char, (usize, usize))>
Read-only view of the file-marks table — uppercase / “file”
marks ('A–'Z) the host has set this session. Returns an
iterator of (mark_char, (row, col)) pairs.
Mutate via the FSM (m{A-Z} keystroke) or via
Editor::restore_snapshot.
0.0.36: file marks now live in the unified Editor::marks
map; this accessor is kept for source compatibility and
filters the unified map to uppercase entries.
Sourcepub fn syntax_fold_ranges(&self) -> Vec<(usize, usize)>
pub fn syntax_fold_ranges(&self) -> Vec<(usize, usize)>
Read-only view of the cached syntax-derived block ranges that
:foldsyntax consumes. Returns the slice the host last
installed via Editor::set_syntax_fold_ranges; empty when
no syntax integration is active.
pub fn set_syntax_fold_ranges(&mut self, ranges: Vec<(usize, usize)>)
Sourcepub fn settings(&self) -> &Settings
pub fn settings(&self) -> &Settings
Live settings (read-only). :set mutates these via
Editor::settings_mut.
Sourcepub fn settings_mut(&mut self) -> &mut Settings
pub fn settings_mut(&mut self) -> &mut Settings
Live settings (mutable). :set flows through here to mutate
shiftwidth / tabstop / textwidth / ignore_case / wrap. Hosts
configuring at startup typically construct a Settings
snapshot and overwrite via *editor.settings_mut() = ….
Sourcepub fn set_filetype(&mut self, lang: &str)
pub fn set_filetype(&mut self, lang: &str)
Set the active filetype (language name) for the current buffer.
Used by comment-continuation and future language-aware features.
Equivalent to :set filetype=<lang>. Pass "" to clear.
Sourcepub fn is_readonly(&self) -> bool
pub fn is_readonly(&self) -> bool
Returns true when :set readonly is active. Convenience
accessor for hosts that cannot import the internal Settings
type. Phase 5 binary uses this to gate :w writes.
Sourcepub fn is_modifiable(&self) -> bool
pub fn is_modifiable(&self) -> bool
Returns true when the buffer is modifiable (default). When false
(:set nomodifiable), ALL edits and insert-mode entry are blocked.
Sourcepub fn search_state(&self) -> &SearchState
pub fn search_state(&self) -> &SearchState
Borrow the engine search state. Hosts inspecting the
committed / / ? pattern (e.g. for status-line display) or
feeding the active regex into BufferView::search_pattern
read it from here.
Sourcepub fn search_state_mut(&mut self) -> &mut SearchState
pub fn search_state_mut(&mut self) -> &mut SearchState
Mutable engine search state. Hosts driving search programmatically (test fixtures, scripted demos) write the pattern through here.
Sourcepub fn set_search_pattern(&mut self, pattern: Option<Regex>)
pub fn set_search_pattern(&mut self, pattern: Option<Regex>)
Install pattern as the active search regex on the engine
state and clear the cached row matches. Pass None to clear.
0.0.37: dropped the buffer-side mirror that 0.0.35 introduced
— BufferView now takes the regex through its search_pattern
field per step 3 of DESIGN_33_METHOD_CLASSIFICATION.md.
Sourcepub fn search_advance_forward(&mut self, skip_current: bool) -> bool
pub fn search_advance_forward(&mut self, skip_current: bool) -> bool
Drive n (or the / commit equivalent) — advance the cursor
to the next match of search_state.pattern from the cursor’s
current position. Returns true when a match was found.
skip_current = true excludes a match the cursor sits on.
Opens any fold hiding the match row (vim-correct: search reveals folds).
Sourcepub fn search_advance_backward(&mut self, skip_current: bool) -> bool
pub fn search_advance_backward(&mut self, skip_current: bool) -> bool
Drive N — symmetric counterpart of Editor::search_advance_forward.
Opens any fold hiding the match row (vim-correct: search reveals folds).
Sourcepub fn registers(&self) -> MutexGuard<'_, Registers>
pub fn registers(&self) -> MutexGuard<'_, Registers>
Borrow the full register bank — ", "0–"9, "a–"z.
Sourcepub fn registers_mut(&self) -> MutexGuard<'_, Registers>
pub fn registers_mut(&self) -> MutexGuard<'_, Registers>
Mutably borrow the full register bank. Returns a guard so callers
can mutate in place. Signature changed from &mut self to &self
because the interior mutability is now via Arc<Mutex<>>.
Sourcepub fn set_registers_arc(&mut self, registers: Arc<Mutex<Registers>>)
pub fn set_registers_arc(&mut self, registers: Arc<Mutex<Registers>>)
Point this editor at a shared register bank. All editors in the app share one bank so yank/paste work cross-buffer without copying.
Sourcepub fn sync_clipboard_register(&mut self, text: String, linewise: bool)
pub fn sync_clipboard_register(&mut self, text: String, linewise: bool)
Host hook: load the OS clipboard’s contents into the "+ / "*
register slot. the host calls this before letting vim consume a
paste so "*p / "+p reflect the live clipboard rather than a
stale snapshot from the last yank.
Sourcepub fn change_list(&self) -> (&[(usize, usize)], Option<usize>)
pub fn change_list(&self) -> (&[(usize, usize)], Option<usize>)
Read-only view of the change list (positions of recent edits) plus the current walk cursor. Newest entry is at the back.
Sourcepub fn set_yank(&mut self, text: impl Into<String>)
pub fn set_yank(&mut self, text: impl Into<String>)
Replace the unnamed register without touching any other slot.
For host-driven imports (e.g. system clipboard); operator
code uses [record_yank] / [record_delete].
Sourcepub fn record_yank(
&mut self,
text: String,
linewise: bool,
target: Option<char>,
)
pub fn record_yank( &mut self, text: String, linewise: bool, target: Option<char>, )
Record a yank into " and "0, plus the named target if the
user prefixed "reg. Updates vim.yank_linewise for the
paste path.
Sourcepub fn set_named_register_text(&mut self, reg: char, text: String)
pub fn set_named_register_text(&mut self, reg: char, text: String)
Direct write to a named register slot — bypasses the unnamed
" and "0 updates that record_yank does. Used by the
macro recorder so finishing a q{reg} recording doesn’t
pollute the user’s last yank.
Sourcepub fn record_delete(
&mut self,
text: String,
linewise: bool,
target: Option<char>,
)
pub fn record_delete( &mut self, text: String, linewise: bool, target: Option<char>, )
Record a delete / change into " and, by size, the "1–"9
ring or the "- small-delete register. Honours the active
named-register prefix.
Sourcepub fn install_syntax_spans(&mut self, spans: Vec<Vec<(usize, usize, Style)>>)
pub fn install_syntax_spans(&mut self, spans: Vec<Vec<(usize, usize, Style)>>)
Install styled syntax spans using the engine-native
crate::types::Style. Always available — engine is ratatui-free.
Ratatui hosts use
hjkl_engine_tui::EditorRatatuiExt::install_ratatui_syntax_spans
which converts at the boundary and delegates here.
Renamed from install_engine_syntax_spans in 0.0.32 — at the
0.1.0 freeze the unprefixed name is the universally-available
engine-native variant.
Sourcepub fn patch_syntax_spans_range(
&mut self,
rows: Range<usize>,
spans: &[Vec<(usize, usize, Style)>],
)
pub fn patch_syntax_spans_range( &mut self, rows: Range<usize>, spans: &[Vec<(usize, usize, Style)>], )
Patch only rows of the installed buffer_spans / styled_spans,
leaving rows outside that range untouched. spans is indexed by
row offset within rows — spans[0] is for rows.start,
spans[1] for rows.start + 1, etc.
Use this instead of Self::install_syntax_spans when a sync
query_viewport produced spans for the visible region only.
Walking the full line_count and re-installing every row on
every j/k that nudges the viewport dominated the per-keystroke
cost on large files; patching just the changed range keeps the
cost proportional to viewport size, not file size.
Ensures buffer_spans / styled_spans are sized to the buffer’s
current line_count (resizes if a row-count edit shifted them).
Sourcepub fn shift_syntax_spans_for_edits(&mut self, edits: &[ContentEdit])
pub fn shift_syntax_spans_for_edits(&mut self, edits: &[ContentEdit])
Translate the cached buffer_spans / styled_spans row indices
in-place to track a batch of crate::types::ContentEdits without
blanking the cache.
Why: spans are installed by the async syntax worker, which can lag
the buffer by one or more frames after an edit. If the edit changes
the row count and we keep the old span rows in place, the renderer
paints last-frame’s spans at the wrong line — visibly garbled colours.
The historical fix was to blank buffer_spans whenever a row-count
change came through, but that produces a white flash on every Enter
or backspace-at-BOL.
What this does instead: for each edit, insert empty span rows where the edit grew the buffer and drain rows where it shrank, so the surviving rows still index the right line. Spans on the edited row itself stay (they’ll show stale colours for that one row until the worker delivers a fresh parse, which is invisible compared to the blank flash).
Edits are applied in order — each edit’s (row, col) positions are
taken to be relative to the post-state of the prior edits in the
batch (matching the order the engine emitted them).
Sourcepub fn style_table(&self) -> &[Style]
pub fn style_table(&self) -> &[Style]
Read-only view of the style table in engine-native form —
id i → style_table[i]. Always available, no cfg gate.
Ratatui hosts that need a ratatui::style::Style slice should
use hjkl_engine_tui::EditorRatatuiExt::ratatui_style_table or
convert individual entries via hjkl_engine_tui::style_to_ratatui.
Sourcepub fn buffer_spans(&self) -> &[Vec<Span>]
pub fn buffer_spans(&self) -> &[Vec<Span>]
Per-row syntax span overlay, one Vec<Span> per buffer row.
Hosts feed this slice into [hjkl_buffer::BufferView::spans]
per draw frame.
0.0.37: replaces editor.buffer().spans() per step 3 of
DESIGN_33_METHOD_CLASSIFICATION.md. The buffer no longer
caches spans; they live on the engine and route through the
Host::syntax_highlights pipeline.
Sourcepub fn intern_style(&mut self, style: Style) -> u32
pub fn intern_style(&mut self, style: Style) -> u32
Intern a SPEC crate::types::Style and return its opaque id.
Engine-native — the unified style_table is always engine-native.
Linear-scan dedup — the table grows only as new tree-sitter token
kinds appear, so it stays tiny. Ratatui callers use
hjkl_engine_tui::EditorRatatuiExt::intern_ratatui_style which
converts at the boundary and delegates here.
Renamed from intern_engine_style in 0.0.32 — at 0.1.0 freeze
the unprefixed name is the universally-available engine-native
variant.
Sourcepub fn engine_style_at(&self, id: u32) -> Option<Style>
pub fn engine_style_at(&self, id: u32) -> Option<Style>
Look up an interned style by id and return it as a SPEC
crate::types::Style. Returns None for ids past the end
of the table.
Sourcepub fn push_buffer_cursor_to_textarea(&mut self)
pub fn push_buffer_cursor_to_textarea(&mut self)
Historical reverse-sync hook from when the textarea mirrored the buffer. Now that View is the cursor authority this is a no-op; call sites can remain in place during the migration.
Sourcepub fn set_viewport_top(&mut self, row: usize)
pub fn set_viewport_top(&mut self, row: usize)
Force the host viewport’s top row without touching the
cursor. Used by tests that simulate a scroll without the
SCROLLOFF cursor adjustment that scroll_down / scroll_up
apply.
0.0.34 (Patch C-δ.1): writes through Host::viewport_mut
instead of the (now-deleted) View::viewport_mut.
Sourcepub fn jump_cursor(&mut self, row: usize, col: usize)
pub fn jump_cursor(&mut self, row: usize, col: usize)
Set the cursor to (row, col), clamped to the buffer’s
content. Hosts use this for goto-line, jump-to-mark, and
programmatic cursor placement.
Resets sticky_col (curswant) to col — every explicit jump
(goto-line, jump-to-mark, search hit, click, ]d) follows vim
semantics. Only j/k/+/- READ sticky_col; everything
else resets it to the column where the cursor actually landed.
Sourcepub fn set_cursor_quiet(&mut self, row: usize, col: usize)
pub fn set_cursor_quiet(&mut self, row: usize, col: usize)
Set the cursor to (row, col) without modifying sticky_col.
Use this for host-side state restores (viewport sync, snapshot replay) where the cursor was already at this position semantically and the host’s sticky tracking should remain authoritative.
For user-facing jumps (goto-line, search hit, picker <CR>, ]d,
click), use Editor::jump_cursor which DOES reset sticky_col
per vim curswant semantics.
Sourcepub fn cursor(&self) -> (usize, usize)
pub fn cursor(&self) -> (usize, usize)
(row, col) cursor read sourced from the migration buffer.
Equivalent to self.textarea.cursor() when the two are in
sync — which is the steady state during Phase 7f because
every step opens with sync_buffer_content_from_textarea and
every ported motion pushes the result back. Prefer this over
self.textarea.cursor() so call sites keep working unchanged
once the textarea field is ripped.
Sourcepub fn char_at_cursor(&self) -> Option<char>
pub fn char_at_cursor(&self) -> Option<char>
The character under the cursor, or None at/after end of line (or on
an empty line). Used by callers that need vim’s on-blank distinctions
(e.g. cw only acts like ce when the cursor is on a non-blank).
Sourcepub fn take_lsp_intent(&mut self) -> Option<LspIntent>
pub fn take_lsp_intent(&mut self) -> Option<LspIntent>
Drain any pending LSP intent raised by the last key. Returns
None when no intent is armed.
Sourcepub fn take_fold_ops(&mut self) -> Vec<FoldOp>
pub fn take_fold_ops(&mut self) -> Vec<FoldOp>
Drain every crate::types::FoldOp raised since the last
call. Hosts that mirror the engine’s fold storage (or that
project folds onto a separate fold tree, LSP folding ranges,
…) drain this each step and dispatch as their own
crate::types::Host::Intent requires.
The engine has already applied every op locally against the
in-tree hjkl_buffer::View fold storage via
crate::buffer_impl::BufferFoldProviderMut, so hosts that
don’t track folds independently can ignore the queue
(or simply never call this drain).
Introduced in 0.0.38 (Patch C-δ.4).
Sourcepub fn apply_fold_op(&mut self, op: FoldOp)
pub fn apply_fold_op(&mut self, op: FoldOp)
Dispatch a crate::types::FoldOp through the canonical fold
surface: queue it for host observation (drained by
Editor::take_fold_ops) and apply it locally against the
in-tree buffer fold storage via
crate::buffer_impl::BufferFoldProviderMut. Engine call sites
(vim FSM z… chords, :fold* Ex commands, edit-pipeline
invalidation) route every fold mutation through this method.
Introduced in 0.0.38 (Patch C-δ.4).
Sourcepub fn sync_buffer_from_textarea(&mut self)
pub fn sync_buffer_from_textarea(&mut self)
Refresh the host viewport’s height from the cached
viewport_height_value(). Called from the per-step
boilerplate; was the textarea → buffer mirror before Phase 7f
put View in charge. 0.0.28 hoisted sticky_col out of
View. 0.0.34 (Patch C-δ.1) routes the height write through
Host::viewport_mut.
Sourcepub fn sync_buffer_content_from_textarea(&mut self)
pub fn sync_buffer_content_from_textarea(&mut self)
Was the full textarea → buffer content sync. View is the content authority now; this remains as a no-op so the per-step call sites don’t have to be ripped in the same patch.
Sourcepub fn record_jump(&mut self, pos: (usize, usize))
pub fn record_jump(&mut self, pos: (usize, usize))
Push a (row, col) onto the back-jumplist so Ctrl-o returns
to it later. Used by host-driven jumps (e.g. gd) that move
the cursor without going through the vim engine’s motion
machinery, where push_jump fires automatically.
Sourcepub fn set_viewport_height(&self, height: u16)
pub fn set_viewport_height(&self, height: u16)
Host apps call this each draw with the current text area height so scroll helpers can clamp the cursor without recomputing layout.
Sourcepub fn viewport_height_value(&self) -> u16
pub fn viewport_height_value(&self) -> u16
Last height published by set_viewport_height (in rows).
Sourcepub fn mutate_edit(&mut self, edit: Edit) -> Edit
pub fn mutate_edit(&mut self, edit: Edit) -> Edit
Apply edit against the buffer and return the inverse so the
host can push it onto an undo stack. Side effects: dirty
flag, change-list ring, mark / jump-list shifts, change_log
append, fold invalidation around the touched rows.
The primary edit funnel — both FSM operators and ex commands route mutations through here so the side effects fire uniformly.
Sourcepub fn mark_content_dirty(&mut self)
pub fn mark_content_dirty(&mut self)
Single choke-point for “the buffer just changed”. Sets the
dirty flag and drops the cached content_arc snapshot so
subsequent reads rebuild from the live textarea. Callers
mutating textarea directly (e.g. the TUI’s bracketed-paste
path) must invoke this to keep the cache honest.
Sourcepub fn take_dirty(&mut self) -> bool
pub fn take_dirty(&mut self) -> bool
Returns true if content changed since the last call, then clears the flag.
Sourcepub fn take_scroll_anim_hint(&mut self) -> bool
pub fn take_scroll_anim_hint(&mut self) -> bool
Drain the one-shot smooth-scroll hint (#195). True if the last step ran a page/recenter motion the app may animate.
Sourcepub fn jump_list(&self) -> (&[(usize, usize)], &[(usize, usize)])
pub fn jump_list(&self) -> (&[(usize, usize)], &[(usize, usize)])
Read-only view of the jumplist as (jump_back, jump_fwd). Newest entry
is at the back of each. Backs :jumps.
Sourcepub fn last_jump_back(&self) -> Option<(usize, usize)>
pub fn last_jump_back(&self) -> Option<(usize, usize)>
Position the cursor was at when the user last jumped back. None
before any jump.
Sourcepub fn jump_back_list(&self) -> &[(usize, usize)]
pub fn jump_back_list(&self) -> &[(usize, usize)]
Read-only view of the jump-back stack.
Sourcepub fn jump_back_list_mut(&mut self) -> &mut Vec<(usize, usize)>
pub fn jump_back_list_mut(&mut self) -> &mut Vec<(usize, usize)>
Mutable access to the jump-back stack.
Sourcepub fn jump_fwd_list(&self) -> &[(usize, usize)]
pub fn jump_fwd_list(&self) -> &[(usize, usize)]
Read-only view of the jump-forward stack.
Sourcepub fn jump_fwd_list_mut(&mut self) -> &mut Vec<(usize, usize)>
pub fn jump_fwd_list_mut(&mut self) -> &mut Vec<(usize, usize)>
Mutable access to the jump-forward stack.
Sourcepub fn viewport_pinned(&self) -> bool
pub fn viewport_pinned(&self) -> bool
Whether the viewport is pinned (suppresses scroll-follow).
Sourcepub fn set_viewport_pinned(&mut self, v: bool)
pub fn set_viewport_pinned(&mut self, v: bool)
Set the viewport-pinned flag.
Sourcepub fn set_pending_lsp(&mut self, intent: Option<LspIntent>)
pub fn set_pending_lsp(&mut self, intent: Option<LspIntent>)
Queue an LSP intent for the host to service on the next tick.
Sourcepub fn set_last_indent_range(&mut self, range: Option<(usize, usize)>)
pub fn set_last_indent_range(&mut self, range: Option<(usize, usize)>)
Record the row range touched by the most recent auto-indent, for the
host to pick up via take_last_indent_range.
Sourcepub fn change_list_cursor(&self) -> Option<usize>
pub fn change_list_cursor(&self) -> Option<usize>
Walk cursor into the change list (g; / g,), or None when not
walking.
Sourcepub fn set_change_list_cursor(&mut self, idx: Option<usize>)
pub fn set_change_list_cursor(&mut self, idx: Option<usize>)
Set the change-list walk cursor.
Sourcepub fn set_scroll_anim_hint(&mut self, v: bool)
pub fn set_scroll_anim_hint(&mut self, v: bool)
Arm the one-shot hint that the next scroll should be animated.
Sourcepub fn set_view_mode(&mut self, v: ViewMode)
pub fn set_view_mode(&mut self, v: ViewMode)
Set the read-only view overlay (Normal / Blame).
Sourcepub fn pending_closes(&self) -> &[(usize, usize, char)]
pub fn pending_closes(&self) -> &[(usize, usize, char)]
Autopair’s queued close-brackets, as (row, col, ch). A discipline’s
insert path consumes a queued close when the user types the matching
character instead of inserting a second one.
Sourcepub fn pending_closes_mut(&mut self) -> &mut Vec<(usize, usize, char)>
pub fn pending_closes_mut(&mut self) -> &mut Vec<(usize, usize, char)>
Mutable access to autopair’s queued close-brackets.
Sourcepub fn yank_linewise(&self) -> bool
pub fn yank_linewise(&self) -> bool
Whether the unnamed register’s content is linewise.
Sourcepub fn set_yank_linewise(&mut self, v: bool)
pub fn set_yank_linewise(&mut self, v: bool)
Set the linewise flag for the unnamed register.
Sourcepub fn search_prompt_state(&self) -> Option<&SearchPrompt>
pub fn search_prompt_state(&self) -> Option<&SearchPrompt>
The live / or ? search-prompt state, if a prompt is open.
Sourcepub fn search_prompt_state_mut(&mut self) -> Option<&mut SearchPrompt>
pub fn search_prompt_state_mut(&mut self) -> Option<&mut SearchPrompt>
Mutable access to the live search-prompt state.
Sourcepub fn take_search_prompt_state(&mut self) -> Option<SearchPrompt>
pub fn take_search_prompt_state(&mut self) -> Option<SearchPrompt>
Take (and close) the search-prompt state.
Sourcepub fn set_search_prompt_state(&mut self, prompt: Option<SearchPrompt>)
pub fn set_search_prompt_state(&mut self, prompt: Option<SearchPrompt>)
Install (or clear) the search-prompt state.
Sourcepub fn last_search_pattern(&self) -> Option<&str>
pub fn last_search_pattern(&self) -> Option<&str>
The last committed search pattern, for n / N (or Find Next).
Sourcepub fn set_last_search_pattern_only(&mut self, pattern: Option<String>)
pub fn set_last_search_pattern_only(&mut self, pattern: Option<String>)
Set the last search pattern without touching direction or highlight.
Sourcepub fn set_last_search_forward_only(&mut self, forward: bool)
pub fn set_last_search_forward_only(&mut self, forward: bool)
Set the last search direction without touching the pattern.
Sourcepub fn search_history(&self) -> &[String]
pub fn search_history(&self) -> &[String]
Read-only view of the search history (oldest first).
Sourcepub fn search_history_mut(&mut self) -> &mut Vec<String>
pub fn search_history_mut(&mut self) -> &mut Vec<String>
Mutable access to the search history.
Sourcepub fn search_history_cursor(&self) -> Option<usize>
pub fn search_history_cursor(&self) -> Option<usize>
Cursor position while walking search history with Up/Down.
Sourcepub fn set_search_history_cursor(&mut self, idx: Option<usize>)
pub fn set_search_history_cursor(&mut self, idx: Option<usize>)
Set the search-history walk cursor.
Sourcepub fn last_input_at(&self) -> Option<Instant>
pub fn last_input_at(&self) -> Option<Instant>
Instant of the last input, when the host supplies a monotonic clock.
Sourcepub fn set_last_input_at(&mut self, t: Option<Instant>)
pub fn set_last_input_at(&mut self, t: Option<Instant>)
Set the instant of the last input.
Sourcepub fn last_input_host_at(&self) -> Option<Duration>
pub fn last_input_host_at(&self) -> Option<Duration>
Host-supplied elapsed time at the last input (no_std hosts).
Sourcepub fn set_last_input_host_at(&mut self, d: Option<Duration>)
pub fn set_last_input_host_at(&mut self, d: Option<Duration>)
Set the host-supplied elapsed time at the last input.
Sourcepub fn viewport_half_rows(&self, count: usize) -> usize
pub fn viewport_half_rows(&self, count: usize) -> usize
Rows spanned by half a viewport, times count (min 1).
Sourcepub fn viewport_full_rows(&self, count: usize) -> usize
pub fn viewport_full_rows(&self, count: usize) -> usize
Rows spanned by a full viewport (less a two-line overlap), times
count (min 1).
Sourcepub fn scroll_cursor_rows(&mut self, delta: isize)
pub fn scroll_cursor_rows(&mut self, delta: isize)
Move the cursor delta rows (clamped to the buffer), landing on the
first non-blank of the target row and resetting the sticky column.
Sourcepub fn scroll_full_page(&mut self, dir: ScrollDir, count: usize)
pub fn scroll_full_page(&mut self, dir: ScrollDir, count: usize)
Scroll the cursor by one full viewport height (height − 2 rows,
preserving a two-line overlap). count multiplies the step.
Sourcepub fn scroll_half_page(&mut self, dir: ScrollDir, count: usize)
pub fn scroll_half_page(&mut self, dir: ScrollDir, count: usize)
Scroll the cursor by half the viewport height. count multiplies.
Sourcepub fn scroll_line(&mut self, dir: ScrollDir, count: usize)
pub fn scroll_line(&mut self, dir: ScrollDir, count: usize)
Scroll the viewport count lines without moving the cursor (the cursor
is clamped into the new visible region if it would fall outside).
Sourcepub fn take_content_edits(&mut self) -> Vec<ContentEdit>
pub fn take_content_edits(&mut self) -> Vec<ContentEdit>
Drain the queue of crate::types::ContentEdits emitted since
the last call. Each entry corresponds to a single buffer
mutation funnelled through Editor::mutate_edit; block edits
fan out to one entry per row touched.
Hosts call this each frame (after Editor::take_content_reset)
to fan edits into a tree-sitter parser via Tree::edit.
Sourcepub fn take_content_reset(&mut self) -> bool
pub fn take_content_reset(&mut self) -> bool
Returns true if a bulk buffer replacement happened since the
last call (e.g. set_content / restore / undo restore), then
clears the flag. When this returns true, hosts should drop
any retained syntax tree before consuming
Editor::take_content_edits.
Sourcepub fn take_content_change(&mut self) -> Option<Arc<String>>
pub fn take_content_change(&mut self) -> Option<Arc<String>>
Pull-model coarse change observation. If content changed since
the last call, returns Some(Arc<String>) with the new content
and clears the dirty flag; otherwise returns None.
Hosts that need fine-grained edit deltas (e.g., DOM patching at
the character level) should diff against their own previous
snapshot. The SPEC take_changes() -> Vec<EditOp> API lands
once every edit path inside the engine is instrumented; this
coarse form covers the pull-model use case in the meantime.
Sourcepub fn lnum_width(&self) -> u16
pub fn lnum_width(&self) -> u16
Width in cells of the line-number gutter for the current buffer
and settings. Matches what Editor::cursor_screen_pos reserves
in front of the text column. Returns 0 when both number and
relativenumber are off.
Sourcepub fn cursor_screen_row(&mut self, height: u16) -> u16
pub fn cursor_screen_row(&mut self, height: u16) -> u16
Returns the cursor’s row within the visible textarea (0-based), updating the stored viewport top so subsequent calls remain accurate.
Sourcepub fn cursor_screen_pos(
&self,
area_x: u16,
area_y: u16,
area_width: u16,
area_height: u16,
extra_gutter_width: u16,
) -> Option<(u16, u16)>
pub fn cursor_screen_pos( &self, area_x: u16, area_y: u16, area_width: u16, area_height: u16, extra_gutter_width: u16, ) -> Option<(u16, u16)>
Returns the cursor’s screen position (x, y) for the textarea
described by (area_x, area_y, area_width, area_height).
Accounts for line-number gutter, viewport scroll, and any extra
gutter width to the left of the number column (sign column, fold
column). Returns None if the cursor is outside the visible
viewport. Always available (engine-native; no ratatui dependency).
extra_gutter_width is added to the number-column width before
computing the cursor x position. Callers (e.g. apps/hjkl/src/render.rs)
pass sign_w + fold_w here so the cursor lands on the correct cell
when a dedicated sign or fold column is present.
Renamed from cursor_screen_pos_xywh in 0.0.32.
Sourcepub fn coarse_mode(&self) -> CoarseMode
pub fn coarse_mode(&self) -> CoarseMode
Discipline-agnostic coarse mode for app chrome (status badge, cursor
shape). App code that only needs “inserting / selecting / idle” — not the
precise vim mode — should read this so it works identically under any
keybinding discipline (vim, vscode, future helix/emacs). See
crate::CoarseMode (epic #265 G3). Today this projects from the vim
mode; once FSM state is pluggable each discipline supplies its own.
Sourcepub fn extra_selections(&self) -> &[Sel]
pub fn extra_selections(&self) -> &[Sel]
The secondary selections, in char columns. Empty for a single-cursor editor.
The primary selection is not included: its head is Editor::cursor
and its anchor lives in the discipline — see the extra_selections field
docs for why.
Sourcepub fn extra_cursors(&self) -> Vec<Position>
pub fn extra_cursors(&self) -> Vec<Position>
The heads of the secondary selections — the carets a user sees.
Convenience view over Editor::extra_selections for callers that only
care where the carets are (rendering, tests).
Sourcepub fn set_extra_selections(&mut self, sels: Vec<Sel>)
pub fn set_extra_selections(&mut self, sels: Vec<Sel>)
Replace the whole secondary set.
Selections whose head duplicates the primary head, or an earlier entry’s
head, are dropped: two carets on one spot would apply every edit twice at
the same place. Same invariant Editor::add_cursor enforces, applied to
a bulk write — a discipline recomputing every selection after a motion
(helix does this on every keystroke) must not be able to smuggle a
duplicate in through the back door.
Sourcepub fn add_selection(&mut self, sel: Sel)
pub fn add_selection(&mut self, sel: Sel)
Add a secondary selection. Same dedup rule as Editor::add_cursor.
Sourcepub fn add_cursor(&mut self, pos: Position)
pub fn add_cursor(&mut self, pos: Position)
Add a secondary cursor: a zero-width selection at pos. Ignores a
position that duplicates the primary head or an existing secondary head,
so a set never carries two carets at one spot — that would apply an edit
twice at the same place.
Sourcepub fn clear_extra_cursors(&mut self)
pub fn clear_extra_cursors(&mut self)
Drop every secondary selection, collapsing back to the primary.
Sourcepub fn edit_at_all_cursors(
&mut self,
make: impl Fn(Position) -> Edit,
) -> Vec<Edit>
pub fn edit_at_all_cursors( &mut self, make: impl Fn(Position) -> Edit, ) -> Vec<Edit>
Apply an edit at every cursor — the primary and all secondaries — and leave each cursor where its own edit left it (#63).
make is handed each cursor’s position and returns the edit to apply
there, so the caller writes the edit once and it fans out:
ed.edit_at_all_cursors(|at| Edit::InsertStr { at, text: "x".into() });Returns the inverse of each applied edit, in application order, so a
caller can push them as one undo step. This does not touch the undo
stack itself — mutate_edit never does, and a multi-cursor keystroke is
one user action, so the discipline pushes undo once before calling.
§Why the order matters
Edits are applied bottom-up (last cursor in the document first). An edit at position P only moves positions at or after P, so working backwards leaves every not-yet-visited cursor’s coordinates still valid. Going top-down would invalidate them all after the first edit.
Each cursor that has already been edited is parked in extra_cursors,
so Editor::mutate_edit’s shift keeps it correct as the remaining
(earlier) edits land. The bookkeeping is the same machinery, reused.
§Degradation
If any cursor becomes untrackable mid-apply (see selection_shift), the
secondaries are dropped and the editor collapses to the primary rather
than carrying on with a caret that no longer knows where it is.
Sourcepub fn edit_at_all_selections(
&mut self,
primary_anchor: Position,
make: impl Fn(Sel) -> Edit,
) -> (Vec<Edit>, Position)
pub fn edit_at_all_selections( &mut self, primary_anchor: Position, make: impl Fn(Sel) -> Edit, ) -> (Vec<Edit>, Position)
Apply an edit at every selection — the primary and all secondaries —
where make sees the whole selection, not just its head (#63).
This is what an operator needs: d on three selections has to delete
three ranges, and only the caller-visible Sel carries both ends.
Editor::edit_at_all_cursors is the caret-only special case of this.
primary_anchor is passed in — and the primary’s new anchor is returned
— because the primary selection’s anchor lives in the discipline’s state,
not the engine’s (see the extra_selections field docs).
Returns (inverse of each applied edit in application order, new primary anchor). This does not touch the undo stack — mutate_edit never
does, and a multi-cursor keystroke is one user action, so the discipline
pushes undo once before calling.
§Why the order matters
Edits are applied bottom-up (last selection in the document first). An edit at position P only moves positions at or after P, so working backwards leaves every not-yet-visited selection’s coordinates still valid. Going top-down would invalidate them all after the first edit.
Each selection that has already been edited is parked in
extra_selections, so Editor::mutate_edit’s shift keeps it correct as
the remaining (earlier) edits land.
§What happens to the anchors
Each selection’s anchor is shifted through its own edit with the same
insertion-point semantics crate::selection_shift uses everywhere: an
anchor swallowed by a deletion collapses onto the deletion start, which is
exactly where the head lands — so d / c leave a caret at each edit
site, with no bookkeeping. An anchor sitting exactly at an insertion point
slides right with the text. A caller that needs a selection preserved
across a same-length rewrite (helix’s ~, >) should re-set the
selections afterwards via Editor::set_extra_selections rather than
rely on that shift.
§Degradation
If any selection becomes untrackable mid-apply (see selection_shift), the
secondaries are dropped and the editor collapses to the primary rather than
carrying on with a selection that no longer knows where it is.
Sourcepub fn discipline(&self) -> &dyn DisciplineState
pub fn discipline(&self) -> &dyn DisciplineState
The installed discipline’s FSM state, type-erased.
A discipline crate reaches its own concrete state by downcasting:
ed.discipline().as_any().downcast_ref::<VimState>().
Sourcepub fn discipline_mut(&mut self) -> &mut dyn DisciplineState
pub fn discipline_mut(&mut self) -> &mut dyn DisciplineState
Mutable counterpart of Editor::discipline.
Sourcepub fn set_discipline(&mut self, discipline: Box<dyn DisciplineState>)
pub fn set_discipline(&mut self, discipline: Box<dyn DisciplineState>)
Install a keyboard discipline, replacing whatever was there.
Host apps call this once at construction (e.g.
hjkl_vim::install_vim_discipline(&mut ed)); an Editor that never
receives discipline input keeps the default
NoDiscipline.
Sourcepub fn view_mode(&self) -> ViewMode
pub fn view_mode(&self) -> ViewMode
The active read-only view overlay (see crate::ViewMode). Independent
of [Editor::vim_mode]; the host renderer reads this as the source of
truth for whether to draw the git-blame framing.
Sourcepub fn is_blame(&self) -> bool
pub fn is_blame(&self) -> bool
true when the git-blame read-only overlay is active. Masked on the
input mode: BLAME is only meaningful in Normal, so this returns false
the instant the editor enters Insert/Visual/etc., even before the
overlay flag is dropped. Use this for both rendering and mode-label.
Sourcepub fn enter_blame(&mut self)
pub fn enter_blame(&mut self)
Enter the git-blame read-only overlay. No-op unless the editor is in Normal mode (BLAME is a Normal-only view). While active, every mutation funnel is blocked and the host renders the per-commit framing.
Sourcepub fn exit_blame(&mut self)
pub fn exit_blame(&mut self)
Leave the git-blame overlay, returning to a plain Normal view. Idempotent.
Sourcepub fn search_prompt(&self) -> Option<&SearchPrompt>
pub fn search_prompt(&self) -> Option<&SearchPrompt>
Bounds of the active visual-block rectangle as
(top_row, bot_row, left_col, right_col) — all inclusive.
None when we’re not in VisualBlock mode.
Read-only view of the live / or ? prompt. None outside
search-prompt mode.
Sourcepub fn last_search(&self) -> Option<&str>
pub fn last_search(&self) -> Option<&str>
Most recent committed search pattern (persists across n / N
and across prompt exits). None before the first search.
Sourcepub fn last_search_forward(&self) -> bool
pub fn last_search_forward(&self) -> bool
Whether the last committed search was a forward / (true) or
a backward ? (false). n and N consult this to honour the
direction the user committed.
Sourcepub fn set_last_search(&mut self, text: Option<String>, forward: bool)
pub fn set_last_search(&mut self, text: Option<String>, forward: bool)
Set the most recent committed search text + direction. Used by
host-driven prompts (e.g. apps/hjkl’s / ? prompt that lives
outside the engine’s vim FSM) so n / N repeat the host’s
most recent commit with the right direction. Pass None /
true to clear.
Sourcepub fn last_substitute(&self) -> Option<&SubstituteCmd>
pub fn last_substitute(&self) -> Option<&SubstituteCmd>
The most recent successful :s command. None before the first substitute.
Used by :& / :&& to repeat it.
Sourcepub fn set_last_substitute(&mut self, cmd: SubstituteCmd)
pub fn set_last_substitute(&mut self, cmd: SubstituteCmd)
Store the last successful substitute so :& / :&& can repeat it.
Sourcepub fn row_count(&self) -> usize
pub fn row_count(&self) -> usize
Number of rows (lines) in the buffer.
Convenience accessor for call sites that only need the row count without
routing through the Query trait directly (e.g. the VSCode selection
dispatcher computing buffer-end positions).
Sourcepub fn line(&self, row: usize) -> Option<String>
pub fn line(&self, row: usize) -> Option<String>
Row row as an owned String (no trailing newline), or None when
row is out of bounds.
Mode-agnostic buffer read. Hosts and discipline crates (e.g. the vim
accessors on hjkl_vim::VimEditorExt) use this instead of reaching for
the engine’s private buf_line helper.
pub fn content(&self) -> String
Sourcepub fn content_arc(&mut self) -> Arc<String>
pub fn content_arc(&mut self) -> Arc<String>
Same logical output as [content], but returns a cached
Arc<String> so back-to-back reads within an un-mutated window
are ref-count bumps instead of multi-MB joins. The cache is
invalidated by every [mark_content_dirty] call.
pub fn set_content(&mut self, text: &str)
Sourcepub fn set_content_undoable(&mut self, text: &str)
pub fn set_content_undoable(&mut self, text: &str)
Whole-buffer replace that preserves the undo history.
Equivalent to Editor::set_content but pushes the current buffer
state onto the undo stack first, so a subsequent u walks back to
the pre-replacement content. Use this for any operation the user
expects to undo as a single step — e.g. external formatter output
(hjkl-mangler) installed via the async [crate::app::FormatWorker].
Like push_undo, this clears the redo stack (vim semantics: any
new edit invalidates redo).
Sourcepub fn take_changes(&mut self) -> Vec<Edit>
pub fn take_changes(&mut self) -> Vec<Edit>
Drain the pending change log produced by buffer mutations.
Returns a Vec<EditOp> covering edits applied since the last
call. Empty when no edits ran. Pull-model, complementary to
Editor::take_content_change which gives back the new full
content.
Mapping coverage:
- InsertChar / InsertStr → exact
EditOpwith empty range + replacement. - DeleteRange (
Charkind) → exact range + empty replacement. - Replace → exact range + new replacement.
- DeleteRange (
Line/Block), JoinLines, SplitLines, InsertBlock, DeleteBlockChunks → best-effort placeholder covering the touched range. Hosts wanting per-cell deltas should diff their ownlines()snapshot.
Sourcepub fn current_options(&self) -> Options
pub fn current_options(&self) -> Options
Read the engine’s current settings as a SPEC
crate::types::Options.
Bridges between the legacy Settings (which carries fewer
fields than SPEC) and the planned 0.1.0 trait surface. Fields
not present in Settings fall back to vim defaults (e.g.,
expandtab=false, wrapscan=true, timeout_len=1000ms).
Once trait extraction lands, this becomes the canonical config
reader and Settings retires.
Sourcepub fn apply_options(&mut self, opts: &Options)
pub fn apply_options(&mut self, opts: &Options)
Apply a SPEC crate::types::Options to the engine’s settings.
Only the fields backed by today’s Settings take effect;
remaining options become live once trait extraction wires them
through.
Sourcepub fn highlights_for_line(&mut self, line: u32) -> Vec<Highlight>
pub fn highlights_for_line(&mut self, line: u32) -> Vec<Highlight>
SPEC-typed highlights for line.
Two emission modes:
- IncSearch: the user is typing a
/or?prompt andEditor::search_promptisSome. Live-preview matches of the in-flight pattern surface ascrate::types::HighlightKind::IncSearch. - SearchMatch: the prompt has been committed (or absent)
and the buffer’s armed pattern is non-empty. Matches surface
as
crate::types::HighlightKind::SearchMatch.
Selection / MatchParen / Syntax(id) variants land once the
trait extraction routes the FSM’s selection set + the host’s
syntax pipeline through the crate::types::Host trait.
Returns an empty vec when there is nothing to highlight or
line is out of bounds.
Sourcepub fn render_frame(&self) -> RenderFrame
pub fn render_frame(&self) -> RenderFrame
Build the engine’s crate::types::RenderFrame for the
current state. Hosts call this once per redraw and diff
across frames.
Coarse today — covers mode + cursor + cursor shape + viewport
top + line count. SPEC-target fields (selections, highlights,
command line, search prompt, status line) land once trait
extraction routes them through SelectionSet and the
Highlight pipeline.
Sourcepub fn take_snapshot(&self) -> EditorSnapshot
pub fn take_snapshot(&self) -> EditorSnapshot
Capture the editor’s coarse state into a serde-friendly
crate::types::EditorSnapshot.
Today’s snapshot covers mode, cursor, lines, viewport top.
Registers, marks, jump list, undo tree, and full options arrive
once phase 5 trait extraction lands the generic
Editor<B: View, H: Host> constructor — this method’s surface
stays stable; only the snapshot’s internal fields grow.
Distinct from the internal snapshot used by undo (which
returns (Vec<String>, (usize, usize))); host-facing
persistence goes through this one.
Sourcepub fn restore_snapshot(
&mut self,
snap: EditorSnapshot,
) -> Result<(), EngineError>
pub fn restore_snapshot( &mut self, snap: EditorSnapshot, ) -> Result<(), EngineError>
Restore editor state from an [EditorSnapshot]. Returns
crate::EngineError::SnapshotVersion if the snapshot’s
version doesn’t match [EditorSnapshot::VERSION].
Mode is best-effort: SnapshotMode only round-trips the
status-line summary, not the full FSM state. Visual / Insert
mode entry happens through synthetic key dispatch when needed.
Sourcepub fn seed_yank(&mut self, text: String)
pub fn seed_yank(&mut self, text: String)
Install text as the pending yank buffer so the next p/P pastes
it. Linewise is inferred from a trailing newline, matching how yy/dd
shape their payload.
Sourcepub fn scroll_down(&mut self, rows: i16)
pub fn scroll_down(&mut self, rows: i16)
Scroll the viewport down by rows. The cursor stays on its
absolute line (vim convention) unless the scroll would take it
off-screen — in that case it’s clamped to the first row still
visible.
Sourcepub fn scroll_up(&mut self, rows: i16)
pub fn scroll_up(&mut self, rows: i16)
Scroll the viewport up by rows. Cursor stays unless it would
fall off the bottom of the new viewport, then clamp to the
bottom-most visible row.
Sourcepub fn scroll_right(&mut self, cols: i16)
pub fn scroll_right(&mut self, cols: i16)
Scroll the viewport right by cols columns. Only the horizontal
offset (top_col) moves — the cursor is NOT adjusted (matches
vim’s zl behaviour for horizontal scroll without wrap).
Sourcepub fn scroll_left(&mut self, cols: i16)
pub fn scroll_left(&mut self, cols: i16)
Scroll the viewport left by cols columns. Delegates to
scroll_right with a negated argument so the floor-at-zero
clamp is shared.
Sourcepub fn ensure_cursor_in_scrolloff(&mut self)
pub fn ensure_cursor_in_scrolloff(&mut self)
Scroll the viewport so the cursor stays at least scrolloff
rows from each edge. Replaces the bare
View::ensure_cursor_visible call at end-of-step so motions
don’t park the cursor on the very last visible row.
pub fn goto_line(&mut self, line: usize)
Sourcepub fn scroll_cursor_to(&mut self, pos: CursorScrollTarget)
pub fn scroll_cursor_to(&mut self, pos: CursorScrollTarget)
Scroll so the cursor row lands at the given viewport position:
Center → middle row, Top → first row, Bottom → last row.
Cursor stays on its absolute line; only the viewport moves.
Sourcepub fn jump_to(&mut self, line: usize, col: usize)
pub fn jump_to(&mut self, line: usize, col: usize)
Jump the cursor to the given 1-based line/column, clamped to the document.
Sourcepub fn set_cursor_doc(&mut self, row: usize, col: usize)
pub fn set_cursor_doc(&mut self, row: usize, col: usize)
Set the cursor to the given doc-space (row, col), clamped to the
document bounds. Hosts use this for programmatic cursor placement and
as the building block for the mouse-click path.
col may equal line.chars().count() (Insert-mode “one past end”
position); values beyond that are clamped to char_count.
Sourcepub fn mouse_extend_drag_doc(&mut self, row: usize, col: usize)
pub fn mouse_extend_drag_doc(&mut self, row: usize, col: usize)
Extend an in-progress mouse drag to doc-space (row, col).
Moves the live cursor; the Visual anchor stays where
[Editor::mouse_begin_drag] set it. Call after the host has
translated the drag position to doc coordinates.
pub fn insert_str(&mut self, text: &str)
pub fn accept_completion(&mut self, completion: &str)
Sourcepub fn undo(&mut self)
pub fn undo(&mut self)
Walk one step back through the undo history. Equivalent to the
user pressing u in normal mode. Drains the most recent undo
entry and pushes it onto the redo stack.
Sourcepub fn redo(&mut self)
pub fn redo(&mut self)
Walk one step forward through the redo history. Equivalent to
<C-r> in normal mode.
Sourcepub fn earlier_by_steps(&mut self, n: usize) -> usize
pub fn earlier_by_steps(&mut self, n: usize) -> usize
Undo n steps. Returns the number of steps actually applied
(bounded by undo stack size).
Sourcepub fn later_by_steps(&mut self, n: usize) -> usize
pub fn later_by_steps(&mut self, n: usize) -> usize
Redo n steps. Returns the number of steps actually applied
(bounded by redo stack size).
Sourcepub fn earlier_by_time(&mut self, target: SystemTime) -> usize
pub fn earlier_by_time(&mut self, target: SystemTime) -> usize
Undo back until the next-to-pop entry’s timestamp is at or before
target. Entries whose timestamp is strictly greater than target
are popped (undone). Returns the number of steps applied.
Vim :earlier Ns semantics: target = SystemTime::now() - N seconds.
Sourcepub fn later_by_time(&mut self, target: SystemTime) -> usize
pub fn later_by_time(&mut self, target: SystemTime) -> usize
Redo forward while the next-to-pop redo entry’s timestamp is at
or before target. Returns the number of steps applied.
Vim :later Ns semantics: target = current_state_time + N seconds.
Sourcepub fn push_undo(&mut self)
pub fn push_undo(&mut self)
Snapshot current buffer state onto the undo stack and clear
the redo stack. Bounded by settings.undo_levels — older
entries pruned. Call before any group of buffer mutations the
user might want to undo as a single step.
Sourcepub fn restore(&mut self, lines: Vec<String>, cursor: (usize, usize))
pub fn restore(&mut self, lines: Vec<String>, cursor: (usize, usize))
Replace the buffer with lines joined by \n and set the
cursor to cursor. Used by undo / :e! / snapshot restore
paths. Marks the editor dirty.
Emits a single whole-buffer ContentEdit describing the
transition so the syntax layer can apply it as an InputEdit
on the retained tree and run an INCREMENTAL parse — tree-sitter
reuses unchanged subtrees and Tree::changed_ranges reports
just the bytes that differ, which lets the install path walk
only the changed rows instead of the full viewport. Big undos
that revert a large paste now refresh in ~1ms per affected
row instead of a ~30ms full-viewport sync walk.
Sourcepub fn restore_rope(&mut self, rope: Rope, cursor: (usize, usize))
pub fn restore_rope(&mut self, rope: Rope, cursor: (usize, usize))
Restore the buffer from a ropey::Rope snapshot. Used by undo /
redo: snapshots are stored as Rope (O(1) Arc-clone via
View::rope()), so this avoids the full-document to_string
materialization that the old Arc<String> snapshot path forced
on every undo group boundary.
Internally materializes the rope to a String for restore_text
— paying the cost on the restore side instead of the snapshot
side trades one ~3 MB build per undo for none-per-snapshot. Undo
is user-initiated and rare; snapshots fire on every i / o.
Sourcepub fn take_last_indent_range(&mut self) -> Option<(usize, usize)>
pub fn take_last_indent_range(&mut self) -> Option<(usize, usize)>
Drain the row range set by the most recent auto-indent operation.
Returns Some((top_row, bot_row)) (inclusive) on the first call after
an = / == / =G / Visual-= operator, then clears the stored
value so a subsequent call returns None. The host (e.g. apps/hjkl)
uses this to arm a brief visual flash over the reindented rows.
Sourcepub fn filter_range(
&mut self,
top_row: usize,
bot_row: usize,
command: &str,
timeout_secs: Option<u64>,
) -> Result<(), String>
pub fn filter_range( &mut self, top_row: usize, bot_row: usize, command: &str, timeout_secs: Option<u64>, ) -> Result<(), String>
Filter rows top_row..=bot_row through an external shell command.
Spawns sh -c "<command>" (or cmd /C "<command>" on Windows), pipes
the selected lines (joined by \n) to stdin, and waits up to
timeout_secs seconds (default 10) for the process to finish.
On success: the rows are replaced with stdout. No trailing-newline trim.
On non-zero exit, spawn failure, or timeout: returns Err(stderr_or_msg)
without mutating the buffer.
top_row and bot_row are clamped to the buffer’s valid row range.
Sourcepub fn toggle_comment_range(&mut self, top_row: usize, bot_row: usize)
pub fn toggle_comment_range(&mut self, top_row: usize, bot_row: usize)
Toggle line comments on rows top_row..=bot_row (0-based, inclusive).
Algorithm (vim-commentary parity):
- Determine the comment marker(s) for the active filetype.
Priority:
settings.commentstring(:set commentstring=…) → per-filetype default fromhjkl_lang::comment::commentstring_for_lang→ no-op. - Scan non-blank lines. If every non-blank line is already commented → strip the comment marker from each. Otherwise → add it to all non-blank lines.
- Blank / whitespace-only lines are skipped (no marker added or removed).
- The marker is inserted AFTER the leading whitespace (indent-preserving).
- The entire operation is a single undo step.
For block-comment languages (HTML, CSS) each line is individually wrapped
as start text end (per-line block style, not one multi-line block).
top_row and bot_row are clamped to the buffer’s valid row range.
Source§impl<H: Host> Editor<View, H>
impl<H: Host> Editor<View, H>
Sourcepub fn add_abbrev(
&mut self,
lhs: &str,
rhs: &str,
insert: bool,
cmdline: bool,
noremap: bool,
)
pub fn add_abbrev( &mut self, lhs: &str, rhs: &str, insert: bool, cmdline: bool, noremap: bool, )
Register an abbreviation. If an entry for lhs already exists (same
mode flags), it is replaced. Inserts at the front so newer definitions
take priority (first-match wins in try_abbrev_expand).
Sourcepub fn remove_abbrev(&mut self, lhs: &str, insert: bool, cmdline: bool)
pub fn remove_abbrev(&mut self, lhs: &str, insert: bool, cmdline: bool)
Remove the abbreviation with the given lhs. Only removes entries
whose mode flags overlap with the requested insert/cmdline flags.
Sourcepub fn clear_abbrevs(&mut self, insert: bool, cmdline: bool)
pub fn clear_abbrevs(&mut self, insert: bool, cmdline: bool)
Clear all abbreviations matching the given mode flags.
insert=true removes insert-mode abbrevs; cmdline=true removes
cmdline-mode abbrevs. Both true clears everything.
Sourcepub fn push_search_pattern(&mut self, pattern: &str)
pub fn push_search_pattern(&mut self, pattern: &str)
Compile pattern into a regex and install it as the active search
pattern. Respects :set ignorecase / :set smartcase and inline
\c/\C overrides. An empty or invalid pattern clears the highlight
without raising an error.
Sourcepub fn push_jump(&mut self, from: (usize, usize))
pub fn push_jump(&mut self, from: (usize, usize))
Record a pre-jump cursor position onto the back jumplist. Called
before any “big jump” motion (gg/G, %, */#, n/N,
committed / or ?, …). Branching off the history clears the
forward half, matching vim’s “redo-is-lost” semantics.
Sourcepub fn record_search_history(&mut self, pattern: &str)
pub fn record_search_history(&mut self, pattern: &str)
Push pattern onto the committed search history. Skips if the
most recent entry already matches (consecutive dedupe) and trims
the oldest entries beyond the history cap.
Sourcepub fn walk_search_history(&mut self, dir: isize)
pub fn walk_search_history(&mut self, dir: isize)
Walk the search-prompt history by dir steps. dir = -1 moves
toward older entries (Ctrl-P / Up); dir = 1 toward newer ones
(Ctrl-N / Down). Stops at the ends; does nothing if there is no
active search prompt.
Sourcepub fn line_char_count(&self, row: usize) -> usize
pub fn line_char_count(&self, row: usize) -> usize
Return the character count (code-point count) of line row, or 0
when row is out of range.
A raw buffer read with no vim semantics, so it stays on the engine core
while the vim-specific visual/block primitives move to
hjkl_vim::VimEditorExt (#267).