How to emulate Emacs’ transpose-words in Vim?

editor, emacs, usability, vim

Solution

These are from my .vimrc and work well for me.

" swap two words
:vnoremap <C-X> <Esc>`.``gvP``P
" Swap word with next word
nmap <silent> gw    "_yiw:s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/<cr><c-o><c-l> *N*

Problem

Emacs has a useful `transpose-words` command which lets one exchange the word before the cursor with the word after the cursor, preserving punctuation. For example, ‘`stack |overflow`’ + M-t = ‘`overflow stack|`’ (‘`|`’ is the cursor position). `<a>|<p>` becomes `<p><a|>`. Is it possible to emulate it in Vim? I know I can use `dwwP`, but it doesn’t work well with punctuation. Update: No, `dwwP` is really not a solution. Imagine: ``` SOME_BOOST_PP_BLACK_MAGIC( (a)(b)(c) ) // with cursor here ^ ``` Emacs’ M-t would have exchanged `b` and `c`, resulting in `(a)(c)(b)`. What works is `/\w yiwNviwpnviwgp`. But it spoils `""` and `"/`. Is there a cleaner solution? Update²: Solved ``` :nmap gn :s,\v(\w+)(\W*%#\W*)(\w+),\3\2\1\r,<CR>kgJ:nohl<CR> ``` Imperfect, but works. Thanks Camflan for bringing the `%#` item to my attention. Of course, it’s all on the wiki, but I didn’t realize it could solve the problem of exact (Emacs got it completely right) duplication of the `transpose-words` feature.

Original source