diff --git a/config/keybindings.yml b/config/keybindings.yml index 3d64e04..9202c2f 100644 --- a/config/keybindings.yml +++ b/config/keybindings.yml @@ -2,6 +2,9 @@ keybindings: - keybinding: "Ctrl-Q" cursor_modes: ["buffer"] command: "quit" + - keybinding: "Ctrl-X" + cursor_modes: ["buffer"] + command: "cut" - keybinding: "Ctrl-C" cursor_modes: ["buffer"] command: "copy" diff --git a/src/buffer.go b/src/buffer.go index dfead49..874b49a 100644 --- a/src/buffer.go +++ b/src/buffer.go @@ -184,6 +184,62 @@ func (buffer *Buffer) GetSelectedText() string { } } +func (buffer *Buffer) CutText(window *Window) (string, int) { + if buffer.Selection == nil { + // Copy line + copiedText := "" + startOfLine := window.CurrentBuffer.CursorPos + endOfLine := window.CurrentBuffer.CursorPos + + // Add current letter to copied text + if buffer.CursorPos < len(buffer.Contents) { + copiedText = string(buffer.Contents[buffer.CursorPos]) + } + + // Find end of line + for i := buffer.CursorPos + 1; i < len(buffer.Contents); i++ { + currentLetter := buffer.Contents[i] + + endOfLine++ + copiedText += string(currentLetter) + if currentLetter == '\n' { + break + } + } + + // Find start of line + for i := buffer.CursorPos - 1; i >= 0; i-- { + currentLetter := buffer.Contents[i] + if currentLetter != '\n' { + startOfLine-- + copiedText = string(currentLetter) + copiedText + } else { + break + } + } + + // Remove line from buffer contents + buffer.Contents = buffer.Contents[:startOfLine] + buffer.Contents[endOfLine+1:] + + return copiedText, 0 + } else { + // Copy selection + copiedText := buffer.GetSelectedText() + + // Remove selected text + edge1, edge2 := buffer.GetSelectionEdges() + if edge2 == len(buffer.Contents) { + edge2 = len(buffer.Contents) - 1 + } + + buffer.Contents = buffer.Contents[:edge1] + buffer.Contents[edge2+1:] + window.SetCursorPos(edge1) + buffer.Selection = nil + + return copiedText, 1 + } +} + func (buffer *Buffer) CopyText() (string, int) { if buffer.Selection == nil { // Copy line diff --git a/src/command.go b/src/command.go index cfbaf00..d300f1b 100644 --- a/src/command.go +++ b/src/command.go @@ -18,6 +18,24 @@ var commands = make(map[string]*Command) func initCommands() { // Setup commands + cutCmd := Command{ + cmd: "cut", + run: func(window *Window, args ...string) { + // Cut text from buffer + copiedText, copyingMethod := window.CurrentBuffer.CutText(window) + + // Put cut text to clipboard + window.Clipboard = copiedText + + // Send appropriate message and remove text depending on copying method + if copyingMethod == 0 { + PrintMessage(window, "Copied line to clipboard.") + } else { + PrintMessage(window, "Copied selection to clipboard.") + } + }, + } + copyCmd := Command{ cmd: "copy", run: func(window *Window, args ...string) { @@ -474,6 +492,7 @@ func initCommands() { } // Register commands + commands["cut"] = &cutCmd commands["copy"] = ©Cmd commands["paste"] = &pasteCmd commands["save"] = &saveCmd diff --git a/src/top_menu.go b/src/top_menu.go index 639eedf..ad90eac 100644 --- a/src/top_menu.go +++ b/src/top_menu.go @@ -56,11 +56,13 @@ func initTopMenu() { y++ } - d := CreateDropdownMenu([]string{"Copy", "Paste"}, 0, y, 0, func(i int) { + d := CreateDropdownMenu([]string{"Cut", "Copy", "Paste"}, 0, y, 0, func(i int) { switch i { case 0: - RunCommand(window, "copy") + RunCommand(window, "cut") case 1: + RunCommand(window, "copy") + case 2: RunCommand(window, "paste") } ClearDropdowns()