Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion autoload/notmuch.vim
Original file line number Diff line number Diff line change
@@ -1,17 +1,46 @@
let s:search_terms_list = [ "attachment:", "folder:", "id:", "mimetype:",
\ "property:", "subject:", "thread:", "date:", "from:", "lastmod:",
\ "path:", "query:", "tag:", "to:" ]
\ "path:", "query:", "tag:", "is:", "to:", "body:", "and ", "or ", "not " ]

function! notmuch#CompSearchTerms(ArgLead, CmdLine, CursorPos) abort
if match(a:ArgLead, "tag:") != -1
let l:tag_list = split(system('notmuch search --output=tags "*"'), '\n')
return "tag:" .. join(l:tag_list, "\ntag:")
endif
if match(a:ArgLead, "is:") != -1
let l:is_list = split(system('notmuch search --output=tags "*"'), '\n')
return "is:" .. join(l:is_list, "\nis:")
endif
if match(a:ArgLead, "mimetype:") != -1
let l:mimetype_list = ["application/", "audio/", "chemical/",
\ "font/", "image/", "inode/", "message/", "model/",
\ "multipart/", "text/", "video/"]
return "mimetype:" .. join(l:mimetype_list, "\nmimetype:")
endif
if match(a:ArgLead, "from:") != -1
let l:from_list = split(system('notmuch address "*"'), '\n')
return "from:" .. join(l:from_list, "\nfrom:")
endif
if match(a:ArgLead, "to:") != -1
let l:to_list = split(system('notmuch address "*"'), '\n')
return "to:" .. join(l:to_list, "\nto:")
endif
if match(a:ArgLead, "folder:") != -1
let l:folder_list = split(system('find ' .. g:notmuch_mailroot .. ' -type d -name cur -print0| sed -n -z "s|^' .. g:notmuch_mailroot .. '/*||p" | xargs -0 dirname | sort | uniq'), '\n')
return "folder:" .. join(l:folder_list, "\nfolder:")
endif
if match(a:ArgLead, "path:") != -1
let l:path_list = split(system('find ' .. g:notmuch_mailroot .. ' -type d -print0| sed -n -z "s|^' .. g:notmuch_mailroot .. '/*||p" | sort -z | uniq -z | tr "\0" "\n"'), '\n')
return "path:" .. join(l:path_list, "\npath:")
endif
return join(s:search_terms_list, "\n")
endfunction

function! notmuch#CompTags(ArgLead, CmdLine, CursorPos) abort
return system('notmuch search --output=tags "*"')
endfunction

function! notmuch#CompAddress(ArgLead, CmdLine, CursorPos) abort
return system('notmuch address "*"')
endfunction
" vim: tabstop=2:shiftwidth=2:expandtab
20 changes: 16 additions & 4 deletions ftplugin/notmuch-threads.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,30 @@ let r = v:lua.require('notmuch.refresh')
let s = v:lua.require('notmuch.sync')
let tag = v:lua.require('notmuch.tag')

command -buffer -complete=custom,notmuch#CompTags -nargs=+ TagAdd :call tag.thread_add_tag("<args>")
command -buffer -complete=custom,notmuch#CompTags -nargs=+ TagRm :call tag.thread_rm_tag("<args>")
command -buffer -complete=custom,notmuch#CompTags -nargs=+ TagToggle :call tag.thread_toggle_tag("<args>")
command -buffer -range -complete=custom,notmuch#CompTags -nargs=+ TagAdd :call tag.thread_add_tag(<q-args>, <line1>, <line2>)
command -buffer -range -complete=custom,notmuch#CompTags -nargs=+ TagRm :call tag.thread_rm_tag(<q-args>, <line1>, <line2>)
command -buffer -range -complete=custom,notmuch#CompTags -nargs=+ TagToggle :call tag.thread_toggle_tag(<q-args>, <line1>, <line2>)
command -buffer -range DelThread :call tag.thread_add_tag("del", <line1>, <line2>) | :call tag.thread_rm_tag("inbox", <line1>, <line2>)

nmap <buffer> <silent> <CR> :call nm.show_thread()<CR>
nmap <buffer> <silent> r :call r.refresh_search_buffer()<CR>
nmap <buffer> <silent> q :bwipeout<CR>
nmap <buffer> <silent> % :call s.sync_maildir()<CR>
nmap <buffer> + :TagAdd
xmap <buffer> + :TagAdd
nmap <buffer> - :TagRm
xmap <buffer> - :TagRm
nmap <buffer> = :TagToggle
xmap <buffer> = :TagToggle
nmap <buffer> a :TagToggle inbox<CR>j
xmap <buffer> a :TagToggle inbox<CR>
nmap <buffer> A :TagRm inbox unread<CR>j
nmap <buffer> x :TagToggle unread<CR>j
xmap <buffer> A :TagRm inbox unread<CR>
nmap <buffer> x :TagToggle unread<CR>
xmap <buffer> x :TagToggle unread<CR>
nmap <buffer> f :TagToggle flagged<CR>j
xmap <buffer> f :TagToggle flagged<CR>
nmap <buffer> <silent> C :call v:lua.require('notmuch.send').compose()<CR>
nmap <buffer> dd :DelThread<CR>j
xmap <buffer> d :DelThread<CR>
nmap <buffer> <silent> D :lua require('notmuch.delete').purge_del()<CR>
31 changes: 31 additions & 0 deletions lua/notmuch/delete.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
local d = {}
local v = vim.api
local nm = require("notmuch")
local r = require("notmuch.refresh")

