From bcfcd493fc0bbd428d9e865fa9a7980270bd6b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6tz=20Christ?= Date: Sun, 15 Sep 2019 02:30:31 -0500 Subject: [PATCH] feat: add STDOUT selector (#20) Note that the output is a repr string, so for example newlines and tabs are escaped as literals. --- main.go | 2 +- selector.go | 60 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/main.go b/main.go index d622f42..9e21567 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,7 @@ var ( asSelector = app.Flag("select", "Select an item from clipboard history").Short('s').Default("false").Bool() noPersist = app.Flag("no-persist", "Don't persist a copy buffer after a program exits").Short('P').Default("false").Bool() max = app.Flag("max-items", "history size (with -d) or scrollview length (with -s)").Default("15").Int() - tool = app.Flag("selector", "Which selector to use: dmenu/rofi").Default("dmenu").String() + tool = app.Flag("selector", "Which selector to use: dmenu/rofi/-").Default("dmenu").String() histpath = app.Flag("histpath", "Directory where to save history").Default("~/.local/share/clipman.json").String() ) diff --git a/selector.go b/selector.go index e93aed7..102bd9e 100644 --- a/selector.go +++ b/selector.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "os/exec" "strconv" "strings" @@ -29,43 +30,34 @@ func dmenu(list []string, max int, tool string) (string, error) { return "", nil } + if tool == "-" { + escaped, _ := preprocess_history(list, false) + os.Stdout.WriteString(strings.Join(escaped, "\n")) + return "", nil + } + bin, err := exec.LookPath(tool) if err != nil { return "", fmt.Errorf("%s is not installed", tool) } var args []string - if tool == "dmenu" { + switch tool { + case "dmenu": args = []string{"dmenu", "-b", "-fn", "-misc-dejavu sans mono-medium-r-normal--17-120-100-100-m-0-iso8859-16", "-l", strconv.Itoa(max)} - } else { + case "rofi": args = []string{"rofi", "-dmenu", "-lines", strconv.Itoa(max)} + default: + return "", fmt.Errorf("Unsupported tool") } - // dmenu will break if items contain newlines, so we must pass them as literals. - // however, when it sends them back, we need a way to restore them - var escaped []string - guide := make(map[string]string) - for _, original := range list { - repr := fmt.Sprintf("%#v", original) - - // dmenu will split lines longer than 1200 something; we cut at 400 to spare memory - max := len(repr) - 1 // drop right quote - maxChars := 400 - if max > maxChars { - max = maxChars - } - repr = repr[1:max] // drop left quote - - guide[repr] = original - escaped = append(escaped, repr) - } - + escaped, guide := preprocess_history(list, true) input := strings.NewReader(strings.Join(escaped, "\n")) cmd := exec.Cmd{Path: bin, Args: args, Stdin: input} @@ -86,3 +78,29 @@ func dmenu(list []string, max int, tool string) (string, error) { return sel, nil } + +func preprocess_history(list []string, cutting bool) ([]string, map[string]string) { + // dmenu will break if items contain newlines, so we must pass them as literals. + // however, when it sends them back, we need a way to restore them + var escaped []string + guide := make(map[string]string) + + for _, original := range list { + repr := fmt.Sprintf("%#v", original) + max := len(repr) - 1 // drop right quote + + // dmenu will split lines longer than 1200 something; we cut at 400 to spare memory + if cutting { + maxChars := 400 + if max > maxChars { + max = maxChars + } + } + + repr = repr[1:max] // drop left quote + guide[repr] = original + escaped = append(escaped, repr) + } + + return escaped, guide +}