From 19569a81bcefa721d52190d3b893f871ed192718 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:29:12 +0000 Subject: [PATCH 01/11] Log new clipboard entries without $DEBUG --- clipmenud | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clipmenud b/clipmenud index 0f440c1..03c4e8e 100755 --- a/clipmenud +++ b/clipmenud @@ -103,6 +103,10 @@ while sleep "${CLIPMENUD_SLEEP:-0.5}"; do last_filename[$selection]=$filename first_line=$(get_first_line "$data") + + printf 'New clipboard entry on %s selection: "%s"\n' \ + "$selection" "$first_line" + filename="$cache_dir/$(cksum <<< "$first_line")" debug "Writing $data to $filename" printf '%s' "$data" > "$filename" From eecc03171887f4866f12fd011e50c71b4ffabbc9 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:31:01 +0000 Subject: [PATCH 02/11] Use stderr for xsel logging when detached --- clipmenu | 2 +- clipmenud | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clipmenu b/clipmenu index 5b5f873..bdb6489 100755 --- a/clipmenu +++ b/clipmenu @@ -24,5 +24,5 @@ if ! [[ -f "$file" ]]; then fi for selection in clipboard primary; do - xsel --logfile /dev/null -i --"$selection" < "$file" + xsel --logfile /dev/stderr -i --"$selection" < "$file" done diff --git a/clipmenud b/clipmenud index 03c4e8e..782f42d 100755 --- a/clipmenud +++ b/clipmenud @@ -7,7 +7,7 @@ lock_file=$cache_dir/lock lock_timeout=2 _xsel() { - timeout 1 xsel --logfile /dev/null "$@" + timeout 1 xsel --logfile /dev/stderr "$@" } get_first_line() { From 117385015b98004cc359d18e5e3f7892e3aad0f8 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:40:19 +0000 Subject: [PATCH 03/11] Add $CM_LAUNCHER env variable --- clipmenu | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clipmenu b/clipmenu index bdb6489..5094c46 100755 --- a/clipmenu +++ b/clipmenu @@ -7,11 +7,13 @@ shopt -s nullglob cache_dir=/tmp/clipmenu.$major_version.$USER cache_file=$cache_dir/line_cache +: "${CM_LAUNCHER:-dmenu}" + # It's okay to hardcode `-l 8` here as a sensible default without checking # whether `-l` is also in "$@", because the way that dmenu works allows a later # argument to override an earlier one. That is, if the user passes in `-l`, our # one will be ignored. -chosen_line=$(tac "$cache_file" | awk '!seen[$0]++' | dmenu -l 8 "$@") +chosen_line=$(tac "$cache_file" | awk '!seen[$0]++' | "$CM_LAUNCHER" -l 8 "$@") [[ $chosen_line ]] || exit 1 From e65b51b33c6e219b05aab21c909da2a7b5e6dbdc Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:45:36 +0000 Subject: [PATCH 04/11] Use CM_* env vars --- README.md | 4 ++-- clipmenu | 2 +- clipmenud | 14 +++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 360eb74..b175aee 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ there, but it basically works like this: ## clipmenud 1. `clipmenud` polls the clipboard every 0.5 seconds (or another interval as - configured with the `CLIPMENUD_SLEEP` environment variable). Unfortunately - there's no interface to subscribe for changes in X11, so we must poll. + configured with the `CM_SLEEP` environment variable). Unfortunately there's + no interface to subscribe for changes in X11, so we must poll. 2. If `clipmenud` detects changes to the clipboard contents, it writes them out to the cache directory. diff --git a/clipmenu b/clipmenu index 5094c46..203bfe3 100755 --- a/clipmenu +++ b/clipmenu @@ -7,7 +7,7 @@ shopt -s nullglob cache_dir=/tmp/clipmenu.$major_version.$USER cache_file=$cache_dir/line_cache -: "${CM_LAUNCHER:-dmenu}" +: "${CM_LAUNCHER=dmenu}" # It's okay to hardcode `-l 8` here as a sensible default without checking # whether `-l` is also in "$@", because the way that dmenu works allows a later diff --git a/clipmenud b/clipmenud index 782f42d..ad35888 100755 --- a/clipmenud +++ b/clipmenud @@ -6,6 +6,10 @@ cache_file=$cache_dir/line_cache lock_file=$cache_dir/lock lock_timeout=2 +: "${CM_ONESHOT=0}" +: "${CM_OWN_CLIPBOARD=1}" +: "${CM_DEBUG=0}" + _xsel() { timeout 1 xsel --logfile /dev/stderr "$@" } @@ -42,7 +46,7 @@ get_first_line() { } debug() { - if (( DEBUG )); then + if (( CM_DEBUG )); then printf '%s\n' "$@" >&2 fi } @@ -56,9 +60,9 @@ declare -A last_filename exec {lock_fd}> "$lock_file" -while sleep "${CLIPMENUD_SLEEP:-0.5}"; do +while sleep "${CM_SLEEP:-0.5}"; do if ! flock -x -w "$lock_timeout" "$lock_fd"; then - if (( ONESHOT )); then + if (( CM_ONESHOT )); then printf 'ERROR: %s\n' 'Timed out waiting for lock' >&2 exit 1 else @@ -114,7 +118,7 @@ while sleep "${CLIPMENUD_SLEEP:-0.5}"; do debug "Writing $first_line to $cache_file" printf '%s\n' "$first_line" >> "$cache_file" - if ! (( NO_OWN_CLIPBOARD )) && [[ $selection != primary ]]; then + if (( CM_OWN_CLIPBOARD )) && [[ $selection != primary ]]; then # Take ownership of the clipboard, in case the original application # is unable to serve the clipboard request (due to being suspended, # etc). @@ -132,7 +136,7 @@ while sleep "${CLIPMENUD_SLEEP:-0.5}"; do flock -u "$lock_fd" - if (( ONESHOT )); then + if (( CM_ONESHOT )); then debug 'Oneshot mode enabled, exiting' break fi From abe461461b3a0d6d4e54255c984628a4447b9645 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:52:55 +0000 Subject: [PATCH 05/11] Add clipmenu --help --- clipmenu | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/clipmenu b/clipmenu index 203bfe3..af7db72 100755 --- a/clipmenu +++ b/clipmenu @@ -9,6 +9,20 @@ cache_file=$cache_dir/line_cache : "${CM_LAUNCHER=dmenu}" +if [[ $1 == --help ]]; then + cat << EOF +clipmenu is a simple clipboard manager using dmenu and xsel. Launch this +when you want to select a clip. + +All arguments are passed through to dmenu itself. + +Environment variables: + +- \$CM_LAUNCHER: specify a dmenu-compatible launcher (default: dmenu) +EOF + exit 0 +fi + # It's okay to hardcode `-l 8` here as a sensible default without checking # whether `-l` is also in "$@", because the way that dmenu works allows a later # argument to override an earlier one. That is, if the user passes in `-l`, our From 497ba9c95c9da24d368e5eb50c514d9877464952 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 07:55:57 +0000 Subject: [PATCH 06/11] Mention rofi in readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b175aee..ad6b46f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -clipmenu is a simple clipboard manager using [dmenu][] and [xsel][]. +clipmenu is a simple clipboard manager using [dmenu][] (or [rofi][]) and +[xsel][]. # Usage @@ -35,4 +36,5 @@ there, but it basically works like this: selections. [dmenu]: http://tools.suckless.org/dmenu/ +[rofi]: https://github.com/DaveDavenport/Rofi [xsel]: http://www.vergenet.net/~conrad/software/xsel/ From e315d8262cf1ad5b71912c8fc257b3407c10f8e3 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 08:00:27 +0000 Subject: [PATCH 07/11] Forcibly add -dmenu if using rofi as $CM_LAUNCHER --- clipmenu | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clipmenu b/clipmenu index af7db72..2f65084 100755 --- a/clipmenu +++ b/clipmenu @@ -9,6 +9,11 @@ cache_file=$cache_dir/line_cache : "${CM_LAUNCHER=dmenu}" +if [[ "$CM_LAUNCHER" == rofi ]]; then + # rofi supports dmenu-like arguments through the -dmenu flag + set -- -dmenu "$@" +fi + if [[ $1 == --help ]]; then cat << EOF clipmenu is a simple clipboard manager using dmenu and xsel. Launch this From 1b4fcd5b8dd8c8c8a9686341674fc1cc7772b26e Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 09:43:39 +0000 Subject: [PATCH 08/11] Add demo GIF --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ad6b46f..2b94ea0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ clipmenu is a simple clipboard manager using [dmenu][] (or [rofi][]) and [xsel][]. +# Demo + +![Demo](https://cloud.githubusercontent.com/assets/660663/24079784/6f76da94-0c88-11e7-8251-40b1f02ebf3c.gif) + # Usage Start `clipmenud`, then run `clipmenu` to select something to put on the From 92d584e4b305c1b6959c0d2e1e81d2b256fc6d7d Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 09:48:29 +0000 Subject: [PATCH 09/11] Use a function insted of an alias for dmenu shim --- tests/test-clipmenu | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test-clipmenu b/tests/test-clipmenu index 3da51aa..966c7f3 100755 --- a/tests/test-clipmenu +++ b/tests/test-clipmenu @@ -37,7 +37,11 @@ shim() { fi } -alias dmenu='SHIM_STDOUT="Selected text. (2 lines)" shim dmenu' +# Cannot be an alias due to expansion order with $CM_LAUNCHER +dmenu() { + SHIM_STDOUT="Selected text. (2 lines)" shim dmenu +} + alias xsel='shim xsel' alias xclip='shim xclip' EOF From 7d9c46a370e59adbda8d7f1e74177bd203881ef4 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 09:54:47 +0000 Subject: [PATCH 10/11] Pass args in dmenu/rofi shims --- tests/test-clipmenu | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test-clipmenu b/tests/test-clipmenu index 966c7f3..8b2fc62 100755 --- a/tests/test-clipmenu +++ b/tests/test-clipmenu @@ -39,7 +39,11 @@ shim() { # Cannot be an alias due to expansion order with $CM_LAUNCHER dmenu() { - SHIM_STDOUT="Selected text. (2 lines)" shim dmenu + SHIM_STDOUT="Selected text. (2 lines)" shim dmenu "$@" +} + +rofi() { + SHIM_STDOUT="Selected text. (2 lines)" shim rofi "$@" } alias xsel='shim xsel' From 33b0e13404a921609d79084fd6191f2b76a161a6 Mon Sep 17 00:00:00 2001 From: Chris Down Date: Sun, 19 Mar 2017 09:54:56 +0000 Subject: [PATCH 11/11] Test CM_LAUNCHER --- tests/test-clipmenu | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tests/test-clipmenu b/tests/test-clipmenu index 8b2fc62..43af5d5 100755 --- a/tests/test-clipmenu +++ b/tests/test-clipmenu @@ -67,12 +67,10 @@ EOF ### TESTS ### -output=$(/tmp/clipmenu --foo bar 2>&1) - temp=$(mktemp) trap 'rm -f -- "$temp"' EXIT -printf '%s\n' "$output" > "$temp" +/tmp/clipmenu --foo bar > "$temp" 2>&1 # Arguments are transparently passed to dmenu grep -Fxq 'dmenu args: -l 8 --foo bar' "$temp" @@ -82,8 +80,13 @@ grep -Fxq 'dmenu line 1 stdin: Selected text 2. (2 lines)' "$temp" grep -Fxq 'dmenu line 2 stdin: Selected text. (2 lines)' "$temp" # xsel should copy both to clipboard *and* primary -grep -Fxq 'xsel args: --logfile /dev/null -i --clipboard' "$temp" -grep -Fxq 'xsel args: --logfile /dev/null -i --primary' "$temp" +grep -Fxq 'xsel args: --logfile /dev/stderr -i --clipboard' "$temp" +grep -Fxq 'xsel args: --logfile /dev/stderr -i --primary' "$temp" grep -Fxq 'xsel line 1 stdin: Selected text.' "$temp" grep -Fxq "xsel line 2 stdin: Yes, it's selected text." "$temp" + +CM_LAUNCHER=rofi /tmp/clipmenu --foo bar > "$temp" 2>&1 + +# We have a special case to add -dmenu for rofi +grep -Fxq 'rofi args: -l 8 -dmenu --foo bar' "$temp"