Как вставить результат команды в текст в vim?


42

Например, :echo strftime(%c)покажет текущее время внизу, но как вставить эту строку времени в текст (сразу после курсора)?


1
Я считаю, что OP означает "Как вставить результат выражения Vim в текст?"
— Аластер Ирвин

Также стоит упомянуть, что это не тот же вопрос, что и написание функции vim для вставки блока статического текста , однако некоторые ответы все еще применимы.
— Аластер Ирвин

Ваш пример буквально мой вариант использования, и я приветствую вас за это.
— Джо

См. Также перенаправление в регистр: stackoverflow.com/questions/2573021/…
— NeilG

Ответы:


49

Вы можете использовать регистр выражений "=, с p(или P) в обычном режиме или <C-R>в режиме вставки:

В обычном режиме:
( <C-M>здесь означает Control+ M, или просто нажмите Enter/ Return)

"=strftime('%c')<C-M>p

В режиме вставки:
( <C-M>имеет то же значение, что и выше, <C-R>означает Control+ R)

<C-R>=strftime('%c')<C-M>

Если вы хотите вставить результат одного и того же выражения много раз, то вам может потребоваться сопоставить их с ключами в вашем .vimrc:
(здесь <C-M>и <C-R>следует печатать буквально (последовательность из пяти печатных символов - Vim переведет их внутренне))

:nmap <F2> "=strftime('%c')<C-M>p
:imap <F2> <C-R>=strftime('%c')<C-M>

2
+1 С курса! "=Регистр. : - /
— Двенадцать

2
чтобы получить значение переменной vim (например, sessionoptions): <C-R>=&sessionoptions- он даже выполняет wildmode tab-complete!
— Джастин М. Кейс

2
: put = strftime ('% c') <CM>
— brunch875

В режиме вставки использование команды <c-r>=медленно для команды, которая может иметь много выходных данных, а также может нарушить отступ, так что выводимый текст будет нечитаемым. Например, <c-r>=execute('nmap')вывод будет записан построчно, что очень медленно.
— jdhao

22

:r!date +\%c

видеть :help :r!


1
dateявляется внешней командой и !вызывает внешние команды, в то время как OP запрашивает команды vim.
— Двенадцать

@eelvex нет, он не сделал. и то! это vim, а vi - команда. Это канонический метод. Работает и для многих других вещей.
— Кит

5
@Keith: yes !- это команда vi (m), которая вызывает внешние команды. Вы можете быть правым оператором, который не хочет выводить только команды vim, но если он (а) это сделает, !то не будет.
— Двенадцать

11

Эти команды вставят выходные данные strftime("%c")прямо там, где находится ваш курсор:

:exe ":normal i" . strftime("%c")

а также

:call feedkeys("i". strftime("%c"))

Есть и другие способы сделать то, что вы хотите (например, те, которые есть в ответе Микеля ).

Изменить : еще лучше, для вставки на месте, используйте =регистр, как описывает Крис Джонсен


10

Если вы хотите , чтобы вставить вывод в VIM команды (в отличие от возвращаемого значения вызова функции ), вы должны захватить его. Это выполняется с помощью :redirкоманды, которая позволяет перенаправить эквивалент стандартного вывода vim в переменную, файл, регистр или другую цель.

:redirявляется болезненно неудобным для использования; Я бы написал функцию для инкапсуляции ее функциональности более удобным способом, что-то вроде

funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    return output
endfunct!

После того как вы объявили такую ​​функцию, вы можете использовать регистр выражений (как объяснил Крис Джонсен), чтобы вставить вывод команды в позицию курсора. Итак, в обычном режиме нажмите, i^R=Exec('ls')чтобы вставить список текущих буферов vim.

Имейте в виду, что команда будет выполняться в пространстве имен функции, поэтому, если вы используете глобальную переменную, вам придется явно указать пространство имен, поставив перед ней префикс g:. Также обратите внимание, что Exec(), как написано выше, добавляется завершающий символ новой строки даже к выводу одной строки. Возможно, вы захотите добавить вызов substitute()в функцию, чтобы избежать этого.

Также см. Https://stackoverflow.com/questions/2573021/vim-how-to-redirect-ex-command-output-into-current-buffer-or-file/2573054#2573054 для получения дополнительной информации о программе redirи ссылки на связанная команда.


2
Это прекрасно работает. Я добавил set pasteкоманду перед возвратом вывода и set nopasteпосле, чтобы избежать отступа лестницы, когда строки начинаются с пробелов. На самом деле я хотел сохранить значение текущей опции вставки и вернуть его, но я не смог этого сделать.
— Хуан Ланус

1
@JuanLanus После set nopasteне должно работать return output, потому что оператор return является точкой выхода из функции. Я поставил свое решение этой проблемы как отдельный ответ на этой странице.
— Евгений Сергеев

4
:call append(line('.'), strftime("%c"))

Поместите его на следующую строку, затем вы можете нажать J( Shift+ J), чтобы присоединить его к текущей позиции.

Или, если вам нужно все это в одной команде, вы можете сделать

:call setline(line('.'), getline(line('.')) . strftime("%c"))

или

:call setline(line('.'), getline(line('.')) . " " . strftime("%c"))

в зависимости от того, хотите ли вы вставить пробел до даты или нет.


4

Улучшение @intuited ответа, чтобы избежать проблемы с пробелами и растущим отступом:

"Examples:
":call Exec('buffers')
"This will include the output of :buffers into the current buffer.
"
"Also try:
":call Exec('ls')
":call Exec('autocmd')
"
funct! Exec(command)
    redir =>output
    silent exec a:command
    redir END
    let @o = output
    execute "put o"
    return ''
endfunct!

Это будет просто вставить в текущем месте в файле, когда вы :call Exec('command')из нормального режима. Как отмечено в комментарии , оригинальный =Exec('command')подход ( Ctrl + R) в режиме вставки с Exec(..)возвратом строки может быть частично исправлен с помощью set paste, но не дает возможности поместить set nopasteкуда угодно.

let @o = outputСинтаксис устанавливает регистр oна содержимое переменной output, как описано здесь: https://stackoverflow.com/a/22738310/1143274

return ''Линии так , что значение по умолчанию возврата 0не вставляются в буфер.


2

Вот как я это делаю. Он ставит его сразу после курсора, потому что он использует p.

" save previous yank
let reg_save = @@

" save your text to the '@' register
let @@ = strftime('%c')
" paste it after the cursor
exec "normal! p"

" restore previous yank
let @@ = reg_save
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.