rofi/scripts/rofi-emoji 2.2 K raw
1
#!/bin/sh
2
# Requires: rofi, xclip, xdotool, a color emoji font (Noto Color Emoji)
3
# Emoji and kaomoji picker: search by name, Enter copies the character to the
4
# clipboard and pastes it into whatever window was focused before rofi opened.
5
# Terminals don't bind plain ctrl+v to paste, so terminal window classes get
6
# ctrl+shift+v instead; override the whole thing with ROFI_EMOJI_PASTE_KEYS.
7
# Picks are remembered and float to the top, so the handful anyone actually
8
# uses stop needing to be searched for.
9
set -u
10
11
DATA=${ROFI_EMOJI_DATA:-$(dirname "$0")/../emoji.txt}
12
RECENT="${XDG_CACHE_HOME:-$HOME/.cache}/rofi-emoji-recent"
13
RECENT_MAX=${ROFI_EMOJI_RECENT_MAX:-30}
14
15
[ -f "$DATA" ] || { echo "rofi-emoji: no emoji data at $DATA" >&2; exit 1; }
16
touch "$RECENT"
17
18
# Two spaces between the character and its name: a kaomoji can contain single
19
# spaces, so a single space would be ambiguous when splitting the choice back
20
# apart. Names stay in the row because that is what the search filters on.
21
rows() {
22
    cat "$RECENT" "$DATA" | awk -F'\t' '!seen[$1]++ { printf "%s  %s\n", $1, $2 }'
23
}
24
25
TARGET_WIN=$(xdotool getactivewindow 2>/dev/null) || TARGET_WIN=
26
27
CHOICE=$(rows | rofi -dmenu -i -no-custom -p "emoji" -matching normal) || exit 0
28
[ -n "$CHOICE" ] || exit 0
29
30
CHAR=${CHOICE%%  *}
31
NAME=${CHOICE#*  }
32
33
printf '%s' "$CHAR" | xclip -selection clipboard -i
34
35
if [ -n "$TARGET_WIN" ]; then
36
    TARGET_CLASS=$(xdotool getwindowclassname "$TARGET_WIN" 2>/dev/null || echo)
37
    case "$TARGET_CLASS" in
38
        *[Tt]erm*|kitty|st|st-256color|foot|footclient|tilix|konsole)
39
            DEFAULT_PASTE_KEYS="ctrl+shift+v" ;;
40
        *)
41
            DEFAULT_PASTE_KEYS="ctrl+v" ;;
42
    esac
43
    PASTE_KEYS=${ROFI_EMOJI_PASTE_KEYS:-$DEFAULT_PASTE_KEYS}
44
    xdotool windowactivate --sync "$TARGET_WIN" 2>/dev/null
45
    xdotool key --clearmodifiers --window "$TARGET_WIN" "$PASTE_KEYS" 2>/dev/null
46
fi
47
48
# Rewrite the recents file with this pick first and its older copy dropped.
49
tmp="$RECENT.$$"
50
printf '%s\t%s\n' "$CHAR" "$NAME" > "$tmp"
51
grep -Fxv "$(printf '%s\t%s' "$CHAR" "$NAME")" "$RECENT" >> "$tmp" 2>/dev/null
52
head -n "$RECENT_MAX" "$tmp" > "$RECENT"
53
rm -f "$tmp"
54
55
command -v dunstify >/dev/null 2>&1 &&
56
    dunstify -r 7302 "Pasted $CHAR" "$NAME" ||
57
    notify-send "Pasted $CHAR" "$NAME"