Greatly reduce code duplication in clipboard implementations

This commit is contained in:
2024-03-03 23:26:39 -05:00
parent 6fecf5a686
commit 24b899a83a
7 changed files with 112 additions and 140 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ func main() {
default:
cli.HelpCopy()
}
offline.CopyField(targetLocation, field, args[0])
offline.CopyArgument(targetLocation, field, args[0])
case "edit":
var field rune
field = field // TODO temporary to avoid unused variable error
+1 -3
View File
@@ -65,9 +65,7 @@ func EntryReader(decryptedEntry []string, hidePassword bool) {
}
func EntryReaderShortcut(targetLocation string, hidePassword bool) {
if isFile, _ := offline.TargetIsFile(targetLocation, true); isFile {
if isFile, _ := offline.TargetIsFile(targetLocation, true, 2); isFile {
EntryReader(offline.DecryptGPG(targetLocation), hidePassword)
} else {
fmt.Println(offline.AnsiError + "Failed to read \"" + targetLocation + "\" - it is a directory" + offline.AnsiReset)
}
}
+43
View File
@@ -0,0 +1,43 @@
package offline
import (
"bufio"
"fmt"
"os"
)
func CopyArgument(targetLocation string, field int, executableName string) {
if isFile, _ := TargetIsFile(targetLocation, true, 2); isFile {
decryptedEntry := DecryptGPG(targetLocation)
var copySubject string // will store data to be copied
// ensure field exists in entry
if len(decryptedEntry) > field {
copySubject = decryptedEntry[field]
} else {
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
os.Exit(1)
}
// ensure field is not blank
if copySubject == "" {
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
os.Exit(1)
}
// copy field to clipboard, launch clipboard clearing process
copyField(copySubject, executableName)
}
}
func ClipClearArgument() {
// read previous clipboard contents from stdin
clipScanner := bufio.NewScanner(os.Stdin)
if clipScanner.Scan() {
oldContents := clipScanner.Text()
clipClear(oldContents)
} else {
os.Exit(0)
}
}
+16 -38
View File
@@ -13,50 +13,28 @@ import (
// TODO MacOS support is entirely untested - I would appreciate feedback on this implementation
// CopyField copies a field from an entry to the clipboard
func CopyField(targetLocation string, field int, executableName string) {
if isFile, _ := TargetIsFile(targetLocation, true); isFile {
decryptedEntry := DecryptGPG(targetLocation)
var copySubject string // will store data to be copied
// ensure field exists in entry
if len(decryptedEntry) > field {
copySubject = decryptedEntry[field]
} else {
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
os.Exit(1)
}
// ensure field is not blank
if copySubject == "" {
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
os.Exit(1)
}
cmd := exec.Command("pbcopy")
writeToStdin(cmd, copySubject)
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
} else {
fmt.Println(AnsiError + "Failed to read \"" + targetLocation + "\" - it is a directory" + AnsiReset)
func copyField(copySubject string, executableName string) {
cmd := exec.Command("pbcopy")
writeToStdin(cmd, copySubject)
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
os.Exit(0)
}
// ClipClear is called in a separate process to clear the clipboard after 30 seconds
func ClipClear(oldContents string) {
func clipClear(oldContents string) {
time.Sleep(30 * time.Second)
cmd := exec.Command("pbpaste")
+26 -48
View File
@@ -13,61 +13,39 @@ import (
// TODO Implement support for Termux via termux-clipboard-set (in separate file)
// CopyField copies a field from an entry to the clipboard
func CopyField(targetLocation string, field int, executableName string) {
if isFile, _ := TargetIsFile(targetLocation, true); isFile {
decryptedEntry := DecryptGPG(targetLocation)
var copySubject string // will store data to be copied
// ensure field exists in entry
if len(decryptedEntry) > field {
copySubject = decryptedEntry[field]
} else {
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
os.Exit(1)
}
// ensure field is not blank
if copySubject == "" {
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
os.Exit(1)
}
var envSet bool // track whether environment variables are set
var cmd *exec.Cmd
// determine whether to use wl-copy (Wayland) or xclip (X11)
if _, envSet = os.LookupEnv("WAYLAND_DISPLAY"); envSet {
cmd = exec.Command("wl-copy")
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
cmd = exec.Command("xclip", "-sel", "c")
} else {
fmt.Println(AnsiError + "Clipboard platform could not be determined - note that the clipboard does not function in a raw TTY" + AnsiReset)
os.Exit(1)
}
writeToStdin(cmd, copySubject)
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
func copyField(copySubject string, executableName string) {
var envSet bool // track whether environment variables are set
var cmd *exec.Cmd
// determine whether to use wl-copy (Wayland) or xclip (X11)
if _, envSet = os.LookupEnv("WAYLAND_DISPLAY"); envSet {
cmd = exec.Command("wl-copy")
} else if _, envSet = os.LookupEnv("DISPLAY"); envSet {
cmd = exec.Command("xclip", "-sel", "c")
} else {
fmt.Println(AnsiError + "Failed to read \"" + targetLocation + "\" - it is a directory" + AnsiReset)
fmt.Println(AnsiError + "Clipboard platform could not be determined - note that the clipboard does not function in a raw TTY" + AnsiReset)
os.Exit(1)
}
writeToStdin(cmd, copySubject)
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
os.Exit(0)
}
// ClipClear is called in a separate process to clear the clipboard after 30 seconds
func ClipClear(oldContents string) {
func clipClear(oldContents string) {
time.Sleep(30 * time.Second)
var envSet bool // track whether environment variables are set
+15 -37
View File
@@ -11,49 +11,27 @@ import (
)
// CopyField copies a field from an entry to the clipboard
func CopyField(targetLocation string, field int, executableName string) {
if isFile, _ := TargetIsFile(targetLocation, true); isFile {
decryptedEntry := DecryptGPG(targetLocation)
var copySubject string // will store data to be copied
// ensure field exists in entry
if len(decryptedEntry) > field {
copySubject = decryptedEntry[field]
} else {
fmt.Println(AnsiError + "Field does not exist in entry" + AnsiReset)
os.Exit(1)
}
// ensure field is not blank
if copySubject == "" {
fmt.Println(AnsiError + "Field is empty" + AnsiReset)
os.Exit(1)
}
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", copySubject))
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
} else {
fmt.Println(AnsiError + "Failed to read \"" + targetLocation + "\" - it is a directory" + AnsiReset)
func copyField(copySubject string, executableName string) {
cmd := exec.Command("powershell.exe", "-c", fmt.Sprintf("echo '%s' | Set-Clipboard", copySubject))
err := cmd.Run()
if err != nil {
fmt.Println(AnsiError + "Failed to copy to clipboard: " + err.Error() + AnsiReset)
os.Exit(1)
}
cmd = exec.Command(executableName, "clipclear")
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(1)
}
os.Exit(0)
}
// ClipClear is called in a separate process to clear the clipboard after 30 seconds
func ClipClear(oldContents string) {
func clipClear(oldContents string) {
time.Sleep(30 * time.Second)
cmd := exec.Command("powershell.exe", "-c", "Get-Clipboard")
@@ -1,7 +1,6 @@
package offline
import (
"bufio"
"fmt"
"io"
"os"
@@ -9,8 +8,9 @@ import (
)
// TargetIsFile TargetStatusCheck checks if the targetLocation is a file, directory, or is inaccessible
// failCondition: 0 = fail on inaccessible, 1 = fail on inaccessible/file, 2 = fail on inaccessible/directory
// returns: isFile, isAccessible
func TargetIsFile(targetLocation string, errorOnFail bool) (bool, bool) {
func TargetIsFile(targetLocation string, errorOnFail bool, failCondition uint8) (bool, bool) {
targetInfo, err := os.Stat(targetLocation)
if err != nil {
if errorOnFail {
@@ -21,8 +21,16 @@ func TargetIsFile(targetLocation string, errorOnFail bool) (bool, bool) {
}
}
if targetInfo.IsDir() {
if errorOnFail && failCondition == 2 {
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a directory" + AnsiReset)
os.Exit(1)
}
return false, true
} else {
if errorOnFail && failCondition == 1 {
fmt.Println(AnsiError + "\"" + targetLocation + "\" is a file" + AnsiReset)
os.Exit(1)
}
return true, true
}
}
@@ -35,14 +43,3 @@ func writeToStdin(cmd *exec.Cmd, input string) {
io.WriteString(stdin, input)
}()
}
func ClipClearArgument() {
// read previous clipboard contents from stdin
clipScanner := bufio.NewScanner(os.Stdin)
if clipScanner.Scan() {
oldContents := clipScanner.Text()
ClipClear(oldContents)
} else {
os.Exit(0)
}
}