diff --git a/CHANGELOG.md b/CHANGELOG.md index 98c2815..3b0de43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Change - Remove error when empty subject [#229] +- Vim plugin does not render anymore the msg by itself, it uses the one available from the CLI [#220] ## [0.5.0] - 2021-10-10 diff --git a/vim/autoload/himalaya/msg.vim b/vim/autoload/himalaya/msg.vim index 2e013dc..8905296 100644 --- a/vim/autoload/himalaya/msg.vim +++ b/vim/autoload/himalaya/msg.vim @@ -1,34 +1,24 @@ let s:log = function("himalaya#shared#log#info") let s:trim = function("himalaya#shared#utils#trim") let s:cli = function("himalaya#shared#cli#call") +let s:plain_req = function("himalaya#request#plain") let s:msg_id = 0 let s:draft = "" -" Message - -function! s:format_msg_for_list(msg) - let flag_new = index(a:msg.flags, "Seen") == -1 ? "✷" : " " - let flag_flagged = index(a:msg.flags, "Flagged") == -1 ? " " : "!" - let flag_replied = index(a:msg.flags, "Answered") == -1 ? " " : "↵" - let a:msg.flags = printf("%s %s %s", flag_new, flag_replied, flag_flagged) - return a:msg -endfunction - function! himalaya#msg#list_with(account, mbox, page, should_throw) let pos = getpos(".") - let msgs = s:cli( - \"--account %s --mailbox %s list --page %d", - \[shellescape(a:account), shellescape(a:mbox), a:page], - \printf("Fetching %s messages", a:mbox), - \a:should_throw, - \) - let msgs = map(msgs, "s:format_msg_for_list(v:val)") + let msgs = s:plain_req({ + \'cmd': '--account %s --mailbox %s list --max-width %d --page %d', + \'args': [shellescape(a:account), shellescape(a:mbox), s:bufwidth(), a:page], + \'msg': printf("Fetching %s messages", a:mbox), + \'should_throw': a:should_throw, + \}) let buftype = stridx(bufname("%"), "Himalaya messages") == 0 ? "file" : "edit" execute printf("silent! %s Himalaya messages [%s] [page %d]", buftype, a:mbox, a:page) setlocal modifiable silent execute "%d" - call append(0, s:render("list", msgs)) + call append(0, split(msgs, '\n')) silent execute "$d" setlocal filetype=himalaya-msg-list let &modified = 0 @@ -315,50 +305,25 @@ function! himalaya#msg#attachments() endtry endfunction -" Render utils +" Utils -let s:config = { - \"list": { - \"columns": ["id", "flags", "subject", "sender", "date"], - \}, - \"labels": { - \"id": "ID", - \"flags": "FLAGS", - \"subject": "SUBJECT", - \"sender": "SENDER", - \"date": "DATE", - \}, -\} +" https://newbedev.com/get-usable-window-width-in-vim-script +function! s:bufwidth() + let width = winwidth(0) + let numberwidth = max([&numberwidth, strlen(line('$'))+1]) + let numwidth = (&number || &relativenumber)? numberwidth : 0 + let foldwidth = &foldcolumn -function! s:render(type, lines) - let s:max_widths = s:get_max_widths(a:lines, s:config[a:type].columns) - let header = [s:render_line(s:config.labels, s:max_widths, a:type)] - let line = map(copy(a:lines), "s:render_line(v:val, s:max_widths, a:type)") - - return header + line -endfunction - -function! s:render_line(line, max_widths, type) - return "|" . join(map( - \copy(s:config[a:type].columns), - \"s:render_cell(a:line[v:val], a:max_widths[v:key])", - \), "") -endfunction - -function! s:render_cell(cell, max_width) - let cell_width = strdisplaywidth(a:cell[:a:max_width]) - return a:cell[:a:max_width] . repeat(" ", a:max_width - cell_width) . " |" -endfunction - -function! s:get_max_widths(msgs, columns) - let max_widths = map(copy(a:columns), "strlen(s:config.labels[v:val])") - - for msg in a:msgs - let widths = map(copy(a:columns), "has_key(msg, v:val . '_len') ? msg[v:val . '_len'] : strlen(msg[v:val])") - call map(max_widths, "max([widths[v:key], v:val])") - endfor - - return max_widths + if &signcolumn == 'yes' + let signwidth = 2 + elseif &signcolumn == 'auto' + let signs = execute(printf('sign place buffer=%d', bufnr(''))) + let signs = split(signs, '\n') + let signwidth = len(signs)>2? 2: 0 + else + let signwidth = 0 + endif + return width - numwidth - foldwidth - signwidth endfunction function! s:get_focused_msg_id() @@ -378,9 +343,9 @@ function! s:get_focused_msg_ids(from, to) endfunction function! s:close_open_buffers(name) - let l:open_buffers = filter(range(1, bufnr('$')), 'bufexists(v:val)') - let l:target_buffers = filter(l:open_buffers, 'buffer_name(v:val) =~ a:name') - for buffer_to_close in l:target_buffers + let open_buffers = filter(range(1, bufnr('$')), 'bufexists(v:val)') + let target_buffers = filter(open_buffers, 'buffer_name(v:val) =~ a:name') + for buffer_to_close in target_buffers execute ":bwipeout " . buffer_to_close endfor endfunction diff --git a/vim/autoload/himalaya/request.vim b/vim/autoload/himalaya/request.vim new file mode 100644 index 0000000..57712dc --- /dev/null +++ b/vim/autoload/himalaya/request.vim @@ -0,0 +1,59 @@ +function! himalaya#request#json(opts) + let msg = get(a:, 'opts.msg', '') + let cmd = get(a:, 'opts.cmd', '') + let args = get(a:, 'opts.args', []) + let should_throw = get(a:, 'opts.should_throw', v:false) + + call himalaya#shared#log#info(printf('%s…', msg)) + let cmd = call('printf', ['himalaya --output json ' . cmd] + args) + let res = system(cmd) + + if empty(res) + redraw | call himalaya#shared#log#info(printf('%s [OK]', msg)) + else + try + let res = substitute(res, ':null', ':v:null', 'g') + let res = substitute(res, ':true', ':v:true', 'g') + let res = substitute(res, ':false', ':v:false', 'g') + let res = eval(res) + redraw | call himalaya#shared#log#info(printf('%s [OK]', msg)) + return res.response + catch + redraw + for line in split(res, '\n') + call himalaya#shared#log#err(line) + endfor + if should_throw + throw '' + endif + endtry + endif +endfunction + +function! himalaya#request#plain(opts) + let msg = get(a:opts, 'msg', '') + let cmd = get(a:opts, 'cmd', '') + let args = get(a:opts, 'args', []) + let should_throw = get(a:, 'opts.should_throw', v:false) + + call himalaya#shared#log#info(printf('%s…', msg)) + let cmd = call('printf', ['himalaya --output plain ' . cmd] + args) + let res = system(cmd) + + if empty(res) + redraw | call himalaya#shared#log#info(printf('%s [OK]', msg)) + else + try + redraw | call himalaya#shared#log#info(printf('%s [OK]', msg)) + return trim(res) + catch + redraw + for line in split(res, '\n') + call himalaya#shared#log#err(line) + endfor + if should_throw + throw '' + endif + endtry + endif +endfunction diff --git a/vim/syntax/himalaya-msg-list.vim b/vim/syntax/himalaya-msg-list.vim index 9cccd1d..8e200f1 100644 --- a/vim/syntax/himalaya-msg-list.vim +++ b/vim/syntax/himalaya-msg-list.vim @@ -2,23 +2,25 @@ if exists("b:current_syntax") finish endif -syntax match hym_sep /|/ -syntax match hym_uid /^|.\{-}|/ contains=hym_sep -syntax match hym_flags /^|.\{-}|.\{-}|/ contains=hym_uid,hym_sep -syntax match hym_subject /^|.\{-}|.\{-}|.\{-}|/ contains=hym_uid,hym_flags,hym_sep -syntax match hym_sender /^|.\{-}|.\{-}|.\{-}|.\{-}|/ contains=hym_uid,hym_flags,hym_subject,hym_sep -syntax match hym_date /^|.\{-}|.\{-}|.\{-}|.\{-}|.\{-}|/ contains=hym_uid,hym_flags,hym_subject,hym_sender,hym_sep -syntax match hym_head /.*\%1l/ contains=hym_sep -syntax match hym_unseen /^|.\{-}|✷.*$/ contains=hym_sep +syntax match HimalayaSeparator /│/ +syntax match HimalayaHead /.*\%1l/ contains=HimalayaSeparator +syntax match HimalayaId /^.\{-}│/ contains=HimalayaSeparator +syntax match HimalayaFlags /^.\{-}│.\{-}│/ contains=HimalayaId,HimalayaSeparator +syntax match HimalayaSubject /^.\{-}│.\{-}│.\{-}│/ contains=HimalayaId,HimalayaFlags,HimalayaSeparator +syntax match HimalayaSender /^.\{-}│.\{-}│.\{-}│.\{-}│/ contains=HimalayaId,HimalayaFlags,HimalayaSubject,HimalayaSeparator +syntax match HimalayaDate /^.\{-}│.\{-}│.\{-}│.\{-}│.\{-}/ contains=HimalayaId,HimalayaFlags,HimalayaSubject,HimalayaSender,HimalayaSeparator -highlight hym_head term=bold,underline cterm=bold,underline gui=bold,underline -highlight hym_unseen term=bold cterm=bold gui=bold +" FIXME: Find a way to set the line bold AND to keep the style of each columns. +" syntax match HimalayaUnseen /^.\{-}│✷.*$/ contains=HimalayaSeparator +" highlight HimalayaUnseen term=bold cterm=bold gui=bold -highlight default link hym_sep VertSplit -highlight default link hym_uid Identifier -highlight default link hym_flags Special -highlight default link hym_subject String -highlight default link hym_sender Structure -highlight default link hym_date Constant +highlight HimalayaHead term=bold,underline cterm=bold,underline gui=bold,underline + +highlight default link HimalayaSeparator VertSplit +highlight default link HimalayaId Identifier +highlight default link HimalayaFlags Special +highlight default link HimalayaSubject String +highlight default link HimalayaSender Structure +highlight default link HimalayaDate Constant let b:current_syntax = "himalaya-msg-list"