mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-03-14 10:45:42 +08:00
feat(mail): improve vim-mail plugin
This commit is contained in:
parent
1cc4282c99
commit
6adb53df7b
17
autoload/SpaceVim/api/data/quopri.vim
Normal file
17
autoload/SpaceVim/api/data/quopri.vim
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
let s:self = {}
|
||||||
|
|
||||||
|
|
||||||
|
function! s:self.decode(str) abort
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:self.encode(str) abort
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
function! SpaceVim#api#data#quopri#get() abort
|
||||||
|
|
||||||
|
return deepcopy(s:self)
|
||||||
|
|
||||||
|
endfunction
|
@ -48,7 +48,7 @@ endfunction
|
|||||||
|
|
||||||
function! SpaceVim#layers#mail#config() abort
|
function! SpaceVim#layers#mail#config() abort
|
||||||
call SpaceVim#mapping#space#def('nnoremap', ['a', 'm'], 'call mail#client#open()', 'Start mail client', 1)
|
call SpaceVim#mapping#space#def('nnoremap', ['a', 'm'], 'call mail#client#open()', 'Start mail client', 1)
|
||||||
let g:mail_imap_host = s:imap_port
|
let g:mail_imap_host = s:imap_host
|
||||||
let g:mail_imap_port = s:imap_port
|
let g:mail_imap_port = s:imap_port
|
||||||
let g:mail_imap_login = s:imap_login
|
let g:mail_imap_login = s:imap_login
|
||||||
let g:mail_imap_password = s:imap_password
|
let g:mail_imap_password = s:imap_password
|
||||||
|
@ -4,15 +4,21 @@ let s:job_noop_timer = ''
|
|||||||
let s:JOB = SpaceVim#api#import('job')
|
let s:JOB = SpaceVim#api#import('job')
|
||||||
|
|
||||||
function! mail#client#connect(ip, port)
|
function! mail#client#connect(ip, port)
|
||||||
let argv = ['telnet', a:ip, a:port]
|
if has('nvim')
|
||||||
let s:job_id = s:JOB.start(argv,
|
let s:job_id = sockconnect('tcp', a:ip . ':' . a:port,
|
||||||
\ {
|
\ {
|
||||||
\ 'on_stdout' : function('s:on_stdout'),
|
\ 'on_data' : function('s:on_stdout'),
|
||||||
\ 'on_stderr' : function('s:on_stderr'),
|
\ }
|
||||||
\ 'on_exit' : function('s:on_exit'),
|
\ )
|
||||||
\ }
|
call mail#logger#info('mail client job id:' . s:job_id)
|
||||||
\ )
|
else
|
||||||
call mail#client#logger#info('mail client job id:' . s:job_id)
|
let s:job_channel = ch_open(a:ip . ':' . a:port,
|
||||||
|
\ {
|
||||||
|
\ 'callback' : function('s:data_handle'),
|
||||||
|
\ }
|
||||||
|
\ )
|
||||||
|
call mail#logger#info('mail client job channel:' . s:job_channel)
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Wed, 06 Sep 2017 02:55:41 +0000 ===> 2017-09-06
|
" Wed, 06 Sep 2017 02:55:41 +0000 ===> 2017-09-06
|
||||||
@ -37,44 +43,44 @@ let s:_mail_from = ''
|
|||||||
let s:_mail_subject = ''
|
let s:_mail_subject = ''
|
||||||
let s:mail_unseen = 0
|
let s:mail_unseen = 0
|
||||||
|
|
||||||
function! s:parser(data) abort
|
function! s:data_handle(...) abort
|
||||||
if type(a:data) == 3
|
call s:on_stdout(1,1, [a:1])
|
||||||
for data in a:data
|
|
||||||
call mail#client#logger#info('STDOUT: ' . data)
|
|
||||||
if data =~ '^\* \d\+ FETCH '
|
|
||||||
let s:_mail_id = matchstr(data, '\d\+')
|
|
||||||
elseif data =~ '^From: '
|
|
||||||
let s:_mail_from = substitute(data, '^From: ', '', 'g')
|
|
||||||
let s:_mail_from .= repeat(' ', 50 - len(s:_mail_from))
|
|
||||||
elseif data =~ '^Date: '
|
|
||||||
let s:_mail_date = s:convert(substitute(data, '^Date: ', '', 'g'))
|
|
||||||
elseif data =~ '^Subject: '
|
|
||||||
let s:_mail_subject = substitute(data, '^Subject: ', '', 'g')
|
|
||||||
call mail#client#mailbox#updatedir(s:_mail_id, s:_mail_from, s:_mail_date, s:_mail_subject, mail#client#win#currentDir())
|
|
||||||
elseif data =~ '* STATUS INBOX'
|
|
||||||
let s:mail_unseen = matchstr(data, '\d\+')
|
|
||||||
endif
|
|
||||||
endfor
|
|
||||||
else
|
|
||||||
echom a:data
|
|
||||||
endif
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:on_stdout(id, data, event) abort
|
function! s:on_stdout(id, data, event) abort
|
||||||
call mail#client#logger#info('STDOUT: ' . string(a:data))
|
for data in a:data
|
||||||
call s:parser(a:data)
|
call mail#logger#info('STDOUT: ' . data)
|
||||||
|
if data =~ '^\* \d\+ FETCH '
|
||||||
|
let s:_mail_id = matchstr(data, '\d\+')
|
||||||
|
elseif data =~ '^From: '
|
||||||
|
let s:_mail_from = substitute(data, '^From: ', '', 'g')
|
||||||
|
let s:_mail_from .= repeat(' ', 50 - len(s:_mail_from))
|
||||||
|
elseif data =~ '^Date: '
|
||||||
|
let s:_mail_date = s:convert(substitute(data, '^Date: ', '', 'g'))
|
||||||
|
elseif data =~ '^Subject: '
|
||||||
|
let s:_mail_subject = substitute(data, '^Subject: ', '', 'g')
|
||||||
|
call mail#client#mailbox#updatedir(s:_mail_id, s:_mail_from, s:_mail_date, s:_mail_subject, mail#client#win#currentDir())
|
||||||
|
elseif data =~ '* STATUS INBOX'
|
||||||
|
let s:mail_unseen = matchstr(data, '\d\+')
|
||||||
|
elseif data =~# '* OK Coremail System IMap Server Ready'
|
||||||
|
call mail#client#send(mail#command#login(g:mail_imap_login, g:mail_imap_password))
|
||||||
|
call mail#client#send(mail#command#select(mail#client#win#currentDir()))
|
||||||
|
call mail#client#send(mail#command#fetch('1:15', 'BODY[HEADER.FIELDS ("DATE" "FROM" "SUBJECT")]'))
|
||||||
|
call mail#client#send(mail#command#status('INBOX', '["RECENT"]'))
|
||||||
|
let s:job_noop_timer = timer_start(20000, function('s:noop'), {'repeat' : -1})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function! s:on_stderr(id, data, event) abort
|
function! s:on_stderr(id, data, event) abort
|
||||||
for data in a:data
|
for data in a:data
|
||||||
call mail#client#logger#error('STDERR: ' . data)
|
call mail#logger#error('STDERR: ' . data)
|
||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:on_exit(id, data, event) abort
|
function! s:on_exit(id, data, event) abort
|
||||||
call s:parser(a:data)
|
|
||||||
let s:job_id = 0
|
let s:job_id = 0
|
||||||
if !empty(s:job_noop_timer)
|
if !empty(s:job_noop_timer)
|
||||||
call timer_stop(s:job_noop_timer)
|
call timer_stop(s:job_noop_timer)
|
||||||
@ -84,11 +90,15 @@ endfunction
|
|||||||
|
|
||||||
|
|
||||||
function! mail#client#send(command)
|
function! mail#client#send(command)
|
||||||
call mail#client#logger#info('Send command: ' . a:command)
|
call mail#logger#info('Send command: ' . a:command)
|
||||||
if s:job_id >= 0
|
if has('nvim')
|
||||||
call s:JOB.send(s:job_id, a:command)
|
if s:job_id >= 0
|
||||||
|
call chansend(s:job_id, [a:command, ''])
|
||||||
|
else
|
||||||
|
call mail#logger#info('skipped!, job id is:' . s:job_id)
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
call mail#client#logger#info('skipped!, job id is:' . s:job_id)
|
call ch_sendraw(s:job_channel, a:command . "\n")
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -96,11 +106,6 @@ function! mail#client#open()
|
|||||||
if s:job_id == 0
|
if s:job_id == 0
|
||||||
if !empty(g:mail_imap_login) && !empty(g:mail_imap_password)
|
if !empty(g:mail_imap_login) && !empty(g:mail_imap_password)
|
||||||
call mail#client#connect(g:mail_imap_host, g:mail_imap_port)
|
call mail#client#connect(g:mail_imap_host, g:mail_imap_port)
|
||||||
call mail#client#send(mail#command#login(g:mail_imap_login, g:mail_imap_password))
|
|
||||||
call mail#client#send(mail#command#select(mail#client#win#currentDir()))
|
|
||||||
call mail#client#send(mail#command#fetch('1:15', 'BODY[HEADER.FIELDS ("DATE" "FROM" "SUBJECT")]'))
|
|
||||||
call mail#client#send(mail#command#status('INBOX', '["RECENT"]'))
|
|
||||||
let s:job_noop_timer = timer_start(20000, function('s:noop'), {'repeat' : -1})
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
call mail#client#win#open()
|
call mail#client#win#open()
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
let s:LOGGER =SpaceVim#logger#derive('mail')
|
|
||||||
|
|
||||||
function! mail#client#logger#info(msg)
|
|
||||||
call s:LOGGER.info(a:msg)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! mail#client#logger#error(msg)
|
|
||||||
call s:LOGGER.error(a:msg)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! mail#client#logger#warn(msg)
|
|
||||||
|
|
||||||
call s:LOGGER.warn(a:msg)
|
|
||||||
|
|
||||||
endfunction
|
|
@ -2,6 +2,9 @@
|
|||||||
"
|
"
|
||||||
|
|
||||||
let s:BUFFER = SpaceVim#api#import('vim#buffer')
|
let s:BUFFER = SpaceVim#api#import('vim#buffer')
|
||||||
|
let s:BASE64 = SpaceVim#api#import('data#base64')
|
||||||
|
let s:QUOPRI = SpaceVim#api#import('data#quopri')
|
||||||
|
let s:ICONV = SpaceVim#api#import('iconv')
|
||||||
|
|
||||||
|
|
||||||
let s:bufnr = -1
|
let s:bufnr = -1
|
||||||
@ -10,40 +13,67 @@ let s:win_dir = 'INBOX'
|
|||||||
let s:win_unseen = {}
|
let s:win_unseen = {}
|
||||||
|
|
||||||
function! mail#client#win#open()
|
function! mail#client#win#open()
|
||||||
if s:bufnr ==# -1
|
if s:bufnr ==# -1
|
||||||
split __VIM_MAIL__
|
split __VIM_MAIL__
|
||||||
let s:bufnr = bufnr('%')
|
let s:bufnr = bufnr('%')
|
||||||
setlocal buftype=nofile nobuflisted nolist noswapfile nowrap cursorline nospell nomodifiable nowrap norelativenumber number
|
setlocal buftype=nofile nobuflisted nolist noswapfile nowrap cursorline nospell nomodifiable nowrap norelativenumber number
|
||||||
nnoremap <silent><buffer> <F5> :call <SID>refresh()<Cr>
|
nnoremap <silent><buffer> <F5> :call <SID>refresh()<Cr>
|
||||||
setfiletype VimMailClient
|
setfiletype VimMailClient
|
||||||
else
|
else
|
||||||
split
|
split
|
||||||
exe 'b' . s:bufnr
|
exe 'b' . s:bufnr
|
||||||
endif
|
endif
|
||||||
call s:refresh()
|
call s:refresh()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! mail#client#win#currentDir()
|
function! mail#client#win#currentDir()
|
||||||
return s:win_dir
|
return s:win_dir
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" =?<charset>?<encoding>?<encoded-text>?=
|
||||||
|
" '=?UTF-8?B?VGhpcyBpcyBhIGhvcnNleTog8J+Qjg==?='
|
||||||
|
function! s:encode(str) abort
|
||||||
|
" line endings (^M), strip these characters.
|
||||||
|
let origin_str = substitute(a:str, '\r', '', 'g')
|
||||||
|
let target_str = ''
|
||||||
|
let id = 0
|
||||||
|
while !empty(matchstr(origin_str, '^=?[^?]*?[^?]*?[^?]*?='))
|
||||||
|
let id += 1
|
||||||
|
let str = matchstr(origin_str, '^=?[^?]*?[^?]*?[^?]*?=')
|
||||||
|
let origin_str = substitute(origin_str, '^=?[^?]*?[^?]*?[^?]*?=', '', '')
|
||||||
|
let charset = matchstr(str, '^=?\zs[^?]*')
|
||||||
|
let encoding = matchstr(str, '^=?[^?]*?\zs[^?]*')
|
||||||
|
let text = matchstr(str, '^=?[^?]*?[^?]*?\zs[^?]*')
|
||||||
|
if encoding ==? 'b'
|
||||||
|
let text = s:BASE64.decode(text)
|
||||||
|
let target_str .= iconv(text, charset, 'utf-8')
|
||||||
|
elseif encoding ==? 'q' && 0
|
||||||
|
let text = s:QUOPRI.decode(text)
|
||||||
|
let target_str .= text
|
||||||
|
else
|
||||||
|
let target_str .= str
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
return target_str . origin_str
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
function! s:refresh() abort
|
function! s:refresh() abort
|
||||||
let mails = mail#client#mailbox#get(s:win_dir)
|
let mails = mail#client#mailbox#get(s:win_dir)
|
||||||
let lines = ['DATA FROM SUBJECT']
|
let lines = ['DATA FROM SUBJECT']
|
||||||
for id in keys(mails)
|
for id in keys(mails)
|
||||||
call add(lines, mails[id]['data'] . ' ' . mails[id]['from'] . ' ' . mails[id]['subject'])
|
call add(lines, mails[id]['data'] . ' ' . s:encode(mails[id]['from']) . ' ' . s:encode(mails[id]['subject']))
|
||||||
endfor
|
endfor
|
||||||
call setbufvar(s:bufnr, '&modifiable', 1)
|
call setbufvar(s:bufnr, '&modifiable', 1)
|
||||||
call s:BUFFER.buf_set_lines(s:bufnr, 0, len(lines), 0, lines)
|
call s:BUFFER.buf_set_lines(s:bufnr, 0, len(lines), 0, lines)
|
||||||
call setbufvar(s:bufnr, '&modifiable', 0)
|
call setbufvar(s:bufnr, '&modifiable', 0)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! mail#client#win#status() abort
|
function! mail#client#win#status() abort
|
||||||
return {
|
return {
|
||||||
\ 'dir' : s:win_dir,
|
\ 'dir' : s:win_dir,
|
||||||
\ 'unseen' : get(s:win_unseen, 's:win_dir', 0),
|
\ 'unseen' : get(s:win_unseen, 's:win_dir', 0),
|
||||||
\ }
|
\ }
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user