Skip to main content

Plugins

Matcha supports Lua plugins for extending functionality. Plugins can react to events like receiving emails, sending messages, switching folders, and more.

Getting Started

Plugin Location

Place your plugins in ~/.config/matcha/plugins/. Matcha loads them automatically on startup.

A plugin can be either:

  • A single .lua file (e.g. my_plugin.lua)
  • A directory with an init.lua entry point (e.g. my_plugin/init.lua)
~/.config/matcha/plugins/
├── hello.lua
├── notify_github.lua
└── my_plugin/
└── init.lua

Your First Plugin

Create ~/.config/matcha/plugins/hello.lua:

local matcha = require("matcha")

matcha.on("startup", function()
matcha.log("hello plugin loaded")
end)

Restart Matcha and check the log output. You should see hello plugin loaded.

API Reference

All plugin functions are accessed through the matcha module:

local matcha = require("matcha")

matcha.on(event, callback)

Register a function to be called when an event occurs.

matcha.on("email_received", function(email)
matcha.log("New email from: " .. email.from)
end)

matcha.log(message)

Write a message to Matcha's log output (stderr). Useful for debugging.

matcha.log("something happened")

matcha.set_status(area, text)

Set a persistent status string displayed in a specific part of the UI. Pass an empty string to clear it.

Available areas:

AreaWhere it appears
"inbox"Inbox title bar, next to the folder name
"composer"Composer help bar at the bottom
"email_view"Email viewer help bar at the bottom
matcha.set_status("inbox", "5 unread")      -- shows as "INBOX (5 unread)"
matcha.set_status("composer", "420 chars") -- shows in composer help bar
matcha.set_status("inbox", "") -- clears the inbox status

matcha.set_compose_field(field, value)

Set a compose field value from a plugin. Only works when the composer is active (e.g. inside a composer_updated callback). The change is applied after the hook returns.

Available fields:

FieldDescription
"to"Recipient(s)
"cc"CC recipient(s)
"bcc"BCC recipient(s)
"subject"Subject line
"body"Email body
-- Auto-add a BCC on every new email
matcha.on("composer_updated", function(state)
if state.bcc == "" then
matcha.set_compose_field("bcc", "archive@example.com")
end
end)

matcha.bind_key(key, area, description, callback)

Register a custom keyboard shortcut. The shortcut is scoped to a specific view area and shows up in the help bar. The callback receives a context table when the key is pressed.

Parameters:

ParameterTypeDescription
keystringKey string (e.g. "ctrl+k", "g", "ctrl+shift+a")
areastringView area: "inbox", "email_view", or "composer"
descriptionstringShort text shown in the help bar
callbackfunctionCalled when the key is pressed; receives a context table

Context tables by area:

  • inbox / email_view: Same email table as email_viewed (uid, from, to, subject, date, is_read, account_id, folder)
  • composer: Same state table as composer_updated (body, body_len, subject, to, cc, bcc)
-- Add a shortcut to show email subject in inbox
matcha.bind_key("ctrl+i", "inbox", "info", function(email)
if email then
matcha.notify("Subject: " .. email.subject, 3)
end
end)

-- Add a shortcut to insert a greeting in the composer
matcha.bind_key("ctrl+g", "composer", "greeting", function(state)
matcha.set_compose_field("body", "Hi there,\n\n" .. state.body)
end)

matcha.notify(message [, seconds])

Show a temporary notification in the Matcha UI. The optional second argument sets how long the notification is displayed (default 2 seconds).

matcha.notify("You have new mail!")       -- shows for 2 seconds
matcha.notify("Important!", 5) -- shows for 5 seconds
matcha.notify("Quick flash", 0.5) -- shows for half a second

Events

startup

Fired once when Matcha starts, after all plugins are loaded.

matcha.on("startup", function()
matcha.log("plugin ready")
end)

shutdown

Fired when Matcha exits.

matcha.on("shutdown", function()
matcha.log("goodbye")
end)

email_received

Fired for each email when a folder's email list is fetched. Receives an email table.

matcha.on("email_received", function(email)
matcha.log(email.from .. ": " .. email.subject)
end)

Email table fields:

FieldTypeDescription
uidnumberUnique email ID
fromstringSender address
totableList of recipient addresses
subjectstringEmail subject line
datestringISO 8601 date string
is_readbooleanWhether the email has been read
account_idstringID of the account
folderstringFolder name (e.g. "INBOX")

email_viewed

Fired when you open an email to read it. Receives the same email table as email_received.

matcha.on("email_viewed", function(email)
matcha.log("Reading: " .. email.subject)
end)

email_send_before

Fired just before an email is sent. Receives a send table.

matcha.on("email_send_before", function(email)
matcha.log("Sending to: " .. email.to)
end)

Send table fields:

FieldTypeDescription
tostringRecipient(s)
ccstringCC recipient(s)
subjectstringEmail subject line
account_idstringSending account ID

email_send_after

Fired after an email is sent successfully. No arguments.

matcha.on("email_send_after", function()
matcha.notify("Email sent!")
end)

folder_changed

Fired when you switch to a different folder. Receives the folder name as a string.

matcha.on("folder_changed", function(folder)
matcha.log("Now viewing: " .. folder)
end)

composer_updated

Fired on every keystroke while the composer is active. Receives a state table with the current composer content.

matcha.on("composer_updated", function(state)
matcha.set_status("composer", state.body_len .. " chars")
end)

State table fields:

FieldTypeDescription
bodystringCurrent body text
body_lennumberLength of the body in bytes
subjectstringCurrent subject line
tostringCurrent recipient(s)
ccstringCurrent CC recipient(s)
bccstringCurrent BCC recipient(s)

Example Plugins

Example plugins are included in the repository under examples/plugins/:

PluginDescription
hello.luaMinimal example that logs startup/shutdown
notify_github.luaNotifies when GitHub emails arrive
send_logger.luaLogs outgoing email details
folder_announcer.luaShows a notification on folder switch
unread_counter.luaDisplays unread count in the inbox title
char_counter.luaLive character count in the composer

To try one, copy it to your plugins directory:

mkdir -p ~/.config/matcha/plugins
cp examples/plugins/hello.lua ~/.config/matcha/plugins/

Security

Plugins run in a sandboxed Lua 5.1 environment. The following standard libraries are available:

  • base (print, type, tostring, pairs, ipairs, etc.)
  • string
  • table
  • math
  • package (for require)

The os, io, and debug libraries are not available. Plugins cannot access the filesystem or execute system commands.