如何模拟 Emacs Vim 中的转置单词?
Emacs 有一个有用的 transpose-words
命令,它可以让我们将光标之前的单词与光标之后的单词交换,从而保留标点符号。
例如,'stack |overflow
' + Mt = 'overflow stack|
'('|
' 是光标位置)。
可以在 Vim 中模拟吗? 我知道我可以使用 dwwP,但它不能很好地处理标点符号。
更新:不,dwwP
确实不是一个解决方案。 想象一下:
SOME_BOOST_PP_BLACK_MAGIC( (a)(b)(c) )
// with cursor here ^
Emacs 的 Mt 会交换 b
和 c
,从而得到 (a)(c)(b)
。
有效的是 /\w yiwNviwpnviwgp
。 但它破坏了 ""
和 "/
。有更干净的解决方案吗?
更新²:
解决了
:nmap gn :s,\v(\w+)(\W*%#\W*)(\w+),\3\2\1\r,<CR>kgJ:nohl<CR>
不完美,但有效。
感谢 Camflan 带来< code>%# 项目引起了我的注意,当然,这些都在 wiki 上。 ,但我没有意识到它可以解决 transpose-words
功能的精确(Emacs 完全正确)重复的问题。
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
. But it spoils
yiwNviwpnviwgp""
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这些来自我的 .vimrc,对我来说效果很好。
These are from my .vimrc and work well for me.
vim.org 上有一个转置单词脚本,效果非常好。
There's a transpose-words script on vim.org that works beautifully.
您可以使用 dwwP 或 dWwP 正如 Mark 和 CapnNefious 所说,但我有一些自己的注释:
You can use dwwP or dWwP as Mark and CapnNefarious have said, but I have a few notes of my own:
http://vim.wikia.com/wiki/VimTip10 上有一个提示。 但我选择自己动手。
与提示中提到的方法相比,我的代码片段有两个明显的优点:1)当光标不在单词中时它可以工作。 2)它不会突出显示整个屏幕。
它的工作方式几乎与 emacs 的“transpose-words”类似,只不过当不可能进行转置时,它什么也不做。 (emacs 'transpose-words' 会闪烁并将光标位置更改为当前单词的开头。)
There's a tip on http://vim.wikia.com/wiki/VimTip10. But I choose to roll my own.
My snippet has two obvious advantages over the method mentioned in the tip: 1) it works when the cursor isn't in a word. 2) it won't high-light the entire screen.
It works almost like emacs 'transpose-words', except that when transposition is impossible, it does nothing. (emacs 'transpose-words' would blink and change cursor position to the beginning of current word.)
根据情况,您可以使用 W 或 B 命令,如 dWwP 中所示。 “大写”版本跳到下一个/上一个空格,包括标点符号。 f 和 t 命令也可以帮助指定删除范围的末尾。
Vim Tips Wiki 上也有关于各种交换技术的讨论。
Depending on the situation, you can use the W or B commands, as in dWwP. The "capital" versions skip to the next/previous space, including punctuation. The f and t commands can help, as well, for specifying the end of the deleted range.
There's also a discussion on the Vim Tips Wiki about various swapping techniques.
在一行的中间,转到第一个单词的第一个字母,然后执行
在一行的末尾(即该行的最后两个单词),转到单词之间的空格,然后执行
从方便 VIM 和 VIM 的等效项 Emacs 命令
您可以通过在 vimrc 文件中添加类似以下内容来添加快捷键:
在这种情况下,SHIFT-L(在命令模式下)将在行中间切换单词SHIFT-M 将在最后执行此操作。
注意:这最适合用空格分隔的单词,但不能很好地处理 OP 的特定情况。
In the middle of a line, go to the first letter of the first word, then do
At the end of a line (ie the last two words of the line), go to the space between the words and do
From the handy Equivalence of VIM & Emacs commands
You could add shortcut keys for those by adding something like the following to your vimrc file:
In that case, SHIFT-L (in command-mode) would switch words in the middle of the line and SHIFT-M would do it at the end.
NB: This works best with space-separated words and doesn't handle the OP's specific case very well.