5

Other editors I have used are able to decode URLs. For example these can take a string like this:

https://nim-lang.github.io/Nim/osproc#waitForExit%2CProcess%2Cint

and produce this:

https://nim-lang.github.io/Nim/osproc#waitForExit,Process,int

I thought about using this:

%s/%2C/,/g

but then it fails with other strings:

https://nim-lang.github.io/Nim/osproc#startProcess%2Cstring%2Cstring%2C
openArray%5Bstring%5D%2CStringTableRef%2Cset%5BProcessOption%5D

Is a better option available?

4 Answers 4

5

tpope's unimpaired plugin defines some (I think experimental) mappings for this:

ENCODING AND DECODING                           *unimpaired-encoding*

Each of these operations has a map that takes a motion, a map that
targets [count] lines, and a visual mode map.  The linewise variant integrates
with repeat.vim.

Mnemonic: encoding always comes before decoding; "[" always comes before "]".

                                                *[x* *[xx* *v_[x*
[x{motion}              XML encode.
[xx                     <foo bar="baz"> => &lt;foo bar=&quot;baz&quot;&gt;
{Visual}[x

                                                *]x* *]xx* *v_]x*
]x{motion}              XML decode.  HTML entities are handled as well.
]xx
{Visual}]x

                                                *[u* *[uu* *v_[u*
[u{motion}              URL encode.
[uu                     foo bar => foo%20bar
{Visual}[u

                                                *]u* *]uu* *v_]u*
]u{motion}              URL decode.
]uu
{Visual}]u

                                                *[y* *[yy* *v_[y*
[y{motion}              C String encode.  Backslash escape control
[yy                     characters, quotation marks, and backslashes.
{Visual}[y

                                                *]y* *]yy* *v_]y*
]y{motion}              C String decode.
]yy
{Visual}]y
2

The following finds % followed by two hexadecimal digits, and replaces them with the corresponding character:

:%s/%\(\x\x\)/\=nr2char('0x' .. submatch(1))/ge

This is not really fully correct, for example an url like /€ is encoded as /%E2%82%AC since the € character consists of three bytes; to fix this you can use iconv() to convert it to UTF-8 (or any other multibyte encoding you happen to be using):

:%s/%\(\x\x\)/\=iconv(nr2char('0x' .. submatch(1)), 'utf-8', 'latin1')/ge

Which is a bit more typing and a bit slower.

3
  • this failed for me with errors like E15: Invalid expression: . submatch(1)) E116: Invalid arguments for function nr2char('0x' .. submatch(1)) E15: Invalid expression: nr2char('0x' .. submatch(1)) Mar 27, 2023 at 14:53
  • Both patterns work for me with vim --clean @törzsmókus; I guess there's something in your vimrc? Or maybe you're using a (very) old version of Vim? Mar 28, 2023 at 12:48
  • is 8.0 considered very old? Apr 1, 2023 at 5:39
2

If you have nodejs installed, you can shell out and use the js global decodeURIComponent:

:'<,'>!node -e 'console.log(decodeURIComponent(process.argv[1])))' -- `cat`
1
  • this has a syntax error (too many closing round brackets) and also some more serious bug because after removing that bracket it clears anything Mar 27, 2023 at 14:58
1

This is a naive solution, but in general I prefer limited simple solutions to robust complicated solutions. So maybe this will be helpful to someone:

func URL_Decode()
   sub/%2C/,/ge
   sub/%3A/:/ge
   sub/%5B/[/ge
   sub/%5D/]/ge
endfunc

nmap c :call URL_Decode()<CR>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.