Compare commits

..

10 commits

Author SHA1 Message Date
Benjamin Wild
d5cf6d9f17
docs: fix typo 2020-09-30 08:30:22 +02:00
yory8
8aac681b97
docs: fix usage of primary clipboard (#48) 2020-09-10 16:25:56 +02:00
yory8
14bf2b7baa
docs: fixup 2020-09-10 09:04:17 +02:00
yory8
167e9ac93f
docs: correct info on primary clip 2020-09-10 09:03:27 +02:00
yory8
77706941a3 docs: vim visual block breaks 2020-06-29 23:10:10 +02:00
yory8
c5de70df5f docs: up man 2020-05-22 09:05:18 +02:00
yory8
1eb93a5ff0 feat: unix flag to normalize EOLs to LF
Vim doesn't normalize EOLs of pasted text according to the buffer's
filetype. Also see https://gitlab.gnome.org/GNOME/gtk/issues/2307
2020-05-16 15:54:36 +02:00
yory8
bb95b603d0 chore: cut new release 2020-05-12 16:01:01 +02:00
yory8
e1dea61d31 fix: daemonize wl-copy 2020-05-12 15:49:29 +02:00
yory8
ef9e6bece2 fix(selector): revert 6a818c80c4
Breaks fzf, and doesn't seem to be needed anymore
2020-05-10 22:16:53 +02:00
5 changed files with 73 additions and 12 deletions

View file

@ -1,4 +1,17 @@
# 1.5.1 # Next
**New features**
- `--unix` option to normalize all line endings to LF
# 1.5.2
**Notable bug fixes**
- wl-copy is now truly daemonized, allowing calling `alacritty -e sh -c clipman pick`
- fzf couldn't recover the clipboard content in some cases
# 1.5.1
**Notable bug fixes** **Notable bug fixes**

View file

@ -24,10 +24,10 @@ These distros ship with clipman binaries in their repos:
## Usage ## Usage
Run the binary in your Sway session by adding `exec wl-paste -t text --watch clipman store` (or `exec wl-paste -t text --watch clipman store 1>> PATH/TO/LOGFILE 2>&1 &` to log errors) at the beginning of your config. Run the binary in your Sway session by adding `exec wl-paste -t text --watch clipman store` (or `exec wl-paste -t text --watch clipman store 1>> PATH/TO/LOGFILE 2>&1 &` to log errors) at the beginning of your config.
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store --histpath="~/.local/share/clipman-primary.json`.
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store -P --histpath="~/.local/share/clipman-primary.json"` (note that both the `-p` in wl-paste and the `-P` in clipman are mandatory in this case).
To query the history and select items, run the binary as `clipman pick -t wofi`. You can assign it to a keybinding: `bindsym $mod+h exec clipman pick -t wofi`. To query the history and select items, run the binary as `clipman pick -t wofi`. You can assign it to a keybinding: `bindsym $mod+h exec clipman pick -t wofi`.
For primary clipboard support, `clipman pick -t wofi --histpath="~/.local/share/clipman-primary.json`.
You can pass additional arguments to the selector like this: `clipman pick --tool wofi -T'--prompt=my-prompt -i'` (both `--prompt` and `-i` are flags of wofi). You can pass additional arguments to the selector like this: `clipman pick --tool wofi -T'--prompt=my-prompt -i'` (both `--prompt` and `-i` are flags of wofi).
You can use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`. You can use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`.
@ -44,6 +44,10 @@ For more options: `clipman -h`.
- All items stored in history are treated as plain text. - All items stored in history are treated as plain text.
- By default, we continue serving the last copied item even after its owner has exited. This means that, unless you run with the `--no-persist` option, you'll always immediately lose rich content: for example, if you copy formatted text inside Libre Office you'll lose all formatting on paste; or, if you copy a bookmark in Firefox, you won't be able to paste it in another bookmark folder. - By default, we continue serving the last copied item even after its owner has exited. This means that, unless you run with the `--no-persist` option, you'll always immediately lose rich content: for example, if you copy formatted text inside Libre Office you'll lose all formatting on paste; or, if you copy a bookmark in Firefox, you won't be able to paste it in another bookmark folder.
### Vim's Visual Block mode breaks if persistence is enabled
Run `clipman store` with the `--no-persist` option if you are affected. Unfortunately, it seems that there is no way to make them play well together.
## Versions ## Versions
This projects follows SemVer conventions. This projects follows SemVer conventions.

View file

@ -1,4 +1,4 @@
.TH clipman 1 1.5.1 "" .TH clipman 1 1.5.2 ""
.SH "NAME" .SH "NAME"
clipman clipman
.SH "SYNOPSIS" .SH "SYNOPSIS"
@ -35,6 +35,9 @@ history size
.TP .TP
\fB-P, --no-persist\fR \fB-P, --no-persist\fR
Don't persist a copy buffer after a program exits Don't persist a copy buffer after a program exits
.TP
\fB--unix\fR
Normalize line endings to LF
.SS .SS
\fBpick --tool=TOOL [<flags>]\fR \fBpick --tool=TOOL [<flags>]\fR
.PP .PP
@ -76,10 +79,10 @@ Separate items using NULL; recommended if your tool supports --read0 or similar
Serve the last recorded item from history Serve the last recorded item from history
.SH "USAGE" .SH "USAGE"
Run the binary in your Sway session by adding `exec wl-paste -t text --watch clipman store` (or `exec wl-paste -t text --watch clipman store 1>> PATH/TO/LOGFILE 2>&1 &` to log errors) at the beginning of your config. Run the binary in your Sway session by adding `exec wl-paste -t text --watch clipman store` (or `exec wl-paste -t text --watch clipman store 1>> PATH/TO/LOGFILE 2>&1 &` to log errors) at the beginning of your config.
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store --histpath="~/.local/share/clipman-primary.json`. .PP
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store -P --histpath="~/.local/share/clipman-primary.json` (note that both the `-p` in wl-paste and the `-P` in clipman are mandatory in this case).
.PP .PP
To query the history and select items, run the binary as `clipman pick -t wofi`. You can assign it to a keybinding: `bindsym $mod+h exec clipman pick -t wofi`. To query the history and select items, run the binary as `clipman pick -t wofi`. You can assign it to a keybinding: `bindsym $mod+h exec clipman pick -t wofi`.
For primary clipboard support, `clipman pick -t wofi --histpath="~/.local/share/clipman-primary.json`.
You can pass additional arguments to the selector like this: `clipman pick --tool wofi -T'--prompt=my-prompt -i'` (both `--prompt` and `-i` are flags of wofi). You can pass additional arguments to the selector like this: `clipman pick --tool wofi -T'--prompt=my-prompt -i'` (both `--prompt` and `-i` are flags of wofi).
You can use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`. You can use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`.
.PP .PP
@ -87,6 +90,10 @@ To remove items from history, `clipman clear -t wofi` and `clipman clear --all`.
.PP .PP
To serve the last history item at startup, add `exec clipman restore` to your Sway config. To serve the last history item at startup, add `exec clipman restore` to your Sway config.
.SH "KNOWN ISSUES" .SH "KNOWN ISSUES"
All items stored in history are treated as plain text. \fBAll items stored in history are treated as plain text.\fR
.PP .PP
By default, we continue serving the last copied item even after its owner has exited. This means that, unless you run with the `--no-persist` option, you'll always immediately lose rich content: for example, if you copy formatted text inside Libre Office you'll lose all formatting on paste; or, if you copy a bookmark in Firefox, you won't be able to paste it in another bookmark folder. By default, we continue serving the last copied item even after its owner has exited. This means that, unless you run with the `--no-persist` option, you'll always immediately lose rich content: for example, if you copy formatted text inside Libre Office you'll lose all formatting on paste; or, if you copy a bookmark in Firefox, you won't be able to paste it in another bookmark folder.
.PP
\fBVim's Visual Block mode breaks if persistence is enabled\fR
.PP
Run `clipman store` with the `--no-persist` option if you are affected. Unfortunately, it seems that there is no way to make them play well together.

45
main.go
View file

@ -11,11 +11,12 @@ import (
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
"syscall"
"gopkg.in/alecthomas/kingpin.v2" "gopkg.in/alecthomas/kingpin.v2"
) )
const version = "1.5.1" const version = "1.5.2"
var ( var (
app = kingpin.New("clipman", "A clipboard manager for Wayland") app = kingpin.New("clipman", "A clipboard manager for Wayland")
@ -25,6 +26,7 @@ var (
storer = app.Command("store", "Record clipboard events (run as argument to `wl-paste --watch`)") storer = app.Command("store", "Record clipboard events (run as argument to `wl-paste --watch`)")
maxDemon = storer.Flag("max-items", "history size").Default("15").Int() maxDemon = storer.Flag("max-items", "history size").Default("15").Int()
noPersist = storer.Flag("no-persist", "Don't persist a copy buffer after a program exits").Short('P').Default("false").Bool() noPersist = storer.Flag("no-persist", "Don't persist a copy buffer after a program exits").Short('P').Default("false").Bool()
unix = storer.Flag("unix", "Normalize line endings to LF").Bool()
picker = app.Command("pick", "Pick an item from clipboard history") picker = app.Command("pick", "Pick an item from clipboard history")
maxPicker = picker.Flag("max-items", "scrollview length").Default("15").Int() maxPicker = picker.Flag("max-items", "scrollview length").Default("15").Int()
@ -178,8 +180,14 @@ func serveTxt(s string) {
smartLog(fmt.Sprintf("couldn't find wl-copy: %v\n", err), "low", *alert) smartLog(fmt.Sprintf("couldn't find wl-copy: %v\n", err), "low", *alert)
} }
// daemonize wl-copy into a truly independent process
// necessary for running stuff like `alacritty -e sh -c clipman pick`
attr := &syscall.SysProcAttr{
Setpgid: true,
}
// we mandate the mime type because we know we can only serve text; not doing this leads to weird bugs like #35 // we mandate the mime type because we know we can only serve text; not doing this leads to weird bugs like #35
cmd := exec.Cmd{Path: bin, Args: []string{bin, "-t", "TEXT"}, Stdin: strings.NewReader(s)} cmd := exec.Cmd{Path: bin, Args: []string{bin, "-t", "TEXT"}, Stdin: strings.NewReader(s), SysProcAttr: attr}
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
smartLog(fmt.Sprintf("error running wl-copy: %s\n", err), "low", *alert) smartLog(fmt.Sprintf("error running wl-copy: %s\n", err), "low", *alert)
} }
@ -193,14 +201,43 @@ func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if i := bytes.IndexByte(data, '\n'); i >= 0 { if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line. // We have a full newline-terminated line.
return i + 1, data[0 : i+1], nil b := data[0 : i+1]
if *unix {
b = dropCR(b)
}
return i + 1, b, nil
} }
// If we're at EOF, we have a final, non-terminated line. Return it. // If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF { if atEOF {
return len(data), data, nil b := data
if *unix {
b = dropCR(b)
}
return len(data), b, nil
} }
// Request more data. // Request more data.
return 0, nil, nil return 0, nil, nil
} }
// dropCR drops a terminal \r from the data. Modified from Go's Stdlib
func dropCR(data []byte) []byte {
orig := data
var lf bool
if len(data) > 0 && data[len(data)-1] == '\n' {
lf = true
data = data[0 : len(data)-1]
}
if len(data) > 0 && data[len(data)-1] == '\r' {
b := data[0 : len(data)-1]
if lf {
b = append(b, '\n')
}
return b
}
return orig
}

View file

@ -80,7 +80,7 @@ func selector(data []string, max int, tool, prompt, toolArgs string, null bool)
sep = "\000" sep = "\000"
} }
cmd := exec.Cmd{Path: bin, Args: args, Stdin: strings.NewReader(strings.Join(processed, sep) + "\n")} cmd := exec.Cmd{Path: bin, Args: args, Stdin: strings.NewReader(strings.Join(processed, sep))}
cmd.Stderr = os.Stderr // let stderr pass to console cmd.Stderr = os.Stderr // let stderr pass to console
b, err := cmd.Output() b, err := cmd.Output()
if err != nil { if err != nil {