From 9bcbde8bb2db99a14af4b53a87747319fe56cc23 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 26 Sep 2022 07:00:13 +0200 Subject: [PATCH] Add screen.SetClipboard Fixes #561 --- _demos/set_clipboard.go | 88 +++++++++++++++++++++++++++++++++++++ screen.go | 2 + simulation.go | 4 ++ terminfo/dynamic/dynamic.go | 3 +- terminfo/terminfo.go | 1 + tscreen.go | 11 +++++ 6 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 _demos/set_clipboard.go diff --git a/_demos/set_clipboard.go b/_demos/set_clipboard.go new file mode 100644 index 00000000..fb31a466 --- /dev/null +++ b/_demos/set_clipboard.go @@ -0,0 +1,88 @@ +// +build ignore + +// Copyright 2020 The TCell Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use file except in compliance with the License. +// You may obtain a copy of the license at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "fmt" + "os" + + "github.com/gdamore/tcell/v2" + "github.com/gdamore/tcell/v2/encoding" + + "github.com/mattn/go-runewidth" +) + +func emitStr(s tcell.Screen, x, y int, style tcell.Style, str string) { + for _, c := range str { + var comb []rune + w := runewidth.RuneWidth(c) + if w == 0 { + comb = []rune{c} + c = ' ' + w = 1 + } + s.SetContent(x, y, c, comb, style) + x += w + } +} + +func displayHelloWorld(s tcell.Screen) { + w, h := s.Size() + s.Clear() + style := tcell.StyleDefault.Foreground(tcell.ColorCadetBlue.TrueColor()).Background(tcell.ColorWhite) + emitStr(s, w/2-14, h/2, style, "Press Enter to set clipboard") + emitStr(s, w/2-9, h/2+1, tcell.StyleDefault, "Press ESC to exit.") + s.Show() +} + +// This program just prints "Hello, World!". Press ESC to exit. +func main() { + encoding.Register() + + s, e := tcell.NewScreen() + if e != nil { + fmt.Fprintf(os.Stderr, "%v\n", e) + os.Exit(1) + } + if e := s.Init(); e != nil { + fmt.Fprintf(os.Stderr, "%v\n", e) + os.Exit(1) + } + + defStyle := tcell.StyleDefault. + Background(tcell.ColorBlack). + Foreground(tcell.ColorWhite) + s.SetStyle(defStyle) + + displayHelloWorld(s) + + for { + switch ev := s.PollEvent().(type) { + case *tcell.EventResize: + s.Sync() + displayHelloWorld(s) + case *tcell.EventKey: + switch ev.Key() { + case tcell.KeyEnter: + s.SetClipboard("enjoy your new clipboard content") + case tcell.KeyEscape: + s.Fini() + os.Exit(0) + } + } + } +} diff --git a/screen.go b/screen.go index 43c3a54b..9f194bef 100644 --- a/screen.go +++ b/screen.go @@ -248,6 +248,8 @@ type Screen interface { // does not support application-initiated resizing, whereas the legacy terminal does. // Also, some emulators can support this but may have it disabled by default. SetSize(int, int) + + SetClipboard(string) bool } // NewScreen returns a default Screen suitable for the user's terminal diff --git a/simulation.go b/simulation.go index 9ad6131e..2491d8ac 100644 --- a/simulation.go +++ b/simulation.go @@ -478,6 +478,10 @@ func (s *simscreen) SetSize(w, h int) { s.Unlock() } +func (s *simscreen) SetClipboard(content string) bool { + return false +} + func (s *simscreen) GetContents() ([]SimCell, int, int) { s.Lock() cells, w, h := s.front, s.physw, s.physh diff --git a/terminfo/dynamic/dynamic.go b/terminfo/dynamic/dynamic.go index 08ff2484..5cde193d 100644 --- a/terminfo/dynamic/dynamic.go +++ b/terminfo/dynamic/dynamic.go @@ -117,7 +117,7 @@ func unescape(s string) string { } func (tc *termcap) setupterm(name string) error { - cmd := exec.Command("infocmp", "-1", name) + cmd := exec.Command("infocmp", "-x", "-1", name) output := &bytes.Buffer{} cmd.Stdout = output @@ -219,6 +219,7 @@ func LoadTerminfo(name string) (*terminfo.Terminfo, string, error) { t.SetCursor = tc.getstr("cup") t.CursorBack1 = tc.getstr("cub1") t.CursorUp1 = tc.getstr("cuu1") + t.SetClipboard = tc.getstr("Ms") t.KeyF1 = tc.getstr("kf1") t.KeyF2 = tc.getstr("kf2") t.KeyF3 = tc.getstr("kf3") diff --git a/terminfo/terminfo.go b/terminfo/terminfo.go index cf157864..504cf6cf 100644 --- a/terminfo/terminfo.go +++ b/terminfo/terminfo.go @@ -230,6 +230,7 @@ type Terminfo struct { EnterUrl string ExitUrl string SetWindowSize string + SetClipboard string } const ( diff --git a/tscreen.go b/tscreen.go index dcde34ed..980f00be 100644 --- a/tscreen.go +++ b/tscreen.go @@ -16,6 +16,7 @@ package tcell import ( "bytes" + "encoding/base64" "errors" "io" "os" @@ -1777,6 +1778,16 @@ func (t *tScreen) SetSize(w, h int) { t.resize() } +func (t *tScreen) SetClipboard(content string) bool { + ti := t.ti + if ti.SetClipboard == "" { + return false + } + encoded := base64.StdEncoding.EncodeToString([]byte(content)) + t.TPuts(ti.TParm(ti.SetClipboard, "c", encoded)) + return true +} + func (t *tScreen) Resize(int, int, int, int) {} func (t *tScreen) Suspend() error {