VIM Заменить слово содержимым буфера вставки?


110

Мне нужно сделать кучу замен слов в файле, и я хочу сделать это с помощью команды vi, а не команды EX, такой как :%s///g. Я знаю, что это типичный способ cw<text><esc>замены слова в текущей позиции курсора: но есть ли способ сделать это с содержимым безымянного регистра в качестве замещающего текста и без перезаписи регистра?


8
РЕШЕНИЕ: Для моей непосредственной необходимости я 12ylвыдергивал 12 символов и "_cw^r0заменял слово. Затем я смог использовать эту .команду, чтобы повторить замену во всем файле.
Плонг

Ответы:


127

Я думаю, что под "вставкой" вы подразумеваете безымянный регистр (копирование / установка / изменение / удаление / замена), верно? (Так как это тот, который будет перезаписан командой изменения.)

Регистры , как правило , указано, введя "затем имя (один символ) регистра, как "ayзатем "apдергать в регистр a, а затем поместить содержимое регистра a. То же самое и с командой изменения. В этом случае, если вы не хотите, чтобы текст удалить с помощью команды изменения , чтобы пойти куда - нибудь, вы можете использовать черную дыру реестр "_: "_cw. Затем, войдя в режим вставки, вы можете нажать ctrl-R, а затем регистр, который вы хотите (возможно ") поместить в содержимое этого регистра.

  • "* - регистр выбора (вставка средней кнопки)
  • "+ - регистр буфера обмена (возможно, также доступен с помощью ctrl-shift-v через терминал)
  • "" - стандартный (безымянный) регистр vim yank / put / change / delete / replace.

Короткий ответ: "_cw^R"

Изменить: как предлагают другие, вы, конечно, можете использовать другой регистр для восстановления (или чего-то еще), который поместил ваш текст в регистр по умолчанию. Однако вы не всегда думаете об этом в первую очередь, поэтому неплохо сделать одну команду изменения, не сдувая ее. Хотя это не совсем так. Пронумерованные регистры "0проходят через "9:

Vim заполняет эти регистры текстом из команд восстановления и удаления.

