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

42

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

xzhu
источник
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"))

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

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

Eelvex
источник
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"))

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

Mikel
источник
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
Хуан Ибиапина
источник