diff options
author | David Bremner <bremner@debian.org> | 2013-02-16 08:03:09 -0400 |
---|---|---|
committer | David Bremner <bremner@debian.org> | 2013-02-16 08:03:09 -0400 |
commit | 6ee07a9c6db59e91852f2fe47a2701f5e08fee21 (patch) | |
tree | 8c802dbc03b6bb5e2aef9d19197377b501b6d32d /vim | |
parent | 41a29a84721235e33aff23bf6ef61b9ffdded2ef (diff) |
notmuch-vim: deprecate, move to contrib
As discussed in id:871udhcmks.fsf@zancas.localnet, notmuch-vim doesn't
really meet the standards of the CLI, emacs interface, or python
bindings in terms of being well maintained.
Diffstat (limited to 'vim')
-rw-r--r-- | vim/Makefile | 23 | ||||
-rw-r--r-- | vim/README | 86 | ||||
-rw-r--r-- | vim/notmuch.yaml | 8 | ||||
-rw-r--r-- | vim/plugin/notmuch.vim | 1432 | ||||
-rw-r--r-- | vim/syntax/notmuch-compose.vim | 7 | ||||
-rw-r--r-- | vim/syntax/notmuch-folders.vim | 12 | ||||
-rw-r--r-- | vim/syntax/notmuch-git-diff.vim | 26 | ||||
-rw-r--r-- | vim/syntax/notmuch-search.vim | 12 | ||||
-rw-r--r-- | vim/syntax/notmuch-show.vim | 24 |
9 files changed, 0 insertions, 1630 deletions
diff --git a/vim/Makefile b/vim/Makefile deleted file mode 100644 index f17bebfe..00000000 --- a/vim/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -.PHONY: all help install link symlink - -files = plugin/notmuch.vim \ - $(wildcard syntax/notmuch-*.vim) -prefix = $(HOME)/.vim -destdir = $(prefix)/plugin - -INSTALL = install -D -m644 - -all: help - -help: - @echo "I don't actually build anything, but I will help you install" - @echo "notmuch support for vim." - @echo - @echo " make install - copy plugin scripts and syntax files to ~/.vim" - @echo " make symlink - create symlinks in ~/.vim (useful for development)" - -install: - @for x in $(files); do $(INSTALL) $(CURDIR)/$$x $(prefix)/$$x; done - -link symlink: INSTALL = ln -fs -link symlink: install diff --git a/vim/README b/vim/README deleted file mode 100644 index 53f1c4e1..00000000 --- a/vim/README +++ /dev/null @@ -1,86 +0,0 @@ -This directory contains a vim script that allows reading notmuch mail -through vim. - -NOTE: this is a work in progress. Patches welcome. <bart@jukie.net> - -Dependencies: - notmuch: - Naturally, it expects you have notmuch installed and configured. - - sendmail: - To send mail, notmuch.vim uses sendmail as default. Most modern MTAs - provide a compatibility binary, and so should work well. - - -To install: - make install - - -To run: - vim -c ':NotMuch' - - from vim: - :NotMuch - :NotMuch new to:bart@jukie.net 'subject:this is a test' - - -Buffer types: - [notmuch-folders] - Folder list, or technically a list of saved searches. - - Keybindings: - <Enter> - show the selected search - m - compose a new message - s - enter search criteria - = - refresh display - - [notmuch-search] - You are presented with the search results when you run :NotMuch. - - Keybindings: - <Space> - show the selected thread collapsing unmatched items - <Enter> - show the entire selected thread - a - archive message (remove inbox tag) - f - filter the current search terms - o - toggle search screen order - m - compose a new message - r - reply to thread - s - enter search criteria - ,s - alter search criteria - t - filter the current search terms with tags - q - return to folder display, or undo filter - + - add tag(s) to selected message - - - remove tag(s) from selected message - = - refresh display - ? - reveal the thread ID of what's under cursor - ^] - search using word under cursor - - [notmuch-show] - This is the display of the message. - - Keybindings: - <Space> - mark read, archive, go to next matching message - ^n - next message - ^p - previous message - b - toggle folding of message bodies - c - toggle folding of citations - h - toggle folding of extra header lines - i - toggle folding of signatures - m - compose a new message - r - reply to the message - s - enter search criteria - q - return to search display - ? - reveal the message and thread IDs of what's under cursor - ^] - search using word under cursor - - [notmuch-compose] - When you're writing an email, you're in this mode. - - Insert-mode keybindings: - <Tab> - go to the next header line - - Normal-mode keybindings: - <Tab> - go to the next header line - ,s - send this message - ,q - abort this message - diff --git a/vim/notmuch.yaml b/vim/notmuch.yaml deleted file mode 100644 index 3d8422c8..00000000 --- a/vim/notmuch.yaml +++ /dev/null @@ -1,8 +0,0 @@ -addon: notmuch -description: "notmuch mail user interface" -files: - - plugin/notmuch.vim - - syntax/notmuch-compose.vim - - syntax/notmuch-folders.vim - - syntax/notmuch-search.vim - - syntax/notmuch-show.vim diff --git a/vim/plugin/notmuch.vim b/vim/plugin/notmuch.vim deleted file mode 100644 index 8f27fb92..00000000 --- a/vim/plugin/notmuch.vim +++ /dev/null @@ -1,1432 +0,0 @@ -" notmuch.vim plugin --- run notmuch within vim -" -" Copyright © Carl Worth -" -" This file is part of Notmuch. -" -" Notmuch is free software: you can redistribute it and/or modify it -" under the terms of the GNU General Public License as published by -" the Free Software Foundation, either version 3 of the License, or -" (at your option) any later version. -" -" Notmuch is distributed in the hope that it will be useful, but -" WITHOUT ANY WARRANTY; without even the implied warranty of -" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -" General Public License for more details. -" -" You should have received a copy of the GNU General Public License -" along with Notmuch. If not, see <http://www.gnu.org/licenses/>. -" -" Authors: Bart Trojanowski <bart@jukie.net> -" Contributors: Felipe Contreras <felipe.contreras@gmail.com>, -" Peter Hartman <peterjohnhartman@gmail.com> -" -" --- configuration defaults {{{1 - -let s:notmuch_defaults = { - \ 'g:notmuch_cmd': 'notmuch' , - \ 'g:notmuch_sendmail': '/usr/sbin/sendmail' , - \ 'g:notmuch_debug': 0 , - \ - \ 'g:notmuch_search_newest_first': 1 , - \ 'g:notmuch_search_from_column_width': 20 , - \ - \ 'g:notmuch_show_fold_signatures': 1 , - \ 'g:notmuch_show_fold_citations': 1 , - \ 'g:notmuch_show_fold_bodies': 0 , - \ 'g:notmuch_show_fold_headers': 1 , - \ - \ 'g:notmuch_show_message_begin_regexp': 'message{' , - \ 'g:notmuch_show_message_end_regexp': 'message}' , - \ 'g:notmuch_show_header_begin_regexp': 'header{' , - \ 'g:notmuch_show_header_end_regexp': 'header}' , - \ 'g:notmuch_show_body_begin_regexp': 'body{' , - \ 'g:notmuch_show_body_end_regexp': 'body}' , - \ 'g:notmuch_show_attachment_begin_regexp': 'attachment{' , - \ 'g:notmuch_show_attachment_end_regexp': 'attachment}' , - \ 'g:notmuch_show_part_begin_regexp': 'part{' , - \ 'g:notmuch_show_part_end_regexp': 'part}' , - \ 'g:notmuch_show_marker_regexp': '\\(message\\|header\\|body\\|attachment\\|part\\)[{}].*$', - \ - \ 'g:notmuch_show_message_parse_regexp': '\(id:[^ ]*\) depth:\([0-9]*\) match:\([0-9]*\) excluded:\([0-9]*\) filename:\(.*\)$', - \ 'g:notmuch_show_tags_regexp': '(\([^)]*\))$' , - \ - \ 'g:notmuch_show_signature_regexp': '^\(-- \?\|_\+\)$' , - \ 'g:notmuch_show_signature_lines_max': 12 , - \ - \ 'g:notmuch_show_citation_regexp': '^\s*>' , - \ - \ 'g:notmuch_compose_insert_mode_start': 1 , - \ 'g:notmuch_compose_header_help': 1 , - \ 'g:notmuch_compose_temp_file_dir': '~/.notmuch/compose' , - \ } - -" defaults for g:notmuch_initial_search_words -" override with: let g:notmuch_initial_search_words = [ ... ] -let s:notmuch_initial_search_words_defaults = [ - \ 'tag:inbox and tag:unread', - \ ] - -" defaults for g:notmuch_show_headers -" override with: let g:notmuch_show_headers = [ ... ] -let s:notmuch_show_headers_defaults = [ - \ 'Subject', - \ 'To', - \ 'Cc', - \ 'Bcc', - \ 'Date', - \ ] - -" defaults for g:notmuch_folders -" override with: let g:notmuch_folders = [ ... ] -let s:notmuch_folders_defaults = [ - \ [ 'new', 'tag:inbox and tag:unread' ], - \ [ 'inbox', 'tag:inbox' ], - \ [ 'unread', 'tag:unread' ], - \ ] - -" defaults for g:notmuch_signature -" override with: let g:notmuch_signature = [ ... ] -let s:notmuch_signature_defaults = [ - \ '', - \ '-- ', - \ 'email sent from notmuch.vim plugin' - \ ] - -" defaults for g:notmuch_compose_headers -" override with: let g:notmuch_compose_headers = [ ... ] -let s:notmuch_compose_headers_defaults = [ - \ 'From', - \ 'To', - \ 'Cc', - \ 'Bcc', - \ 'Subject' - \ ] - -" --- keyboard mapping definitions {{{1 - -" --- --- bindings for folders mode {{{2 - -let g:notmuch_folders_maps = { - \ 'm': ':call <SID>NM_new_mail()<CR>', - \ 's': ':call <SID>NM_search_prompt()<CR>', - \ 'q': ':call <SID>NM_kill_this_buffer()<CR>', - \ '=': ':call <SID>NM_folders_refresh_view()<CR>', - \ '<Enter>': ':call <SID>NM_folders_show_search()<CR>', - \ } - -" --- --- bindings for search screen {{{2 -let g:notmuch_search_maps = { - \ '<Space>': ':call <SID>NM_search_show_thread(0)<CR>', - \ '<Enter>': ':call <SID>NM_search_show_thread(1)<CR>', - \ '<C-]>': ':call <SID>NM_search_expand(''<cword>'')<CR>', - \ 'I': ':call <SID>NM_search_mark_read_thread()<CR>', - \ 'a': ':call <SID>NM_search_archive_thread()<CR>', - \ 'A': ':call <SID>NM_search_mark_read_then_archive_thread()<CR>', - \ 'D': ':call <SID>NM_search_delete_thread()<CR>', - \ 'f': ':call <SID>NM_search_filter()<CR>', - \ 'm': ':call <SID>NM_new_mail()<CR>', - \ 'o': ':call <SID>NM_search_toggle_order()<CR>', - \ 'r': ':call <SID>NM_search_reply_to_thread()<CR>', - \ 's': ':call <SID>NM_search_prompt()<CR>', - \ ',s': ':call <SID>NM_search_edit()<CR>', - \ 't': ':call <SID>NM_search_filter_by_tag()<CR>', - \ 'q': ':call <SID>NM_kill_this_buffer()<CR>', - \ '+': ':call <SID>NM_search_add_tags([])<CR>', - \ '-': ':call <SID>NM_search_remove_tags([])<CR>', - \ '=': ':call <SID>NM_search_refresh_view()<CR>', - \ '?': ':echo <SID>NM_search_thread_id() . '' @ '' . join(<SID>NM_get_search_words())<CR>', - \ } - -" --- --- bindings for show screen {{{2 -let g:notmuch_show_maps = { - \ '<C-P>': ':call <SID>NM_show_previous(1, 0)<CR>', - \ '<C-N>': ':call <SID>NM_show_next(1, 0)<CR>', - \ '<C-]>': ':call <SID>NM_search_expand(''<cword>'')<CR>', - \ 'q': ':call <SID>NM_kill_this_buffer()<CR>', - \ 's': ':call <SID>NM_search_prompt()<CR>', - \ - \ 'b': ':call <SID>NM_show_fold_toggle(''b'', ''bdy'', !g:notmuch_show_fold_bodies)<CR>', - \ 'c': ':call <SID>NM_show_fold_toggle(''c'', ''cit'', !g:notmuch_show_fold_citations)<CR>', - \ 'h': ':call <SID>NM_show_fold_toggle(''h'', ''hdr'', !g:notmuch_show_fold_headers)<CR>', - \ 'i': ':call <SID>NM_show_fold_toggle(''i'', ''sig'', !g:notmuch_show_fold_signatures)<CR>', - \ - \ 'I': ':call <SID>NM_show_mark_read_thread()<CR>', - \ 'a': ':call <SID>NM_show_archive_thread()<CR>', - \ 'A': ':call <SID>NM_show_mark_read_then_archive_thread()<CR>', - \ 'D': ':call <SID>NM_show_delete_thread()<CR>', - \ 'd': ':call <SID>NM_show_delete_message()<CR>', - \ 'N': ':call <SID>NM_show_mark_read_then_next_open_message()<CR>', - \ 'v': ':call <SID>NM_show_view_all_mime_parts()<CR>', - \ '+': ':call <SID>NM_show_add_tag()<CR>', - \ '-': ':call <SID>NM_show_remove_tag()<CR>', - \ '<Space>': ':call <SID>NM_show_advance_marking_read_and_archiving()<CR>', - \ '\|': ':call <SID>NM_show_pipe_message()<CR>', - \ - \ '<S-Tab>': ':call <SID>NM_show_previous_fold()<CR>', - \ '<Tab>': ':call <SID>NM_show_next_fold()<CR>', - \ '<Enter>': ':call <SID>NM_show_toggle_fold()<CR>', - \ - \ 'r': ':call <SID>NM_show_reply()<CR>', - \ 'm': ':call <SID>NM_new_mail()<CR>', - \ '?': ':echo <SID>NM_show_message_id() . '' @ '' . join(<SID>NM_get_search_words())<CR>', - \ } - -" --- --- bindings for compose screen {{{2 -let g:notmuch_compose_nmaps = { - \ ',s': ':call <SID>NM_compose_send()<CR>', - \ ',a': ':call <SID>NM_compose_attach()<CR>', - \ ',q': ':call <SID>NM_kill_this_buffer()<CR>', - \ '<Tab>': ':call <SID>NM_compose_next_entry_area()<CR>', - \ } -let g:notmuch_compose_imaps = { - \ '<Tab>': '<C-r>=<SID>NM_compose_next_entry_area()<CR>', - \ } - -" --- implement folders screen {{{1 - -function! s:NM_cmd_folders(words) - if len(a:words) - throw 'Not expecting any arguments for folders command.' - endif - let cmd = ['count'] - let disp = [] - let searches = [] - for entry in g:notmuch_folders - let [ name, search ] = entry - let data = s:NM_run(cmd + [search]) - let cnt = matchlist(data, '\(\d\+\)')[1] - call add(disp, printf('%9d %-20s (%s)', cnt, name, search)) - call add(searches, search) - endfor - - call <SID>NM_newBuffer('', 'folders', join(disp, "\n")) - let b:nm_searches = searches - let b:nm_timestamp = reltime() - - call <SID>NM_cmd_folders_mksyntax() - call <SID>NM_set_map('n', g:notmuch_folders_maps) - setlocal cursorline - setlocal nowrap -endfunction - -function! s:NM_cmd_folders_mksyntax() -endfunction - -" --- --- folders screen action functions {{{2 - -function! s:NM_folders_refresh_view() - let lno = line('.') - setlocal bufhidden=delete - call s:NM_cmd_folders([]) - exec printf('norm %dG', lno) -endfunction - -function! s:NM_folders_show_search() - let line = line('.') - let search = b:nm_searches[line-1] - - let prev_bufnr = bufnr('%') - setlocal bufhidden=hide - call <SID>NM_cmd_search([search]) - setlocal bufhidden=delete - let b:nm_prev_bufnr = prev_bufnr -endfunction - - -" --- implement search screen {{{1 - -function! s:NM_cmd_search(words) - let cmd = ['search'] - if g:notmuch_search_newest_first - let cmd = cmd + ['--sort=newest-first'] - else - let cmd = cmd + ['--sort=oldest-first'] - endif - let data = s:NM_run(cmd + a:words) - let lines = split(data, "\n") - let disp = copy(lines) - call map(disp, 's:NM_cmd_search_fmtline(v:val)') - - call <SID>NM_newBuffer('', 'search', join(disp, "\n")) - let b:nm_raw_lines = lines - let b:nm_search_words = a:words - - call <SID>NM_set_map('n', g:notmuch_search_maps) - setlocal cursorline - setlocal nowrap -endfunction -function! s:NM_cmd_search_fmtline(line) - let m = matchlist(a:line, '^\(thread:\S\+\)\s\(.\{12\}\) \[\(\d\+\)/\d\+\] \([^;]\+\); \%(\[[^\[]\+\] \)*\(.*\) (\([^(]*\))$') - if !len(m) - return 'ERROR PARSING: ' . a:line - endif - let max = g:notmuch_search_from_column_width - let flist = {} - for at in split(m[4], '[|,] ') - let p = split(at, '[@.]') - let flist[p[0]] = 1 - endfor - let from = join(keys(flist), ", ") - return printf("%-12s %3s %-20.20s | %s (%s)", m[2], m[3], from, m[5], m[6]) -endfunction - -" --- --- search screen action functions {{{2 - -function! s:NM_search_show_thread(everything) - let words = [ <SID>NM_search_thread_id() ] - if !a:everything && exists('b:nm_search_words') - call extend(words, ['AND', '(']) - call extend(words, b:nm_search_words) - call add(words, ')') - endif - call <SID>NM_cmd_show(words) - let b:nm_show_everything = a:everything -endfunction - -function! s:NM_search_prompt() - " TODO: input() can support completion - let text = input('NotMuch Search: ') - if strlen(text) - let tags = split(text) - else - let tags = s:notmuch_initial_search_words_defaults - endif - let prev_bufnr = bufnr('%') - if b:nm_type == 'search' && exists('b:nm_prev_bufnr') - " TODO: we intend to replace the current buffer, - " ... maybe we could just clear it - let prev_bufnr = b:nm_prev_bufnr - setlocal bufhidden=delete - else - setlocal bufhidden=hide - endif - call <SID>NM_cmd_search(tags) - setlocal bufhidden=delete - let b:nm_prev_bufnr = prev_bufnr -endfunction - -function! s:NM_search_edit() - " TODO: input() can support completion - let text = input('NotMuch Search: ', join(b:nm_search_words, ' ')) - if strlen(text) - call <SID>NM_cmd_search(split(text)) - endif -endfunction - -function! s:NM_search_mark_read_thread() - call <SID>NM_tag([], ['-unread']) - norm j -endfunction - -function! s:NM_search_archive_thread() - call <SID>NM_tag([], ['-inbox']) - norm j -endfunction - -function! s:NM_search_mark_read_then_archive_thread() - call <SID>NM_tag([], ['-unread', '-inbox']) - norm j -endfunction - -function! s:NM_search_delete_thread() - call <SID>NM_tag([], ['+delete','-inbox','-unread']) - norm j -endfunction - -function! s:NM_search_filter() - call <SID>NM_search_filter_helper('Filter: ', '', '') -endfunction - -function! s:NM_search_filter_by_tag() - call <SID>NM_search_filter_helper('Filter Tag(s): ', 'tag:', 'and') -endfunction - -function! s:NM_search_filter_helper(prompt, prefix, joiner) - " TODO: input() can support completion - let text = substitute(input(a:prompt), '\v(^\s*|\s*$|\n)', '', 'g') - if !strlen(text) - return - endif - - let tags = b:nm_search_words + ['AND'] - \ + <SID>NM_combine_tags(a:prefix, split(text), a:joiner, '()') - - let prev_bufnr = bufnr('%') - setlocal bufhidden=hide - call <SID>NM_cmd_search(tags) - setlocal bufhidden=delete - let b:nm_prev_bufnr = prev_bufnr -endfunction - -function! s:NM_search_toggle_order() - let g:notmuch_search_newest_first = !g:notmuch_search_newest_first - " FIXME: maybe this would be better done w/o reading re-reading the lines - " reversing the b:nm_raw_lines and the buffer lines would be better - call <SID>NM_search_refresh_view() -endfunction - -function! s:NM_search_reply_to_thread() - let cmd = ['reply'] - call add(cmd, <SID>NM_search_thread_id()) - call add(cmd, 'AND') - call extend(cmd, <SID>NM_get_search_words()) - - let data = <SID>NM_run(cmd) - let lines = split(data, "\n") - call <SID>NM_newComposeBuffer(lines, 0) -endfunction - -function! s:NM_search_add_tags(tags) - call <SID>NM_search_add_remove_tags('Add Tag(s): ', '+', a:tags) -endfunction - -function! s:NM_search_remove_tags(tags) - call <SID>NM_search_add_remove_tags('Remove Tag(s): ', '-', a:tags) -endfunction - -function! s:NM_search_refresh_view() - let lno = line('.') - let prev_bufnr = b:nm_prev_bufnr - setlocal bufhidden=delete - call <SID>NM_cmd_search(b:nm_search_words) - let b:nm_prev_bufnr = prev_bufnr - " FIXME: should find the line of the thread we were on if possible - exec printf('norm %dG', lno) -endfunction - -" --- --- search screen helper functions {{{2 - -function! s:NM_search_thread_id() - if !exists('b:nm_raw_lines') - throw 'Eeek! no b:nm_raw_lines' - endif - let mnum = line('.') - 1 - if len(b:nm_raw_lines) <= mnum - return '' - endif - let info = b:nm_raw_lines[mnum] - let what = split(info, '\s\+')[0] - return what -endfunction - -function! s:NM_search_add_remove_tags(prompt, prefix, intags) - if type(a:intags) != type([]) || len(a:intags) == 0 - " TODO: input() can support completion - let text = input(a:prompt) - if !strlen(text) - return - endif - let tags = split(text, ' ') - else - let tags = a:intags - endif - call map(tags, 'a:prefix . v:val') - call <SID>NM_tag([], tags) -endfunction - -" --- implement show screen {{{1 - -function! s:NM_cmd_show(words) - let prev_bufnr = bufnr('%') - let data = s:NM_run(['show', '--entire-thread'] + a:words) - let lines = split(data, "\n") - - let info = s:NM_cmd_show_parse(lines) - - setlocal bufhidden=hide - call <SID>NM_newBuffer('', 'show', join(info['disp'], "\n")) - setlocal bufhidden=delete - let b:nm_search_words = a:words - let b:nm_raw_info = info - let b:nm_prev_bufnr = prev_bufnr - - call <SID>NM_cmd_show_mkfolds() - call <SID>NM_cmd_show_mksyntax() - call <SID>NM_set_map('n', g:notmuch_show_maps) - setlocal foldtext=NM_cmd_show_foldtext() - setlocal fillchars= - setlocal foldcolumn=6 - -endfunction - -function! s:NM_show_previous(can_change_thread, find_matching) - let everything = exists('b:nm_show_everything') ? b:nm_show_everything : 0 - let info = b:nm_raw_info - let lnum = line('.') - for msg in reverse(copy(info['msgs'])) - if a:find_matching && msg['match'] == '0' - continue - endif - if lnum <= msg['start'] - continue - endif - - exec printf('norm %dGzt', msg['start']) - " TODO: try to fit the message on screen - return - endfor - if !a:can_change_thread - return - endif - call <SID>NM_kill_this_buffer() - if line('.') > 1 - norm k - call <SID>NM_search_show_thread(everything) - norm G - call <SID>NM_show_previous(0, a:find_matching) - else - echo 'No more messages.' - endif -endfunction - -function! s:NM_show_next(can_change_thread, find_matching) - let info = b:nm_raw_info - let lnum = line('.') - for msg in info['msgs'] - if a:find_matching && msg['match'] == '0' - continue - endif - if lnum >= msg['start'] - continue - endif - - exec printf('norm %dGzt', msg['start']) - " TODO: try to fit the message on screen - return - endfor - if a:can_change_thread - call <SID>NM_show_next_thread() - endif -endfunction - -function! s:NM_show_next_thread() - let everything = exists('b:nm_show_everything') ? b:nm_show_everything : 0 - call <SID>NM_kill_this_buffer() - if line('.') != line('$') - norm j - call <SID>NM_search_show_thread(everything) - else - echo 'No more messages.' - endif -endfunction - -function! s:NM_show_mark_read_thread() - call <SID>NM_tag(b:nm_search_words, ['-unread']) - call <SID>NM_show_next_thread() -endfunction - -function! s:NM_show_archive_thread() - call <SID>NM_tag(b:nm_search_words, ['-inbox']) - call <SID>NM_show_next_thread() -endfunction - -function! s:NM_show_mark_read_then_archive_thread() - call <SID>NM_tag(b:nm_search_words, ['-unread', '-inbox']) - call <SID>NM_show_next_thread() -endfunction - -function! s:NM_show_delete_thread() - call <SID>NM_tag(b:nm_search_words, ['+delete', '-inbox', '-unread']) - call <SID>NM_show_next_thread() -endfunction - -function! s:NM_show_delete_message() - let msg = <SID>NM_show_get_message_for_line(line('.')) - call <SID>NM_tag([msg['id']], ['+delete', '-inbox', '-unread']) -endfunction - -function! s:NM_show_mark_read_then_next_open_message() - echo 'not implemented' -endfunction - -function! s:NM_show_previous_message() - echo 'not implemented' -endfunction - -function! s:NM_show_reply() - let cmd = ['reply'] - call add(cmd, <SID>NM_show_message_id()) - call add(cmd, 'AND') - call extend(cmd, <SID>NM_get_search_words()) - - let data = <SID>NM_run(cmd) - let lines = split(data, "\n") - call <SID>NM_newComposeBuffer(lines, 0) -endfunction - -function! s:NM_show_view_all_mime_parts() - echo 'not implemented' -endfunction - -function! s:NM_show_view_raw_message() - echo 'not implemented' -endfunction - -function! s:NM_show_add_tag() - echo 'not implemented' -endfunction - -function! s:NM_show_remove_tag() - echo 'not implemented' -endfunction - -" if entire message is not visible scroll down 1/2 page or less to get to the bottom of message -" otherwise go to next message -" any message that is viewed entirely has inbox and unread tags removed -function! s:NM_show_advance_marking_read_and_archiving() - let advance_tags = ['unread', 'inbox'] - - let vis_top = line('w0') - let vis_bot = line('w$') - - let msg_top = <SID>NM_show_get_message_for_line(vis_top) - if !has_key(msg_top,'id') - throw "No top visible message." - endif - - " if the top message is the last message, just expunge the entire thread and move on - if msg_top['end'] == line('$') - let ids = [] - for msg in b:nm_raw_info['msgs'] - if has_key(msg,'match') && msg['match'] != '0' - call add(ids, msg['id']) - endif - endfor - let filter = <SID>NM_combine_tags('tag:', advance_tags, 'OR', '()') - \ + ['AND'] - \ + <SID>NM_combine_tags('', ids, 'OR', '()') - call map(advance_tags, '"-" . v:val') - call <SID>NM_tag(filter, advance_tags) - call <SID>NM_show_next(1, 1) - return - endif - - let msg_bot = <SID>NM_show_get_message_for_line(vis_bot) - if !has_key(msg_bot,'id') - throw "No bottom visible message." - endif - - " if entire message fits on the screen, read/archive it, move to the next one - if msg_top['id'] != msg_bot['id'] || msg_top['end'] <= vis_bot - exec printf('norm %dG', vis_top) - call <SID>NM_show_next(0, 1) - if has_key(msg_top,'match') && msg_top['match'] != '0' - redraw - " do this last to hide the latency - let filter = <SID>NM_combine_tags('tag:', advance_tags, 'OR', '()') - \ + ['AND', msg_top['id']] - call map(advance_tags, '"-" . v:val') - call <SID>NM_tag(filter, advance_tags) - endif - return - endif - - " entire message does not fit on the screen, scroll down to bottom, max 1/2 screen - let jmp = winheight(winnr()) / 2 - let max = msg_bot['end'] - vis_bot - if jmp > max - let jmp = max - endif - exec printf('norm %dGzt', vis_top + jmp) - return -endfunction - -function! s:NM_show_pipe_message() - echo 'not implemented' -endfunction - -function! s:NM_show_previous_fold() - echo 'not implemented' -endfunction - -function! s:NM_show_next_fold() - echo 'not implemented' -endfunction - -function! s:NM_show_toggle_fold() - echo 'not implemented' -endfunction - - -" --- --- show screen helper functions {{{2 - -function! s:NM_show_get_message_for_line(line) - for msg in b:nm_raw_info['msgs'] - if a:line > msg['end'] - continue - endif - return msg - endfor - return {} -endfunction - -function! s:NM_show_message_id() - if !exists('b:nm_raw_info') - throw 'Eeek! no b:nm_raw_info' - endif - let msg = <SID>NM_show_get_message_for_line(line('.')) - if has_key(msg,'id') - return msg['id'] - endif - return '' -endfunction - -function! s:NM_show_fold_toggle(key, type, fold) - let info = b:nm_raw_info - let act = 'open' - if a:fold - let act = 'close' - endif - for fld in info['folds'] - if fld[0] != a:type - continue - endif - "let idx = fld[3] - "let msg = info['msgs'][idx] - "if has_key(msg,'match') && msg['match'] == '0' - " continue - "endif - let cls = foldclosed(fld[1]) - if cls != -1 && cls != fld[1] - continue - endif - exec printf('%dfold%s', fld[1], act) - endfor - exec printf('nnoremap <buffer> %s :call <SID>NM_show_fold_toggle(''%s'', ''%s'', %d)<CR>', a:key, a:key, a:type, !a:fold) -endfunction - - -" s:NM_cmd_show_parse returns the following dictionary: -" 'disp': lines to display -" 'msgs': message info dicts { start, end, id, depth, filename, descr, header } -" 'folds': fold info arrays [ type, start, end ] -" 'foldtext': fold text indexed by start line -function! s:NM_cmd_show_parse(inlines) - let info = { 'disp': [], - \ 'msgs': [], - \ 'folds': [], - \ 'foldtext': {} } - let msg = {} - let hdr = {} - - let in_message = 0 - let in_header = 0 - let in_body = 0 - let in_part = '' - - let body_start = -1 - let part_start = -1 - - let mode_type = '' - let mode_start = -1 - - let inlnum = 0 - for line in a:inlines - let inlnum = inlnum + 1 - let foldinfo = [] - - if strlen(in_part) - let part_end = 0 - - if match(line, g:notmuch_show_part_end_regexp) != -1 - let part_end = len(info['disp']) - else - call add(info['disp'], line) - endif - - if in_part == 'text/plain' - if !part_end && mode_type == '' - if match(line, g:notmuch_show_signature_regexp) != -1 - let mode_type = 'sig' - let mode_start = len(info['disp']) - elseif match(line, g:notmuch_show_citation_regexp) != -1 - let mode_type = 'cit' - let mode_start = len(info['disp']) - endif - elseif mode_type == 'cit' - if part_end || match(line, g:notmuch_show_citation_regexp) == -1 - let outlnum = len(info['disp']) - if !part_end - let outlnum = outlnum - 1 - endif - let foldinfo = [ mode_type, mode_start, outlnum, len(info['msgs']), - \ printf('[ %d-line citation. Press "c" to show. ]', 1 + outlnum - mode_start) ] - let mode_type = '' - endif - elseif mode_type == 'sig' - let outlnum = len(info['disp']) - if (outlnum - mode_start |