" banana.vim - Convert Base Banana (https://git.lattuga.net/itec/banana) and back " T4 - totem4@tropici.net " Version: 0.1 if exists("g:autoloaded_Banana") || &cp finish endif let g:autoloaded_Banana= 1 fun! banana#Enc() range call s:ReplSel(s:Dec2Ban(s:GetSel())) endfun! fun! banana#EncLine() call setline('.', substitute(getline('.'), '\d\d*', '\=toupper(s:Doban(submatch(0)))','g')) endfun! fun! banana#Dec() range call s:ReplSel(s:Ban2Dec(s:GetSel())) endfun! fun! banana#DecLine() call setline('.', substitute(getline('.'), '\C\u\u*', '\=s:Unban(tolower(submatch(0)))','g')) endfun! let s:dictionary = [['b', 'c', 'd', 'f', 'g', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'z'], ['a', 'e', 'i', 'o', 'u']] let s:numdict = len(s:dictionary) fun! s:Doban(num) let l:v = a:num let l:st = '' let l:l = 0 let l:i = (s:numdict - 1) % s:numdict while ! (l:v == 0 && l:i == (s:numdict -1) % s:numdict && l:l >= 0) let l:r = l:v % len(s:dictionary[l:i]) let l:v = l:v / len(s:dictionary[l:i]) let l:st = s:dictionary[l:i][l:r] . l:st let l:i = abs((l:i - 1) % s:numdict) let l:l = l:l + 1 endwhile return l:st endfun! fun! s:Unban(ban) if ! s:IsBanana(a:ban) return toupper(a:ban) endif let l:v = 0 for l:i in range(len(a:ban)) let l:r = (s:numdict + l:i) % s:numdict let l:p = index(s:dictionary[l:r],a:ban[l:i]) let l:v = l:v * len(s:dictionary[l:r]) + l:p endfor return l:v endfun! fun! s:IsBanana(ban) if (len(a:ban) % s:numdict) != 0 return 0 endif for l:i in range(len(a:ban)) let l:r = (s:numdict + l:i) % s:numdict if index(s:dictionary[l:r],a:ban[l:i]) == -1 return 0 endif endfor return 1 endfun! fun! s:GetSel() let [l:lstart, l:cstart] = getcharpos("'<")[1:2] let [l:lend, l:cend] = getcharpos("'>")[1:2] let l:lines = getline(l:lstart, l:lend) if len(l:lines) == 0 return '' endif let l:lines[-1] = l:lines[-1][: l:cend - (&selection == 'inclusive' ? 1 : 2)] let l:lines[0] = l:lines[0][l:cstart - 1:] return join(l:lines, "\n") endfun! fun! s:ReplSel(str) let [l:lstart, l:cstart] = getcharpos("'<")[1:2] let [l:lend, l:cend] = getcharpos("'>")[1:2] let l:lines = getline(l:lstart, l:lend) let l:new_str = slice(l:lines[0],0,l:cstart - 1) . a:str . l:lines[-1][l:cend:] let l:new_str_lst = split(l:new_str,'\n') call setline(l:lstart ,l:new_str_lst) call setcursorcharpos(lstart, cstart) endfun! fun! s:Dec2Ban(text) return substitute(a:text, '\d\d*', '\=toupper(s:Doban(submatch(0)))', 'g') endfun! fun! s:Ban2Dec(text) return substitute(a:text, '\C\u\u*', '\=s:Unban(tolower(submatch(0)))', 'g') endfun!