I’m trying to execute base64 --decode
on a piece of text selected in Visual mode, but it is the entire line that seems to be passed to the base64
comma
Here’s a script that uses Python and the base64
module to provide base64 decode and encode commands. It’d be pretty simple to support any other base64 program as well, as long as it reads from stdin — just replace python -m base64 -e
with the encoding command and python -m base64 -d
with the decoding command.
function! Base64Encode() range
" go to first line, last line, delete into @b, insert text
" note the substitute() call to join the b64 into one line
" this lets `:Base64Encode | Base64Decode` work without modifying the text
" at all, regardless of line length -- although that particular command is
" useless, lossless editing is a plus
exe "normal! " . a:firstline . "GV" . a:lastline . "G"
\ . "\"bdO0\\\"
\ . "=substitute(system('python -m base64 -e', @b), "
\ . "'\\n', '', 'g')\\"
endfunction
function! Base64Decode() range
let l:join = "\"bc"
if a:firstline != a:lastline
" gJ exits vis mode so we need a cc to change two lines
let l:join = "gJ" . l:join . "c"
endif
exe "normal! " . a:firstline . "GV" . a:lastline . "G" . l:join
\ . "0\\\"
\ . "=system('python -m base64 -d', @b)\\\"
endfunction
command! -nargs=0 -range -bar Base64Encode ,call Base64Encode()
command! -nargs=0 -range -bar Base64Decode ,call Base64Decode()
Some features this provides:
Supports ranges, converts only the current line by default (use :%Base64Encode
to encode the whole file, for example, and it’ll work as expected from within visual mode, although it only converts whole lines)
Doesn’t leave output indented — all indents (tabs/spaces) is encoded into base64, and then preserved when decoding.
Supports being combined with other commands with |
Relevant :help
tags: user-functions
, func-range
, i_0_CTRL-D
, i_CTRL-R_CTRL-O
, expr-register
, system()
, user-commands
, command-nargs
, command-range
, :normal