Vim Tips Wiki
(Major review and cleanup, merged-in tips VimTip329, VimTip470)
m (Reverted edits by 194.14.32.4 (talk | block) to last version by 46.5.18.121)
(37 intermediate revisions by 18 users not shown)
Line 1: Line 1:
  +
{{TipImported
== Normal-Mode Commands ==
 
  +
|id=47
  +
|previous=45
  +
|next=48
  +
|created=2001
  +
|complexity=basic
  +
|author=
  +
|version=6.0
  +
|rating=15/14
  +
|category1=Usage
  +
|category2=
  +
}}
  +
==Normal-mode commands==
 
Swap the '''current character''' (the character under the cursor) with the next:
 
Swap the '''current character''' (the character under the cursor) with the next:
  +
<pre>
xp
 
  +
xp
  +
</pre>
   
Swap the '''current line''' with the next:
+
Swap the '''current character''' with the previous:
  +
<pre>
ddp
 
  +
Xp
  +
</pre>
  +
  +
Swap the '''current line''' with the next (but see [[#Mappings|below]] for a better method):
  +
<pre>
 
ddp
  +
</pre>
  +
  +
Swap the '''current line''' with the previous:
  +
<pre>
  +
ddkP or ddkkp
  +
</pre>
   
 
Swap the '''current word''' with the next (see note):
 
Swap the '''current word''' with the next (see note):
  +
<pre>
dawwP
+
dawwP
dawelp
+
dawelp
  +
hdeep (works at start of first word)
  +
"xdiwdwep"xp (works with most punctuations too)
  +
</pre>
   
 
Swap the '''current word''' with the previous (see note):
 
Swap the '''current word''' with the previous (see note):
  +
<pre>
dawbP
+
dawbP
  +
</pre>
   
''Note:'' these approaches to swap words don't work around punctuation and will do the wrong thing. For this reason, it is recommended that you create some mappings that will more intelligently move words around.
+
''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.
   
== Normal-Mode Mappings ==
+
==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:
+
To use <code>gc</code> to swap the '''current character''' with the next, without changing the cursor position:
  +
<pre>
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l>
 
 
:nnoremap <silent> gc xph
" This version will work across newlines:
 
  +
</pre>
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l>
 
   
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.)
+
To use <code>gw</code> to swap the '''current word''' with the next, without changing cursor position: (See note.)
  +
<pre>
:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>: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>
 
" This version will work across newlines:
 
:nnoremap <silent> gw "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>
  +
</pre>
   
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.)
+
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>
:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o>/\w\+\_W\+<CR><c-l>
 
 
:nnoremap <silent> gl "_yiw?\w\+\_W\+\%#<CR>:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o><c-l>
  +
</pre>
   
To use '''g{''' to swap the '''current paragraph''' with the next:
+
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>
:nnoremap g{ {dap}p{
 
 
:nnoremap <silent> gr "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<CR><c-o>/\w\+\_W\+<CR><c-l>
  +
</pre>
   
 
To use <code>g{</code> to swap the '''current paragraph''' with the next:
== Other Solutions ==
 
  +
<pre>
 
:nnoremap g{ {dap}p{
  +
</pre>
   
  +
''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}}
=== Visual-Mode swapping ===
 
   
 
==Visual-mode swapping==
To use this mapping: first, delete some text (using any normal Vim command, such as '''daw''', '''dt,''' in normal mode, '''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.
+
To use this mapping: first, delete some text (using a command such as <code>daw</code> or <code>dt</code> in normal mode, or <code>x</code> 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.
  +
<pre>
 
:vnoremap <C-X> <Esc>`.``gvP``P
  +
</pre>
   
  +
==Related plugins==
:vnoremap <C-X> <Esc>`.``gvP``P
 
  +
*[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=3656|text=Transpose words plugin}} swap two words as M-t (transpose words) in Emacs or bash
  +
*{{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
   
=== Scripts ===
+
==See also==
  +
*[[VimTip646|Moving lines up or down]] mappings to move lines up/down, with re-indenting
  +
*[[VimTip191|Transposing]] script to move current or selected lines up/down
   
  +
==Comments==
* Chip Campbell has written a script for Visual mode-based swapping similar to the above, available at http://mysite.verizon.net/astronaut/vim/index.html#VimFuncs
 
  +
===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:
   
  +
<pre>
== References ==
 
  +
function SwapAll() range
* [[VimTip47]] "Swapping characters, words and lines"
 
  +
if a:firstline != a:lastline
* [[VimTip329]] "A map for swapping words" by Chip Campbell, Arun Easi, Benji Fisher, and others.
 
  +
if a:firstline < a:lastline
* [[VimTip470]] "Map to quickly swap/exchange arbitrary text" by Piet Delport
 
  +
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>
[[Category:Usage]]
 
  +
vnoremap <silent> <C-x> :call SwapAll()<CR>
  +
</pre>
  +
--December 4, 2013

Revision as of 14:55, 7 April 2016

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

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

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>

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>

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

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