A powerful and flexible mail reader interface for NeoVim. This plugin bridges your email and text editing experiences directly within NeoVim by interfacing with the Notmuch mail indexer.
Notmuch.nvim is a NeoVim plugin that serves as a front-end for the Notmuch mail indexer, enabling users to read, compose, and manage their emails from within NeoVim. It facilitates a streamlined workflow for handling emails using the familiar Vim interface and motions.
- 📧 Email Browsing: Navigate emails with Vim-like movements.
- 🔍 Search Your Email: Leverage
notmuchto search your email interactively. - 🔗 Thread Viewing: Messages are loaded with folding and threading intact.
- 📎 Attachment Management: View, open and save attachments easily.
- ⬇️ Offline Mail Sync: Supports
mbsyncfor efficient sync processes. - 🔓 Async Search: Large mailboxes with thousands of email? No problem.
- 🏷️ Tag Management: Conveniently add, remove, or toggle email tags.
- 🔭 (WIP)
Telescope.nvim Integration: Search interactively, extract URL's, jump efficiently, with the powerful file picker of choice.
- NeoVim: Version 0.5 or later is required due to LuaJIT support.
- Notmuch: Ensure Notmuch and libnotmuch library are installed
- (WIP)
Telescope.nvim: File picker of choice for many use cases.
You can install Notmuch.nvim using your favorite NeoVim plugin manager.
{
'yousefakbar/notmuch.nvim',
config = function()
-- Configuration goes here
local opts = {}
require('notmuch').setup(opts)
end,
}If you are using nvim v0.12, or above, you can install using the builtin
package manager:
vim.pack.add({
'https://github.com/yousefakbar/notmuch.nvim',
})
-- Or to pin to a specific tag/version:
vim.pack.add({
{
src = 'https://github.com/yousefakbar/notmuch.nvim',
version = 'v0.2.0', -- Or git commit, etc.
},
})Clone the repository and add the directory to your runtimepath:
git clone https://github.com/yousefakbar/notmuch.nvim.gitHere are the core commands within Notmuch.nvim:
-
:Notmuch: Lists available tags in your Notmuch database in a buffer. Setup key bindings for easy access. Example:-- Define a keymap to run `:Notmuch` and launch the plugin landing page vim.keymap.set("n", "<leader>n", "<CMD>Notmuch<CR>")
-
:NmSearch <query>: Executes an asynchronous search based on provided Notmuch query terms." Loads the threads in your inbox received today :NmSearch tag:inbox and date:today
You can configure several global options to tailor the plugin's behavior:
| Option | Description | Default |
|---|---|---|
notmuch_db_path |
Directory containing the .notmuch/ dir |
From notmuch config |
maildir_sync_cmd |
Bash command to run for syncing maildir | mbsync -a |
sync.sync_mode |
Async mode for the maildir_sync_cmd |
buffer |
keymaps |
Configure any (WIP) command's keymap | See config.lua1 |
open_handler |
Callback function for opening attachments | Runs OS-aware open2 |
view_handler |
Callback function for converting attachments to text to view in floating window | See default_view_handler()2 |
Example configuration in plugin manager (lazy.nvim):
{
"yousefakbar/notmuch.nvim",
opts = {
notmuch_db_path = "/home/xxx/Documents/Mail",
maildir_sync_cmd = "mbsync personal",
sync = {
sync_mode = "buffer" -- OR "background"
},
keymaps = {
sendmail = "<C-g><C-g>",
},
},
},The plugin provides two handlers for working with attachments:
Open Handler: Opens attachments externally with your system's default
application. The default handler automatically detects your OS and uses open
(macOS), xdg-open (Linux), or start (Windows).
View Handler: Converts attachments to text for display in a floating window within Neovim. The default handler supports HTML, PDF, images, Office documents, Markdown, archives, and plain text files. It tries multiple CLI tools for each format and falls back gracefully if tools aren't available.
To customize either handler, pass a function to setup():
require('notmuch').setup({
-- Custom open handler
open_handler = function(attachment)
-- attachment.path contains the full file path
vim.fn.system({ 'my-custom-opener', attachment.path })
end,
-- Custom view handler
view_handler = function(attachment)
-- Must return a string to display in the floating window
local path = attachment.path
if path:match('%.pdf$') then
return vim.fn.system({ 'pdftotext', '-layout', path, '-' })
end
return vim.fn.system({ 'cat', path })
end,
})The default handlers are defined in lua/notmuch/handlers.lua and handle many
common formats out of the box. Only override them if you need specific behavior.
This project is licensed under the MIT License, granting you the freedom to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell copies. The
MIT License's full text can be found in the LICENSE section of the project's
documentation.
For more details on usage and advanced configuration options, please refer to
the in-depth plugin help within NeoVim: :help notmuch.