Вопрос или проблема
Большую часть времени, когда я вставляю дату, я пытаюсь сделать это в середине строки. По умолчанию, похоже, что вставка с помощью :r!
всегда помещает результат на новую строку. Это имеет некоторый смысл, так как большинство команд оболочки выводят новую строку перед результатом команды, и это, безусловно, предпочтительнее в терминале. В случае выхода из Vim для небольшой команды, такой как date +%x
, это не мое предпочтительное поведение. Как мне это обойти?
В режиме вставки вы можете использовать Ctrl-R= для вставки выражения в текущую позицию курсора.
Вы могли бы использовать, например, функцию system()
, к сожалению, это решает лишь половину проблемы, так как вывод system()
всегда будет содержать как минимум конечный разрыв строки, что приведет к разрыву строки после ввода. Для решения вопроса о том, как избежать этих конечных разрывов строки в случае system()
, посмотрите этот мой ответ на vi.stackexchange.
(так что вы можете использовать, например, Ctrl-R=systemlist(‘date’)[0]Enter).
Альтернативный способ вставки даты в текущую позицию курсора – это использование Ctrl-R=strftime(‘%c’)Enter
Ctrl-R= использует регистр выражений для вставки содержимого. Вы можете узнать больше с помощью команды :help i_ctrl-r
или посмотреть документацию на appspot.
Я считаю, что проблема заключается не столько в том, что команды оболочки обычно заканчиваются новой строкой, сколько в том, что команда read
предназначена для работы с строками (т.е. команда ex). Она присутствовала в оригинальной версии ed
в 1970-х годах, до появления :r!команда
, и чаще всего использовалась для чтения нескольких строк (например, C-функции или абзаца текста) из одного файла в другой. Большинство пользователей хотели бы вставлять их как новые, отдельные строки в большинстве случаев.
Вы можете проверить/демонстрировать это, выполнив :r!printf Tuesday
. Даже если команда printf Tuesday
не записывает новую строку (так как вы не указали \n
), вы получите Tuesday
на отдельной строке.
Возможно, самое простое решение – сделать i Enter Esc (чтобы разорвать текущую строку), - или k, чтобы вернуться на строку выше, затем выполнить вашу :r!команда
и затем J, чтобы Join
соединить строки вместе. Если вы часто делаете это, возможно, имеет смысл настроить макрос для этого.
Разоблачение: Я неплохо знаю vi
, но многому в vim
я еще не научился. Возможно, есть более простой способ сделать это в vim
.
Используя комбинацию вышеперечисленных ответов
Вы можете экспортировать функцию где-нибудь, например, в .zshrc / .zshenv
export function dateTime() {
printf "$(date +'%y/%m/%d-%H:%M')"
}
Затем создайте такое отображение
nmap <leader>D i<cr><Esc>k:r! dateTime<cr>kJJ
Это не работает идеально, если вы находитесь в конце строки.
.
Ответ или решение
Для пользователей Vim, сталкивающихся с проблемой добавления новой строки при использовании команды :r!date
или других shell-команд, существует несколько решений, которые позволят вставить вывод команды прямо в середину строки без пробелов.
Проблема
Когда вы используете в Vim команду :r!
, такие команды, как date +%x
, распечатывают результат на новой строке. Это поведение связано с тем, что команда :r
является ориентированной на строку. Исторически, она была разработана для добавления блоков текста из одного файла в другой, поэтому вставка результатов shell-команд на новой строке была ожидаемым поведением.
Решения
Использование Ctrl-R и функции
-
Вставка выражений:
- В режиме вставки (
Insert
) используйте комбинациюCtrl-R =
, чтобы вставить результат на текущую позицию курсора. Например, для вывода текущей даты можно использовать:Ctrl-R =strftime('%c')<Enter>
Стандартная библиотека Vim предоставляет функцию
strftime
, которая аналогична командеdate
и позволяет форматировать дату и время без проблем с новой строкой.
- В режиме вставки (
-
Использование функции systemlist:
- Мамогущая альтернатива — использовать функцию
systemlist()
. Она позволяет извлечь результат shell-команды без завершающего переноса строки:Ctrl-R =systemlist('date')[0]<Enter>
Эта формула позволит вам получить вывод команды без добавления ненужного разделителя, так как
systemlist()
возвращает список строк без лишних символов.
- Мамогущая альтернатива — использовать функцию
Обходные пути
-
Предварительное разбиение строки:
- Если вы часто оказываетесь в ситуации, когда необходимо вставить результат shell-команды в середину строки, можно следовать следующему процессу:
- Вставьте новую строку (нажмите
i <Enter> Esc
). - Вернитесь на одну строку вверх с помощью клавиши
k
. - Выполните вашу команду
:r!command
. - Объедините строки обратно, использовав команду
J
.
- Вставьте новую строку (нажмите
- Если вы часто оказываетесь в ситуации, когда необходимо вставить результат shell-команды в середину строки, можно следовать следующему процессу:
-
Создание функции в оболочке:
- Создайте shell-функцию в вашем файле конфигурации (например,
.zshrc
):export function dateTime() { printf "$(date +'%y/%m/%d-%H:%M')" }
- В Vim настройте соответствующую маппинг:
nmap <leader>D i<cr><Esc>k:r! dateTime<cr>kJJ
Этот подход вставляет вашу дату в нужное место, а затем объединяет строки обратно. Обратите внимание, что это может не работать идеально, если вы находитесь в конце строки.
- Создайте shell-функцию в вашем файле конфигурации (например,
Заключение
Вышеперечисленные методы должны помочь вам избежать автоматического добавления новой строки при выполнении shell-команд в Vim. Выбор конкретного метода зависит от ваших предпочтений и задач. Если вы часто сталкиваетесь с этой проблемой, создание макроса или скрипта может сэкономить время и упростить рабочий процесс в редакторе.