Как я могу отобразить d [count] d?

18

NB Это не дубликат Как работает команда "d3fg"? Пожалуйста, прочитайте это перед голосованием, чтобы закрыть!

Я попал в тупик в своем стремлении заставить маленькие удаления работать как большие . Проблема в том, что я не могу понять, как переназначить команды, как d3d. На самом деле, я даже не могу понять, как они работают в первую очередь, и не нахожу упоминания о них в помощи Vim. *

d3jэто просто: он применяет dоператор к 3jдвижению,

3ddтакже прост: он запускает ddкоманду с «счетом» 3.

d3d Похоже, это должно быть просто, это относится к dоператору ... но что это 3d? Это не движение. Если вы печатаете 3dсамостоятельно, Vim обрабатывает его как счет, за которым следует оператор, и терпеливо ждет дальнейшего ввода.

И вы не можете применять операторы к другим операторам. ddне описывается в справке как последовательность двух операторов. Это отдельная команда, состоящая из двух клавиш. (ср. dc, который ничего не делает.)

Также не похоже, что положение счетчика является гибким для команд, требующих двух нажатий клавиш: 2gjперемещает курсор вниз на две строки экрана, но полностью g2jотбрасывает первые два нажатия клавиш и перемещает курсор вниз на одну строку.

Итак, как это работает? Это особый случай во внутреннем коде Vim? Есть ли способ, которым я могу создать d[count]dотображение?

РЕДАКТИРОВАТЬ : это текстовый объект? :h text-objectsне включить его в список «текстовых команд выбора объектов», но тогда он действительно включает дд в списке удалений «сгруппированных от маленьких до больших объектов». И d2awдействительно удаляет слово под курсором и следующее. С другой стороны, c2dничего не делает.

* Я уверен, что некоторые упоминания о них должны существовать, но я не могу их найти. Я прочитал :help deleting, :help motion.txtи пытался :helpgrep dNdпри всех значениях N от 1-9 .

Богатый
источник
2
Я думаю, что последнее dдействует как подтверждение; Так что это так же, как d3<CR>. y3yи c3cтакже работают так же ... Я не могу найти никаких документов по этому вопросу, хотя в Vim: help, vi (1), nvi (1), или в спецификации POSIX ... Он ведет себя одинаково в viи nviкстати ,
Мартин Турной
1
В некотором смысле, ddидентичен d_. _переводит курсор к первому [count]непустому в ( -1)-й строке вниз, но это также происходит, поэтому в паре с оператором он работает на целых строках. По этой причине, имеет смысл, что счет может появиться между двумя ds.
Tommcdo

Ответы:

28

Режим ожидания оператора

Между набрав оператора (например d, cили gU) и движение (например w, i}или /foo<CR>), Вим находится в режиме оператора находящейся на рассмотрении. Вы можете создать сопоставления для этого с помощью :omapи :onoremap.

В моих примерах я собираюсь отобразить ожидающий оператор dна w. Это случайный выбор, потому что я не знаю, для чего вы на самом деле хотели его использовать.

Создать omap

Давайте создадим отображение для dв режиме ожидания оператора. Я предполагаю, что мы пишем VimScript здесь (например, в вашем .vimrc), поэтому я опущу ведущие :s.

onoremap d w

Это заставляет ddдействовать как dw. Это также заставляет d[count]dдействовать как d[count]w. Но держу пари, что вы не хотели влиять на поведение dd(то есть не [count]поставлялись).

Отображения выражений

Отображения выражений позволяют вам оценить выражение VimScript, чтобы получить правую часть сопоставления. Выражение должно вычисляться как строка. Отображения выражений обозначаются <expr>ключевым словом.

В Vim также есть некоторые встроенные переменные, которые заполняются в разное время и часто полезны при отображениях. Одним из них является то v:count, что [count]подается оператору или движению.

Давайте сложим все это вместе. Если нет [count], v:countбудет 0. Мы можем сказать, что наше отображение просто использовать dв этом случае.

onoremap <expr> d v:count == 0 ? 'd' : 'w'

Теперь ddведет себя как по умолчанию (удаляет строку), но d[count]dведет себя как d[count]w. Здорово!

Ограничить его использование после dоператора

Вы можете заметить что-то, хотя. Теперь cdтакже ведет себя как cw. Это может не быть проблемой, но для полноты давайте ограничим это, чтобы оно работало только после dоператора.

В Vim есть еще одна переменная, v:operatorкоторая содержит оператор, который использовался последним. Давайте проверим это тоже, прежде чем делать что-то особенное.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

ПРИМЕЧАНИЕ. Поскольку :mapкоманды могут быть объединены в цепочку |, мы должны экранировать их в нашем выражении здесь. Таким образом, логический оператор ИЛИ ||становится \|\|.

Круто, так cdи c[count]dвернулись к тому, чтобы ничего не делать, как раньше. Это хорошо, так что другие плагины могут определить cd.

Я не хочу просто удалить другое движение

Если вы хотите отобразить d[count]dчто-то совершенно другое, не имеющее ничего общего с удалением текста, мы можем сделать это тоже.

Когда вы вводите команды в обычном режиме и начинаете вводить команду по ошибке, вы можете нажать, <Esc>чтобы отменить эту команду. То же самое относится и к вашим сопоставлениям.

Давайте d[count]dизменим текущую строку на что угодно [count].

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

Последняя часть отображения является выражением VimScript: <Esc>cc' . v:count . '<Esc>'. Это <Esc>для отмены ожидающей dкоманды, затем ccдля изменения текущей строки, v:countдля ввода значения [count](в режиме вставки) и <Esc>возврата в обычный режим. Обратите внимание, что здесь мы строим строку, используя оператор конкатенации VimScript ..


Ваш фактический вариант использования, вероятно, будет отличаться от того, что я изложил здесь, но, надеюсь, это поможет вам добиться успеха.

Счастливого Вимминга!

tommcdo
источник
Отличный ответ! Upvoted. В начале вопроса я ссылался на свой вариант использования (также на vi.SE), но, наверное, вы его пропустили. Мне в основном нужно сделать :omap d d(!), Но, к сожалению, режим ожидания оператора фактически никогда не достигается из-за моего отображения для d, которое устанавливает пользовательскую функцию оператора. Хотелось бы надеяться, что можно настроить вещи так, чтобы они d3dработали так, как должны. (Дайте мне знать, если у вас есть какие-либо идеи, или не стесняйтесь опубликовать полное решение другого вопроса, если вы предпочитаете.) Если я не смогу это выяснить в ближайшее время, я приму это и опубликую другой, более конкретный вопрос. Благодарность!
Рич
1
На самом деле, если подумать, я принимаю это сейчас. Вы объяснили, как создать такое отображение, а также как оно работает под капотом, о чем я и просил.
Рич