2008-09-26 38 views
13

Emacs提供了一个有用的transpose-words命令,让您可以将光标前的单词与光标后面的单词交换,从而保留标点符号。如何在Vim中模拟Emacs的转置单词?

例如,'stack |overflow'+ M-t ='overflow stack|'('|'是光标位置)。

<a>|<p>变成<p><a|>

是否可以在Vim中模拟它?我知道我可以使用dwwP,但它不符合标点符号。

更新:没有,dwwP真的不是办法。试想一下:

SOME_BOOST_PP_BLACK_MAGIC((a)(b)(c)) 
//    with cursor here^

Emacs的M-T会交换bc,导致(a)(c)(b)

什么适用/\w yiwNviwpnviwgp。但它损坏了"""/。有更清洁的解决方案吗?

Update²:

解决

:nmap gn :s,\v(\w+)(\W*%#\W*)(\w+),\3\2\1\r,<CR>kgJ:nohl<CR> 

不完美的,但工程。

感谢Camflan为我带来%#项目。当然,这一切都在wiki上,但我没有意识到它可以解决确切的(Emacs完全正确)重复transpose-words功能的问题。

+0

我很难用google搜索“%#”。他们在这里表示什么? – 2009-05-03 02:54:58

+0

使用内置的Vim帮助::h/\%# – 2009-06-02 06:29:52

回答

7

这些来自我的.vimrc并且适合我。

" 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* 
5

根据情况,可以使用W或B命令,如在dWwP中。 “大写”版本跳到下一个/上一个空格,包括标点符号。 f和t命令也可以帮助指定删除范围的结束。

还有关于Vim Tips Wiki关于各种交换技术的讨论。

5

在线路中间,去的第一个单词的第一个字母,然后做

dw wP 

在一条线(即该行的最后两个单词)的结束,进入在单词之间和空间做

2dw bhP 

从便利Equivalence of VIM & Emacs commands


您可以通过添加类似以下到你的vimrc文件中添加快捷键为那些:

map L dwwP 
map M 2dwbhP 

在这种情况下,SHIFT-L(在命令模式)将切换词语的线的中间, SHIFT-M最后会做。

注意:这适用于空格分隔的单词,并且不能很好地处理OP的特定情况。

0

您可以使用dwwP或dWwP马克和CapnNefarious说,但我有我自己的几点注意事项:

  • 如果光标在第二个单词的第一个字母,如你给的例子,你可以使用dwbP(或dWbP来处理标点符号);
  • 如果光标位于单词的中间,则可以使用dawbP/daWbP。
2

有关于http://vim.wikia.com/wiki/VimTip10的提示。但我选择自己推出。 与我在提示中提到的方法相比,我的代码段有两个明显的优点:1)当光标不在单词中时,它有效。 2)它不会高亮显示整个屏幕。

它的工作原理与emacs'transpose-words'几乎相同,只是当转换不可能时,它什么也不做。 (emacs'transpose-words'将会闪烁,并将光标位置改变为当前字的开头。)

"transpose words (like emacs `transpose-words') 
function! TransposeWords() 
    if search('\w\+\%#\w*\W\+\w\+') 
    elseif search('\w\+\W\+\%#\W*\w\+') 
    endif 
    let l:pos = getpos('.') 
    exec 'silent! :s/\(\%#\w\+\)\(\W\+\)\(\w\+\)/\3\2\1/' 
    call setpos('.', l:pos) 
    let l:_ = search('\(\%#\w\+\W\+\)\@<=\w\+') 
    normal el 
endfunction 

nmap <silent> <M-right> :call TransposeWords()<CR> 
imap <silent> <M-right> <C-O>:call TransposeWords()<CR>