" =============================================================== " TareRSS Main " Kyosuke Takayama (http://espion.just-size.jp/) " " $Id: tarerss.vim 12 2005-02-25 02:48:03Z takayama $ " =============================================================== scriptencoding euc-jp if exists('g:tarerss_disable') finish endif let s:tarerss_version = '1.10rc' let s:tarerss_agent = 'TareRSS/'.s:tarerss_version.' for VIM/'.v:version "" Main -------------------------------------------------------------- function! s:TareRss() if !has('iconv') echohl ErrorMsg echo "TareRSS requires Vim to have +iconv support." echohl None return endif let s:tarerss_looping = 1 let s:org_statusline = &statusline let s:org_equalalways = &equalalways let s:org_splitbelow = &splitbelow set statusline=%{TareRssSetStatusLine()} set noequalalways set splitbelow call s:TareRssOpenList() wincmd w let b:tarerss_ident = '' call s:TareRssSelectList() augroup tarerss autocmd! CursorHold *.tarerss call s:TareRssCursorHold() augroup END let s:tarerss_loop = 1 call s:TareRssLoop() endfun "" Open List File ---------------------------------------------------- function! s:TareRssOpenList() silent! 24vsp silent! exe 'edit ++enc='.&enc.' ++ff='.&ff.' '.g:tarerss_file silent! setlocal bufhidden=delete nobackup noswf nobuflisted nowrap nonumber let b:tarerss_ident = '' let b:tarerss_title = '- TareRSS -' call s:TareRssReadConf(0) nnoremap :call TareRssLoop() nnoremap :call TareRssSelectRss(0) nnoremap p :call TareRssSelectRss(1) nnoremap S :call TareRssSetConf() nnoremap U :call TareRssReadConf(0) nnoremap :call TareRssReadConf(1) nnoremap R :call TareRssUpdateLine() nnoremap = :call TareRssToggleZoom() nnoremap J :call TareRssScrollArticle(0) nnoremap K :call TareRssScrollArticle(1) nnoremap q :call TareRssQuit(1) if has('syntax') && exists("g:syntax_on") syntax match Special /^.*R$/ syntax match Statement /^.*B$/ endif endfun "" Open RSS File ----------------------------------------------------- function! s:TareRssOpenRss(ident) let file = g:tarerss_comp_orememo == 1 ? g:tarerss_cachedir.'taredir.'.a:ident.'.orememo/' : g:tarerss_cachedir.'taredir'.a:ident.'/' if !isdirectory(file) let file = escape(file, '"') let res = system('mkdir "'.file.'"') endif let file = file.'rss.tarerss' silent! exe 'edit ++enc='.&enc.' ++ff='.&ff.' '.file silent! setlocal bufhidden=delete nobackup noswf nobuflisted nowrap let b:tarerss_ident = a:ident let b:tarerss_title = '- TareRSS - ['.s:tarelist_{a:ident}_title.'] '.s:tarelist_{a:ident}_url let s:tarerss_loop = 2 nnoremap :call TareRssLoop() nnoremap :call TareRssReadArticle(0) nnoremap W :call TareRssReadArticle(1) nnoremap J :call TareRssScrollArticle(0) nnoremap K :call TareRssScrollArticle(1) nnoremap q :call TareRssSelectBeforeList(0) if has('syntax') && exists("g:syntax_on") syntax match Comment display '^\* ' endif endfun function! s:TareRssCursorHold() echo "Hit to get online" endfun function! s:TareRssLineCursor() if has('syntax') && g:tarerss_linecursor == 1 match DiffText /^.*\%#.*$/ endif redraw endfun "" Start Loop -------------------------------------------------------- function! s:TareRssLoop() let s:tarerss_looping = 1 let s:tarerss_loop_i = 0 redraw! try while 1 try call s:TareRssKeyPress(getchar(0)) if s:tarerss_loop_i > 500 let s:tarerss_loop_i = 300 call s:TareRssUpdateAll() sleep 250 m endif catch /^TareQUIT$/ break catch /^Vim:Interrupt$/ break endtry let s:tarerss_loop_i = s:tarerss_loop_i + 1 sleep 1 m endwhile finally if has('syntax') && g:tarerss_linecursor == 1 match None /^.*\%#.*$/ endif let s:tarerss_looping = 0 redraw! endtry endfun "" Event key press --------------------------------------------------- function! s:TareRssKeyPress(key) let key = (a:key == 10) ? 13 : a:key if key == '' return endif let char = nr2char(key) let s:tarerss_loop_i = 0 if char =~# '[hjkl]' exe 'normal' char " 1 and 2 elseif char ==# "\" exe 'normal' char elseif char ==# '\' call s:TareRssReadConf(1) elseif char =~# '[JK]' exe 'normal' char elseif char ==# 'q' call s:TareRss{s:tarerss_loop == 1 ? 'Quit' : 'SelectBeforeList' }(0) " only 1 elseif char =~# '[=pSUR]' && s:tarerss_loop == 1 exe 'normal' char " only 2 elseif char ==# 'W' && s:tarerss_loop == 2 exe 'normal' char " all elseif char =~? '[/?]' let word = has('migemo') ? migemo(input(char)) : input(char) if strlen(word) let @/ = word endif exe 'normal!' (char == '/' ? 'n' : 'N') elseif char =~# '[`FTfgmtzd]' exe 'normal ' char.nr2char(getchar()) elseif char == "\" || char == "\" || char == "\" \ || char == "\" || char == "\" \ || char == "\" || char == "\" \ || char == "\" || char == "\" \ || char =~# '[-#$*+0;BEGHLMN^benwu]' exe 'normal' char elseif char =~ '[0-9]' let comd = char while 1 let key2 = getchar() let comd = comd.nr2char(key2) if !(key2 >= 48 && key2 <= 57) break endif endwhile silent! exe 'normal!' comd endif call s:TareRssLineCursor() endfun "" Set configuration ------------------------------------------------- function! s:TareRssSetConf() let line = getline('.') let num = '0/0 ' let title = '' let url = '' let ident = 'www' let update = '' let descript = 0 if line =~ '\v^\d' let num = substitute(line, '\v^(\d+/\d+\s+).*', '\1', '') let lident = s:TareRssLineToIdent(line) let title = s:tarelist_{lident}_title let url = s:tarelist_{lident}_url let ident = s:tarelist_{lident}_ident let update = s:tarelist_{lident}_update let descript = s:tarelist_{lident}_descript elseif line != '' return endif let title = input('Title: ', title) let url = input('RSS url: ', url) let ident = input('Identity: ', ident) let update = input('Update cycle (sec): ', update) let descript = input('Show description? (0 or 1): ', descript) if title == '' || url == '' || ident == '' || update == '' || descript == '' echo 'It is necessary to input all data.' return 0 endif call setline('.', num.title.' '.ident.' '.update.' '.descript.' '.url.' 0 N') call s:TareRssReadConf(0) endfun "" Read configuration ------------------------------------------------ function! s:TareRssReadConf(mode) let i = 0 while i <= line('$') let line = getline(i) if line =~ '\v^\d' let ident = s:TareRssLineToIdent(line) let s:tarelist_{ident}_title = substitute(line, '\v^\d+/\d+\s+(.{-})\s+\S+\s+\d+\s+\d+\s+\S+\s+\S+\s+.$', '\1', '') let s:tarelist_{ident}_ident = substitute(line, '\v^\d+/\d+\s+.{-}\s+(\S+)\s+\d+\s+\d+\s+\S+\s+\S+\s+.$', '\1', '') let s:tarelist_{ident}_update = substitute(line, '\v^\d+/\d+\s+.{-}\s+\S+\s+(\d+)\s+\d+\s+\S+\s+\S+\s+.$', '\1', '') let s:tarelist_{ident}_descript = substitute(line, '\v^\d+/\d+\s+.{-}\s+\S+\s+\d+\s+(\d+)\s+\S+\s+\S+\s+.$', '\1', '') let s:tarelist_{ident}_url = substitute(line, '\v^\d+/\d+\s+.{-}\s+\S+\s+\d+\s+\d+\s+(\S+)\s+\S+\s+.$', '\1', '') let s:tarelist_{ident}_last = substitute(line, '\v^\d+/\d+\s+.{-}\s+\S+\s+\d+\s+\d+\s+\S+\s+(\S+)\s+.$', '\1', '') let s:tarelist_{ident}_modified = 0 if !exists('s:tarersschlasttime'.ident) || a:mode == 1 let s:tarersschlasttime{ident} = 0 endif endif let i = i + 1 endwhile echo "loading done..." endfun "" Auto Update ------------------------------------------------------- function! s:TareRssUpdateAll() let flag = b:tarerss_ident if flag == '' wincmd w endif let winident = b:tarerss_ident call s:TareRssSelectList() let winnum = line('.') let i = 0 let winflag = 0 let dnflag = 0 while i <= line('$') let line = getline(i) if line =~ '\v^\d' let ident = s:TareRssLineToIdent(line) let ltime = s:tarersschlasttime{ident} if ltime + s:tarelist_{ident}_update < localtime() if s:TareRssParseHeadline(ident, i) == 1 let winflag = 1 endif let dnflag = 1 endif endif let i = i + 1 endwhile if winflag == 1 call s:TareRssReWriteFlag() exe 'normal! '.winnum.'G' wincmd w if winident != '' call s:TareRssOpenRss(winident) endif endif call s:TareRssSelectList() if flag != '' wincmd w let s:tarerss_loop = 2 endif if dnflag == 1 redraw echohl WarningMsg echo 'Done...' echohl None call s:TareRssLineCursor() endif endfun "" Manual Update ----------------------------------------------------- function! s:TareRssUpdateLine() let ident = s:TareRssLineToIdent(getline('.')) if s:TareRssParseHeadline(ident, line('.')) == 1 call s:TareRssReWriteFlag() endif echohl WarningMsg echo 'Done...' echohl None sleep 1 silent! redraw endfun "" Parse Headline ---------------------------------------------------- function! s:TareRssParseHeadline(ident, num) let s:tarersschlasttime{a:ident} = localtime() echohl WarningMsg redraw echo 'DownloadHeadline... '.s:tarelist_{a:ident}_title if s:TareRssCheckHeader(a:ident) == 1 return 0 endif let result = system(g:tarerss_curlprg.' -A "'.s:tarerss_agent.'" -s "'.s:tarelist_{a:ident}_url.'"') . "\" redraw echo 'ParseHeadline... '.s:tarelist_{a:ident}_title sleep 1 let f = 0 let enc = 'UTF-8' let tmp_last = 0 if &ff == 'unix' && result =~ ' ' let result = substitute(result, ' ', '', 'g') endif echohl None while result != '' let idx = match(result, "\") let buf = strpart(result, 0, idx) let buf = substitute(buf, '\v^\s+', '', '') let result = strpart(result, idx+1) let result = substitute(result, '\v^\s+', '', '') if buf =~ 'xml.* encoding="' let enc = substitute(buf, '\v.* encoding\="(.{-})".*', '\1', '') endif if buf =~ '^' && result != '' let idx = match(result, "\") let buf = strpart(result, 0, idx) let buf = substitute(buf, '\v^\s+', '', '') let result = strpart(result, idx+1) let result = substitute(result, '\v^\s+', '', '') if buf =~ '^]*>\(.*\)$', '\1', '') let title = TareRssDecode(title) elseif buf =~ '^' && s:tarelist_{a:ident}_descript == 1 let buf = iconv(buf, enc, &enc) let description = substitute(buf, '^\(.*\)$', '\1', '') let description = TareRssDecode(description) elseif buf =~ '^' let link = substitute(buf, '^\(.*\)$', '\1', '') let link = s:TareRssParseCommand(1, a:ident, 'Link', link, '') elseif buf =~ '^' let date = substitute(buf, '^\(.*\)$', '\1', '') elseif buf =~ '^' let date = substitute(buf, '^.... \(.*\) .\{-\}$', '\1', '') let date = s:TareRssParsePubDate(date) endif endwhile if link == '' continue endif let last = s:TareRssParseCommand(1, a:ident, 'Date', date, link) if date == 0 let date = last endif if last > s:tarelist_{a:ident}_last let time = substitute(date, '\v(.*)\+.*', '\1', '') let time = substitute(time, 'T', '_', '') let time = substitute(time, '\v(\D)(\d)(\D)', '\1'.'0'.'\2\3', 'g') let space = 150 - (strlen(title) + strlen(time)) let i = 0 while i < space let title = title.' ' let i = i + 1 endwhile let f = f + 1 let append_list_{f} = '* '.time.' '.title .' '. link let append_des_{f} = description if last > tmp_last let tmp_last = last endif elseif s:TareRssParseCommand(0, a:ident, 'Mode', 0, '') == 1 break endif endif endwhile if f >= 1 " TODO let s:tarelist_{a:ident}_last = tmp_last call setline(a:num, '0/0 '.s:tarelist_{a:ident}_title.' '.s:tarelist_{a:ident}_ident.' '.s:tarelist_{a:ident}_update.' '.s:tarelist_{a:ident}_descript.' '.s:tarelist_{a:ident}_url.' '.s:tarelist_{a:ident}_last.' F') silent! update! exe 'normal! '.a:num.'G' wincmd w call s:TareRssOpenRss(a:ident) while f >= 1 if append_des_{f} != '' call append('1', '') call append('1', ' '.append_des_{f}) let z = 2 while strlen(append_des_{f}) > g:tarerss_textwidth call cursor(z, g:tarerss_textwidth) exe "normal! i\" let append_des_{f} = getline('.') let z = z + 1 endwhile endif call append('1', append_list_{f}) let f = f - 1 endwhile normal! gg silent! update! call s:TareRssSelectBeforeList(1) return 1 endif return 0 endfun "" Check Header ------------------------------------------------------ function! s:TareRssCheckHeader(ident) let result = system(g:tarerss_curlprg.' -A "'.s:tarerss_agent.'" -I -s "'.s:tarelist_{a:ident}_url.'"') . "\" while result != '' let idx = match(result, "\") let buf = strpart(result, 0, idx) let buf = substitute(buf, '\v^\s+', '', '') let result = strpart(result, idx+1) let type = substitute(buf, '\v^(\S+) .*', '\1', '') let data = substitute(buf, '\v^\S+ (.*)', '\1', '') if type == 'HTTP/1.1' && data =~ '404 Not Found' call confirm('"' . s:tarelist_{a:ident}_url . '" is not found') return 1 elseif type == 'Last-Modified:' let data = substitute(data, '^.... \(.*\) .\{-\}$', '\1', '') let data = s:TareRssParsePubDate(data) if s:tarelist_{a:ident}_modified < data let s:tarelist_{a:ident}_modified = data return 0 else return 1 endif endif endwhile return 0 endfun "" Read Article ------------------------------------------------------ function! s:TareRssReadArticle(mode) let ident = b:tarerss_ident let line = getline('.') if line !~ '^\v[*|\-]' return -1 endif let state = substitute(line, '\v^(.) \S+ .*', '\1', '') let time = substitute(line, '\v^. (\S+) .*', '\1', '') let title = substitute(line, '\v^. \S+ (.+)\s+http.*', '\1', '') let url = substitute(line, '\v^. \S+ .+\s+(http.*)', '\1', '') let time = substitute(time, ':', '-', 'g') let file = g:tarerss_comp_orememo == 1 ? g:tarerss_cachedir.'taredir.'.ident.'.orememo/' : g:tarerss_cachedir.'taredir'.ident.'/' let file = file.time let add = s:TareRssParseCommand(0, ident, 'File', url, '') if add != '' let file = file . '_' . add endif let flag = 0 let file = file.g:tarerss_ext if state == '*' call cursor(line('.'), 1) normal! r- silent! update! let flag = 1 endif if s:tarelist_{ident}_ident == 'www' || a:mode == 1 || add =~ '^http://' let cmd = substitute(g:tarerss_wwwprg, '%URL%', url, 'g') let cmd = escape(cmd, '%#') silent! exe '!'.cmd else let winno = winnr() call s:TareRssSelectArticle() echohl WarningMsg echo 'ReadArticle...'.title if (flag || getfsize(expand(file)) < 0) && g:tarerss_w3mprg != '' let tmp = file let file = tempname() endif silent! exe 'edit ++enc='.&enc.' ++ff='.&ff.' +1 '.file silent! setlocal bufhidden=delete nobackup noswf nobuflisted if flag || getfsize(expand(file)) < 0 if g:tarerss_w3mprg != '' call TareRssParseArticle_{s:tarelist_{ident}_ident}(url) silent! update! let result = system(g:tarerss_w3mprg.' -dump -T "text/html" -cols '.g:tarerss_textwidth.' "'.file.'"') silent! exe 'edit ++enc='.&enc.' ++ff='.&ff.' +1 '.tmp silent! setlocal bufhidden=delete nobackup noswf nobuflisted endif normal! dG call append('0', '= ['.s:tarelist_{ident}_title.'] '.title) call append('1', '') call append('2', 'Date: '.time) call append('3', 'URL : '.url) if g:tarerss_w3mprg != '' call TareRssParseArticle_BASE(result) else call TareRssParseArticle_{s:tarelist_{ident}_ident}(url) endif silent! %s/\s\+$// if &ff == 'unix' silent! %s/ //g endif silent! %s/\n\n\+/\r\r/ normal! gg silent! update! endif let b:tarerss_ident = '' let b:tarerss_title = '['. s:tarelist_{ident}_title . '] '.title silent! exe winno.'wincmd w' echo 'Done...' echohl None endif silent! redraw endfun "" Line to ident ----------------------------------------------------- function! s:TareRssLineToIdent(line) let url = substitute(a:line, '\v^\d+/\d+\s+.{-}\s+\S+\s+\d+\s+\d+\s+(\S+)\s+\S+\s+.$', '\1', '') let ident = substitute(url, '\v\W', '', 'g') return ident endfun "" Parse command execute --------------------------------------------- function! s:TareRssParseCommand(ret, ident, cate, val, add) let val = a:val if exists('*TareRssParse'.a:cate.'_'.s:tarelist_{a:ident}_ident) let val = TareRssParse{a:cate}_{s:tarelist_{a:ident}_ident}(val, a:add) return val endif if a:ret == 1 return val else return '' endif endfun "" puDate to dc:date ------------------------------------------------- function! s:TareRssParsePubDate(date) let date = a:date let month_Jan = '01' let month_Feb = '02' let month_Mar = '03' let month_Apr = '04' let month_May = '05' let month_Jun = '06' let month_Jul = '07' let month_Aug = '08' let month_Sep = '09' let month_Oct = '10' let month_Nov = '11' let month_Dec = '12' let day = substitute(date, '\(..\) .*', '\1', '') let mon = substitute(date, '.. \(...\) .... .*', '\1', '') let year = substitute(date, '.. ... \(....\) .*', '\1', '') let time = substitute(date, '.. ... .... \(.*\)', '\1', '') let date = year.'-'.month_{mon}.'-'.day.'T'.time return date endfun "" REWrite Read Flag ------------------------------------------------- function! s:TareRssReWriteFlag() silent! %s/R$/B/ silent! %s/F$/R/ silent! update! endfun "" Decode ------------------------------------------------------------ function! TareRssDecode(result) let result = a:result let result = substitute(result, ''', "'", 'g') let result = substitute(result, '>', '>', 'g') let result = substitute(result, '<', '<', 'g') let result = substitute(result, '"', '"', 'g') let result = substitute(result, ''', "'", 'g') let result = substitute(result, ' ', ' ', 'g') let result = substitute(result, '&', '\&', 'g') let result = substitute(result, '»', 'Άδ', 'g') let result = substitute(result, '«', 'Άγ', 'g') return result endfun "" Set StatusLine ---------------------------------------------------- function! TareRssSetStatusLine() let title = exists('b:tarerss_title') ? b:tarerss_title : bufname('%') let line = '' if exists('b:tarerss_title') && b:tarerss_title == '- TareRSS -' if s:tarerss_looping == 1 let line = 'ON' else let line = '--' endif else let line = line('$') endif return "[".line.'] '.title endfun "" Select List Window ------------------------------------------------ function! s:TareRssSelectList() let winno = bufwinnr('list.tarerss') let s:tarerss_loop = 1 if winno == -1 call s:TareRssOpenList() else exe winno.'wincmd w' endif endfun "" Count RSS File ---------------------------------------------------- function! s:TareRssSelectBeforeList(mode) if a:mode == 0 && has('syntax') && g:tarerss_linecursor == 1 match None /^.*\%#.*$/ endif silent! update! let lcm = 0 let lct = 0 let i = 0 while i <= line('$') let line = getline(i) if line =~ '^*' let lcm = lcm + 1 let lct = lct + 1 elseif line =~ '^\-' let lct = lct + 1 endif if lct == g:tarerss_maxcount break endif let i = i + 1 endwhile call s:TareRssSelectList() if a:mode == 0 silent! s/.$/N/ endif let i = 0 let space = strlen(g:tarerss_maxcount) * 2 + 1 - (strlen(lct) + strlen(lcm)) while i < space let lct = lct.' ' let i = i + 1 endwhile exe 'silent! s/\v^\d+\/\d+\s+/'.lcm.'\/'.lct.'/' silent! update! endfun "" Select RSS Window ------------------------------------------------- function! s:TareRssSelectRss(mode) if has('syntax') && g:tarerss_linecursor == 1 match Search /^.*\%#.*$/ endif let line = getline('.') if line !~ '^"' && line =~ '\v^\d' let ident = s:TareRssLineToIdent(getline('.')) silent! s/.$/N/ silent! update! wincmd w call s:TareRssOpenRss(ident) if a:mode == 1 call s:TareRssSelectList() else " keyword search system "let @/ = 'keyword' "silent! exe 'vert resize' endif endif endfun "" Select Article Window --------------------------------------------- function! s:TareRssSelectArticle() let winno = winnr() silent! exe 'wincmd w' if winnr() != 3 silent! exe winno.'wincmd w' new endif endfun "" Scroll Article ---------------------------------------------------- function! s:TareRssScrollArticle(mode) let winno = winnr() silent! exe 'wincmd w' if a:mode == 1 exe "normal! \" else exe "normal! \" endif silent! exe winno.'wincmd w' endfun "" ToggleZoom List Window -------------------------------------------- function! s:TareRssToggleZoom() if s:tlist_win_maximized vert resize 24 let s:tlist_win_maximized = 0 else vert resize let s:tlist_win_maximized = 1 endif endfun "" Quit TareRSS ------------------------------------------------------ function! s:TareRssQuit(mode) if confirm("Quit TareRss OK?", "&OK\n&NO") == 1 silent! only silent! bw let &statusline = s:org_statusline let &equalalways = s:org_equalalways let &splitbelow = s:org_splitbelow if a:mode == 0 throw 'TareQUIT' endif endif endfun "" Initialise -------------------------------------------------------- function! s:TareRssInit() if !exists('g:tarerss_comp_orememo') let g:tarerss_comp_orememo = 0 endif if !exists('g:tarerss_cachedir') let g:tarerss_cachedir = '~/.tarerss/' endif if !exists('g:tarerss_ext') let g:tarerss_ext = '.tarerss' endif if !exists('g:tarerss_textwidth') let g:tarerss_textwidth = 80 endif if !exists('g:tarerss_w3mprg') let g:tarerss_w3mprg = '' endif if !exists('g:tarerss_curlprg') let g:tarerss_curlprg = 'curl --connect-timeout 20 -m 20' endif if !exists('g:tarerss_wwwprg') let g:tarerss_wwwprg = g:tarerss_w3mprg.' %URL%' endif if !exists('g:tarerss_maxcount') let g:tarerss_maxcount = 499 endif if !exists('g:tarerss_linecursor') let g:tarerss_linecursor = 1 endif if g:tarerss_comp_orememo == 1 let g:tarerss_ext = '.orememo' endif let g:tarerss_cachedir = expand(g:tarerss_cachedir) let g:tarerss_file = g:tarerss_cachedir.'list.tarerss' let s:tlist_win_maximized = 0 command! TareRSS call s:TareRss() endfun call s:TareRssInit()