Skip to content

Instantly share code, notes, and snippets.

@tadly
Last active April 14, 2024 01:12
Show Gist options
  • Star 72 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save tadly/0741821d3694deaec1ee454a95c591fa to your computer and use it in GitHub Desktop.
Save tadly/0741821d3694deaec1ee454a95c591fa to your computer and use it in GitHub Desktop.
Rofi emoji picker
#!/usr/bin/env bash
#
# Use rofi to pick emoji because that's what this
# century is about apparently...
#
# Requirements:
# rofi, xsel, xdotool, curl, xmllint
#
# Usage:
# 1. Download all emoji
# $ rofi-emoji --download
#
# 2. Run it!
# $ rofi-emoji
#
# Notes:
# * You'll need a emoji font like "Noto Emoji" or "EmojiOne".
# * Confirming an item will automatically paste it WITHOUT
# writing it to your clipboard.
# * Ctrl+C will copy it to your clipboard WITHOUT pasting it.
#
# Where to save the emojis file.
EMOJI_FILE="$HOME/.cache/emojis.txt"
# Urls of emoji to download.
# You can remove what you don't need.
URLS=(
'https://emojipedia.org/people/'
'https://emojipedia.org/nature/'
'https://emojipedia.org/food-drink/'
'https://emojipedia.org/activity/'
'https://emojipedia.org/travel-places/'
'https://emojipedia.org/objects/'
'https://emojipedia.org/symbols/'
'https://emojipedia.org/flags/'
)
function notify() {
if [ "$(command -v notify-send)" ]; then
notify-send "$1" "$2"
fi
}
function download() {
notify `basename "$0"` 'Downloading all emoji for your pleasure'
echo "" > "$EMOJI_FILE"
for url in "${URLS[@]}"; do
echo "Downloading: $url"
# Download the list of emoji and remove all the junk around it
emojis=$(curl -s "$url" | \
xmllint --html \
--xpath '//ul[@class="emoji-list css_test1"]' - 2>/dev/null)
# Get rid of starting/closing ul tags
emojis=$(echo "$emojis" | head -n -1 | tail -n +1)
# Extract the emoji and its description
emojis=$(echo "$emojis" | \
sed -rn 's/.*<span class="emoji">(.*)<\/span> (.*)<\/a><\/li>/\1 \2/p')
echo "$emojis" >> "$EMOJI_FILE"
done
notify `basename "$0"` "We're all set!"
}
function display() {
emoji=$(cat "$EMOJI_FILE" | grep -v '#' | grep -v '^[[:space:]]*$')
line=$(echo "$emoji" | rofi -dmenu -i -p emoji -kb-custom-1 Ctrl+c $@)
exit_code=$?
line=($line)
if [ $exit_code == 0 ]; then
sleep 0.1 # Delay pasting so the text-entry can come active
xdotool type --clearmodifiers "${line[0]}"
elif [ $exit_code == 10 ]; then
echo -n "${line[0]}" | xsel -i -b
fi
}
# Some simple argparsing
if [[ "$1" =~ -D|--download ]]; then
download
exit 0
elif [[ "$1" =~ -h|--help ]]; then
echo "usage: $0 [-D|--download]"
exit 0
fi
# Download all emoji if they don't exist yet
if [ ! -f "$EMOJI_FILE" ]; then
download
fi
# display displays :)
display
@tadly
Copy link
Author

tadly commented Feb 23, 2018

If you need help or want me to change something, please ping me directly within the comment (@tadly) as otherwise I'll not get notified :)

Edit:
SO...! I since have learned that notifications for gists aren't a thing... Like at at all.
Therefore it's a matter of me checking the comments every once in a while sigh

Copy link

ghost commented Feb 24, 2018

This is beautiful - thank you

@NearHuscarl
Copy link

NearHuscarl commented Mar 4, 2018

@tadly I made a modified version of your script which change the following things:

  • Add quantifier argument to print n number of emoijs (Tab to autocomplete emoij and type a number from 1 to 9)
  • Change xsel to xclip because that's what I use ;)
  • Always copy to clipboard because sometimes xdotool type not work in google chrome so I will have to paste it manually

@gangelop
Copy link

@tau-rho
Copy link

tau-rho commented Oct 13, 2022

@tadly I think the html page changed its format: in line 58 it now needs to be 'emoji-list css_test1'

@gangelop
Copy link

gangelop commented Oct 13, 2022

indeed! I had noticed the problem but hadn't found the time to fix it yet. Thank you! @tau-rho

@tadly
Copy link
Author

tadly commented Oct 13, 2022

thanks @tau-rho
I've updated the gist (untested as I'm no longer using this)

@gangelop
Copy link

it works @tadly 👌✅🚀 gangelop/dotfiles@9225039

@literalplus
Copy link

Just encountered this same problem & delighted to see it also fixed here :) This XPath might be more robust to future markup changes: //ul[contains(@class,"emoji-list")]

@omc8db
Copy link

omc8db commented Mar 5, 2023

This project is a crime and I love it.

Wrote this patch to download the list from the official unicode website instead of emojipedia. This only requires one download, should have a more stable format over time and cuts out the xmllint dependency + most of the parsing code.
https://gist.github.com/omc8db/d95462784bc1c5c41f7f489df5dbc377

@mmirus
Copy link

mmirus commented Nov 29, 2023

Here is a fork of @omc8db's fork that works with wayland, fixes an error with recent versions of rofi that prevents it from launching because ctrl+c is already bound by rofi, and fixes shellcheck warnings. https://gist.github.com/mmirus/840c907f02dfb491a150be4e459893d1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment