Ответ 1
Это из моего .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*
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 ^
Emacs M-t обменял бы b
и c
, в результате получив (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
.
Это из моего .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 Tips Wiki о различных методах замены.
В середине строки перейдите к первой букве первого слова, затем выполните
dw wP
В конце строки (т.е. последние два слова строки) перейдите в пространство между словами и сделайте
2dw bhP
Из удобного Эквивалентность команд VIM и Emacs
Вы можете добавить для них сочетания клавиш, добавив в файл vimrc что-то вроде следующего:
map L dwwP
map M 2dwbhP
В этом случае SHIFT-L (в командном режиме) переключит слова в середине строки, а SHIFT-M сделает это в конце.
NB: Это лучше всего работает с словами, разделенными пробелами, и не очень хорошо справляется с конкретным случаем 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, как сказали Mark и CapnNefarious, но у меня есть несколько собственных нот:
На vim.org есть скрипт transpose-words, который прекрасно работает.