local confirm_purge = function()
-- remove keymap
vim.keymap.del("n", "DD", { buffer = true })
-- Confirm
local choice = v.nvim_call_function("confirm", {
"Purge deleted emails?",
"&Yes\n&No",
2, -- Default to no
})

if choice == 1 then
v.nvim_command("silent ! notmuch search --output=files --format=text0 tag:del and tag:/./ | xargs -0 rm")
v.nvim_command("silent ! notmuch new")
r.refresh_search_buffer()
end
end

d.purge_del = function()
nm.search_terms("tag:del and tag:/./")
-- Set keymap for purgin
vim.keymap.set("n", "DD", function()
confirm_purge()
end, { buffer = true })
end

return d
6 changes: 4 additions & 2 deletions lua/notmuch/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ end
--
-- @param search string: search terms matching format from
-- `notmuch-search-terms(7)`
-- @param jumptothreadid string: jump to thread id after search
--
-- @usage
-- lua require('notmuch').search_terms('tag:inbox')
nm.search_terms = function(search)
nm.search_terms = function(search, jumptothreadid)
local num_threads_found = 0
if search == '' then
return nil
Expand All @@ -77,14 +78,15 @@ nm.search_terms = function(search)
v.nvim_buf_set_name(buf, search)
v.nvim_win_set_buf(0, buf)

local hint_text = "Hints: <Enter>: Open thread | q: Close | r: Refresh | %: Sync maildir | a: Archive | A: Archive and Read | +: Add tag | -: Remove tag | =: Toggle tag"
local hint_text = "Hints: <Enter>: Open thread | q: Close | r: Refresh | %: Sync maildir | a: Archive | A: Archive and Read | +/-/=: Add, remove, toggle tag | dd: Delete"
v.nvim_buf_set_lines(buf, 0, 2, false, { hint_text , "" })

-- Async notmuch search to make the UX non blocking
require('notmuch.async').run_notmuch_search(search, buf, function()
-- Completion logic
if vim.fn.getline(2) ~= '' then num_threads_found = vim.fn.line('$') - 1 end
print('Found ' .. num_threads_found .. ' threads')
vim.fn.search(jumptothreadid)
end)

-- Set cursor at head of buffer, declare filetype, and disable modifying
Expand Down
5 changes: 4 additions & 1 deletion lua/notmuch/refresh.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ local nm = require('notmuch')
-- -- Normally invoked by pressing `r` in the search results buffer
-- lua require('notmuch.refresh').refresh_search_buffer()
r.refresh_search_buffer = function()
local line = v.nvim_get_current_line()
local threadid = string.match(line, "%S+", 8)
local search = string.match(v.nvim_buf_get_name(0), '%a+:%C+')
v.nvim_command('bwipeout')
nm.search_terms(search)
nm.search_terms(search, threadid)
vim.fn.search(threadid)
end

-- Refreshes the thread view buffer
Expand Down
7 changes: 5 additions & 2 deletions lua/notmuch/send.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,18 @@ end
-- message headers and body. The mail content is stored in `/tmp/` so the user
-- can come back to it later if needed.
--
-- @param to string: recipient address (optionaal argument)
--
-- @usage
-- -- Typically you can run this with `:ComposeMail` or pressing `C`
-- require('notmuch.send').compose()
s.compose = function()
s.compose = function(to)
to = to or ''
local compose_filename = '/tmp/compose.eml'

