summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/application.go1
-rw-r--r--client/clipboard/clipboard.go19
-rw-r--r--client/clipboard/shell_clipboard.go78
-rw-r--r--client/main.go7
-rw-r--r--client/ui.go23
5 files changed, 122 insertions, 6 deletions
diff --git a/client/application.go b/client/application.go
index 5b60ca4..388272f 100644
--- a/client/application.go
+++ b/client/application.go
@@ -21,6 +21,7 @@ type application struct {
channelList channelList
cmdWindow cmdWindow
prompts []window.Prompt
+ activePaste <-chan string
}
func newApplication(serverAddress string) *application {
diff --git a/client/clipboard/clipboard.go b/client/clipboard/clipboard.go
index b110378..b81b500 100644
--- a/client/clipboard/clipboard.go
+++ b/client/clipboard/clipboard.go
@@ -1,4 +1,4 @@
-package tui
+package clipboard
import (
"sync"
@@ -12,23 +12,30 @@ type Clipboard interface {
type virtualClipboard string
func (clip *virtualClipboard) Copy(text string) {
- *clip = text
+ *clip = virtualClipboard(text)
}
var ch = make(chan string)
func (clip *virtualClipboard) Paste() <-chan string {
go func() {
- ch <- *clip
+ ch <- string(*clip)
}()
return ch
}
-var clipboard Clipboard = virtualClipboard {}
-var mut RWMutex
+var defaultClipboard virtualClipboard
+var clipboard Clipboard = &defaultClipboard
+var mut sync.RWMutex
-func Get() {
+func Get() Clipboard {
mut.RLock()
c := clipboard
mut.RUnlock()
return c
}
+
+func Set(c Clipboard) {
+ mut.Lock()
+ clipboard = c
+ mut.Unlock()
+}
diff --git a/client/clipboard/shell_clipboard.go b/client/clipboard/shell_clipboard.go
new file mode 100644
index 0000000..9d8ecc8
--- /dev/null
+++ b/client/clipboard/shell_clipboard.go
@@ -0,0 +1,78 @@
+package clipboard
+
+import (
+ "os/exec"
+ "strings"
+ "bytes"
+)
+
+type ShellClipboard struct {
+ copyCommand string
+ pasteCommand string
+ testCommand string
+}
+
+var try = []ShellClipboard {
+ ShellClipboard {"wl-copy", "wl-paste -n", "wl-copy -h"},
+ ShellClipboard {
+ "xclip -selection clipboard", "xclip -selection clipboard -o",
+ "xclip -h",
+ },
+ ShellClipboard {"pbcopy", "pbpaste", "pbcopy -help"},
+}
+
+func command(command string) *exec.Cmd {
+ args := strings.Split(command, " ")
+ return exec.Command(args[0], args[1:]...)
+}
+
+func (c ShellClipboard) Test() bool {
+ cmd := command(c.testCommand)
+ return cmd.Run() == nil
+}
+
+func (c ShellClipboard) Copy(text string) {
+ cmd := command(c.copyCommand)
+ pipe, err := cmd.StdinPipe()
+ cmd.Start()
+ go func() {
+ if err != nil {
+ return
+ }
+ defer pipe.Close()
+
+ buf := bytes.NewBuffer([]byte(text))
+ buf.WriteTo(pipe)
+ }()
+}
+
+func (c ShellClipboard) Paste() <-chan string {
+ cmd := command(c.pasteCommand)
+ pipe, err := cmd.StdoutPipe()
+ cmd.Start()
+ ch := make(chan string, 1)
+ go func() {
+ if err != nil {
+ return
+ }
+ defer pipe.Close()
+
+ buf := bytes.NewBuffer(nil)
+ _, err = buf.ReadFrom(pipe)
+ if err != nil {
+ return
+ }
+ ch <- buf.String()
+ close(ch)
+ }()
+ return ch
+}
+
+func DiscoverCommand() {
+ for _, c := range try {
+ if c.Test() {
+ Set(c)
+ break
+ }
+ }
+}
diff --git a/client/main.go b/client/main.go
index 5b88117..c9da6c3 100644
--- a/client/main.go
+++ b/client/main.go
@@ -2,6 +2,7 @@ package main
import (
"citrons.xyz/talk/tui"
+ "citrons.xyz/talk/client/clipboard"
"time"
"fmt"
"os"
@@ -10,6 +11,8 @@ import (
var globalApp *application
func main() {
+ go clipboard.DiscoverCommand()
+
err := tui.Start()
if err != nil {
fmt.Fprintln(os.Stderr, "error initializing terminal: ", err)
@@ -39,6 +42,10 @@ func main() {
globalApp.show()
redraw = false
}
+ case text := <-globalApp.activePaste:
+ globalApp.onPaste(text)
+ globalApp.activePaste = nil
+ redraw = true
}
if globalApp.quit == true {
return
diff --git a/client/ui.go b/client/ui.go
index 51d64e5..a71a106 100644
--- a/client/ui.go
+++ b/client/ui.go
@@ -1,6 +1,7 @@
package main
import (
+ "citrons.xyz/talk/client/clipboard"
"citrons.xyz/talk/client/window"
"citrons.xyz/talk/tui"
"citrons.xyz/talk/proto"
@@ -68,18 +69,40 @@ func (a *application) onInput(ev tui.Event) {
input.SetText("")
}
}
+
+ case 'c' | keys.Ctrl:
+ sel := prompt.Input().Selection()
+ if sel != "" {
+ clipboard.Get().Copy(sel)
+ }
+ case 'v' | keys.Ctrl:
+ if globalApp.activePaste == nil {
+ globalApp.activePaste = clipboard.Get().Paste()
+ }
+ case 'x' | keys.Ctrl:
+ sel := prompt.Input().Selection()
+ if sel != "" {
+ clipboard.Get().Copy(sel)
+ prompt.Input().Write("")
+ }
+
case keys.Up | keys.Alt:
a.channelList.traverse(-1)
case keys.Down | keys.Alt:
a.channelList.traverse(1)
+
case 'p' | keys.Ctrl:
a.traverseHistory(-1)
case 'n' | keys.Ctrl:
a.traverseHistory(1)
+
case '0' | keys.Alt:
a.goTo(cmdWindowLocation{})
}
+}
+func (a *application) onPaste(text string) {
+ a.getPrompt().Input().Write(text)
}
func (a *application) logUserUpdate(uid string, update proto.Object) {