mirror of
https://github.com/soywod/himalaya.git
synced 2024-11-25 04:20:22 +00:00
vim: render msg table directly from cli (#238)
* vim: render msg table from cli directly * doc: update changelog
This commit is contained in:
parent
e154481c5b
commit
43785b3c1e
4 changed files with 106 additions and 79 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
59
vim/autoload/himalaya/request.vim
Normal file
59
vim/autoload/himalaya/request.vim
Normal file
|
@ -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
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue