improve fzfclip

This commit is contained in:
2026-02-11 15:40:33 +01:00
parent 2d43f929e3
commit ad5e4a1303
3 changed files with 64 additions and 51 deletions
+45 -39
View File
@@ -6,8 +6,8 @@
# Requirements: # Requirements:
# - fzf # - fzf
# - cliphist # - cliphist
# - wl-clipboard # - wl-clipboard (including wl-copy and wl-paste)
# - python with urllib (for URL quoting/unquoting) # - python3 with urllib (for URL quoting/unquoting)
# - chafa (optional, for image preview) # - chafa (optional, for image preview)
# - ffmpegthumbnailer (optional, for video thumbnails) # - ffmpegthumbnailer (optional, for video thumbnails)
# Credits: # Credits:
@@ -50,6 +50,26 @@ _cleanup() {
} }
trap _cleanup EXIT trap _cleanup EXIT
_check_dependencies() {
local missing=()
for cmd in fzf cliphist wl-copy wl-paste python3; do
if ! type "$cmd" &>/dev/null; then
missing+=("$cmd")
fi
done
if [ ${#missing[@]} -ne 0 ]; then
echo "Error: Missing dependencies: ${missing[*]}" >&2
exit 1
fi
for cmd in chafa ffmpegthumbnailer; do
if ! type "$cmd" &>/dev/null; then
echo "Warning: Optional dependency '$cmd' not found. Some features may be unavailable." >&2
fi
done
}
_check_dependencies
CACHE_DIR=$(mktemp -d) CACHE_DIR=$(mktemp -d)
export CACHE_DIR export CACHE_DIR
@@ -58,9 +78,11 @@ export C_PRIMARY='\x1b[1;34m'
export C_CYAN='\x1b[1;36m' export C_CYAN='\x1b[1;36m'
export C_RESET='\x1b[0m' export C_RESET='\x1b[0m'
export C_PATTERN='\x1b\[[0-9];?([0-9]+)?m'
# Check for terminal graphics support and set environment variables accordingly # Check for terminal graphics support and set environment variables accordingly
graphics-query() { _graphics_query() {
# Port of [graphics-query](https://github.com/Uyanide/dotfiles/blob/main/config/scripts/.local/scripts/graphics-query) # Port of [graphics-query](https://github.com/Uyanide/dotfiles/blob/main/config/scripts/.local/scripts/graphics-query)
# Ensure in a interactive terminal # Ensure in a interactive terminal
@@ -147,9 +169,8 @@ ENABLE_SIXEL=0
ENABLE_ITERM2=0 ENABLE_ITERM2=0
_check_graphics_support() { _check_graphics_support() {
# type graphics-query &>/dev/null || return
local result local result
result=$(graphics-query) result=$(_graphics_query)
if [[ "$result" == *"kitty"* ]]; then if [[ "$result" == *"kitty"* ]]; then
SUPPORT_ICAT=1 SUPPORT_ICAT=1
elif [[ "$result" == *"sixels"* ]]; then elif [[ "$result" == *"sixels"* ]]; then
@@ -259,7 +280,7 @@ export -f _preview_text
_preview_video() { _preview_video() {
local video_hash thumb_file path local video_hash thumb_file path
path="$1" path="$1"
video_hash=$(echo "$path" | md5sum | cut -d" " -f1) video_hash=$(echo -n "$path" | md5sum | cut -d" " -f1)
thumb_file="$CACHE_DIR/$video_hash.png" thumb_file="$CACHE_DIR/$video_hash.png"
if [ ! -f "$thumb_file" ]; then if [ ! -f "$thumb_file" ]; then
if type ffmpegthumbnailer &>/dev/null; then if type ffmpegthumbnailer &>/dev/null; then
@@ -309,28 +330,27 @@ preview() {
entry="$1" entry="$1"
content=$(echo "$entry" | cut -f2-) mimeType=$(echo -n "$entry" | cliphist decode | file -b --mime-type -)
mimeType=$(echo "$entry" | cliphist decode | file -b --mime-type -) ext=$(echo -n "$mimeType" | awk -F"/" "{print \$2}")
ext=$(echo "$mimeType" | awk -F"/" "{print \$2}")
if [[ $mimeType =~ image ]]; then if [[ $mimeType =~ image ]]; then
img_hash=$(echo "$entry" | cliphist decode | md5sum | cut -d" " -f1) img_hash=$(echo -n "$entry" | cliphist decode | md5sum | cut -d" " -f1)
cache_file="$CACHE_DIR/$img_hash.$ext" cache_file="$CACHE_DIR/$img_hash.$ext"
[ -f "$cache_file" ] || echo "$entry" | cliphist decode >"$cache_file" [ -f "$cache_file" ] || echo -n "$entry" | cliphist decode >"$cache_file"
_preview_image "$cache_file" _preview_image "$cache_file"
elif path=$(echo "$entry" | cliphist decode) && [[ "$path" == /* ]]; then elif path=$(echo -n "$entry" | cliphist decode) && [[ "$path" == /* ]]; then
if [ -e "$path" ]; then if [ -e "$path" ]; then
_preview_file "$path" _preview_file "$path"
else else
_preview_text "$path does not exist." _preview_text "$path does not exist."
fi fi
elif decoded=$(echo "$entry" | cliphist decode) && [[ "$decoded" == file://* ]]; then elif decoded=$(echo -n "$entry" | cliphist decode) && [[ "$decoded" == file://* ]]; then
paths=() paths=()
for path in $decoded; do for path in $decoded; do
raw_path="${path#file://}" raw_path="${path#file://}"
raw_path=$(echo "$raw_path" | url_unquote) raw_path=$(echo -n "$raw_path" | url_unquote)
paths+=("$raw_path") paths+=("$raw_path")
done done
@@ -348,7 +368,7 @@ preview() {
if [ "$ENABLE_ICAT" = 1 ]; then if [ "$ENABLE_ICAT" = 1 ]; then
printf "\x1b_Ga=d\x1b\\" printf "\x1b_Ga=d\x1b\\"
fi fi
_preview_text "$(echo "$entry" | cliphist decode)" _preview_text "$(echo -n "$entry" | cliphist decode)"
fi fi
} }
export -f preview export -f preview
@@ -358,12 +378,12 @@ export -f preview
format_clip_list() { format_clip_list() {
sed -E \ sed -E \
-e "s/(\t).*\.(mp4|mkv|webm|avi|mov|flv|wmv)$/\1${C_TERTIARY}[VIDEO]File.\2${C_RESET}/" \ -e "s/(\t).*\.(mp4|mkv|webm|avi|mov|flv|wmv)$/\1${C_TERTIARY}[VIDEO]File.\2${C_RESET}/" \
-e "s/(\t)file:\/\/.*\.(mp4|mkv|webm|avi|mov|flv|wmv)$/\1${C_TERTIARY}[VIDEO]Url.\2${C_RESET}/" \ -e "s/(\t)file:\/\/.*\.(mp4|mkv|webm|avi|mov|flv|wmv)$/\1${C_TERTIARY}[URL]Video.\2${C_RESET}/" \
-e "s/(\t)file:\/\/.*\.gif$/\1${C_PRIMARY}[IMG]Url.gif${C_RESET}/" \ -e "s/(\t)file:\/\/.*\.gif$/\1${C_PRIMARY}[URL]Image.gif${C_RESET}/" \
-e "s/(\t)file:\/\/.*\.(png|jpg|jpeg|webp|bmp)$/\1${C_TERTIARY}[IMG]Url.\2${C_RESET}/" \ -e "s/(\t)file:\/\/.*\.(png|jpg|jpeg|webp|bmp)$/\1${C_TERTIARY}[URL]Image.\2${C_RESET}/" \
-e "s/(\t)file:\/\/.*/\1${C_CYAN}[URL]File${C_RESET}/" \ -e "s/(\t)file:\/\/.*/\1${C_CYAN}[URL]File${C_RESET}/" \
-e "s/(\t)\/.*\.gif$/\1${C_PRIMARY}[IMG]Path.gif${C_RESET}/" \ -e "s/(\t)\/.*\.gif$/\1${C_PRIMARY}[PATH]Image.gif${C_RESET}/" \
-e "s/(\t)\/.*\.(png|jpg|jpeg|webp|bmp)$/\1${C_TERTIARY}[IMG]Path.\2${C_RESET}/" \ -e "s/(\t)\/.*\.(png|jpg|jpeg|webp|bmp)$/\1${C_TERTIARY}[PATH]Image.\2${C_RESET}/" \
-e "s/\[\[ binary data .* (png|jpg|jpeg|gif|webp) .*\]\]/${C_TERTIARY}[IMG]Bin.\1${C_RESET}/" \ -e "s/\[\[ binary data .* (png|jpg|jpeg|gif|webp) .*\]\]/${C_TERTIARY}[IMG]Bin.\1${C_RESET}/" \
-e "s/\[\[ binary data .* \]\]/${C_CYAN}[BINARY]${C_RESET}/" -e "s/\[\[ binary data .* \]\]/${C_CYAN}[BINARY]${C_RESET}/"
} }
@@ -378,28 +398,14 @@ export -f add_num
copy_selection() { copy_selection() {
local input="$1" local input="$1"
local decoded local content
decoded=$(echo "$input" | cliphist decode) content=$(echo -n "$input" | awk "{print \$3}")
local mime
mime=$(echo "$decoded" | file -b --mime-type -)
# Image if [[ "$content" == "[URL]"* ]]; then
if [[ "$mime" =~ image ]]; then echo -n "$input" | cliphist decode | wl-copy --type text/uri-list
printf "%s" "$decoded" | wl-copy
# URL starting with file://
elif [[ "$decoded" == file://* ]]; then
printf "%s" "$decoded" | wl-copy --type text/uri-list
# file path
elif [[ "$decoded" == /* ]] && [ -e "$decoded" ]; then
local encoded_path
encoded_path=$(echo "$decoded" | url_quote)
printf "%s" "file://$encoded_path" | wl-copy --type text/uri-list
# Other data, just copy
else else
printf "%s" "$decoded" | wl-copy echo -n "$input" | cliphist decode | wl-copy
fi fi
} }
export -f copy_selection export -f copy_selection
+3 -4
View File
@@ -5,15 +5,14 @@
# without relying on environment variables or external tools. # without relying on environment variables or external tools.
# #
# Usage: # Usage:
# This script will print 1 or more of the following strings to stdout, depending # This script will print one or more of the following strings to stdout, each on a new line,
# on the detected capabilities: # depending on the detected capabilities:
# - "kitty" if Kitty's terminal Graphics Protocol is supported # - "kitty" if Kitty's terminal Graphics Protocol is supported
# - "iterm" if iTerm2's inline image support is detected # - "iterm" if iTerm2's inline image support is detected
# - "sixels" if Sixel graphics support is detected # - "sixels" if Sixel graphics support is detected
# Do NOT source this script directly, as it will modify the terminal state
# and print its result directly to stdout.
# #
# See also: # See also:
# For separate queries for specific protocols, see the related scripts in the same directory:
# - kgp-query: specifically checks for Kitty's terminal Graphics Protocol support # - kgp-query: specifically checks for Kitty's terminal Graphics Protocol support
# - iterm2-query: specifically checks for iTerm2 inline image support # - iterm2-query: specifically checks for iTerm2 inline image support
# - sixel-query: specifically checks for Sixel graphics support # - sixel-query: specifically checks for Sixel graphics support
+10 -2
View File
@@ -1,4 +1,6 @@
de 布局太全能了: de 布局太全能了
## Shift & Altgr
<img src="https://upload.wikimedia.org/wikipedia/commons/3/3e/KB_Germany_Linux.svg" alt="Deutsche Tastaturbelegung unter Linux"/> <img src="https://upload.wikimedia.org/wikipedia/commons/3/3e/KB_Germany_Linux.svg" alt="Deutsche Tastaturbelegung unter Linux"/>
@@ -24,4 +26,10 @@ altgr | » « ¢ „ “ ” µ · …
sh+al ˍ © º × ÷ — sh+al ˍ © º × ÷ —
``` ```
btw, `^` 死键对数字键(上方一排和小键盘均可)也有效, 作用为打出n次幂, 例如 `^` + `9` -> `⁹`. ## Dead keys
- `^`
- `^` + `+`: `⁺`
- `^` + `-`: `⁻`
- `^` + `.`: `·`
- `^` + number: `⁹`