yousefakbar
notmuch.nvim
Lua

Read/write mail offline in your favorite text editor. Notmuch interface for neovim written in Lua

Last updated Jul 2, 2026
70
Stars
11
Forks
10
Issues
0
Stars/day
Attention Score
58
Language breakdown
Lua 96.9%
Vim Script 2.4%
Shell 0.4%
Makefile 0.4%
โ–ธ Files click to expand
README

๐Ÿ“จ Notmuch.nvim

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.

Introduction

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.

Feature Overview

  • ๐Ÿ“ง Email Browsing: Navigate emails with Vim-like movements.
  • ๐Ÿ” Search Your Email: Leverage notmuch to search your email interactively.
  • ๐Ÿ”— Thread Viewing: Messages are loaded with folding and threading intact.
  • ๐Ÿ“Ž Attachment Management: View, open and save attachments easily.
  • ๐ŸŒ Inline HTML Rendering: Render HTML email bodies as text via w3m.
  • โฌ‡๏ธ Offline Mail Sync: Supports mbsync for efficient sync processes, with buffer, background, and interactive terminal modes.
  • ๐Ÿ”“ Async Search: Large mailboxes with thousands of email? No problem.
  • ๐Ÿท๏ธ Tag Management: Conveniently add, remove, or toggle email tags.
  • ๐Ÿ’ป Pure Lua: Fully implemented in Lua for performance and maintainability.
  • ๐Ÿ”ญ (WIP) ~~Telescope.nvim Integration: Search interactively, extract URL's, jump
efficiently, with the powerful file picker of choice.~~

Requirements

  • NeoVim: Version 0.10 or later is
required (uses vim.system(), vim.b buffer variables, and other modern APIs).
  • Notmuch: Ensure Notmuch and libnotmuch library
are installed
  • w3m (optional): Required for inline HTML
email rendering when renderhtmlbody = true picker of choice for many use cases.~~

Installation

You can install Notmuch.nvim using your favorite NeoVim plugin manager.

Using lazy.nvim:

{
    'yousefakbar/notmuch.nvim',
    config = function()
        -- Configuration goes here
        local opts = {}
        require('notmuch').setup(opts)
    end,
}

Using vim.pack:

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.3.0', -- Or git commit, etc. }, })

Manual Installation:

Clone the repository and add the directory to your runtimepath:
git clone https://github.com/yousefakbar/notmuch.nvim.git

Usage

Here 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
  • :Inbox [email]: Quick access to your inbox. Optionally filter by
recipient email address (Useful for multi-account setups.)
" Open all inbox messages
  :Inbox

" Open inbox for a specific account :Inbox work@example.com

Configuration Options

You can configure several global options to tailor the plugin's behavior:

| Option | Description | Default | | :----------------- | :-----------------------------------------------------------------------------: | :------------------------------ | | notmuchdbpath | Directory containing the .notmuch/ dir | From notmuch config | | maildirsynccmd | Bash command to run for syncing maildir | mbsync -a | | sync.sync_mode | Sync display mode: "buffer", "background", or "terminal" (PTY with stdin) | buffer | | queries | Saved/pinned queries shown at top of :Notmuch dashboard; hidden when empty | {} | | keymaps | Configure any (WIP) command's keymap | See config.lua[1] | | open_handler | Callback function for opening attachments | Runs OS-aware open[2] | | viewhandler | Callback function for converting attachments to text to view in floating window | See defaultview_handler()[2] | | renderhtmlbody | Render HTML email bodies inline using w3m (requires w3m installed) | false | | threadviewmode | Thread view mode: "threaded", "newest-first", or "oldest-first" | "threaded" | | suppressdeprecationwarning | Suppress the warning shown when using deprecated notmuch API (< 0.32) | false |

[1]: https://github.com/yousefakbar/notmuch.nvim/blob/main/lua/notmuch/config.lua [2]: https://github.com/yousefakbar/notmuch.nvim/blob/main/lua/notmuch/handlers.lua

Example configuration in plugin manager (lazy.nvim):

{
    "yousefakbar/notmuch.nvim",
    opts = {
        notmuchdbpath = "/home/xxx/Documents/Mail",
        maildirsynccmd = "mbsync personal",
        sync = {
            sync_mode = "buffer" -- OR "background" OR "terminal"
        },
        keymaps = {
            sendmail = "<C-g><C-g>",
        },
        renderhtmlbody = true, -- Render HTML emails inline (requires w3m)
        queries = {
            { name = "๐Ÿ“ค Sent today",    query = "tag:sent and date:today" },
            { name = "โš ๏ธ IMPORTANT",     query = "tag:flagged or tag:pr or tag:urgent" },
            { name = "โŒ› Overdue (+3d)", query = "tag:inbox and date:..3d" },
        },
        threadviewmode = "threaded", -- OR "newest-first" OR "oldest-first"
    },
},

Customizing Attachment Handlers

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.

Statusline Integration

When viewing a thread, the plugin exposes buffer-local variables that can be used for statusline integration or other extensibility purposes:

| Variable | Description | | :------- | :---------- | | vim.b.notmuch_thread | Thread metadata (ID, subject, tags, authors, message count) | | vim.b.notmuch_messages | Array of all messages with line positions and metadata | | vim.b.notmuch_current | Cursor-tracked current message (updates on CursorMoved) | | vim.b.notmuch_status | Pre-formatted statusline string (e.g., "2/5 John Doe ๐Ÿ“Ž1") |

Example statusline integration with lualine:

require('lualine').setup({
  sections = {
    lualine_c = {
      {
        function() return vim.b.notmuch_status or '' end,
        cond = function() return vim.bo.filetype == 'mail' end,
      },
    },
  },
})

License

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.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท yousefakbar/notmuch.nvim ยท Updated daily from GitHub