diff --git a/CHANGELOG.md b/CHANGELOG.md index f3763f9..2cd4326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,4 +4,8 @@ - switch from flags to subcommands: `wl-paste -t text --watch clipman store` instead than `clipman -d` and `clipman pick` instead than `clipman -s` - switch demon from polling to event-driven: requires wl-clipboard >= 2.0 + +**New features**: + - primary clipboard support: `wl-paste -p -t text --watch clipman store --histpath="~/.local/share/clipman-primary.json` and `clipman pick --histpath="~/.local/share/clipman-primary.json` +- new `clear` command for removing item(s) from history diff --git a/main.go b/main.go index 19b312e..07b947e 100644 --- a/main.go +++ b/main.go @@ -7,20 +7,25 @@ import ( "io/ioutil" "log" "os" + "os/exec" "strings" "gopkg.in/alecthomas/kingpin.v2" ) var ( - app = kingpin.New("clipman", "A clipboard manager for Wayland") - histpath = app.Flag("histpath", "Path of history file").Default("~/.local/share/clipman.json").String() - storer = app.Command("store", "Run from `wl-paste --watch` to record clipboard events") - picker = app.Command("pick", "Pick an item from clipboard history") - noPersist = storer.Flag("no-persist", "Don't persist a copy buffer after a program exits").Short('P').Default("false").Bool() - maxDemon = storer.Flag("max-items", "history size").Default("15").Int() - maxPicker = picker.Flag("max-items", "scrollview length").Default("15").Int() - tool = picker.Flag("selector", "Which selector to use: dmenu/rofi/-").Default("dmenu").String() + app = kingpin.New("clipman", "A clipboard manager for Wayland") + histpath = app.Flag("histpath", "Path of history file").Default("~/.local/share/clipman.json").String() + storer = app.Command("store", "Run from `wl-paste --watch` to record clipboard events") + picker = app.Command("pick", "Pick an item from clipboard history") + clearer = app.Command("clear", "Remove an item from history") + noPersist = storer.Flag("no-persist", "Don't persist a copy buffer after a program exits").Short('P').Default("false").Bool() + maxDemon = storer.Flag("max-items", "history size").Default("15").Int() + maxPicker = picker.Flag("max-items", "scrollview length").Default("15").Int() + pickTool = picker.Flag("selector", "Which selector to use: dmenu/rofi/-").Default("dmenu").String() + clearTool = clearer.Flag("selector", "Which selector to use: dmenu/rofi/-").Default("dmenu").String() + maxClearer = clearer.Flag("max-items", "scrollview length").Default("15").Int() + clearAll = clearer.Flag("all", "Remove all items").Short('a').Default("false").Bool() ) func main() { @@ -52,7 +57,32 @@ func main() { log.Fatal(err) } - if err := selector(history, *maxPicker, *tool); err != nil { + selection, err := selector(history, *maxPicker, *pickTool) + if err != nil { + log.Fatal(err) + } + + // serve selection to the OS + err = exec.Command("wl-copy", []string{"--", selection}...).Run() + case "clear": + histfile, history, err := getHistory() + if err != nil { + log.Fatal(err) + } + + if *clearAll { + if err := os.Remove(histfile); err != nil { + log.Fatal(err) + } + os.Exit(0) + } + + selection, err := selector(history, *maxClearer, *clearTool) + if err != nil { + log.Fatal(err) + } + + if err := write(filter(history, selection), histfile); err != nil { log.Fatal(err) } } diff --git a/selector.go b/selector.go index 0971397..db46d63 100644 --- a/selector.go +++ b/selector.go @@ -9,25 +9,23 @@ import ( "strings" ) -func selector(history []string, max int, tool string) error { +func selector(history []string, max int, tool string) (string, error) { if len(history) == 0 { log.Fatal("No history available") } + // don't modify in-place! + tmp := make([]string, len(history)) + copy(tmp, history) + // reverse the history for i, j := 0, len(history)-1; i < j; i, j = i+1, j-1 { - history[i], history[j] = history[j], history[i] + tmp[i], tmp[j] = tmp[j], tmp[i] } - selected, err := dmenu(history, max, tool) - if err != nil { - return err - } + selected, err := dmenu(tmp, max, tool) - // serve selection to the OS - err = exec.Command("wl-copy", []string{"--", selected}...).Run() - - return err + return selected, err } func dmenu(list []string, max int, tool string) (string, error) {