Open clipboard entries from history
This commit is contained in:
Executable
+69
@@ -0,0 +1,69 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# omarchy:summary=Open a clipboard history entry
|
||||||
|
# omarchy:group=clipboard
|
||||||
|
# omarchy:args=--history-index <index>
|
||||||
|
|
||||||
|
history_index=""
|
||||||
|
history_path="$HOME/.local/state/omarchy/clipboard-history.json"
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--history-index)
|
||||||
|
history_index="${2:-}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: omarchy-clipboard-open --history-index <index>" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[[ $history_index =~ ^[0-9]+$ ]] || exit 1
|
||||||
|
[[ -r $history_path ]] || exit 1
|
||||||
|
|
||||||
|
entry_type=$(jq -er --argjson index "$history_index" '.[$index].type' "$history_path") || exit 1
|
||||||
|
|
||||||
|
open_image() {
|
||||||
|
local path="$1"
|
||||||
|
|
||||||
|
[[ -r $path ]] || exit 1
|
||||||
|
exec satty --filename "$path" --output-filename "$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
open_text() {
|
||||||
|
local text="$1"
|
||||||
|
local url=""
|
||||||
|
local open_dir=""
|
||||||
|
local open_file=""
|
||||||
|
|
||||||
|
url=$(grep -Eom1 'https?://[^[:space:]"'\''<>]+' <<<"$text" || true)
|
||||||
|
if [[ -z $url && $text =~ ^[[:space:]]*([[:alnum:]][[:alnum:].-]+\.[[:alpha:]]{2,})(/[^[:space:]]*)?[[:space:]]*$ ]]; then
|
||||||
|
url="https://${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $url ]]; then
|
||||||
|
exec omarchy-launch-browser "$url"
|
||||||
|
fi
|
||||||
|
|
||||||
|
open_dir="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/clipboard-open"
|
||||||
|
mkdir -p "$open_dir"
|
||||||
|
open_file=$(mktemp --tmpdir="$open_dir" clipboard.XXXXXX.txt) || exit 1
|
||||||
|
printf '%s' "$text" >"$open_file"
|
||||||
|
exec omarchy-launch-editor "$open_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$entry_type" in
|
||||||
|
image)
|
||||||
|
path=$(jq -er --argjson index "$history_index" '.[$index].path' "$history_path") || exit 1
|
||||||
|
open_image "$path"
|
||||||
|
;;
|
||||||
|
text)
|
||||||
|
text=$(jq -er --argjson index "$history_index" '.[$index].text' "$history_path") || exit 1
|
||||||
|
open_text "$text"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -19,7 +19,7 @@ Item {
|
|||||||
|
|
||||||
property string historyPath: Quickshell.env("HOME") + "/.local/state/omarchy/clipboard-history.json"
|
property string historyPath: Quickshell.env("HOME") + "/.local/state/omarchy/clipboard-history.json"
|
||||||
property string captureScript: root.omarchyPath + "/shell/plugins/clipboard/capture.sh"
|
property string captureScript: root.omarchyPath + "/shell/plugins/clipboard/capture.sh"
|
||||||
property string watchCommand: "script=$1\ntrap 'kill $(jobs -p) 2>/dev/null' EXIT\nwl-paste --watch \"$script\" &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/png wl-paste --type image/png --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/jpeg wl-paste --type image/jpeg --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/webp wl-paste --type image/webp --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/gif wl-paste --type image/gif --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/bmp wl-paste --type image/bmp --watch \"$script\" 2>/dev/null &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/tiff wl-paste --type image/tiff --watch \"$script\" 2>/dev/null &\nwait"
|
property string watchCommand: "script=$1\ntrap 'kill $(jobs -p) 2>/dev/null' EXIT\nwl-paste --watch \"$script\" &\nOMARCHY_CLIPBOARD_WATCH_MIME=image/png wl-paste --type image/png --watch \"$script\" 2>/dev/null &\nwait"
|
||||||
// Shares the [menu] surface tokens — themes that style the menu also
|
// Shares the [menu] surface tokens — themes that style the menu also
|
||||||
// style the clipboard. Selected-row colors composed in the
|
// style the clipboard. Selected-row colors composed in the
|
||||||
// singleton so consumers drop them straight into Rectangle bindings.
|
// singleton so consumers drop them straight into Rectangle bindings.
|
||||||
@@ -182,6 +182,12 @@ Item {
|
|||||||
root.copySelected(row)
|
root.copySelected(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openIndex(index) {
|
||||||
|
if (index < 0 || index >= displayModel.count) return
|
||||||
|
var row = displayModel.get(index)
|
||||||
|
root.openSelected(row)
|
||||||
|
}
|
||||||
|
|
||||||
function applySelected(row) {
|
function applySelected(row) {
|
||||||
if (!row) return
|
if (!row) return
|
||||||
root.opened = false
|
root.opened = false
|
||||||
@@ -202,6 +208,12 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openSelected(row) {
|
||||||
|
if (!row) return
|
||||||
|
root.opened = false
|
||||||
|
Quickshell.execDetached([root.omarchyPath + "/bin/omarchy-clipboard-open", "--history-index", String(row.historyIndex)])
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: initProc.running = true
|
Component.onCompleted: initProc.running = true
|
||||||
|
|
||||||
ListModel { id: displayModel }
|
ListModel { id: displayModel }
|
||||||
@@ -312,7 +324,8 @@ Item {
|
|||||||
root.select(6)
|
root.select(6)
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
if (root.cursorActive && (event.modifiers & Qt.ShiftModifier)) root.copyIndex(root.selectedIndex)
|
if (root.cursorActive && (event.modifiers & Qt.AltModifier)) root.openIndex(root.selectedIndex)
|
||||||
|
else if (root.cursorActive && (event.modifiers & Qt.ShiftModifier)) root.copyIndex(root.selectedIndex)
|
||||||
else if (root.cursorActive) root.activateIndex(root.selectedIndex)
|
else if (root.cursorActive) root.activateIndex(root.selectedIndex)
|
||||||
else if (displayModel.count > 0) root.cursorActive = true
|
else if (displayModel.count > 0) root.cursorActive = true
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ function imagePreviewText(entry) {
|
|||||||
if (!timestamp) return "Image"
|
if (!timestamp) return "Image"
|
||||||
|
|
||||||
var label = String(entry && entry.mime || "") === "image/png" ? "Screenshot" : "Image"
|
var label = String(entry && entry.mime || "") === "image/png" ? "Screenshot" : "Image"
|
||||||
return label + " " + timestamp
|
return label + " from " + timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
function previewText(entry) {
|
function previewText(entry) {
|
||||||
|
|||||||
@@ -73,13 +73,13 @@ assertDeepEqual(
|
|||||||
|
|
||||||
assertDeepEqual(
|
assertDeepEqual(
|
||||||
clipboard.displayRows([{ type: 'image', path: '/tmp/a.png', mime: 'image/png', capturedAt: 'Friday 14:42' }], '', 50)[0].previewText,
|
clipboard.displayRows([{ type: 'image', path: '/tmp/a.png', mime: 'image/png', capturedAt: 'Friday 14:42' }], '', 50)[0].previewText,
|
||||||
'Screenshot Friday 14:42',
|
'Screenshot from Friday 14:42',
|
||||||
'clipboard labels timestamped png image entries as screenshots'
|
'clipboard labels timestamped png image entries as screenshots'
|
||||||
)
|
)
|
||||||
|
|
||||||
assertDeepEqual(
|
assertDeepEqual(
|
||||||
clipboard.displayRows([{ type: 'image', path: '/tmp/a.jpg', mime: 'image/jpeg', capturedAt: 'Friday 14:42' }], '', 50)[0].previewText,
|
clipboard.displayRows([{ type: 'image', path: '/tmp/a.jpg', mime: 'image/jpeg', capturedAt: 'Friday 14:42' }], '', 50)[0].previewText,
|
||||||
'Image Friday 14:42',
|
'Image from Friday 14:42',
|
||||||
'clipboard labels timestamped non-png image entries as images'
|
'clipboard labels timestamped non-png image entries as images'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -114,7 +114,23 @@ cat >"$TMPDIR/bin/wtype" <<'SH'
|
|||||||
printf '%s\n' "$*" >"$WTYPE_OUT"
|
printf '%s\n' "$*" >"$WTYPE_OUT"
|
||||||
SH
|
SH
|
||||||
|
|
||||||
chmod +x "$TMPDIR/bin/wl-copy" "$TMPDIR/bin/wtype"
|
cat >"$TMPDIR/bin/omarchy-launch-browser" <<'SH'
|
||||||
|
#!/bin/bash
|
||||||
|
printf '%s\n' "$*" >"$BROWSER_OUT"
|
||||||
|
SH
|
||||||
|
|
||||||
|
cat >"$TMPDIR/bin/omarchy-launch-editor" <<'SH'
|
||||||
|
#!/bin/bash
|
||||||
|
printf '%s\n' "$1" >"$EDITOR_PATH_OUT"
|
||||||
|
cat "$1" >"$EDITOR_TEXT_OUT"
|
||||||
|
SH
|
||||||
|
|
||||||
|
cat >"$TMPDIR/bin/satty" <<'SH'
|
||||||
|
#!/bin/bash
|
||||||
|
printf '%s\n' "$*" >"$SATTY_OUT"
|
||||||
|
SH
|
||||||
|
|
||||||
|
chmod +x "$TMPDIR/bin/wl-copy" "$TMPDIR/bin/wtype" "$TMPDIR/bin/omarchy-launch-browser" "$TMPDIR/bin/omarchy-launch-editor" "$TMPDIR/bin/satty"
|
||||||
|
|
||||||
jq -n --arg text "$(printf 'large block line 1\nlarge block line 2\n')" '[{type:"text", text:"ignored"}, {type:"text", text:$text}]' >"$TMPDIR/home/.local/state/omarchy/clipboard-history.json"
|
jq -n --arg text "$(printf 'large block line 1\nlarge block line 2\n')" '[{type:"text", text:"ignored"}, {type:"text", text:$text}]' >"$TMPDIR/home/.local/state/omarchy/clipboard-history.json"
|
||||||
|
|
||||||
@@ -147,3 +163,27 @@ pass "clipboard file paste helper copy-only copies file content"
|
|||||||
|
|
||||||
[[ ! -e "$TMPDIR/wtype" ]] || fail "clipboard file paste helper copy-only skips paste keystroke"
|
[[ ! -e "$TMPDIR/wtype" ]] || fail "clipboard file paste helper copy-only skips paste keystroke"
|
||||||
pass "clipboard file paste helper copy-only skips paste keystroke"
|
pass "clipboard file paste helper copy-only skips paste keystroke"
|
||||||
|
|
||||||
|
jq -n --arg url 'https://example.com/docs' --arg text "$(printf 'plain text\nsecond line')" --arg image "$TMPDIR/image.png" \
|
||||||
|
'[{type:"text", text:$url}, {type:"text", text:$text}, {type:"image", mime:"image/png", path:$image}]' >"$TMPDIR/home/.local/state/omarchy/clipboard-history.json"
|
||||||
|
|
||||||
|
BROWSER_OUT="$TMPDIR/browser" HOME="$TMPDIR/home" PATH="$TMPDIR/bin:$PATH" \
|
||||||
|
"$ROOT/bin/omarchy-clipboard-open" --history-index 0
|
||||||
|
|
||||||
|
[[ $(<"$TMPDIR/browser") == "https://example.com/docs" ]] || fail "clipboard open helper opens URL entries in browser"
|
||||||
|
pass "clipboard open helper opens URL entries in browser"
|
||||||
|
|
||||||
|
EDITOR_PATH_OUT="$TMPDIR/editor-path" EDITOR_TEXT_OUT="$TMPDIR/editor-text" HOME="$TMPDIR/home" XDG_STATE_HOME="$TMPDIR/state" PATH="$TMPDIR/bin:$PATH" \
|
||||||
|
"$ROOT/bin/omarchy-clipboard-open" --history-index 1
|
||||||
|
|
||||||
|
[[ $(<"$TMPDIR/editor-text") == "$(printf 'plain text\nsecond line')" ]] || fail "clipboard open helper opens text entries in editor"
|
||||||
|
pass "clipboard open helper opens text entries in editor"
|
||||||
|
|
||||||
|
[[ $(<"$TMPDIR/editor-path") == "$TMPDIR"/state/omarchy/clipboard-open/clipboard.*.txt ]] || fail "clipboard open helper writes text entries to a temporary file"
|
||||||
|
pass "clipboard open helper writes text entries to a temporary file"
|
||||||
|
|
||||||
|
SATTY_OUT="$TMPDIR/satty" HOME="$TMPDIR/home" PATH="$TMPDIR/bin:$PATH" \
|
||||||
|
"$ROOT/bin/omarchy-clipboard-open" --history-index 2
|
||||||
|
|
||||||
|
[[ $(<"$TMPDIR/satty") == "--filename $TMPDIR/image.png --output-filename $TMPDIR/image.png" ]] || fail "clipboard open helper opens image entries in satty"
|
||||||
|
pass "clipboard open helper opens image entries in satty"
|
||||||
|
|||||||
Reference in New Issue
Block a user