2026-03-25 08:39:31 +09:00
|
|
|
package editor
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"tea.kareha.org/lab/levi/internal/console"
|
2026-03-25 09:20:12 +09:00
|
|
|
"tea.kareha.org/lab/levi/internal/util"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type mode int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
modeCommand = iota
|
|
|
|
|
modeInsert
|
2026-03-25 08:39:31 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Editor struct {
|
|
|
|
|
scr *Screen
|
|
|
|
|
kb *Keyboard
|
|
|
|
|
x, y int
|
|
|
|
|
line *strings.Builder
|
2026-03-25 09:20:12 +09:00
|
|
|
mode mode
|
2026-03-25 08:39:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func New() *Editor {
|
|
|
|
|
scr := NewScreen()
|
|
|
|
|
kb := NewKeyboard()
|
|
|
|
|
|
|
|
|
|
return &Editor{
|
|
|
|
|
scr: &scr,
|
|
|
|
|
kb: &kb,
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
line: new(strings.Builder),
|
2026-03-25 09:20:12 +09:00
|
|
|
mode: modeCommand,
|
2026-03-25 08:39:31 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ed *Editor) addRune(r rune) {
|
|
|
|
|
ed.line.WriteRune(r)
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-25 09:20:12 +09:00
|
|
|
func (ed *Editor) drawStatus() {
|
|
|
|
|
_, h := console.Size()
|
|
|
|
|
|
|
|
|
|
console.MoveCursor(0, h - 2)
|
|
|
|
|
switch ed.mode {
|
|
|
|
|
case modeCommand:
|
|
|
|
|
console.Print("-- [command] q: quit, i: insert --")
|
|
|
|
|
case modeInsert:
|
|
|
|
|
console.Print("-- [insert] Esc: command mode --")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ed *Editor) drawBuffer() {
|
|
|
|
|
console.Print(ed.line.String())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ed *Editor) repaint() {
|
|
|
|
|
console.HideCursor()
|
|
|
|
|
|
2026-03-25 08:39:31 +09:00
|
|
|
console.Clear()
|
|
|
|
|
console.HomeCursor()
|
|
|
|
|
|
2026-03-25 09:20:12 +09:00
|
|
|
ed.drawBuffer()
|
|
|
|
|
ed.drawStatus()
|
2026-03-25 08:39:31 +09:00
|
|
|
|
|
|
|
|
console.MoveCursor(ed.x, ed.y)
|
2026-03-25 09:20:12 +09:00
|
|
|
|
|
|
|
|
console.ShowCursor()
|
2026-03-25 08:39:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (ed *Editor) Main() {
|
|
|
|
|
for {
|
2026-03-25 09:20:12 +09:00
|
|
|
ed.repaint()
|
2026-03-25 08:39:31 +09:00
|
|
|
|
|
|
|
|
r := ed.kb.ReadRune()
|
2026-03-25 09:20:12 +09:00
|
|
|
switch ed.mode {
|
|
|
|
|
case modeCommand:
|
|
|
|
|
switch r {
|
|
|
|
|
case 'q':
|
|
|
|
|
return
|
|
|
|
|
case 'i':
|
|
|
|
|
ed.mode = modeInsert
|
|
|
|
|
}
|
|
|
|
|
case modeInsert:
|
|
|
|
|
switch r {
|
|
|
|
|
case Esc:
|
|
|
|
|
ed.mode = modeCommand
|
|
|
|
|
default:
|
|
|
|
|
ed.addRune(r)
|
|
|
|
|
ed.x += util.RuneWidth(r)
|
|
|
|
|
}
|
2026-03-25 08:39:31 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|