After writing the post about setting up Neovim I got to thinking about the :Gitmoji command I made and a better way of doing it.
It works well enough, but since there are over 70 different emojis, finding one in the list can be a bit difficult. A way to filter the list would be nice.
It turns out that using vim.ui.input for this instead of vim.ui.select is possible, but I couldn't find any examples of using a custom completion function from Lua.
I was able to get it working after some trial and error, but it requires a little more setup than just adding code to init.lua.
Instead, this needs to be housed within it's own module, i.e. ~\nvim\lua\gitmoji.lua folder.
We still need the list of emoji and descriptions:
local gitmojis = {
{'๐จ', 'Improve structure/format of the code.'},
{'โก๏ธ', 'Improve performance.'},
{'๐ฅ', 'Remove code or files.'},
{'๐', 'Fix a bug.'},
{'๐๏ธ', 'Critical hotfix.'},
{'โจ', 'Introduce new features.'},
{'๐', 'Add or update documentation.'},
{'๐', 'Deploy stuff.'},
{'๐', 'Add or update the UI and style files.'},
{'๐', 'Begin a project.'},
{'โ
', 'Add, update, or pass tests.'},
{'๐๏ธ', 'Fix security or privacy issues.'},
{'๐', 'Add or update secrets.'},
{'๐', 'Release/version tags.'},
{'๐จ', 'Fix compiler/linter warnings.'},
{'๐ง', 'Work in progress.'},
{'๐', 'Fix CI build.'},
{'โฌ๏ธ' , 'Downgrade dependencies.'},
{'โฌ๏ธ' , 'Upgrade dependencies.'},
{'๐', 'Pin dependencies to specific versions.'},
{'๐ท', 'Add or update CI build system.'},
{'๐', 'Add or update analytics or track code.'},
{'โป๏ธ' , 'Refactor code.'},
{'โ', 'Add a dependency.'},
{'โ', 'Remove a dependency.'},
{'๐ง', 'Add or update configuration files.'},
{'๐จ', 'Add or update development scripts.'},
{'๐', 'Internationalization and localization.'},
{'โ๏ธ' , 'Fix typos.'},
{'๐ฉ', 'Write bad code that needs to be improved.'},
{'โช๏ธ', 'Revert changes.'},
{'๐', 'Merge branches.'},
{'๐ฆ๏ธ', 'Add or update compiled files or packages.'},
{'๐ฝ๏ธ', 'Update code due to external API changes.'},
{'๐', 'Move or rename resources (e.g.: files, paths, routes).'},
{'๐', 'Add or update license.'},
{'๐ฅ', 'Introduce breaking changes.'},
{'๐ฑ', 'Add or update assets.'},
{'โฟ๏ธ', 'Improve accessibility.'},
{'๐ก', 'Add or update comments in source code.'},
{'๐ป', 'Write code drunkenly.'},
{'๐ฌ', 'Add or update text and literals.'},
{'๐๏ธ', 'Perform database related changes.'},
{'๐', 'Add or update logs.'},
{'๐', 'Remove logs.'},
{'๐ฅ', 'Add or update contributor(s).'},
{'๐ธ', 'Improve user experience/usability.'},
{'๐๏ธ', 'Make architectural changes.'},
{'๐ฑ', 'Work on responsive design.'},
{'๐คก', 'Mock things.'},
{'๐ฅ', 'Add or update easter egg.'},
{'๐', 'Add or update .gitignore file.'},
{'๐ธ', 'Add or update snapshots.'},
{'โ๏ธ' , 'Perform experiments.'},
{'๐๏ธ', 'Improve SEO.'},
{'๐ท๏ธ', 'Add or update types.'},
{'๐ฑ', 'Add or update seed files.'},
{'๐ฉ', 'Add, update, or remove feature flags.'},
{'๐ฅ
', 'Catch errors.'},
{'๐ซ', 'Add or update animations and transitions.'},
{'๐๏ธ', 'Deprecate code that needs to be cleaned up.'},
{'๐', 'Work on code related to authorization, roles, and permissions.'},
{'๐ฉน', 'Simple fix for a non-critical issue.'},
{'๐ง', 'Data exploration/inspection.'},
{'โฐ๏ธ' , 'Remove dead code.'},
{'๐งช', 'Add a failing test.'},
{'๐', 'Add or update business logic.'},
{'๐ฉบ', 'Add or update healthcheck.'},
{'๐งฑ', 'Infrastructure related changes.'},
{'๐งโ๐ป', 'Improve developer experience.'},
{'๐ธ', 'Add sponsorships or money related infrastructure.'},
{'๐งต', 'Add or update code related to multithreading or concurrency.'},
{'๐ฆบ', 'Add or update code related to validation.'},
}
Next, define a table to hold our module and the actual functions:
local M = {}
function M.complete_gitmoji(arglead, cmdline, cursorpos)
local matches = {}
for i, g in ipairs(gitmojis) do
if string.match(string.lower(g[2]), string.lower(cmdline)) then
table.insert(matches, string.format('%s - %s', g[1], g[2]))
end
end
return table.concat(matches, '\n')
end
local function oncomplete(text)
if not text then return end
local description = string.match(text, '. %- (.+)')
if not description then
print('Invalid selection.')
return
end
for i,g in ipairs(gitmojis) do
if g[2]==description then
vim.cmd('normal! i' .. g[1] .. ' ')
return
end
end
print('Invalid gitmoji: ' .. description)
end
vim.api.nvim_create_user_command('Gitmoji', function()
vim.ui.input({
prompt = 'Select Gitmoji (type a partial description and press tab):',
completion = "custom,v:lua.require'gitmoji'.complete_gitmoji",
}, oncomplete)
end, { nargs = 0 })
return M
complete_gitmoji is called when the user presses tab when the input window is open. The cmdline parameter contains the entire line of text from the input box. This is used to filter the list of gitmojis, which are returned as a newline separated list.
oncomplete is called when the user either cancels or selects a gitmoji. This function compares the text with all of the gitmoji descriptions. If one matches, it inserts that unicode gitmoji into the buffer. If the there is no match it displays a message instead.
The real magic is in the call to vim.ui.input. The completion option specifies how the autocompletion is performed, in this case, our module is loaded and the complete_gitmoji function is called.
Finally, just load the module in init.lua:
require('gitmoji')