From 73934a8c41cee7f8dc932d1e22e56615766957db Mon Sep 17 00:00:00 2001 From: hchac Date: Sat, 15 Jun 2024 19:38:15 -0400 Subject: [PATCH] Adding selection for ParagraphPrevious and ParagraphNext. Also tweaked the behavior of Paragraph/{Previous/Next} so that it skips all empty lines immediately next to cursor position, until it finds the start/end of the paragraph closest to it. Once it finds the paragraph closest to it, the same behavior as before applies. With the previous behavior if the cursor was surrounded by empty lines, then Paragraph/{Previous/Next} would only jump to the next empty line, instead of jumping to the start/end of a paragraph. --- internal/action/actions.go | 74 ++++++++++++++++++++++++++++++++----- internal/action/bufpane.go | 2 + runtime/help/keybindings.md | 2 + 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/internal/action/actions.go b/internal/action/actions.go index 79bff07d74..8b40677362 100644 --- a/internal/action/actions.go +++ b/internal/action/actions.go @@ -490,38 +490,92 @@ func (h *BufPane) SelectToEndOfLine() bool { return true } -// ParagraphPrevious moves the cursor to the previous empty line, or beginning of the buffer if there's none -func (h *BufPane) ParagraphPrevious() bool { +func (h *BufPane) paragraphPrevious() { var line int + // Skip to the first non-empty line for line = h.Cursor.Y; line > 0; line-- { - if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y { + if len(h.Buf.LineBytes(line)) != 0 { + break + } + } + // Find the first empty line + for ; line > 0; line-- { + if len(h.Buf.LineBytes(line)) == 0 { h.Cursor.X = 0 h.Cursor.Y = line break } } - // If no empty line found. move cursor to end of buffer + // If no empty line was found, move the cursor to the start of the buffer if line == 0 { h.Cursor.Loc = h.Buf.Start() } - h.Relocate() - return true } -// ParagraphNext moves the cursor to the next empty line, or end of the buffer if there's none -func (h *BufPane) ParagraphNext() bool { +func (h *BufPane) paragraphNext() { var line int + // Skip to the first non-empty line for line = h.Cursor.Y; line < h.Buf.LinesNum(); line++ { - if len(h.Buf.LineBytes(line)) == 0 && line != h.Cursor.Y { + if len(h.Buf.LineBytes(line)) != 0 { + break + } + } + // Find the first empty line + for ; line < h.Buf.LinesNum(); line++ { + if len(h.Buf.LineBytes(line)) == 0 { h.Cursor.X = 0 h.Cursor.Y = line break } } - // If no empty line found. move cursor to end of buffer + // If no empty line was found, move the cursor to the end of the buffer if line == h.Buf.LinesNum() { h.Cursor.Loc = h.Buf.End() } +} + +// ParagraphPrevious moves the cursor to the first empty line that comes before +// the paragraph closest to the cursor, or beginning of the buffer if there +// isn't a paragraph +func (h *BufPane) ParagraphPrevious() bool { + h.Cursor.Deselect(true) + h.paragraphPrevious() + h.Relocate() + return true +} + +// ParagraphNext moves the cursor to the first empty line that comes after the +// paragraph closest to the cursor, or end of the buffer if there isn't a +// paragraph +func (h *BufPane) ParagraphNext() bool { + h.Cursor.Deselect(true) + h.paragraphNext() + h.Relocate() + return true +} + +// SelectToParagraphPrevious selects to the first empty line that comes before +// the paragraph closest to the cursor, or beginning of the buffer if there +// isn't a paragraph +func (h *BufPane) SelectToParagraphPrevious() bool { + if !h.Cursor.HasSelection() { + h.Cursor.OrigSelection[0] = h.Cursor.Loc + } + h.paragraphPrevious() + h.Cursor.SelectTo(h.Cursor.Loc) + h.Relocate() + return true +} + +// SelectToParagraphNext selects to the first empty line that comes after the +// paragraph closest to the cursor, or end of the buffer if there isn't a +// paragraph +func (h *BufPane) SelectToParagraphNext() bool { + if !h.Cursor.HasSelection() { + h.Cursor.OrigSelection[0] = h.Cursor.Loc + } + h.paragraphNext() + h.Cursor.SelectTo(h.Cursor.Loc) h.Relocate() return true } diff --git a/internal/action/bufpane.go b/internal/action/bufpane.go index 34808ecaf5..7df09fd640 100644 --- a/internal/action/bufpane.go +++ b/internal/action/bufpane.go @@ -759,6 +759,8 @@ var BufKeyActions = map[string]BufKeyAction{ "SelectToEndOfLine": (*BufPane).SelectToEndOfLine, "ParagraphPrevious": (*BufPane).ParagraphPrevious, "ParagraphNext": (*BufPane).ParagraphNext, + "SelectToParagraphPrevious": (*BufPane).SelectToParagraphPrevious, + "SelectToParagraphNext": (*BufPane).SelectToParagraphNext, "InsertNewline": (*BufPane).InsertNewline, "Backspace": (*BufPane).Backspace, "Delete": (*BufPane).Delete, diff --git a/runtime/help/keybindings.md b/runtime/help/keybindings.md index 17f9ab3531..f0c2570aa8 100644 --- a/runtime/help/keybindings.md +++ b/runtime/help/keybindings.md @@ -237,6 +237,8 @@ StartOfText StartOfTextToggle ParagraphPrevious ParagraphNext +SelectToParagraphPrevious +SelectToParagraphNext ToggleHelp ToggleDiffGutter ToggleRuler