X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=vim%2Fplugin%2Fnotmuch.vim;h=ade2e45df9a168d4fc09f611e4b04e05be94d4c9;hp=8f6c7748ca5c1495c88c923f39cc9caa511bef93;hb=e2fd1d9970d5ad61017a307ab133990150192d37;hpb=5a32a1d48f790d5bb63e5e7e70b989cd94692c0a diff --git a/vim/plugin/notmuch.vim b/vim/plugin/notmuch.vim index 8f6c7748..ade2e45d 100644 --- a/vim/plugin/notmuch.vim +++ b/vim/plugin/notmuch.vim @@ -110,8 +110,8 @@ let g:notmuch_search_maps = { " --- --- bindings for show screen {{{2 let g:notmuch_show_maps = { - \ '': ':call NM_show_previous(1)', - \ '': ':call NM_show_next(1)', + \ '': ':call NM_show_previous(1, 0)', + \ '': ':call NM_show_next(1, 0)', \ '': ':call NM_search_expand('''')', \ 'q': ':call NM_kill_this_buffer()', \ @@ -276,8 +276,8 @@ function! s:NM_search_edit() endfunction function! s:NM_search_archive_thread() - call NM_add_remove_tags_on_screen('-', ['inbox']) - call NM_add_remove_tags('-', ['inbox']) + call NM_add_remove_tags_on_screen('', '-', ['inbox']) + call NM_add_remove_tags([], '-', ['inbox']) norm j endfunction @@ -351,12 +351,15 @@ function! s:NM_search_thread_id() if !exists('b:nm_raw_lines') echoe 'no b:nm_raw_lines' return '' - else - let line = line('.') - let info = b:nm_raw_lines[line-1] - let what = split(info, '\s\+')[0] - return what endif + let mnum = line('.') - 1 + if len(b:nm_raw_lines) <= mnum + return '' + endif + echo 'len=' . string(len(b:nm_raw_lines)) . ' mnum=' . string(mnum) + 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) @@ -370,8 +373,8 @@ function! s:NM_search_add_remove_tags(prompt, prefix, intags) else let tags = a:intags endif - call NM_add_remove_tags(a:prefix, tags) - call NM_add_remove_tags_on_screen(a:prefix, tags) + call NM_add_remove_tags([], a:prefix, tags) + call NM_add_remove_tags_on_screen('', a:prefix, tags) endfunction " --- implement show screen {{{1 @@ -399,49 +402,56 @@ function! s:NM_cmd_show(words) endfunction -function! s:NM_show_previous(can_change_thread) +function! s:NM_show_previous(can_change_thread, find_matching) 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 %dG', msg['start']) + exec printf('norm %dGzt', msg['start']) " TODO: try to fit the message on screen - norm zz return endfor if !a:can_change_thread return endif call NM_kill_this_buffer() - if line('.') != line('0') + if line('.') > 1 norm k call NM_search_show_thread() norm G - call NM_show_previous(0) + call NM_show_previous(0, a:find_matching) else echo 'No more messages.' endif endfunction -function! s:NM_show_next(can_change_thread) +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 %dG', msg['start']) + exec printf('norm %dGzt', msg['start']) " TODO: try to fit the message on screen - norm zz return endfor - if !a:can_change_thread - return + if a:can_change_thread + call NM_show_next_thread() endif +endfunction + +function! s:NM_show_next_thread() call NM_kill_this_buffer() if line('.') != line('$') norm j @@ -459,10 +469,6 @@ function! s:NM_show_mark_read_then_archive_thread() echo 'not implemented' endfunction -function! s:NM_show_next_message() - echo 'not implemented' -endfunction - function! s:NM_show_mark_read_then_next_open_message() echo 'not implemented' endfunction @@ -491,8 +497,65 @@ 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() - echo 'not implemented' + let advance_tags = ['unread', 'inbox'] + + let vis_top = line('w0') + let vis_bot = line('w$') + + let msg_top = NM_show_get_message_for_line(vis_top) + if !has_key(msg_top,'id') + echo "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' + if len(ids) + call add(ids, 'OR') + endif + call add(ids, msg['id']) + endif + endfor + + let filter = ['('] + advance_tags + [')', 'AND', '('] + ids + [')'] + call NM_add_remove_tags(filter, '-', advance_tags) + call NM_show_next(1, 1) + return + endif + + let msg_bot = NM_show_get_message_for_line(vis_bot) + if !has_key(msg_bot,'id') + echo "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 + call NM_add_remove_tags_on_screen(msg_top['start'], '-', advance_tags) + exec printf('norm %dG', vis_top) + call 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 = ['('] + advance_tags + [')', 'AND', msg_top['id']] + call NM_add_remove_tags(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() @@ -514,22 +577,25 @@ 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') echoe 'no b:nm_raw_info' return '' endif - let info = b:nm_raw_info - let lnum = line('.') - for msg in info['msgs'] - if lnum > msg['end'] - continue - endif - if has_key(msg,'id') - return msg['id'] - endif - return '' - endfor + let msg = NM_show_get_message_for_line(line('.')) + if has_key(msg,'id') + return msg['id'] + endif return '' endfunction @@ -785,6 +851,8 @@ function! s:NM_newBuffer(type, content) silent put=a:content keepjumps 0d setlocal nomodifiable + set scrolloff=0 + set sidescrolloff=0 execute printf('set filetype=notmuch-%s', a:type) execute printf('set syntax=notmuch-%s', a:type) let b:nm_type = a:type @@ -845,26 +913,29 @@ function! s:NM_search_expand(arg) let b:nm_prev_bufnr = prev_bufnr endfunction -function! s:NM_add_remove_tags(prefix, tags) - let id = NM_search_thread_id() - if id == '' +function! s:NM_add_remove_tags(filter, prefix, tags) + let filter = len(a:filter) ? a:filter : [NM_search_thread_id()] + if !len(filter) echoe 'Eeek! I couldn''t find the thead id!' endif call map(a:tags, 'a:prefix . v:val') + let args = ['tag'] + call extend(args, a:tags) + call add(args, '--') + call extend(args, filter) " TODO: handle errors - call NM_run(['tag'] + a:tags + ['--', id]) + call NM_run(args) endfunction -function! s:NM_add_remove_tags_on_screen(prefix, tags) - let online = '' +function! s:NM_add_remove_tags_on_screen(online, prefix, tags) setlocal modifiable if a:prefix == '-' for tagname in a:tags - exec printf('silent %ss/(\([^)]*\)\<%s\>\([^)]*\))$/(\1\2)/', online, tagname) + exec printf('silent! %ss/(\([^)]*\)\<%s\>\([^)]*\))$/(\1\2)/', string(a:online), tagname) endfor else for tagname in a:tags - exec printf('silent %ss/(\([^)]*\)\([^)]*\))$/(\1 %s)/', online, tagname) + exec printf('silent! %ss/(\([^)]*\)\([^)]*\))$/(\1 %s)/', string(a:online), tagname) endfor endif setlocal nomodifiable