idet-core 0.4.0

Editing logic for text editors, without a frontend
Documentation
# Idet Core — editing logic for text editors, without a frontend

Word autocomplete, line moves, word swaps, indentation edits, find and replace,
bracket-pair matching, soft wrapping and syntax classification. The editing
modules are pure functions — each takes a `&str` and a character index and
returns a new string and cursor position (or a range). Drive them from a
terminal UI, an egui widget, or anything else that owns the text buffer and the
keybindings.

Built for [idet](https://gitlab.com/porky11/idet), a terminal editor, and its
egui-based sibling `gidet`, sharing one editing core between two very different
frontends.

## Modules

- **`completion`** — word collection and prefix/whole-word matching for
  autocomplete (`collect_words`, `current_word`, `matches`).
- **`edits`** — insertion, indentation and newline-with-autoindent, plus
  line-start/line-end lookup (`insert`, `newline_indent`, `indent_line`,
  `dedent_line`, `line_start_char`, `line_end_char`).
- **`lineops`** — moving the current line up or down, and translating between
  character offsets and line/column coordinates (`move_line`, `line_column`,
  `cursor_at`).
- **`wordops`** — swapping the word at the cursor with an adjacent word
  (`swap`).
- **`brackets`** — finding the matching bracket for `()`, `[]` or `{}` at or
  near the cursor (`find_matching_bracket`).
- **`search`** — case-insensitive literal find and replace (`find_matches`,
  `replace_range`, `replace_all`).
- **`wrap`** — laying text out in screen rows at a given width, with or without
  soft wrapping, and mapping between rows and character positions (`rows`,
  `visible_end`, `locate`).
- **`syntax`** — highlighting classes for a language, read from plain-text
  definition files under `$XDG_CONFIG_HOME/idet/syntax` (`Syntax`, `Class`,
  `for_path`).
- **`options`** — the settings both frontends share, stored one option per line
  under `$XDG_CONFIG_HOME/idet/options.conf` (`Options`).
- **`files`** (behind the `files` feature, off by default) — saving and opening
  a named path on top of [`document-state`]https://crates.io/crates/document-state,
  reporting the outcome rather than deciding for the host.
- **`dialogs`** (behind the `dialogs` feature, off by default) — the same
  operations asking for the path through a native
  [rfd]https://github.com/PolyMeilex/rfd dialog first. Both frontends use it;
  a host without a desktop session to show a dialog on can take `files` alone
  and ask for the path however it likes.
- **`widget`** (behind the `egui` feature, off by default) — a drop-in
  `egui::TextEdit`-based multiline editor wired to the modules above:
  move-line, swap-word, indent/dedent, auto-indent, word autocomplete and
  find. Enable with `idet-core = { version = "...", features = ["egui"] }`.
  Application-specific concerns (save/undo/reload, window chrome, tabs) stay
  the host's responsibility — the widget only owns the text buffer it's
  handed each frame.

## Design

Every editing operation is a pure function over character indices, not byte
offsets — callers don't need to think about UTF-8 boundaries. The modules that
do touch the disk (`options`, `syntax`, `files`) are separate from them and, in
the case of `files`, behind a feature. Multi-cursor editing is the
caller's responsibility: run the same operation once per cursor, in descending
position order, shifting later cursors by the delta each edit produces.