mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-28 04:46:42 -04:00
Allow clearing the clipboard instantly; improve code sharing between platforms; facilitate GUI/TUI client development regarding the clipboard
This commit is contained in:
+36
-3
@@ -59,18 +59,51 @@ func CopyArgument(targetLocation string, field int) {
|
||||
}
|
||||
}
|
||||
|
||||
// ClipClearArgument is called to clear the clipboard after 30 seconds if the contents have not been modified.
|
||||
// ClipClearArgument reads the assigned clipboard contents from stdin and passes them to clipClearProcess.
|
||||
func ClipClearArgument() {
|
||||
// read previous clipboard contents from stdin
|
||||
clipScanner := bufio.NewScanner(os.Stdin)
|
||||
if clipScanner.Scan() {
|
||||
oldContents := clipScanner.Text()
|
||||
clipClear(oldContents)
|
||||
assignedContents := clipScanner.Text()
|
||||
clipClearProcess(assignedContents)
|
||||
} else {
|
||||
os.Exit(0) // use os.Exit instead of core.Exit, as this function runs out of a background subprocess that is invisible to the user (will never appear in GUI/TUI environment)
|
||||
}
|
||||
}
|
||||
|
||||
// clipClearProcess clears the clipboard after 30 seconds if the clipboard contents have not changed.
|
||||
// assignedContents can be omitted to clear the clipboard immediately and unconditionally.
|
||||
func clipClearProcess(assignedContents string) {
|
||||
cmdPaste, cmdClear := getClipCommands()
|
||||
|
||||
clearClipboard := func() {
|
||||
err := cmdClear.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
Exit(0)
|
||||
}
|
||||
|
||||
// if assignedContents is empty, clear the clipboard immediately and unconditionally
|
||||
if assignedContents == "" {
|
||||
clearClipboard()
|
||||
}
|
||||
|
||||
// wait 30 seconds before checking clipboard contents
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
newContents, err := cmdPaste.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
if assignedContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
clearClipboard()
|
||||
}
|
||||
}
|
||||
|
||||
// GenTOTP generates a TOTP token from a secret (supports standard and Steam TOTP).
|
||||
func GenTOTP(secret string, time time.Time, forSteam bool) string {
|
||||
var totpToken string
|
||||
|
||||
+6
-24
@@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copyString copies a string to the clipboard.
|
||||
@@ -21,29 +19,13 @@ func copyString(continuous bool, copySubject string) {
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
launchClipClear(copySubject)
|
||||
launchClipClearProcess(copySubject)
|
||||
}
|
||||
}
|
||||
|
||||
// clipClear is called in a separate process to clear the clipboard after 30 seconds.
|
||||
func clipClear(oldContents string) {
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
cmd := exec.Command("pbpaste")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
if oldContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
cmd = exec.Command("pbcopy")
|
||||
writeToStdin(cmd, "")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
}
|
||||
Exit(0)
|
||||
// getClipCommands returns the commands for pasting and clearing the clipboard contents.
|
||||
func getClipCommands() (*exec.Cmd, *exec.Cmd) {
|
||||
cmdClear := exec.Command("pbcopy")
|
||||
writeToStdin(cmdClear, "")
|
||||
return exec.Command("pbpaste"), cmdClear
|
||||
}
|
||||
|
||||
+7
-25
@@ -1,4 +1,4 @@
|
||||
//go:build linux && termux
|
||||
//go:build android && termux
|
||||
|
||||
package core
|
||||
|
||||
@@ -6,8 +6,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copyString copies a string to the clipboard.
|
||||
@@ -21,29 +19,13 @@ func copyString(continuous bool, copySubject string) {
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
launchClipClear(copySubject)
|
||||
launchClipClearProcess(copySubject)
|
||||
}
|
||||
}
|
||||
|
||||
// clipClear is called in a separate process to clear the clipboard after 30 seconds.
|
||||
func clipClear(oldContents string) {
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
cmd := exec.Command("termux-clipboard-get")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
if oldContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
cmd = exec.Command("termux-clipboard-set")
|
||||
writeToStdin(cmd, "")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
}
|
||||
Exit(0)
|
||||
// getClipCommands returns the commands for pasting and clearing the clipboard contents.
|
||||
func getClipCommands() (*exec.Cmd, *exec.Cmd) {
|
||||
cmdClear := exec.Command("termux-clipboard-set")
|
||||
writeToStdin(cmdClear, "")
|
||||
return exec.Command("termux-clipboard-get"), cmdClear
|
||||
}
|
||||
|
||||
+13
-42
@@ -6,68 +6,39 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copyString copies a string to the clipboard.
|
||||
func copyString(continuous bool, copySubject string) {
|
||||
var envSet bool // track whether environment variables are set
|
||||
var cmd *exec.Cmd
|
||||
var envSet, isWayland bool // track whether environment variables are set
|
||||
var cmdCopy *exec.Cmd
|
||||
// determine whether to use wl-copy (Wayland) or xclip (X11)
|
||||
if _, envSet = os.LookupEnv("WAYLAND_DISPLAY"); envSet {
|
||||
cmd = exec.Command("wl-copy", "-t", "text/plain")
|
||||
cmdCopy = exec.Command("wl-copy", "-t", "text/plain")
|
||||
isWayland = true
|
||||
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
|
||||
cmd = exec.Command("xclip", "-sel", "c", "-t", "text/plain")
|
||||
cmdCopy = exec.Command("xclip", "-sel", "c", "-t", "text/plain")
|
||||
} else {
|
||||
fmt.Println(AnsiError + "Clipboard platform could not be determined - Note that the clipboard does not function in a raw TTY" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
writeToStdin(cmd, copySubject)
|
||||
err := cmd.Run()
|
||||
writeToStdin(cmdCopy, copySubject)
|
||||
err := cmdCopy.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to copy to clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
launchClipClear(copySubject)
|
||||
launchClipClearProcess(copySubject, isWayland)
|
||||
}
|
||||
}
|
||||
|
||||
// clipClear is called in a separate process to clear the clipboard after 30 seconds.
|
||||
func clipClear(oldContents string) {
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
// determine clipboard tool to use (wl-clipboard VS xclip)
|
||||
var envSet bool
|
||||
var cmdClear, cmdPaste *exec.Cmd
|
||||
if _, envSet = os.LookupEnv("WAYLAND_DISPLAY"); envSet {
|
||||
cmdClear = exec.Command("wl-copy", "-c")
|
||||
cmdPaste = exec.Command("wl-paste")
|
||||
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
|
||||
cmdClear = exec.Command("xclip", "-i", "/dev/null", "-sel", "c")
|
||||
cmdPaste = exec.Command("xclip", "-o", "-sel", "c")
|
||||
} else {
|
||||
fmt.Println(AnsiError + "Clipboard platform could not be determined - Neither $WAYLAND_DISPLAY nor $DISPLAY are set" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
// getClipCommands returns the commands for pasting and clearing the clipboard contents.
|
||||
func getClipCommands() (*exec.Cmd, *exec.Cmd) {
|
||||
if os.Args[2] == "true" { // wayland
|
||||
return exec.Command("wl-paste"), exec.Command("wl-copy", "-c")
|
||||
}
|
||||
|
||||
// read current clipboard contents
|
||||
newContents, err := cmdPaste.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
// clear clipboard if contents have not been modified
|
||||
if oldContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
err = cmdClear.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
}
|
||||
Exit(0)
|
||||
return exec.Command("xclip", "-o", "-sel", "c"), exec.Command("xclip", "-i", "/dev/null", "-sel", "c")
|
||||
}
|
||||
|
||||
+4
-22
@@ -7,7 +7,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copyString copies a string to the clipboard.
|
||||
@@ -20,28 +19,11 @@ func copyString(continuous bool, copySubject string) {
|
||||
}
|
||||
|
||||
if !continuous {
|
||||
launchClipClear(copySubject)
|
||||
launchClipClearProcess(copySubject)
|
||||
}
|
||||
}
|
||||
|
||||
// clipClear is called in a separate process to clear the clipboard after 30 seconds.
|
||||
func clipClear(oldContents string) {
|
||||
time.Sleep(30 * time.Second)
|
||||
|
||||
cmd := exec.Command("powershell.exe", "-c", "Get-Clipboard")
|
||||
newContents, err := cmd.Output()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to read clipboard contents:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
|
||||
if oldContents == strings.TrimRight(string(newContents), "\r\n") {
|
||||
cmd = exec.Command("powershell.exe", "-c", "Set-Clipboard")
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError+"Failed to clear clipboard:", err.Error()+AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
}
|
||||
Exit(0)
|
||||
// getClipCommands returns the commands for pasting and clearing the clipboard contents.
|
||||
func getClipCommands() (*exec.Cmd, *exec.Cmd) {
|
||||
return exec.Command("powershell.exe", "-c", "Get-Clipboard"), exec.Command("powershell.exe", "-c", "Set-Clipboard")
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !returnOnExit
|
||||
//go:build (windows || darwin || android || termux || wsl) && !returnOnExit
|
||||
|
||||
package core
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// launchClipClear launches the automated clipboard clearing process.
|
||||
// launchClipClearProcess launches the automated clipboard clearing process.
|
||||
// For non-interactive CLI implementations, an entirely separate process is created for this purpose.
|
||||
func launchClipClear(copySubject string) {
|
||||
func launchClipClearProcess(copySubject string) {
|
||||
executableName := os.Args[0]
|
||||
cmd := exec.Command(executableName, "clipclear")
|
||||
writeToStdin(cmd, copySubject)
|
||||
@@ -0,0 +1,24 @@
|
||||
//go:build !windows && !darwin && !android && !termux && !wsl && !returnOnExit
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// launchClipClearProcess launches the automated clipboard clearing process.
|
||||
// For non-interactive CLI implementations, an entirely separate process is created for this purpose.
|
||||
func launchClipClearProcess(copySubject string, isWayland bool) {
|
||||
executableName := os.Args[0]
|
||||
cmd := exec.Command(executableName, "clipclear", strconv.FormatBool(isWayland))
|
||||
writeToStdin(cmd, copySubject)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
fmt.Println(AnsiError + "Failed to launch automated clipboard clearing process - Does this libmutton implementation support the \"clipclear\" argument?" + AnsiReset)
|
||||
os.Exit(ErrorClipboard)
|
||||
}
|
||||
os.Exit(0) // use os.Exit directly since this version of this function is only meant for non-interactive CLI implementations
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
//go:build returnOnExit
|
||||
|
||||
package core
|
||||
|
||||
// launchClipClear launches the automated clipboard clearing process.
|
||||
// For interactive GUI/TUI implementations, the clipboard clearing process is launched as a goroutine.
|
||||
func launchClipClear(copySubject string) {
|
||||
go clipClear(copySubject)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
//go:build (windows || darwin || android || termux || wsl) && returnOnExit
|
||||
|
||||
package core
|
||||
|
||||
// launchClipClearProcess launches the automated clipboard clearing process.
|
||||
// For interactive GUI/TUI implementations, the clipboard clearing process is launched as a goroutine.
|
||||
func launchClipClearProcess(copySubject string) {
|
||||
go clipClearProcess(copySubject)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build !windows && !darwin && !android && !termux && !wsl && returnOnExit
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// launchClipClearProcess launches the automated clipboard clearing process.
|
||||
// For interactive GUI/TUI implementations, the clipboard clearing process is launched as a goroutine.
|
||||
func launchClipClearProcess(copySubject string, isWayland bool) {
|
||||
os.Args[2] = strconv.FormatBool(isWayland)
|
||||
go clipClearProcess(copySubject)
|
||||
}
|
||||
Reference in New Issue
Block a user