Compare commits

..

No commits in common. "d5cf6d9f17d1f4de0441351bc56714f29238454b" and "b069dfe4f6453c01286aa3412301df60c8fdbfc9" have entirely different histories.

5 changed files with 12 additions and 73 deletions

View file

@ -1,16 +1,3 @@
# 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**

View file

@ -24,10 +24,10 @@ These distros ship with clipman binaries in their repos:
## 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.
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).
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store --histpath="~/.local/share/clipman-primary.json`.
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 use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`.
@ -44,10 +44,6 @@ For more options: `clipman -h`.
- 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.
### 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
This projects follows SemVer conventions.

View file

@ -1,4 +1,4 @@
.TH clipman 1 1.5.2 ""
.TH clipman 1 1.5.1 ""
.SH "NAME"
clipman
.SH "SYNOPSIS"
@ -35,9 +35,6 @@ history size
.TP
\fB-P, --no-persist\fR
Don't persist a copy buffer after a program exits
.TP
\fB--unix\fR
Normalize line endings to LF
.SS
\fBpick --tool=TOOL [<flags>]\fR
.PP
@ -79,10 +76,10 @@ Separate items using NULL; recommended if your tool supports --read0 or similar
Serve the last recorded item from history
.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.
.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).
For primary clipboard support, also add `exec wl-paste -p -t text --watch clipman store --histpath="~/.local/share/clipman-primary.json`.
.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`.
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 use a custom selector like this: `clipman pick --print0 --tool=CUSTOM --tool-args="fzf --prompt 'pick > ' --bind 'tab:up' --cycle --read0"`.
.PP
@ -90,10 +87,6 @@ To remove items from history, `clipman clear -t wofi` and `clipman clear --all`.
.PP
To serve the last history item at startup, add `exec clipman restore` to your Sway config.
.SH "KNOWN ISSUES"
\fBAll items stored in history are treated as plain text.\fR
All items stored in history are treated as plain text.
.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.
.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,12 +11,11 @@ import (
"os"
"os/exec"
"strings"
"syscall"
"gopkg.in/alecthomas/kingpin.v2"
)
const version = "1.5.2"
const version = "1.5.1"
var (
app = kingpin.New("clipman", "A clipboard manager for Wayland")
@ -26,7 +25,6 @@ var (
storer = app.Command("store", "Record clipboard events (run as argument to `wl-paste --watch`)")
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()
unix = storer.Flag("unix", "Normalize line endings to LF").Bool()
picker = app.Command("pick", "Pick an item from clipboard history")
maxPicker = picker.Flag("max-items", "scrollview length").Default("15").Int()
@ -180,14 +178,8 @@ func serveTxt(s string) {
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
cmd := exec.Cmd{Path: bin, Args: []string{bin, "-t", "TEXT"}, Stdin: strings.NewReader(s), SysProcAttr: attr}
cmd := exec.Cmd{Path: bin, Args: []string{bin, "-t", "TEXT"}, Stdin: strings.NewReader(s)}
if err := cmd.Run(); err != nil {
smartLog(fmt.Sprintf("error running wl-copy: %s\n", err), "low", *alert)
}
@ -201,43 +193,14 @@ func scanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
if i := bytes.IndexByte(data, '\n'); i >= 0 {
// We have a full newline-terminated line.
b := data[0 : i+1]
if *unix {
b = dropCR(b)
}
return i + 1, b, nil
return i + 1, data[0 : i+1], nil
}
// If we're at EOF, we have a final, non-terminated line. Return it.
if atEOF {
b := data
if *unix {
b = dropCR(b)
}
return len(data), b, nil
return len(data), data, nil
}
// Request more data.
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"
}
cmd := exec.Cmd{Path: bin, Args: args, Stdin: strings.NewReader(strings.Join(processed, sep))}
cmd := exec.Cmd{Path: bin, Args: args, Stdin: strings.NewReader(strings.Join(processed, sep) + "\n")}
cmd.Stderr = os.Stderr // let stderr pass to console
b, err := cmd.Output()
if err != nil {