Implement vim-style line editor using terminal FFI #52

Closed
opened 2026-01-18 20:03:27 +00:00 by navicore · 1 comment
navicore commented 2026-01-18 20:03:27 +00:00 (Migrated from github.com)

Background

Seq now has terminal FFI primitives (patch-seq v1.0.5+) that enable building interactive terminal applications in pure Seq:

Builtin Stack Effect Description
terminal.raw-mode ( Bool -- ) Enable/disable raw terminal mode
terminal.read-char ( -- Int ) Read single byte (blocking)
terminal.read-char? ( -- Int ) Read single byte (non-blocking)
terminal.width ( -- Int ) Get terminal width
terminal.height ( -- Int ) Get terminal height
terminal.flush ( -- ) Flush stdout

This enables replacing the current libedit-based REPL with a vim-style editor written in pure Seq.

Goal

Implement vim-style line editing for the seq-lisp REPL, similar to vim-line in seq-repl but written entirely in Seq.

Features

Phase 1: Basic Modal Editing

  • Normal mode (default)
  • Insert mode (i, a, A, I)
  • Escape to return to normal mode
  • Basic cursor movement (h, l, 0, $)
  • Backspace and delete (x)
  • Enter to submit

Phase 2: Vim Motions

  • Word motions (w, b, e)
  • Line navigation (^, g_)
  • Character find (f, F, t, T)

Phase 3: Operators

  • Delete with motion (d + motion, dd)
  • Change with motion (c + motion, cc)
  • Yank (y + motion, yy, p, P)

Phase 4: Polish

  • Visual mode (v)
  • Command history (up/down in normal mode, or j/k)
  • Status line showing mode
  • Undo (u) - at least single level

Implementation Notes

Architecture

  • State machine for modes (normal, insert, visual, operator-pending)
  • Text buffer as String with cursor position as Int
  • Render loop: clear line, write text, position cursor, flush

ANSI Escape Codes

"\e[2K"      # Clear entire line
"\e[G"       # Move cursor to column 1
"\e[{n}C"    # Move cursor right n columns
"\e[{n}D"    # Move cursor left n columns

Key Detection

  • Regular chars: 32-126
  • Escape: 27 (need to disambiguate from escape sequences)
  • Backspace: 127 or 8
  • Enter: 13 or 10
  • Arrow keys: escape sequences (\e[A, \e[B, \e[C, \e[D)
  • patch-seq#274 - Terminal FFI implementation (DONE)
  • Inspired by vim-line crate in seq-repl

Why Pure Seq

  • Keeps seq-lisp as a pure Seq project (no Rust dependencies beyond Seq itself)
  • Educational value - implementing vim motions in a stack-based language
  • Reusable - could become a standalone Seq library for other projects
## Background Seq now has terminal FFI primitives (patch-seq v1.0.5+) that enable building interactive terminal applications in pure Seq: | Builtin | Stack Effect | Description | |---------|--------------|-------------| | `terminal.raw-mode` | `( Bool -- )` | Enable/disable raw terminal mode | | `terminal.read-char` | `( -- Int )` | Read single byte (blocking) | | `terminal.read-char?` | `( -- Int )` | Read single byte (non-blocking) | | `terminal.width` | `( -- Int )` | Get terminal width | | `terminal.height` | `( -- Int )` | Get terminal height | | `terminal.flush` | `( -- )` | Flush stdout | This enables replacing the current libedit-based REPL with a vim-style editor written in pure Seq. ## Goal Implement vim-style line editing for the seq-lisp REPL, similar to vim-line in seq-repl but written entirely in Seq. ## Features ### Phase 1: Basic Modal Editing - [ ] Normal mode (default) - [ ] Insert mode (`i`, `a`, `A`, `I`) - [ ] Escape to return to normal mode - [ ] Basic cursor movement (`h`, `l`, `0`, `$`) - [ ] Backspace and delete (`x`) - [ ] Enter to submit ### Phase 2: Vim Motions - [ ] Word motions (`w`, `b`, `e`) - [ ] Line navigation (`^`, `g_`) - [ ] Character find (`f`, `F`, `t`, `T`) ### Phase 3: Operators - [ ] Delete with motion (`d` + motion, `dd`) - [ ] Change with motion (`c` + motion, `cc`) - [ ] Yank (`y` + motion, `yy`, `p`, `P`) ### Phase 4: Polish - [ ] Visual mode (`v`) - [ ] Command history (up/down in normal mode, or `j`/`k`) - [ ] Status line showing mode - [ ] Undo (`u`) - at least single level ## Implementation Notes ### Architecture - State machine for modes (normal, insert, visual, operator-pending) - Text buffer as String with cursor position as Int - Render loop: clear line, write text, position cursor, flush ### ANSI Escape Codes ```seq "\e[2K" # Clear entire line "\e[G" # Move cursor to column 1 "\e[{n}C" # Move cursor right n columns "\e[{n}D" # Move cursor left n columns ``` ### Key Detection - Regular chars: 32-126 - Escape: 27 (need to disambiguate from escape sequences) - Backspace: 127 or 8 - Enter: 13 or 10 - Arrow keys: escape sequences (`\e[A`, `\e[B`, `\e[C`, `\e[D`) ## Related - patch-seq#274 - Terminal FFI implementation (DONE) - Inspired by vim-line crate in seq-repl ## Why Pure Seq - Keeps seq-lisp as a pure Seq project (no Rust dependencies beyond Seq itself) - Educational value - implementing vim motions in a stack-based language - Reusable - could become a standalone Seq library for other projects
navicore commented 2026-02-01 02:09:25 +00:00 (Migrated from github.com)
https://github.com/navicore/seq-lisp/pull/54
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
navicore/seq-lisp#52
No description provided.