Editor now supports bracketed paste
* Solves problem of pasting content with newlines and accidentally
sending everything
* Improves pasting speed imensly
* Allows paste without external utility (xclip and so on)
MODIFY
ui/commandview.go
ui/commandview.go
@@ -27,7 +27,7 @@ type CommandView struct {
// NewCommandView creates a new struct containing the components necessary
// for a command view. It also contains the state for those components.
-func NewCommandView(onExecuteCommand func(command string)) *CommandView {
+func NewCommandView(app *tview.Application, onExecuteCommand func(command string)) *CommandView {
commandOutput := tview.NewTextView()
commandOutput.SetDynamicColors(true).
SetWordWrap(true).
@@ -36,7 +36,7 @@ func NewCommandView(onExecuteCommand func(command string)) *CommandView {
SetBorder(true).
SetIndicateOverflow(true)
- commandInput := NewEditor()
+ commandInput := NewEditor(app)
commandInput.internalTextView.
SetWrap(false).
SetWordWrap(false)

MODIFY
ui/editor.go
ui/editor.go
package ui
import (
- "fmt"
- "log"
"unicode"
"github.com/Bios-Marcel/cordless/tview"
@@ -29,6 +27,10 @@ type Editor struct {
heightRequestHandler func(requestHeight int)
requestedHeight int
autocompleteFrom *femto.Loc
+
+ // App is the tview Application this editor is used in. The reference is
+ // required to query the current bracketed paste state.
+ App *tview.Application
}
func (editor *Editor) applyBuffer() {
@@ -376,6 +378,17 @@ func (editor *Editor) Paste(event *tcell.EventKey) {
}
}
+func (editor *Editor) insertCharacterWithoutApply(character rune) {
+ selectionEnd := editor.buffer.Cursor.CurSelection[1]
+ selectionStart := editor.buffer.Cursor.CurSelection[0]
+ if editor.buffer.Cursor.HasSelection() {
+ editor.buffer.Replace(selectionStart, selectionEnd, string(character))
+ } else {
+ editor.buffer.Insert(editor.buffer.Cursor.Loc, string(character))
+ }
+ editor.buffer.Cursor.ResetSelection()
+}
+
func (editor *Editor) InsertCharacter(character rune) {
selectionEnd := editor.buffer.Cursor.CurSelection[1]
selectionStart := editor.buffer.Cursor.CurSelection[0]
@@ -389,12 +402,13 @@ func (editor *Editor) InsertCharacter(character rune) {
}
// NewEditor instantiates a ready to use text editor.
-func NewEditor() *Editor {
+func NewEditor(app *tview.Application) *Editor {
editor := Editor{
internalTextView: tview.NewTextView(),
requestedHeight: 3,
buffer: femto.NewBufferFromString("", ""),
tempBuffer: femto.NewBufferFromString("", ""),
+ App: app,
}
editor.internalTextView.SetWrap(true)
@@ -408,9 +422,29 @@ func NewEditor() *Editor {
editor.buffer.Cursor.SetSelectionStart(editor.buffer.Start())
editor.buffer.Cursor.SetSelectionEnd(editor.buffer.End())
+ if editor.App != nil {
+ editor.internalTextView.SetOnPaste(func(pastedRunes []rune) {
+ var wasLastCharacterSlashR bool
+ for _, r := range pastedRunes {
+ //Workaround! Sometimes no \n is received, but only \r. Why? Unsure.
+ if r == '\r' {
+ wasLastCharacterSlashR = true
+ editor.insertCharacterWithoutApply('\n')
+ } else {
+ if wasLastCharacterSlashR {
+ wasLastCharacterSlashR = false
+ }
+ if r != '\n' {
+ editor.insertCharacterWithoutApply(r)
+ }
+ }
+ }
+ editor.applyBuffer()
+ editor.TriggerHeightRequestIfNecessary()
+ editor.internalTextView.ScrollToHighlight()
+ })
+ }
editor.internalTextView.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
- log.Println(fmt.Sprintf("Key: %v, Modifier: %v, Rune: %v, When: %v", event.Key(), event.Modifiers(), event.Rune(), event.When()))
-
inputCapture := editor.inputCapture
if inputCapture != nil {
event = inputCapture(event)

MODIFY
ui/window.go
ui/window.go
@@ -120,7 +120,7 @@ func NewWindow(app *tview.Application, session *discordgo.Session, readyEvent *d
}()
}
- window.commandView = NewCommandView(window.ExecuteCommand)
+ window.commandView = NewCommandView(window.app, window.ExecuteCommand)
logging.SetAdditionalOutput(window.commandView)
for _, engine := range window.extensionEngines {
@@ -399,7 +399,7 @@ func NewWindow(app *tview.Application, session *discordgo.Session, readyEvent *d
})
window.messageContainer = window.chatView.GetPrimitive()
- window.messageInput = NewEditor()
+ window.messageInput = NewEditor(window.app)
window.messageInput.internalTextView.SetIndicateOverflow(true)
window.messageInput.SetOnHeightChangeRequest(func(height int) {
_, _, _, chatViewHeight := window.chatView.internalTextView.GetRect()

Editor now supports bracketed paste

* Solves problem of pasting content with newlines and accidentally
sending everything
* Improves pasting speed imensly
* Allows paste without external utility (xclip and so on)