-- TODO: Add ability to modify default body message and signature
local headers = {
'To: ',
'To: ' .. to,
'Cc: ',
'Subject: ',
'',
Expand Down
78 changes: 45 additions & 33 deletions lua/notmuch/tag.lua
Original file line number Diff line number Diff line change
Expand Up @@ -49,52 +49,64 @@ t.msg_toggle_tag = function(tags)
db.close()
end

t.thread_add_tag = function(tags)
t.thread_add_tag = function(tags, startlinenr, endlinenr)
startlinenr = startlinenr or v.nvim_win_get_cursor(0)[1]
endlinenr = endlinenr or startlinenr
local t = u.split(tags, '%S+')
local line = v.nvim_get_current_line()
local threadid = string.match(line, '%S+', 8)
local db = require'notmuch.cnotmuch'(config.options.notmuch_db_path, 1)
local query = db.create_query('thread:' .. threadid)
local thread = query.get_threads()[1]
for i,tag in pairs(t) do
thread:add_tag(tag)
for linenr = startlinenr, endlinenr do
local line = vim.fn.getline(linenr)
local threadid = string.match(line, "%S+", 8)
local db = require("notmuch.cnotmuch")(config.options.notmuch_db_path, 1)
local query = db.create_query("thread:" .. threadid)
local thread = query.get_threads()[1]
for i,tag in pairs(t) do
thread:add_tag(tag)
end
db.close()
end
db.close()
print('+(' .. tags .. ')')
end

t.thread_rm_tag = function(tags)
t.thread_rm_tag = function(tags, startlinenr, endlinenr)
startlinenr = startlinenr or v.nvim_win_get_cursor(0)[1]
endlinenr = endlinenr or startlinenr
local t = u.split(tags, '%S+')
local line = v.nvim_get_current_line()
local threadid = string.match(line, '%S+', 8)
local db = require'notmuch.cnotmuch'(config.options.notmuch_db_path, 1)
local query = db.create_query('thread:' .. threadid)
local thread = query.get_threads()[1]
for i,tag in pairs(t) do
thread:rm_tag(tag)
for linenr = startlinenr, endlinenr do
local line = vim.fn.getline(linenr)
local threadid = string.match(line, "%S+", 8)
local db = require("notmuch.cnotmuch")(config.options.notmuch_db_path, 1)
local query = db.create_query("thread:" .. threadid)
local thread = query.get_threads()[1]
for i,tag in pairs(t) do
thread:rm_tag(tag)
end
db.close()
end
db.close()
print('-(' .. tags .. ')')
end

t.thread_toggle_tag = function(tags)
t.thread_toggle_tag = function(tags, startlinenr, endlinenr)
startlinenr = startlinenr or v.nvim_win_get_cursor(0)[1]
endlinenr = endlinenr or startlinenr
local t = u.split(tags, '%S+')
local line = v.nvim_get_current_line()
local threadid = string.match(line, '%S+', 8)
local db = require'notmuch.cnotmuch'(config.options.notmuch_db_path, 1)
local query = db.create_query('thread:' .. threadid)
local thread = query.get_threads()[1]
local curr_tags = thread:get_tags()
for i,tag in pairs(t) do
if curr_tags[tag] == true then
thread:rm_tag(tag)
print('-' .. tag)
else
thread:add_tag(tag)
print('+' .. tag)
for linenr = startlinenr, endlinenr do
local line = vim.fn.getline(linenr)
local threadid = string.match(line, "%S+", 8)
local db = require("notmuch.cnotmuch")(config.options.notmuch_db_path, 1)
local query = db.create_query("thread:" .. threadid)
local thread = query.get_threads()[1]
local curr_tags = thread:get_tags()
for i,tag in pairs(t) do
if curr_tags[tag] == true then
thread:rm_tag(tag)
print("-" .. tag)
else
thread:add_tag(tag)
print("+" .. tag)
end
end
db.close()
end
db.close()
end

return t
Expand Down
5 changes: 3 additions & 2 deletions plugin/notmuch.vim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
command -complete=custom,notmuch#CompSearchTerms -nargs=* NmSearch :call v:lua.require('notmuch').search_terms("<args>")
command ComposeMail :call v:lua.require('notmuch.send').compose()
let g:notmuch_mailroot = trim(system('notmuch config get database.mail_root'))
command -complete=custom,notmuch#CompSearchTerms -nargs=* NmSearch :call v:lua.require('notmuch').search_terms(<q-args>)
command -complete=custom,notmuch#CompAddress -nargs=* ComposeMail :call v:lua.require('notmuch.send').compose(<q-args>)

" vim: tabstop=2:shiftwidth=2:expandtab
2 changes: 1 addition & 1 deletion syntax/notmuch-threads.vim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ syntax region nmHints start=/^Hints:/ end=/$/ oneline contains=nmHintsIdentifi
syntax match nmHintsIdentifier "^Hints:" contained nextgroup=nmHintsKey
syntax match nmHintsKey "\s\+[^:\s]\+" contained nextgroup=nmHintsKVDelimiter
syntax match nmHintsKVDelimiter ":" contained nextgroup=nmHintsValue
syntax match nmHintsValue "\s\+[A-Za-z0-9\ ]\+" contained nextgroup=nmHintsDelimiter
syntax match nmHintsValue "\s\+[A-Za-z0-9\ ,.]\+" contained nextgroup=nmHintsDelimiter
syntax match nmHintsDelimiter "|" contained nextgroup=nmHintsKey

highlight link nmHintsIdentifier Comment
Expand Down