Browse files

Encode and decode Base64 on [Y and ]Y

It is proposed that in the future the encoding and decoding mappings are
changed to:

 * [\x and ]\x : xml entities
 * [\c and ]\c : C-style string literals
 * [\u and ]\u : URL-encoding
 * [\b and ]\b : Base64
  • Loading branch information...
1 parent 0af2721 commit e8013727a008a68664a789fe0d2b5c2ab2ecf657 @salsifis salsifis committed with Mar 7, 2012
Showing with 72 additions and 1 deletion.
  1. +1 −1 README.markdown
  2. +10 −0 doc/unimpaired.txt
  3. +61 −0 plugin/unimpaired.vim
View
2 README.markdown
@@ -16,7 +16,7 @@ line with the one above or below it.
There are mappings for encoding and decoding. `[x` and `]x` encode and
decode XML (and HTML). `[u` and `]u` encode and decode URLs. `[y` and
-`]y` do C String style escaping.
+`]y` do C String style escaping. `[Y` and `]Y` encode and decode Base64.
And in the miscellaneous category, there's `[o` and `]o` to go to the
next/previous file in the directory, and `[n` and `]n` to jump between
View
10 doc/unimpaired.txt
@@ -104,6 +104,16 @@ Mnenomic: encoding always comes before decoding; "[" always comes before "]".
]yy
{Visual}]y
+ *[Y* *[YY* *v_[Y*
+[Y{motion} Base64 encode.
+[YY foo bar => Zm9vIGJhcg==
+{Visual}[Y
+
+ *]Y* *]YY* *v_]Y*
+]Y{motion} Base64 decode
+]YY Input length must be a multiple of 4.
+{Visual}]Y
+
TODO *unimpaired-todo*
Avoid munging null characters when encoding and decoding.
View
61 plugin/unimpaired.vim
@@ -186,6 +186,65 @@ function! s:UrlDecode(str)
return substitute(str,'%\(\x\x\)','\=nr2char("0x".submatch(1))','g')
endfunction
+let g:unimpaired_base64_chars = map(range(char2nr('A'),char2nr('Z')),'nr2char(v:val)')
+ \ + map(range(char2nr('a'),char2nr('z')),'nr2char(v:val)')
+ \ + map(range(char2nr('0'),char2nr('9')),'nr2char(v:val)')
+ \ + ['+','/']
+
+let g:unimpaired_base64_filler = '='
+let g:unimpaired_base64_reverse_map = {}
+let s:pos = 0
+for s:char in g:unimpaired_base64_chars
+ let g:unimpaired_base64_reverse_map[s:char] = s:pos
+ let s:pos = s:pos + 1
+endfor
+unlet s:pos
+
+function! s:Base64Encode(str)
+ " Respect current file encoding
+ let to_be_encoded=a:str
+ let encoded = ''
+ while len(to_be_encoded) > 2
+ let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
+ \ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )+char2nr(to_be_encoded[1])/16]
+ \ . g:unimpaired_base64_chars[4 *(char2nr(to_be_encoded[1])%16)+char2nr(to_be_encoded[2])/64]
+ \ . g:unimpaired_base64_chars[char2nr(to_be_encoded[2])%64]
+ let to_be_encoded = to_be_encoded[3:]
+ endwhile
+ if len(to_be_encoded) == 2
+ let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
+ \ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )+char2nr(to_be_encoded[1])/16]
+ \ . g:unimpaired_base64_chars[4 *(char2nr(to_be_encoded[1])%16)]
+ \ . g:unimpaired_base64_filler
+ elseif len(to_be_encoded) == 1
+ let encoded .= g:unimpaired_base64_chars[char2nr(to_be_encoded[0])/4]
+ \ . g:unimpaired_base64_chars[16*(char2nr(to_be_encoded[0])%4 )]
+ \ . g:unimpaired_base64_filler
+ \ . g:unimpaired_base64_filler
+ endif
+ return encoded
+endfunction
+
+function! s:Base64Decode(str)
+ let to_be_decoded=a:str
+ let decoded=''
+ while len(to_be_decoded) % 4 == 0
+ let decoded .= nr2char( 4 * (g:unimpaired_base64_reverse_map[to_be_decoded[0]] )
+ \ + (g:unimpaired_base64_reverse_map[to_be_decoded[1]] / 16 )
+ \)
+ if to_be_decoded[2] !=# g:unimpaired_base64_filler
+ let decoded .= nr2char(16 * (g:unimpaired_base64_reverse_map[to_be_decoded[1]] % 16) + (g:unimpaired_base64_reverse_map[to_be_decoded[2]]/4))
+ if to_be_decoded[3] !=# g:unimpaired_base64_filler
+ let decoded .= nr2char(64 * (g:unimpaired_base64_reverse_map[to_be_decoded[2]] % 4) + g:unimpaired_base64_reverse_map[to_be_decoded[3]])
+ endif
+ endif
+ let to_be_decoded = to_be_decoded[4:]
+ if empty(to_be_decoded)
+ return decoded
+ endif
+ endwhile
+endfunction
+
" HTML entities {{{2
let g:unimpaired_html_entities = {
@@ -331,6 +390,8 @@ call s:MapTransform('UrlEncode','[u')
call s:MapTransform('UrlDecode',']u')
call s:MapTransform('XmlEncode','[x')
call s:MapTransform('XmlDecode',']x')
+call s:MapTransform('Base64Encode','[Y')
+call s:MapTransform('Base64Decode',']Y')
" }}}1

0 comments on commit e801372

Please sign in to comment.