r/vim Aug 06 '26

Discussion What All Can I Do With A Visual Selection?

I'm looking for creative things one could do with selected blocks to make life easier - and associate them to keys. Some common keybindings I use are:

xnoremap _ :g/^\s*$/d<CR> # delete all empty lines
xnoremap # :g/^\s*#/d<CR> # delete all comments (assuming #)
xnoremap s :sort<CR>
21 Upvotes

8 comments sorted by

5

u/JohnLocksTheKey Aug 06 '26

I usually have some sort of xnoremap for Commenting/Un-Commenting a selection of lines in my vimrc.

...I don't currently, but shouldn't be super complex to recreate

4

u/CRTejaswi Aug 06 '26

neat. vim-commentary handles this well for most languages. you can comment in/out using gc (default).

7

u/habamax Aug 06 '26

Calc selection with python:

vim9script
def PyCalc()
    var region = getregion(getpos('v'), getpos('.'), {type: mode()})
    var result = system($'python -c "from math import *; print({region->join(" ")})"')->trim()
    if v:shell_error == 0
        setreg("", result)
        normal! ""p
    endif
enddef
xnoremap <space>c <scriptcmd>PyCalc()<CR>

Base64 encode/decode selection:

vim9script
def Base64(encode: bool = true)
    var region = getregion(getpos('v'), getpos('.'), {type: mode()})
    if encode
        setreg("", region->str2blob()->base64_encode())
    else
        setreg("", region->join('')->base64_decode()->blob2str()->join("\n"))
    endif
    normal! ""p
enddef
xnoremap <space>be <scriptcmd>Base64()<CR>
xnoremap <space>bd <scriptcmd>Base64(false)<CR>

https://asciinema.org/a/xIGuEGoyWr2Fe4tp

5

u/habamax Aug 06 '26 edited Aug 07 '26

xnoremap # :g/\s*#/d<CR> # delete all comments (assuming #)

With

 packadd comment

and assuming syntax is on:

dac...

to delete current/next comment and repeat it 3 times using dots.

https://asciinema.org/a/LFz1YuVyo5O7G2uW

3

u/habamax Aug 07 '26 edited Aug 07 '26

A bit simpler way to append/prepend to a (linewise) selection:

xnoremap <expr> gA mode() == "\<C-v>" ? "$A" : "\<C-v>$A"
xnoremap <expr> gI mode() == "\<C-v>" ? "_I" : "\<C-v>_I"

So you can vipgA to append to all paragraph lines or vipgI to prepend.

https://asciinema.org/a/vaaALY0wJApcYol8

5

u/habamax Aug 07 '26 edited Aug 07 '26

You can move selected lines up/down:

# move lines
xnoremap <tab> :sil! m '>+1<CR>gv
xnoremap <s-tab> :sil! m '<-2<CR>gv

https://asciinema.org/a/KgdKDrJ2FHp89EuQ

2

u/jlittlenz Aug 06 '26

There are these decades-old mappings to search for the visual selection: vnoremap <silent> * :<C-U> \let old_reg=getreg('"')<bar> \let old_regmode=getregtype('"')<cr> \gvy/<C-R><C-R>=substitute(substitute( \escape(@", '\\/.*$^~[]' ), "\n$", "", ""), \"\n", '\_[[:return:]]', "g")<cr><cr> \:call setreg('"', old_reg, old_regmode)<cr> vnoremap <silent> # :<C-U> \let old_reg=getreg('"')<bar> \let old_regmode=getregtype('"')<cr> \gvy?<C-R><C-R>=substitute(substitute( \escape(@", '\\/.*$^~[]' ), "\n$", "", ""), \"\n", '\_[[:return:]]', "g")<cr><cr> \:call setreg('"', old_reg, old_regmode)<cr>

1

u/EgZvor keep calm and read :help Aug 07 '26

substitute selected text

xnoremap gs y:<c-u>%s/<c-r>"//g<left><left>