Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CodeEditorHandle

CodeEditorHandle preview

Multi-line plain-text and code editing surfaces.

Public types

KindName
structCodeEditorHandle — A handle onto a live editor, cloneable and detachable from the widget
structCompletionItem — A completion candidate
enumCompletionKind — The category of a completion candidate — drives a small leading badge only
structCompletionContext — What a completion provider is told about the caret when asked for candidates
enumIndentStyle — How a line's leading indentation is written
structBracketPair — A pair of characters the editor treats as opening and closing delimiters
constCOMMON_BRACKETS — The three pairs that are structural in essentially every bracketed language
structCodeConfig — Editing behaviour the code editor applies, all supplied by the application

Public functions

CodeEditorHandle

ReturnsFunction
Methods
usizecursor_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()
boolis_read_only()
teksilo_core::Signal<bool>can_redo()
teksilo_core::Signal<u64>document_version()
teksilo_core::Signal<f32>scroll_y()

CompletionItem

IndentStyle

ReturnsFunction
Methods
Stringunit()
u8width()

BracketPair

ReturnsFunction
Constructors
Selfnew(open: char, close: char)

CodeConfig

ReturnsFunction
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

CodeEditorHandle at Touch density

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 to label.
  • 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

  • Text
  • Keyword
  • Function
  • Method
  • Variable
  • Field
  • Type
  • Module
  • Constant
  • Snippet

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) — width spaces per indent level.
  • Tabs { width: u8 } — One tab character per level, rendered width columns 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: char
  • close: 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 ("//", "#", "--", ";"). None disables CodeCommand::ToggleLineComment entirely 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.