CodeEditorHandle

Multi-line plain-text and code editing surfaces.
Public types
| Kind | Name |
|---|---|
struct | CodeEditorHandle — A handle onto a live editor, cloneable and detachable from the widget |
struct | CompletionItem — A completion candidate |
enum | CompletionKind — The category of a completion candidate — drives a small leading badge only |
struct | CompletionContext — What a completion provider is told about the caret when asked for candidates |
enum | IndentStyle — How a line's leading indentation is written |
struct | BracketPair — A pair of characters the editor treats as opening and closing delimiters |
const | COMMON_BRACKETS — The three pairs that are structural in essentially every bracketed language |
struct | CodeConfig — Editing behaviour the code editor applies, all supplied by the application |
Public functions
CodeEditorHandle
| Returns | Function |
|---|---|
| Methods | |
usize | cursor_position() |
teksilo_core::Signal<usize> | cursor_position_signal() |
teksilo_core::Signal<usize> | caret_count() |
teksilo_core::Signal<Option<(usize, usize)>> | bracket_match() |
teksilo_core::Signal<bool> | has_selection() |
teksilo_core::Signal<bool> | can_undo() |
undo() | |
redo() | |
copy(ctx: &teksilo_core::widget::EventContext<'_>) | |
cut(ctx: &teksilo_core::widget::EventContext<'_>) | |
paste(ctx: &teksilo_core::widget::EventContext<'_>) | |
select_all() | |
bool | is_read_only() |
teksilo_core::Signal<bool> | can_redo() |
teksilo_core::Signal<u64> | document_version() |
teksilo_core::Signal<f32> | scroll_y() |
CompletionItem
| Returns | Function |
|---|---|
| Constructors | |
Self | new(label: impl Into<String>) |
| Builder methods | |
Self | insert_text(text: impl Into<String>) |
Self | detail(detail: impl Into<String>) |
Self | kind(kind: CompletionKind) |
IndentStyle
BracketPair
| Returns | Function |
|---|---|
| Constructors | |
Self | new(open: char, close: char) |
CodeConfig
| Returns | Function |
|---|---|
| Methods | |
Option<char> | closing_for(open: char) |
Option<char> | opening_for(close: char) |
Detailed description
Three faces over one core:
CodeEditor— a source editor: gutter, current-line highlight, indentation, bracket handling, multiple carets.PlainTextEditor— the same core with the code affordances off and wrapping on: a notes field, a commit message, a description box.LogView— read-only, append-only, tail-following.
They are one implementation because they differ in configuration, not in kind. All three are a monospaced-or-not run of lines with a caret in it; a separate widget per face would triplicate the caret, selection, IME, clipboard, scrolling, and accessibility and let them drift.
Why not RichTextEditor
RichTextEditor already edits multi-line text, and this deliberately does
not build on it. Its command vocabulary is tables, lists, blockquotes, and
bold — reusing it would put Tab-navigates-a-table-cell and
Ctrl+B-emboldens into a source file, where the first is wrong and the second
is meaningless. Its state carries a table-aware Ctrl+A ladder and a rich
clipboard fragment; this one carries an indent policy and a caret vector.
The overlap is real but it is the clock — the caret blink, the debounce
window, the scroll arithmetic — and that lives in the crate-internal
common::editor_runtime, shared by both.
Language-agnostic by construction
There is no Language enum here. Comment tokens, bracket pairs, indent
width, and highlighting are CodeConfig values the application supplies:
the editor knows how to toggle a line comment, not that Rust uses //.
Guessing would be worse than not knowing — inserting // into a Python file
corrupts it silently.
Density
The picture above is the widget at TargetDensity::Compact, the mouse-and-keyboard ladder. Below is the same subject on the same canvas with only the ladder changed, so what moves is the density and nothing else — where the subject no longer fits, that is what the denser targets cost it at that size. See docs/density-and-targets.md.
Touch

API reference
📖 Full rustdoc API for this module
pub struct CodeEditorHandle
Import: use teksilo::widgets::CodeEditorHandle;
A handle onto a live editor, cloneable and detachable from the widget.
The EditorHandle pattern: an app keeps one to drive the editor from a
toolbar, a shortcut, or a test without holding the widget itself.
#![allow(unused)] fn main() { pub struct CodeEditorHandle { /* fields */ } }
Methods
pub fn cursor_position(&self) -> usize
The caret's document position.
pub fn cursor_position_signal(&self) -> teksilo_core::Signal<usize>
The primary caret's document position — a character offset into the whole document, not a line or column — as a reactive signal. Bind it in a status bar to show a caret position that tracks every caret move, not only edits.
pub fn caret_count(&self) -> teksilo_core::Signal<usize>
Live caret count — 1 unless multi-caret editing is active.
pub fn bracket_match(&self) -> teksilo_core::Signal<Option<(usize, usize)>>
The bracket next to the caret and its match, as document positions, or
None. Populated only when the editor was configured with
match_brackets and bracket pairs; a status surface can bind it, or an
app can read it to drive its own overlay.
pub fn has_selection(&self) -> teksilo_core::Signal<bool>
pub fn can_undo(&self) -> teksilo_core::Signal<bool>
pub fn undo(&self)
Undo this editor's last edit.
The handle could report can_undo long before it could
act on it, which left a host able to light an Undo button here and
unable to make it do anything. Ctrl+Z inside the widget always worked;
this is the same command from outside.
pub fn redo(&self)
Redo this editor's last undone edit.
pub fn copy(&self, ctx: &teksilo_core::widget::EventContext<'_>)
Copy the selection to the clipboard.
pub fn cut(&self, ctx: &teksilo_core::widget::EventContext<'_>)
Cut the selection to the clipboard.
pub fn paste(&self, ctx: &teksilo_core::widget::EventContext<'_>)
Paste over the selection.
pub fn select_all(&self)
Select the whole document.
pub fn is_read_only(&self) -> bool
Is this editor refusing edits?
pub fn can_redo(&self) -> teksilo_core::Signal<bool>
pub fn document_version(&self) -> teksilo_core::Signal<u64>
Bumps on every content or format change.
pub fn scroll_y(&self) -> teksilo_core::Signal<f32>
pub struct CompletionItem
Import: none — CompletionItem is public in a private module of teksilo-widgets and nothing re-exports it.
A completion candidate. Build with CompletionItem::new and the fluent
setters; insert_text defaults to label.
#![allow(unused)] fn main() { pub struct CompletionItem { /* fields */ } }
Fields
label:String— The text shown in the list.insert_text:String— The text that replaces the word being completed when accepted. Defaults tolabel.detail:Option<String>— Optional dimmed detail shown at the trailing edge of the row (a type, a signature, a source).kind:CompletionKind— A category driving the row's leading badge — purely visual, no behaviour.
Methods
pub fn new(label: impl Into<String>) -> Self
A candidate whose inserted text is its label.
pub fn insert_text(mut self, text: impl Into<String>) -> Self
Override the text inserted on accept (when it differs from the label).
pub fn detail(mut self, detail: impl Into<String>) -> Self
Trailing dimmed detail (a type or signature).
pub fn kind(mut self, kind: CompletionKind) -> Self
The leading badge category.
pub enum CompletionKind
Import: none — CompletionKind is public in a private module of teksilo-widgets and nothing re-exports it.
The category of a completion candidate — drives a small leading badge only. Deliberately a fixed, language-neutral set: the editor renders a glyph, the application decides which candidate is which kind.
#![allow(unused)] fn main() { pub enum CompletionKind { /* variants */ } }
Variants
TextKeywordFunctionMethodVariableFieldTypeModuleConstantSnippet
pub struct CompletionContext
Import: none — CompletionContext is public in a private module of teksilo-widgets and nothing re-exports it.
What a completion provider is told about the caret when asked for candidates.
#![allow(unused)] fn main() { pub struct CompletionContext<'a> { /* fields */ } }
Fields
prefix:&'a str— The identifier characters immediately before the caret.line:&'a str— The whole current line.column:usize— The caret's column within the line (character index).position:usize— The caret's absolute document position.
pub enum IndentStyle
Import: none — IndentStyle is public in a private module of teksilo-widgets and nothing re-exports it.
How a line's leading indentation is written.
#![allow(unused)] fn main() { pub enum IndentStyle { /* variants */ } }
Variants
Spaces(u8)—widthspaces per indent level.Tabs{ width: u8 }— One tab character per level, renderedwidthcolumns wide.
Methods
pub fn unit(&self) -> String
The text one indent level inserts.
pub fn width(&self) -> u8
How many columns one level occupies on screen. Both styles need this: spaces to know how many to strip on dedent, tabs to render the stop.
pub struct BracketPair
Import: none — BracketPair is public in a private module of teksilo-widgets and nothing re-exports it.
A pair of characters the editor treats as opening and closing delimiters.
Used for auto-closing and for match highlighting. The application declares
the set, because the same character means different things per language:
< is a bracket in a generic parameter list and a less-than sign in
arithmetic, and only the caller knows which document this is.
#![allow(unused)] fn main() { pub struct BracketPair { /* fields */ } }
Fields
open:charclose:char
Methods
pub const fn new(open: char, close: char) -> Self
pub const COMMON_BRACKETS
Import: none — COMMON_BRACKETS is public in a private module of teksilo-widgets and nothing re-exports it.
The three pairs that are structural in essentially every bracketed language. A convenience starting point, not a default — an editor with no configured pairs simply does no bracket handling, which is correct for prose or a log.
#![allow(unused)] fn main() { pub const COMMON_BRACKETS: &[BracketPair] = &[ BracketPair::new('(', ')'), BracketPair::new('[', ']'), BracketPair::new('{', '}'), ]; }
pub struct CodeConfig
Import: none — CodeConfig is public in a private module of teksilo-widgets and nothing re-exports it.
Editing behaviour the code editor applies, all supplied by the application.
#![allow(unused)] fn main() { pub struct CodeConfig { /* fields */ } }
Fields
indent:IndentStyle— How indentation is written and how wide a level is.auto_indent:bool— Whether Enter carries the current line's leading whitespace onto the new line.line_comment:Option<String>— Token that starts a line comment ("//","#","--",";").NonedisablesCodeCommand::ToggleLineCommententirely rather than guessing.brackets:Vec<BracketPair>— Delimiter pairs for auto-closing and match highlighting. Empty disables both.auto_close_brackets:bool— Whether typing an opening delimiter inserts its closing partner.match_brackets:bool— Whether the delimiter matching the caret's is highlighted.
Methods
pub fn closing_for(&self, open: char) -> Option<char>
The closing partner for open, if it is a configured opening delimiter.
pub fn opening_for(&self, close: char) -> Option<char>
The opening partner for close, if it is a configured closing delimiter.