Vim: удалить и вставить
Одна из сил vimа в том, что называется {motion}, то есть некое движение. Например, нажимая w
, я перемещаюсь к началу следующего слова. А 3w
перескочит к началу третьего слова. Ну, этим никого не удивишь: в обычном редакторе можно нажать Ctrl и стрелку вправо. Три раза.
Ну а как насчет такого: нажимая %
, я двигаюсь от открывающей круглой скобке к соответствующей закрывающей, и наоборот. В обычном редакторе придётся искать закрывающую скобку глазами, ничего не поделаешь. А потом к ней ползти.
Но основная сила в том, что {motion} может комбинироваться с операторами. Если я жму yw
, то оператор y (yank = copy) копирует текст от сих и до начала следующего слова. А если y%
(например, на вызове функции), то от сих и до закрывающей круглой скобки (то есть весь вызов целиком, вместе со всеми вложенными скобками). А если yi"
(i = inner), находясь где-нибудь внутри строки, ограниченной кавычками, то всё содержимое этой строки. Ну и так далее.
Идём дальше. Допустим, есть такой код:
if (check_err(errhp, OCIParamGet(stmtp, OCI_HTYPE_STMT, errhp, (dvoid**)&parmp, i) )) {
И захотел я заменить в нём выделенный вызов функции на другой, который предварительно скопировал (с помощью %
, конечно). Встав на начало вызова (в начале строки для этого достаточно fO
, что переместит нас к первой букве O), приходится сначала удалить ненужный вызов: d%
(d = delete), а затем вставить скопированное. Но поскольку d сам по себе копирует удалённое (то есть работает как cut), то скопированное ранее надо извлечь из специального регистра "0: "0P
(P = put, то есть paste).
Посчитаем нажатия: d%"0P
, 5 штук. Много. Хочется такой оператор, чтобы удалял {motion} и сразу вставлял на его место скопированный текст. А такого почему-то нет. Хотя подобную операцию приходится проделывать довольно часто.
К счастью, у нас есть help :map-operator
, а в хелпе есть прекрасные примеры, с помощью которых можно шаманить, даже не до конца всё понимая. В итоге рисуется такая функция:
function! PutInstead(type, ...) let sel_save = &selection let &selection = "inclusive" if a:0 silent exe "normal! `<" . a:type . "`>d\"0P" elseif a:type == 'line' silent exe "normal! '[V']d\"0P" elseif a:type == 'block' silent exe "normal! `[\<C-V>`]d\"0P" else silent exe "normal! `[v`]d\"0P" endif let &selection = sel_save endfunction
Она маппится на запятую:
nmap <silent> , :set opfunc=PutInsteadg@ vmap <silent> , :<C-U>call PutInstead(visualmode(), 1)
После этого вся процедура требует двух нажатий: ,%
. Почему запятая? Ну просто все клавиши уже напичканы функциями, а запятая среди них самая ненужная.
no subject
no subject
P.P.S. Этот код был набран в редакторе vim.
no subject
no subject
Вот ещё приделаю свою оракловую приблубу, и будет полное щастье.
no subject
в vim есть режим visual select, активируется кнопочкой v
можно в нём выбрать фрагмент и нажать p, произойдёт именно замена ;)
к сожалению, регистр загадится выделенным куском, но дальше можно и спользовать 0p и т.д.
насчёт выделения - попробуй команды:
iw ow
iW oW
i) o)
i] o]
i" o"
no subject