Как эмулировать транспонированные слова Emacs в Vim?
Вопрос
В Emacs есть полезная transpose-words
команда, которая позволяет заменить слово перед курсором словом после курсора, сохраняя знаки препинания.
Например, ‘stack |overflow
’ + M-t = ‘overflow stack|
’ (‘|
’ - это позиция курсора).
<a>|<p>
становится <p><a|>
.
Можно ли эмулировать это в Vim?Я знаю, что могу использовать dwwP
, но это плохо работает с пунктуацией.
Обновить: НЕТ, dwwP
является в самом деле это не решение проблемы.Представьте себе:
SOME_BOOST_PP_BLACK_MAGIC( (a)(b)(c) )
// with cursor here ^
M-t Emacs заменил бы b
и c
, приводящий к (a)(c)(b)
.
Что работает, так это /\w
yiwNviwpnviwgp
.Но это портит ""
и "/
.Есть ли более чистое решение?
Обновление 2:
Решаемая
:nmap gn :s,\v(\w+)(\W*%#\W*)(\w+),\3\2\1\r,<CR>kgJ:nohl<CR>
Несовершенно, но работает.
Спасибо, Камфлан, что привез %#
обращаю ваше внимание на этот пункт.Конечно, все это находится на Вики, но я не понимал, что это может решить проблему точный (Emacs понял это совершенно правильно) дублирование transpose-words
особенность.
Решение
Они из my .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*
Другие советы
В зависимости от ситуации вы можете использовать команды W или B, как в dWwP."Заглавные" версии переходят к следующему / предыдущему пробелу, включая знаки препинания.Команды f и t также могут помочь указать конец удаленного диапазона.
Там также обсуждается Советы Vim Вики о различных методах подкачки.
В середине строки перейдите к первой букве первого слова, затем выполните
dw wP
В конце строки (то есть в последних двух словах строки) перейдите к пробелу между словами и выполните
2dw bhP
Из подручных средств Эквивалентность команд VIM и Emacs
Вы могли бы добавить для них сочетания клавиш, добавив в свой файл vimrc что-то вроде следующего:
map L dwwP
map M 2dwbhP
В этом случае SHIFT-L (в командном режиме) переключит слова в середине строки, а SHIFT-M сделает это в конце.
Примечание:Это лучше всего работает со словами, разделенными пробелами, и не очень хорошо обрабатывает конкретный случай OP.
Там есть подсказка по http://vim.wikia.com/wiki/VimTip10.Но я предпочитаю свернуть свой собственный.Мой фрагмент имеет два очевидных преимущества по сравнению с методом, упомянутым в подсказке:1) это работает, когда курсор не находится в слове.2) он не будет сильно освещать весь экран.
Это работает почти как "транспонирование слов" emacs, за исключением того, что, когда транспонирование невозможно, оно ничего не делает.(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>
Вы можете использовать dwwP или dWwP, как сказали Марк и CapnNefarious, но у меня есть несколько собственных замечаний:
- Если курсор находится на первой букве второго слова, как в приведенном вами примере, вы можете использовать dwbP (или dWbP для обработки знаков препинания).;
- Если курсор находится в середине слова, вы можете использовать dawbP/daWbP.
Там есть сценарий транспонирования слов вкл. vim.org это прекрасно работает.