Skip to content

Commit b8f0924

Browse files
committed
REPL polish: line editor with history, cursor keys, tab completion
Replace bufio.Scanner with a proper terminal line editor (golang.org/x/term): - Up/Down: history navigation (persisted to ~/.odek/repl_history) - Left/Right/Home/End: cursor movement within line - Backspace/Delete: character deletion - Ctrl+U: clear line, Ctrl+K: delete to end - Ctrl+L: clear screen, Ctrl+D: EOF, Ctrl+C: interrupt - Tab: slash command completion (/exit, /help, /info, etc.) - Bracketed paste: multi-line paste support - Fallback to bufio.Scanner when terminal can't go raw
1 parent c86541e commit b8f0924

4 files changed

Lines changed: 540 additions & 5 deletions

File tree

cmd/odek/repl.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package main
22

33
import (
4-
"bufio"
54
"context"
65
"fmt"
76
"os"
87
"os/signal"
8+
"path/filepath"
99
"strings"
1010

1111
"github.com/BackendStack21/kode"
@@ -168,25 +168,40 @@ func replCmd(args []string) error {
168168
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
169169
defer cancel()
170170

171-
scanner := bufio.NewScanner(os.Stdin)
172171
turn := 0
172+
173+
// Line editor with history and tab completion for slash commands
174+
editor := newReplEditor(
175+
fmt.Sprintf("odek %d> ", turn+1),
176+
[]string{
177+
"/exit", "/quit", "/help", "/info",
178+
"/sandbox", "/model", "/session",
179+
},
180+
)
181+
editor.history.Load(filepath.Join(odekDir(), historyFilename))
173182
for {
174183
fmt.Fprintf(os.Stderr, "─── Turn %d ───\n", turn+1)
175-
fmt.Fprint(os.Stderr, "> ")
176184

177-
if !scanner.Scan() {
185+
input, err := editor.ReadLine()
186+
if err != nil {
187+
if err.Error() == "EOF" || err.Error() == "interrupt" {
188+
fmt.Fprintf(os.Stderr, "\n")
189+
break
190+
}
178191
break
179192
}
180-
input := strings.TrimSpace(scanner.Text())
193+
input = strings.TrimSpace(input)
181194

182195
if input == "" {
196+
turn++
183197
continue
184198
}
185199

186200
if strings.HasPrefix(input, "/") {
187201
if handleREPLCommand(input, sess) {
188202
break
189203
}
204+
turn++
190205
continue
191206
}
192207

0 commit comments

Comments
 (0)