Пронумерованный регистр 0 содержит текст из самой последней команды восстановления, если в команде не указан другой регистр с помощью ["x].

Пронумерованный регистр 1 содержит текст, удаленный самой последней командой удаления или изменения, если в команде не указан другой регистр или текст меньше одной строки (тогда используется малый регистр удаления). Исключение делается для удаления оператора с этими командами движения: %, (, ), `, /, ?, n, N, {и }. В этом случае всегда используется регистр «1» (он совместим с Vi). Регистр «-» также используется, если удаление выполняется внутри строки.

При каждом последующем удалении или изменении Vim сдвигает предыдущее содержимое регистра 1 в регистр 2, 2 в регистр 3 и так далее, теряя предыдущее содержимое регистра 9.


1
Хорошо, думаете, что я уже скопировал в свой ответ достаточно документации по регистрам? Это все там внизу :help registers.
Cascabel

48

Используя информацию в этом посте, я сформировал это полезное отображение. Я выбрал "cp", потому что он означает "изменить вставку"

nmap <silent> cp "_cw<C-R>"<Esc>

РЕДАКТИРОВАТЬ:

Также я пошел дальше и поддержал любое движение.

Чтобы получить эквивалент приведенной выше команды, это будет cpw«изменить вставить слово»

"This allows for change paste motion cp{motion}
nmap <silent> cp :set opfunc=ChangePaste<CR>g@
function! ChangePaste(type, ...)
    silent exe "normal! `[v`]\"_c"
    silent exe "normal! p"
endfunction

<silent> заставляет его не работать для меня ... любая идея, почему это должно быть? Я новичок в отображениях и функциях.
Холлистер,

Единственная проблема в том, что вы не можете выбрать регистр для вставки ... но в этом случае я полагаю, вы могли бы просто cw и использовать CTRL + R
Стив Вермёлен

2
Может быть, есть лучший способ добавить именование регистров, но для меня работает следующее: nmap <silent> cp :let g:currentRegister=v:register<cr>:set opfunc=ChangePaste<CR>g@ function! ChangePaste(type, ...) silent exe "normal! `[v`]\"_c".getreg(g:currentRegister) endfunction
Стив Вермёлен

@eventualEntropy, это хорошо работает для замены строк, как я могу сделать эту работу для слов вместо строк, я все еще изучаю vim. Спасибо за помощь.
Xavitoj Cheema

@XavitojCheema Я даже не помню, чтобы делал этот комментарий, ха-ха. Но, как оказалось, с тех пор я написал плагин для обеспечения этой функциональности ( github.com/svermeulen/vim-easyclip )
Стив Вермёлен

27

Для этого вы можете использовать визуальный режим vim. например, скопируйте слово: yeа затем замените другое скопированным словом:vep


9
Это работает, но следует также отметить, что визуальная вставка перезаписывает буфер восстановления для только что удаленного текста.
ostler.c 09

24

Если ваш курсор находится на слове, которое вы хотите заменить содержимым безымянного регистра, вы можете использовать viwp. vпереключается в визуальный режим, iwвыбирает внутреннее слово и pпомещает содержимое регистра на его место.

На практике, когда мне нужно заменить одно слово (имя функции и т. Д.) Другим, я перейду к тому, которое будет использоваться в качестве замены, yiwчтобы перенести внутреннее слово в безымянный регистр, а затем перейду к слову I ' м замена, и viwpна замену. Довольно быстрый способ замены одного слова другим. Если вы искали ( /) слово, которое вы заменяете, чтобы добраться до него, вы можете просто нажать, nчтобы перейти к следующему вхождению, которое вам нужно заменить. Очевидно, что это не заменит использование :%s/find/replace/g, но для пары быстрых замен это может быть удобно, особенно если у вас уже есть новое слово в регистре.


4
Я удивлен, что это не приемлемое решение: все вышеперечисленное, хотя и более гибкое в некоторых крайних случаях, гораздо более подробное для простого `` замены текущего безымянного регистра для выбора где-то '', что является исходной ситуацией. спрашивающий пришел сюда для.
ELLIOTTCABLE

1
Это очень полезно и интуитивно понятно.
lacostenycoder

6

Если вы используете именованный регистр (например, используйте "ayили "adи т. Д., Чтобы заполнить свой регистр вставки), вы можете сделать что-то вроде

cw<CTRL-R>a<esc>

Что заменит слово содержимым регистра a. Насколько я могу судить, вы не можете использовать регистр по умолчанию, потому что, когда вы cwего заполните, он будет заполнен словом, вырезанным этой командой.


Вы можете использовать регистр по умолчанию! Ознакомьтесь с моим ответом.
Cascabel

2

Вы имеете в виду системный буфер вставки или регистр vi?

Если вы хотите использовать системный буфер вставки, тогда все в порядке dw"+P- "выбирает регистр и "+является системным буфером вставки.

В противном случае скопируйте в регистр не по умолчанию, скажем, "ayчтобы скопировать в регистр, aа затем что-то заменить, сделайтеdw"aP


Спасибо, Хэмиш. Я пробовал это, но dwудалял конечные пробелы после того, что я бы считал «словом», тогда как изменял cwтолько слово. По этой причине dwмне это не подходит.
plong

В этом случае deу вас должно работать - он удалит до конца этого слова, а dwудалит до начала следующего слова.
Хэмиш Даунер

1

Вы можете использовать ywдля восстановления слова, затем вы можете изменить слово с помощью выделенного слова, vipwчтобы восстановить слово и вставить ранее восстановленное слово.


0

Для этого можно использовать регистры:

первый текст замены в регистре <mark some text>"ay

где a имя регистра

тогда вы можете использовать этот регистр вместо

ve"ap


К сожалению, я не мог просто повторить последнюю операцию вставки через ., а это еще одна вещь, которую я хотел сделать. Спасибо хоть. Очень признателен.
плонг

0

Или вы можете сделать Shift+ v- p(выделите всю строку и вставьте на ее место)


1
или pdw ... Разве вы не любите vim? : P
elimirks
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.