Vim Tips Wiki
Freakdom (talk | contribs)
No edit summary
Tag: Visual edit: Switched
 
(11 intermediate revisions by 10 users not shown)
Line 15: Line 15:
 
<pre>
 
<pre>
 
xp
 
xp
  +
</pre>
  +
  +
Swap the '''current character''' with the previous:
  +
<pre>
  +
Xp or hxp
 
</pre>
 
</pre>
   
Line 31: Line 36:
 
dawwP
 
dawwP
 
dawelp
 
dawelp
hdeep (works at start of first word)
+
hdeep (works at start of first word, useful if your separators aren't spaces)
 
"xdiwdwep"xp (works with most punctuations too)
 
"xdiwdwep"xp (works with most punctuations too)
 
</pre>
 
</pre>
Line 40: Line 45:
 
</pre>
 
</pre>
   
''Note:'' These swap-word techniques don't work with punctuation. Use the mappings below to more intelligently move words. However, for many more complex swaps, several [[#Related plugins|plugins]] are available with often do a better job.
+
''Note:'' These swap-word techniques don't work with punctuation. Use the mappings below to more intelligently move words. However, for many more complex swaps, several [[#Related plugins|plugins]] are available which often do a better job.
   
 
==Mappings==
 
==Mappings==
Line 52: Line 57:
 
To use <code>gw</code> to swap the '''current word''' with the next, without changing cursor position: (See note.)
 
To use <code>gw</code> to swap the '''current word''' with the next, without changing cursor position: (See note.)
 
<pre>
 
<pre>
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>
+
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
 
" This version will work across newlines:
 
" This version will work across newlines:
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>
+
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
 
</pre>
 
</pre>
   
 
To use <code>gl</code> to swap the '''current word''' with the previous, keeping cursor on current word: (This feels like "pushing" the word to the left.) (See note.)
 
To use <code>gl</code> to swap the '''current word''' with the previous, keeping cursor on current word: (This feels like "pushing" the word to the left.) (See note.)
 
<pre>
 
<pre>
:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>
+
:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
 
</pre>
 
</pre>
   
 
To use <code>gr</code> to swap the '''current word''' with the next, keeping cursor on current word: (This feels like "pushing" the word to the right.) (See note.)
 
To use <code>gr</code> to swap the '''current word''' with the next, keeping cursor on current word: (This feels like "pushing" the word to the right.) (See note.)
 
<pre>
 
<pre>
:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o>/\w\+\_W\+<CR><c-l>
+
:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o>/\w\+\_W\+<CR><c-l>:nohlsearch<CR>
 
</pre>
 
</pre>
   
Line 73: Line 78:
   
 
''Note:'' Mappings above which perform a search-and-replace (ones containing <code>:s//</code>) will operate incorrectly on words with accented characters. To adjust the mappings above to work with your locale, replace all <code>\w</code> with [''alphabet''] and <code>\W</code> with <code>[^''alphabet'']</code>, where ''alphabet'' is the set of characters in your alphabet. {{help|/\w}}
 
''Note:'' Mappings above which perform a search-and-replace (ones containing <code>:s//</code>) will operate incorrectly on words with accented characters. To adjust the mappings above to work with your locale, replace all <code>\w</code> with [''alphabet''] and <code>\W</code> with <code>[^''alphabet'']</code>, where ''alphabet'' is the set of characters in your alphabet. {{help|/\w}}
  +
  +
For ISO/IEC_8859-1 Latin-1 Supplement characters, substitute all <code>\w</code> instances with <code>[0-9A-Za-zÀ-ÖØ-öø-ÿ_]</code> and all <code>\_W</code> instances with <code>\_[^0-9A-Za-zÀ-ÖØ-öø-ÿ_]</code>.
   
 
==Visual-mode swapping==
 
==Visual-mode swapping==
Line 81: Line 88:
   
 
==Related plugins==
 
==Related plugins==
  +
*[https://github.com/tommcdo/vim-exchange vim-exchange] Easy text exchange/swap operator (+ [https://github.com/tommcdo/vim-exchange/issues/58 script using vim-exchange to swap two words])
 
*[http://www.drchip.org/astronaut/vim/index.html#VISSWAP Visual Mode Based Swapping] script by Chip Campbell to swap visually-selected text
 
*[http://www.drchip.org/astronaut/vim/index.html#VISSWAP Visual Mode Based Swapping] script by Chip Campbell to swap visually-selected text
 
*{{script|id=3250|text=Swap plugin}} provides mappings to swap adjacent words or selected text around a "pivot"
 
*{{script|id=3250|text=Swap plugin}} provides mappings to swap adjacent words or selected text around a "pivot"
Line 86: Line 94:
 
*{{script|id=3708|text=Swap two columns plugin}} swap two columns (words) in one line or multiple selected lines
 
*{{script|id=3708|text=Swap two columns plugin}} swap two columns (words) in one line or multiple selected lines
 
*{{script|id=4020|text=Flipwords plugin}} swap delimited words
 
*{{script|id=4020|text=Flipwords plugin}} swap delimited words
  +
*[https://github.com/LucHermitte/lh-misc/blob/master/plugin/vim-tip-swap-word.vim vim-tip-swap-word] variation on the topic that avoids side effects like polluting registers
   
 
==See also==
 
==See also==
Line 96: Line 105:
 
the opposite order. To easily change this I created this small function:
 
the opposite order. To easily change this I created this small function:
   
<code>
+
<pre>
 
function SwapAll() range
 
function SwapAll() range
if a:firstline != a:lastline
+
if a:firstline != a:lastline
if a:firstline < a:lastline
+
if a:firstline < a:lastline
let first=a:firstline
+
let first=a:firstline
let last=a:lastline
+
let last=a:lastline
else
+
else
let first=a:lastline
+
let first=a:lastline
let last=a:firstline
+
let last=a:firstline
endif
 
 
while first < last
 
exec first.'m'.last.'|'.(last-1).'m'.(first-1)
 
let first=first+1
 
let last=last-1
 
endwhile
 
 
endif
 
endif
 
while first < last
 
exec first.'m'.last.'|'.(last-1).'m'.(first-1)
 
let first=first+1
 
let last=last-1
 
endwhile
 
endif
 
endfunction
 
endfunction
   
 
vmap <silent> <C-s> :call SwapAll()<CR>
 
vmap <silent> <C-s> :call SwapAll()<CR>
 
vnoremap <silent> <C-x> :call SwapAll()<CR>
 
vnoremap <silent> <C-x> :call SwapAll()<CR>
</code>
+
</pre>
  +
--December 4, 2013

Latest revision as of 15:41, 20 October 2022

Tip 47 Printable Monobook Previous Next

created 2001 · complexity basic · version 6.0


Normal-mode commands[]

Swap the current character (the character under the cursor) with the next:

xp

Swap the current character with the previous:

Xp or hxp

Swap the current line with the next (but see below for a better method):

ddp

Swap the current line with the previous:

ddkP or ddkkp

Swap the current word with the next (see note):

dawwP
dawelp
hdeep                (works at start of first word, useful if your separators aren't spaces)
"xdiwdwep"xp         (works with most punctuations too)

Swap the current word with the previous (see note):

dawbP

Note: These swap-word techniques don't work with punctuation. Use the mappings below to more intelligently move words. However, for many more complex swaps, several plugins are available which often do a better job.

Mappings[]

See moving lines up or down for the best method to move lines.

To use gc to swap the current character with the next, without changing the cursor position:

:nnoremap <silent> gc xph

To use gw to swap the current word with the next, without changing cursor position: (See note.)

:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>
" This version will work across newlines:
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>

To use gl to swap the current word with the previous, keeping cursor on current word: (This feels like "pushing" the word to the left.) (See note.)

:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>:nohlsearch<CR>

To use gr to swap the current word with the next, keeping cursor on current word: (This feels like "pushing" the word to the right.) (See note.)

:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o>/\w\+\_W\+<CR><c-l>:nohlsearch<CR>

To use g{ to swap the current paragraph with the next:

:nnoremap g{ {dap}p{

Note: Mappings above which perform a search-and-replace (ones containing :s//) will operate incorrectly on words with accented characters. To adjust the mappings above to work with your locale, replace all \w with [alphabet] and \W with [^alphabet], where alphabet is the set of characters in your alphabet. :help /\w

For ISO/IEC_8859-1 Latin-1 Supplement characters, substitute all \w instances with [0-9A-Za-zÀ-ÖØ-öø-ÿ_] and all \_W instances with \_[^0-9A-Za-zÀ-ÖØ-öø-ÿ_].

Visual-mode swapping[]

To use this mapping: first, delete some text (using a command such as daw or dt in normal mode, or x in visual mode). Then, use visual mode to select some other text, and press Ctrl-X. The two pieces of text should then be swapped.

:vnoremap <C-X> <Esc>`.``gvP``P

Related plugins[]

See also[]

Comments[]

Swap all lines in a visual selected block[]

When working with arrays I sometimes realize that I have to do things in the opposite order. To easily change this I created this small function:

function SwapAll() range
  if a:firstline != a:lastline
    if a:firstline < a:lastline
      let first=a:firstline
      let last=a:lastline
    else
      let first=a:lastline
      let last=a:firstline
    endif
    while first < last
      exec first.'m'.last.'|'.(last-1).'m'.(first-1)
      let first=first+1
      let last=last-1
    endwhile
  endif
endfunction

vmap     <silent> <C-s>   :call SwapAll()<CR>
vnoremap <silent> <C-x>   :call SwapAll()<CR>

--December 4, 2013