Skip to content

micro

micro is a “modern and intuitive terminal-based text editor” positioned as a successor to nano: easy to use, no config required to start, but deeply customizable. It ships as a single batteries-included static binary. Core capabilities: splits and tabs, mouse support (drag to select, double-click word, triple-click line), syntax highlighting for 130+ languages, multiple cursors, persistent undo, a command bar (Ctrl-e), and — the part that matters most here — a nano-like bottom menu that reminds you of the keybindings, plus a built-in Lua plugin system with a plugin manager that installs/removes/updates plugins.

Default keybindings are the familiar desktop set — Ctrl-s save, Ctrl-c/v copy/paste, Ctrl-z undo, Ctrl-e command mode — and every binding is rebindable via bindings.json.

micro is the cleanest worked example of two things KN-86 has already committed to but hasn’t fully systematized: a persistent bottom key-hint bar and a host-language plugin layer with a small, well-bounded API surface.

  • Bottom key-hint bar → KN-86’s firmware action bar. micro’s nano-style bar advertises the current contextual keybindings at the bottom of the screen. KN-86’s bottom firmware row is exactly this slot (see software/cartridges/authoring/screen-design-rules.md — the bottom firmware row is reserved, never drawn on by cartridges). The REPL spec already mandates a permanent bottom-row advertisement of the TERM key (software/runtime/repl.md). micro is the precedent for generalizing that into a context-sensitive key-hint strip: the bottom firmware row should always show the live, surface-specific bindings (mission board vs. REPL vs. cart content vs. nEmacs), the way micro’s bar changes with focus. The Ferris Sweep’s context-sensitive TERM key (per Canonical Hardware Specification) makes this even more necessary — when one physical key means different things by surface, the bottom row is where the operator reads what it means right now.
  • Splits + tabs as a layout vocabulary. micro’s split-pane + tab-strip model is the standard multi-buffer terminal UI. KN-86 is single-surface today, but nEmacs and the REPL both raise the “two things on screen at once” question (edit buffer + evaluation output). micro’s splits are the reference IA.
  • Plugin manager UX. micro’s > plugin install <name> flow is a model for how KN-86 cartridges-as-capability-modules could eventually be browsed/installed from the SYS surface, not just hot-swapped physically.

micro leans on syntax-highlight color to communicate structure; KN-86 cannot. The portable lessons are the non-color ones, which is most of micro’s value here:

  • The bottom key-hint bar carries zero color dependency — it’s text in fixed screen positions. It ports to amber-on-black untouched. The hint bar communicates by position and wording, which is exactly the single-color reframing KN-86 needs (shape/position/character over hue).
  • Where micro uses color to mark the active split or selected tab, KN-86 substitutes inversion (amber-on-black ↔ black-on-amber for the focused pane/tab) and bracket/marker glyphs ([ ], ) for the inactive ones — the inversion-for-focus pattern is already the KN-86 idiom.
  • micro’s syntax highlighting, ported to monochrome, becomes the character-density / weight problem: comments dim (sparse glyph or trailing-space treatment), keywords bold (a heavier CP437 glyph or inversion). This is the same problem the REPL and nEmacs already face; micro is a concrete reference for which token classes deserve distinct treatment.

micro’s Lua plugin system is the headline cross-read for KN-86’s KEC Lisp cartridge/extension model (ADR-0001 / ADR-0005 NoshAPI). The architecture maps almost one-to-one:

  • Lifecycle hooks. Plugins define preinit() / init() / postinit() / deinit(). KN-86 cartridges already have load/reset boundaries (arena reset at cart-load and mission-instance boundaries per ADR-0004); micro’s named lifecycle is a cleaner public contract than KN-86 currently documents for cart Lisp.
  • Event callbacks return a boolean to control chaining. micro exposes onAction(bufpane), preAction(bufpane) (return false to cancel the action), onRune / preRune (intercept character insertion), onBufferOpen, onBufPaneOpen, onSetActive, onAnyEvent. This pre/on + cancel-by-return pattern is exactly what KN-86’s input-dispatch event model (software/runtime/input-dispatch.md) wants for letting cart Lisp intercept or veto key events before the runtime handles them.
  • Command + key registration from the plugin side. config.MakeCommand(name, fn, completer) registers a named command (with tab-completers: FileComplete, OptionComplete, NoComplete, …); config.TryBindKey(key, action, overwrite) binds a key. KN-86’s REPL/nEmacs surfaces should expose the equivalent: cart Lisp registering named commands and (sandboxed) key actions into the runtime’s dispatch table.
  • A small, curated module surface exposed to the host language. Plugins import("micro"), import("micro/config"), import("micro/buffer"), import("micro/shell"), import("micro/util") — a deliberately bounded set of namespaced Go modules, not the whole Go stdlib by default. This is precisely the NoshAPI design philosophy (ADR-0005: 54 curated C primitives exposed as Lisp builtins, cart authors never touch C). micro validates the approach: namespace the FFI by domain (micro/buffer ≈ a KN-86 nosh/grid or nosh/state namespace) rather than dumping every primitive into one flat global.
  • Status-line injection. micro.SetStatusInfoFn(fn) lets a plugin register a Lua function whose return value appears in the statusline format. KN-86’s equivalent would let a cart contribute a fragment to the top firmware status row (within the firmware-owned-row contract) — a small, bounded write surface rather than free drawing.

The one place KN-86 diverges deliberately: micro plugins can reach os, net/http, io from Lua. KN-86’s Fe VM is arena-allocated with no GC and a closed FFI — cart Lisp gets the curated NoshAPI and nothing else. micro is the “what a generous plugin host looks like” reference; KN-86 takes the shape (lifecycle + namespaced modules + register-command/key + pre/on event hooks) and clamps the reach.

  • Batch 8. Lead reference for the bottom-key-hint-bar cluster.
  • Strongest extension-architecture takeaway of the batch: micro’s import("micro/...") namespaced module pattern is a direct argument for namespacing NoshAPI (ADR-0005) by domain rather than flat.
  • Cross-link opentui.md — OpenTUI is the framework-level take on terminal components (focus stack, component set); micro is the application-level take on plugin hooks. Read together for “what primitives + what hooks.”
  • Cross-link microsoft-edit.md — Edit deliberately omits a plugin system for now but designed its immediate-mode UI around a future C-ABI plugin layer; micro is the working Lua-plugin counterpoint. The pair frames the “how much extension surface, and through what ABI” decision for KN-86.
  • Cross-link maki.md and nino.md for the minimal-chrome / single-binary end of the same editor spectrum.

micro editor with splits and the nano-style key-hint bar

TODO (human): Pull a screenshot from the micro README showing splits/tabs and the bottom nano-style key-hint bar in one frame. Drop at inspiration/screenshots/micro.png. The bottom hint bar is the element this entry hinges on — make sure it’s visible.