diff --git a/internal/editor/integration_insert_test.go b/internal/editor/integration_insert_test.go index 3c090ec..3cf27d8 100644 --- a/internal/editor/integration_insert_test.go +++ b/internal/editor/integration_insert_test.go @@ -392,3 +392,67 @@ func TestInsertModeBackspace(t *testing.T) { } }) } + +func TestInsertModeDelete(t *testing.T) { + t.Run("test delete deletes character", func(t *testing.T) { + lines := []string{"world"} + tm := newTestModelWithCursorPosAndLines(t, lines, action.Position{Col: 3, Line: 0}) + sendKeys(tm, "i", "delete", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "word" { + t.Errorf("lines[0] = %q, want 'word'", m.lines[0]) + } + }) + + t.Run("test delete at end of line joins lines", func(t *testing.T) { + lines := []string{"hello", "world"} + tm := newTestModelWithCursorPosAndLines(t, lines, action.Position{Col: 5, Line: 0}) + sendKeys(tm, "i", "delete", "esc") + + m := getFinalModel(t, tm) + if len(m.lines) != 1 { + t.Errorf("len(lines) = %d, want 1", len(m.lines)) + } + if m.lines[0] != "helloworld" { + t.Errorf("lines[0] = %q, want 'helloworld'", m.lines[0]) + } + }) + + t.Run("test delete at start of empty line joins lines", func(t *testing.T) { + lines := []string{"", "world"} + tm := newTestModelWithLines(t, lines) + sendKeys(tm, "i", "delete", "esc") + + m := getFinalModel(t, tm) + if len(m.lines) != 1 { + t.Errorf("len(lines) = %d, want 1", len(m.lines)) + } + if m.lines[0] != "world" { + t.Errorf("lines[0] = %q, want 'world'", m.lines[0]) + } + }) + + t.Run("test delete at end of last line does nothing", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithCursorPosAndLines(t, lines, action.Position{Col: 5, Line: 0}) + sendKeys(tm, "i", "delete", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "hello" { + t.Errorf("lines[0] = %q, want 'hello'", m.lines[0]) + } + }) + + t.Run("test multiple delete", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithCursorPosAndLines(t, lines, action.Position{Col: 1, Line: 0}) + sendKeys(tm, "i", "delete", "delete", "delete", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "ho" { + t.Errorf("lines[0] = %q, want 'he'", m.lines[0]) + } + }) + +} diff --git a/internal/editor/model.go b/internal/editor/model.go index bb6b917..061669f 100644 --- a/internal/editor/model.go +++ b/internal/editor/model.go @@ -185,6 +185,15 @@ func (m *Model) processInsertKey(key string) { m.SetCursorX(newX) } + case "delete": + if x == len(l) && y < m.LineCount() { + nextLine := m.Line(y + 1) + m.SetLine(y, l+nextLine) + m.DeleteLine(y + 1) + } else if x >= 0 { + m.SetLine(y, l[:x]+l[x+1:]) + } + // Regular character default: if x < len(l) { diff --git a/internal/input/keymap.go b/internal/input/keymap.go index 2272192..80b3618 100644 --- a/internal/input/keymap.go +++ b/internal/input/keymap.go @@ -19,7 +19,7 @@ func NewNormalKeymap() *Keymap { "h": motion.MoveLeft{Count: 1}, "l": motion.MoveRight{Count: 1}, "G": motion.MoveToBottom{}, - "gg": motion.MoveToTop{}, // multi-key example + "gg": motion.MoveToTop{}, "0": motion.MoveToLineStart{}, "$": motion.MoveToLineEnd{}, },