Add clipboard paste support to textarea

This commit is contained in:
Christian Rocha 2020-07-21 16:49:27 -04:00
parent 10022c964c
commit f11ca377f4
No known key found for this signature in database
GPG Key ID: D6CC7A16E5878018
3 changed files with 47 additions and 0 deletions

1
go.mod
View File

@ -3,6 +3,7 @@ module github.com/charmbracelet/bubbles
go 1.13
require (
github.com/atotto/clipboard v0.1.2 // indirect
github.com/charmbracelet/bubbletea v0.9.1-0.20200713153904-2f53eeb54b90
github.com/mattn/go-runewidth v0.0.9
github.com/muesli/termenv v0.5.3-0.20200625163851-04b5c30e4c04

2
go.sum
View File

@ -1,3 +1,5 @@
github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY=
github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f h1:5CjVwnuUcp5adK4gmY6i72gpVFVnZDP2h5TmPScB6u4=
github.com/google/goterm v0.0.0-20190703233501-fc88cf888a3f/go.mod h1:nOFQdrUlIlx6M6ODdSpBj1NVA+VgLC6kmw60mkw34H4=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=

View File

@ -5,6 +5,7 @@ import (
"time"
"unicode"
"github.com/atotto/clipboard"
tea "github.com/charmbracelet/bubbletea"
rw "github.com/mattn/go-runewidth"
"github.com/muesli/termenv"
@ -126,6 +127,47 @@ func (m *Model) Reset() {
m.blink = false
}
// Paste pastes the contents of the clipboard into the text area (if supported).
func (m *Model) Paste() {
pasteString, err := clipboard.ReadAll()
if err != nil {
m.Err = err
}
paste := []rune(pasteString)
availSpace := m.CharLimit - len(m.value)
// If the char limit's been reached cancel
if m.CharLimit > 0 && availSpace <= 0 {
return
}
// If there's not enough space to paste the whole thing cut the pasted
// runes down so they'll fit
if availSpace < len(paste) {
paste = paste[:len(paste)-availSpace]
}
// Stuff before and after the cursor
head := m.value[:m.pos]
tailSrc := m.value[m.pos:]
tail := make([]rune, len(tailSrc))
copy(tail, tailSrc)
// Insert pasted runes
for _, r := range paste {
head = append(head, r)
availSpace--
m.pos++
if m.CharLimit > 0 && availSpace <= 0 {
break
}
}
// Put it all back together
m.value = append(head, tail...)
}
// If a max width is defined, perform some logic to treat the visible area
// as a horizontally scrolling viewport.
func (m *Model) handleOverflow() {
@ -322,6 +364,8 @@ func Update(msg tea.Msg, m Model) (Model, tea.Cmd) {
m.value = m.value[m.pos:]
m.pos = 0
m.offset = 0
case tea.KeyCtrlV: // ^V paste
m.Paste()
case tea.KeyRune: // input a regular character
if msg.Alt {