macOS Emoji Chooser with Hammerspoon
💡
I wrote this 7 years ago, but it is standing my test of time: I continue using it daily and have updated it to support Unicode 15 emojis 🪼.
The snippets below have evolved in time; I have left them as originally written, but you can find their up-to-date version on GitHub.
I use the awesome Hammerspoon to automate things on macOS. Today we’ll see how to create an interactive emoji search-engine to pick emojis by using their name or a few keywords:
Smile and say cheese!
# Preliminary setup
To begin, download this archive and unzip into
your ~/.hammerspoon
directory. The archive contains a few thousands emojis in
PNG
format and a JSON
file encoding their details. I generated it through
this script.
# Hammerspoon setup
Now, to Hammerspoon to load the emojis and build the search engine. We’ll use
hs.chooser
to create a Spotlight-like window that allows filtering and
selecting data. We’ll populate it with emojis; once selected, the emoji will be
copied to clipboard and “typed” in the focused application.
Copy and paste the following snippet in your init.lua
file:
-- Build the list of emojis to be displayed.
local choices = {}
for _, emoji in ipairs(hs.json.decode(io.open("emojis/emojis.json"):read())) do
table.insert(choices,
{text=emoji['name'],
subText=table.concat(emoji['kwds'], ", "),
image=hs.image.imageFromPath("emojis/" .. emoji['id'] .. ".png"),
chars=emoji['chars']
})
end
-- Focus the last used window.
local function focusLastFocused()
local wf = hs.window.filter
local lastFocused = wf.defaultCurrentSpace:getWindows(wf.sortByFocusedLast)
if #lastFocused > 0 then lastFocused[1]:focus() end
end
-- Create the chooser.
-- On selection, copy the emoji and type it into the focused application.
local chooser = hs.chooser.new(function(choice)
if not choice then focusLastFocused(); return end
hs.pasteboard.setContents(choice["chars"])
focusLastFocused()
hs.eventtap.keyStrokes(hs.pasteboard.getContents())
end)
chooser:searchSubText(true)
chooser:choices(choices)
If you want, you can also customize the appearance of the chooser:
chooser:rows(5)
chooser:bgDark(true)
Lastly, bind the chooser to any key you like:
hs.hotkey.bind({"cmd", "alt"}, "E", function() chooser:show() end)
# Full result
You’ll find: