CopyLine, CutLine, DeleteLine: respect selection

When there is a selection containing multiple lines, CutLine, DeleteLine
and CopyLine actions currently cut/delete/copy just the "current" line,
as usual. This behavior is at least confusing, since when there is a
selection, the cursor is not displayed, so the user doesn't know which
line is the current one.

So change the behavior. When there is a multi-line selection,
cut/delete/copy all lines covered by the selection, not just the current
line. Note that it will cut/delete/copy whole lines, not just the
selection itself, i.e. if the first and/or the last line of the
selection is only partially within the selection, we will
cut/delete/copy the entire first and last lines nonetheless.
This commit is contained in:
Dmytro Maluka 2024-06-09 12:59:19 +02:00
parent 9f7bdb109b
commit fdacb28962

View File

@ -1162,6 +1162,26 @@ func (h *BufPane) Redo() bool {
return true return true
} }
func (h *BufPane) selectLines() int {
if h.Cursor.HasSelection() {
start := h.Cursor.CurSelection[0]
end := h.Cursor.CurSelection[1]
if start.GreaterThan(end) {
start, end = end, start
}
if end.X == 0 {
end = end.Move(-1, h.Buf)
}
h.Cursor.Deselect(true)
h.Cursor.SetSelectionStart(buffer.Loc{0, start.Y})
h.Cursor.SetSelectionEnd(buffer.Loc{0, end.Y + 1})
} else {
h.Cursor.SelectLine()
}
return h.Cursor.CurSelection[1].Y - h.Cursor.CurSelection[0].Y
}
// Copy the selection to the system clipboard // Copy the selection to the system clipboard
func (h *BufPane) Copy() bool { func (h *BufPane) Copy() bool {
if !h.Cursor.HasSelection() { if !h.Cursor.HasSelection() {
@ -1174,21 +1194,28 @@ func (h *BufPane) Copy() bool {
return true return true
} }
// CopyLine copies the current line to the clipboard // CopyLine copies the current line to the clipboard. If there is a selection,
// CopyLine copies all the lines that are (fully or partially) in the selection.
func (h *BufPane) CopyLine() bool { func (h *BufPane) CopyLine() bool {
origLoc := h.Cursor.Loc origLoc := h.Cursor.Loc
origLastVisualX := h.Cursor.LastVisualX origLastVisualX := h.Cursor.LastVisualX
h.Cursor.SelectLine() origSelection := h.Cursor.CurSelection
if !h.Cursor.HasSelection() {
nlines := h.selectLines()
if nlines == 0 {
return false return false
} }
h.Cursor.CopySelection(clipboard.ClipboardReg) h.Cursor.CopySelection(clipboard.ClipboardReg)
h.freshClip = true h.freshClip = true
if nlines > 1 {
InfoBar.Message(fmt.Sprintf("Copied %d lines", nlines))
} else {
InfoBar.Message("Copied line") InfoBar.Message("Copied line")
}
h.Cursor.Deselect(true)
h.Cursor.Loc = origLoc h.Cursor.Loc = origLoc
h.Cursor.LastVisualX = origLastVisualX h.Cursor.LastVisualX = origLastVisualX
h.Cursor.CurSelection = origSelection
h.Relocate() h.Relocate()
return true return true
} }
@ -1208,10 +1235,11 @@ func (h *BufPane) Cut() bool {
return true return true
} }
// CutLine cuts the current line to the clipboard // CutLine cuts the current line to the clipboard. If there is a selection,
// CutLine cuts all the lines that are (fully or partially) in the selection.
func (h *BufPane) CutLine() bool { func (h *BufPane) CutLine() bool {
h.Cursor.SelectLine() nlines := h.selectLines()
if !h.Cursor.HasSelection() { if nlines == 0 {
return false return false
} }
if h.freshClip && time.Since(h.lastCutTime) < 10*time.Second { if h.freshClip && time.Since(h.lastCutTime) < 10*time.Second {
@ -1228,7 +1256,11 @@ func (h *BufPane) CutLine() bool {
h.Cursor.DeleteSelection() h.Cursor.DeleteSelection()
h.Cursor.ResetSelection() h.Cursor.ResetSelection()
h.Cursor.StoreVisualX() h.Cursor.StoreVisualX()
if nlines > 1 {
InfoBar.Message(fmt.Sprintf("Cut %d lines", nlines))
} else {
InfoBar.Message("Cut line") InfoBar.Message("Cut line")
}
h.Relocate() h.Relocate()
return true return true
} }
@ -1250,16 +1282,21 @@ func (h *BufPane) DuplicateLine() bool {
return true return true
} }
// DeleteLine deletes the current line // DeleteLine deletes the current line. If there is a selection, DeleteLine
// deletes all the lines that are (fully or partially) in the selection.
func (h *BufPane) DeleteLine() bool { func (h *BufPane) DeleteLine() bool {
h.Cursor.SelectLine() nlines := h.selectLines()
if !h.Cursor.HasSelection() { if nlines == 0 {
return false return false
} }
h.Cursor.DeleteSelection() h.Cursor.DeleteSelection()
h.Cursor.ResetSelection() h.Cursor.ResetSelection()
h.Cursor.StoreVisualX() h.Cursor.StoreVisualX()
if nlines > 1 {
InfoBar.Message(fmt.Sprintf("Deleted %d lines", nlines))
} else {
InfoBar.Message("Deleted line") InfoBar.Message("Deleted line")
}
h.Relocate() h.Relocate()
return true return true
} }