Skip to content

Instantly share code, notes, and snippets.

@atripes
Created May 19, 2017 16:35
Show Gist options
  • Save atripes/15372281209daf5678cded1d410e6c16 to your computer and use it in GitHub Desktop.
Save atripes/15372281209daf5678cded1d410e6c16 to your computer and use it in GitHub Desktop.
URL encode/decode vim selection.
" URL encode/decode selection
vnoremap <leader>en :!python -c 'import sys,urllib;print urllib.quote(sys.stdin.read().strip())'<cr>
vnoremap <leader>de :!python -c 'import sys,urllib;print urllib.unquote(sys.stdin.read().strip())'<cr>
@bennypowers
Copy link

bennypowers commented Nov 13, 2022

if you have nodejs installed

:'<,'>!node -e 'console.log(decodeURIComponent(process.argv[1])))' -- `cat`

@Endermanbugzjfc
Copy link

Clever trick 👌 If someone ends up here looking for a native Vimscript solution

function! UrlEncode(mystring)
let urlsafe = ""
for char in split(join(lines, "\n"), '.\zs')
    if matchend(char, '[-_.~a-zA-Z0-9]') >= 0
        let urlsafe = urlsafe . char
    else
        let decimal = char2nr(char)
        let urlsafe = urlsafe . "%" . printf("%02x", decimal)
    endif
endfor
echo urlsafe
" return urlsafe
endfunction

You are GOAT. ❤️

@vimpostor
Copy link

vimpostor commented Aug 24, 2024

Here is a code-golfed version of the above algorithm:

func UrlEncode(s)
	return a:s->map({_, v -> match(v, '[-_.~a-zA-Z0-9]') ? printf("%%%02X", char2nr(v)) : v})
endfunc

It's pretty neat that you can map() characters within strings to strings of different size in Vimscript.

@unphased
Copy link

unphased commented Oct 2, 2024

@Bhupesh-V @vimpostor could you help a brother out with an example vnoremap definition to show how to actually use those functions? I asked o1-mini for this but it seems like your vim-fu outclasses it as it tried to rewrite the function (which set my alarm bells ringing) and also added the nutty looking intermediate vimscript:

" Function to URL encode and replace the visually selected text
function! UrlEncodeAndReplace()
    " Yank the visually selected text into the default register
    " The 'silent!' prevents any messages from being shown
    silent! execute "normal! gv\"zy"

    " Get the yanked text from register 'z'
    let l:original = getreg('z')

    " Apply the UrlEncode function
    let l:encoded = UrlEncode(l:original)

    " Replace the selected text with the encoded string
    " `gv` reselects the last visual selection
    execute "normal! gv\"zc" . l:encoded . "\<Esc>"
endfunction
vnoremap <leader>u :<C-U>call UrlEncodeAndReplace()<CR>

It feels like this is overengineered.

@Bhupesh-V
Copy link

Oi vim friends!

I have stopped using vim for some time now. Having said that @unphased here's a sample xnoremap usage for a function that uses UrlEncode: https://github.com/Bhupesh-V/.Varshney/blob/master/init.vim#L148

@unphased
Copy link

unphased commented Oct 2, 2024

Thanks! What do you use instead now?

The solution I use now is:

function! EncodeURIComponent() range
  let saved_reg = @"
  normal! gvy
  let selected_text = @"
  let encoded = system('node -e "process.stdout.write(encodeURIComponent(process.argv[1]))" -- ' . shellescape(selected_text))
  let @" = encoded
  normal! gv"_d"0P
  let @" = saved_reg
endfunction
vnoremap <leader>ue :call EncodeURIComponent()<CR>

Interesting use case you got there of internet searching something from a buffer. That is pretty neat.

I just wanted to be able to write text fragment links which need to be url-encoded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment