diff --git a/internal/action/actions.go b/internal/action/actions.go index 4aeba6f3..3db9af31 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -1483,6 +1483,41 @@ func (h *BufPane) SpawnMultiCursor() bool { return true } +// SpawnMultiCursorUp creates additional cursor, at the same X (if possible), one Y less. +func (h *BufPane) SpawnMultiCursorUp() bool { + if h.Cursor.Y == 0 { + return false + } else { + h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y - 1}) + h.Cursor.Relocate() + } + + c := buffer.NewCursor(h.Buf, buffer.Loc{h.Cursor.X, h.Cursor.Y + 1}) + h.Buf.AddCursor(c) + h.Buf.SetCurCursor(h.Buf.NumCursors() - 1) + h.Buf.MergeCursors() + + h.Relocate() + return true +} + +// SpawnMultiCursorUp creates additional cursor, at the same X (if possible), one Y more. +func (h *BufPane) SpawnMultiCursorDown() bool { + if h.Cursor.Y+1 == h.Buf.LinesNum() { + return false + } else { + h.Cursor.GotoLoc(buffer.Loc{h.Cursor.X, h.Cursor.Y + 1}) + h.Cursor.Relocate() + } + + c := buffer.NewCursor(h.Buf, buffer.Loc{h.Cursor.X, h.Cursor.Y - 1}) + h.Buf.AddCursor(c) + h.Buf.SetCurCursor(h.Buf.NumCursors() - 1) + h.Buf.MergeCursors() + h.Relocate() + return true +} + // SpawnMultiCursorSelect adds a cursor at the beginning of each line of a selection func (h *BufPane) SpawnMultiCursorSelect() bool { // Avoid cases where multiple cursors already exist, that would create problems diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index 12c50e19..bb79d756 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -595,6 +595,8 @@ var BufKeyActions = map[string]BufKeyAction{ "ScrollUp": (*BufPane).ScrollUpAction, "ScrollDown": (*BufPane).ScrollDownAction, "SpawnMultiCursor": (*BufPane).SpawnMultiCursor, + "SpawnMultiCursorUp": (*BufPane).SpawnMultiCursorUp, + "SpawnMultiCursorDown": (*BufPane).SpawnMultiCursorDown, "SpawnMultiCursorSelect": (*BufPane).SpawnMultiCursorSelect, "RemoveMultiCursor": (*BufPane).RemoveMultiCursor, "RemoveAllMultiCursors": (*BufPane).RemoveAllMultiCursors, diff --git a/internal/action/defaults_darwin.go b/internal/action/defaults_darwin.go index acd3a6ff..45b6359a 100644 --- a/internal/action/defaults_darwin.go +++ b/internal/action/defaults_darwin.go @@ -96,10 +96,12 @@ func DefaultBindings() map[string]string { "MouseMiddle": "PastePrimary", "Ctrl-MouseLeft": "MouseMultiCursor", - "Alt-n": "SpawnMultiCursor", - "Alt-m": "SpawnMultiCursorSelect", - "Alt-p": "RemoveMultiCursor", - "Alt-c": "RemoveAllMultiCursors", - "Alt-x": "SkipMultiCursor", + "Alt-n": "SpawnMultiCursor", + "AltShiftUp": "SpawnMultiCursorUp", + "AltShiftDown": "SpawnMultiCursorDown", + "Alt-m": "SpawnMultiCursorSelect", + "Alt-p": "RemoveMultiCursor", + "Alt-c": "RemoveAllMultiCursors", + "Alt-x": "SkipMultiCursor", } } diff --git a/internal/action/defaults_other.go b/internal/action/defaults_other.go index ff05a89d..1ee40648 100644 --- a/internal/action/defaults_other.go +++ b/internal/action/defaults_other.go @@ -98,10 +98,12 @@ func DefaultBindings() map[string]string { "MouseMiddle": "PastePrimary", "Ctrl-MouseLeft": "MouseMultiCursor", - "Alt-n": "SpawnMultiCursor", - "Alt-m": "SpawnMultiCursorSelect", - "Alt-p": "RemoveMultiCursor", - "Alt-c": "RemoveAllMultiCursors", - "Alt-x": "SkipMultiCursor", + "Alt-n": "SpawnMultiCursor", + "Alt-m": "SpawnMultiCursorSelect", + "AltShiftUp": "SpawnMultiCursorUp", + "AltShiftDown": "SpawnMultiCursorDown", + "Alt-p": "RemoveMultiCursor", + "Alt-c": "RemoveAllMultiCursors", + "Alt-x": "SkipMultiCursor", } }