Fast Emoji Lookup from the Command Line

Bob, Fri 07 May 2021, Tools

command line, emoji, mocking, opensource, packaging, poetry, project, pyperclip, PyPI, pytest

Today I wanted to share a little app I built the other day to search emojis from the command line.

This surely can be done via the OS (and Slack is the absolute winner for their emoji autocomplete!), but at times I still find it more useful (faster) to don't have to click anything in order to get my emojis.

And the tool supports copying multiple matching emojis to the OS clipboard at once:

$ emo

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> snake beer fire ninja
Copying 🐍 🍺 🔥 🥷 to clipboard

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> q
Bye

At this point I have all 4 emojis on my clipboard so voilà, typing Cmd+v here they are: 🐍 🍺 🔥 🥷

Pretty cool, no?

Install and run the package

git clone [email protected]:PyBites-Open-Source/emojisearcher.git
cd emojisearcher
poetry install
poetry run emo

If you are new to poetry, check out our training here, this tool makes dependency management a breeze == happier developer life.

This last command (alias) actually works because I put this in the pyproject.toml file:

[tool.poetry.scripts]
emo = "emojisearcher.script:main"

Optionally you can make the invocation command even shorter (like I had in the first example) by adding this shell alias:

$ alias emo
alias emo='cd YOUR_PATH/emojisearcher && poetry run emo'

(Change YOUR_PATH to the path where you pulled the project.)

Folder structure

Thanks to poetry new the folder structure was put in place from the start following what's considered best practice.

I like the have the tests in a dedicated tests/ folder.

Libraries

I used the emoji library to find emojis leveraging its EMOJI_UNICODE constant:

...
EMOJI_MAPPING = EMOJI_UNICODE[LANGUAGE]

...
def get_emojis_for_word(
    word: str, emoji_mapping: dict[str, str] = EMOJI_MAPPING
) -> list[str]:
    return [emo for name, emo in emoji_mapping.items() if word in name]

And I use pyperclip to copy to the OS' clipboard:

from pyperclip import copy
...
def copy_emojis_to_clipboard(matches: list[str]) -> None:
    all_matching_emojis = ' '.join(matches)
    print(f"Copying {all_matching_emojis} to clipboard")
    copy(all_matching_emojis)

A very cool package I have used multiple times already, thanks Al.

What if there are multiple emoji matches?

In that case I enter interactive mode via the user_select_emoji function.

I had to come up with a creative way to trigger this interactive mode for which I choose a signal character (SIGNAL_CHAR): if a user's search string ends with a dot (.) it goes into interactive mode.

Here's why:

$ emo

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> snake
Copying 🐍 to clipboard

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> flag
Copying 🏴 to clipboard

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> flag.
1 🏴
2 🏁
3 📪
4 📫
5 🎌
6 ⛳
7 📭
8 📬
9 🏴‍☠️
10 🏳️‍🌈
11 🏳️‍⚧️
12 🚩
13 🏳
Select the number of the emoji you want: 12
Copying 🚩 to clipboard

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> q
Bye

We cannot go wrong with the snake emoji, but for flag it selects the first of the 12 matches by default (for "heart" we get 130 matching emojis!), here I want to choose one manually so typing a trailing ., the program lets me do that.

Testing

A few things here:

$ emo

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> tree.
1 🎄
2 🌳
3 🌲
4 🌴
5 🎋
Select the number of the emoji you want: a
a is not an integer.
1 🎄
2 🌳
3 🌲
4 🌴
5 🎋
Select the number of the emoji you want: 10
10 is not a valid option.
1 🎄
2 🌳
3 🌲
4 🌴
5 🎋
Select the number of the emoji you want: 2
Copying 🌳 to clipboard

------------------------------------------------------------------------------------
Type one or more emoji related words ...
End a word with a . if you want to select an emoji if there are multiple
matches, otherwise the first match will be picked. Type 'q' to exit.
> q
Bye

Upload to PyPI

Thanks to some basic metadata in [tool.poetry] in the toml file, publishing to PyPI was just a matter of:

poetry build
poetry publish

(Use the --repository of publish first to try it on the test PyPI to see if it all looks good.)

You can learn more about this and much more in our 6 Key Ingredients of a Successful Pythonista free training.

That's it, if you like this project, give it a star on Github and happy to receive contributions to add features and what not ...


Keep Calm and Code in Python!

-- Bob

PyBites Python Tips

Do you want to get 250+ concise and applicable Python tips in an ebook that will cost you less than 10 bucks (future updates included), check it out here.

Get our Python Tips Book

"The discussions are succinct yet thorough enough to give you a solid grasp of the particular problem. I just wish I would have had this book when I started learning Python." - Daniel H

"Bob and Julian are the masters at aggregating these small snippets of code that can really make certain aspects of coding easier." - Jesse B

"This is now my favourite first Python go-to reference." - Anthony L

"Do you ever go on one of those cooking websites for a recipe and have to scroll for what feels like an eternity to get to the ingredients and the 4 steps the recipe actually takes? This is the opposite of that." - Sergio S

Get the book