Vim: выполнить команду оболочки без фильтрации
Я хочу выбрать блок текста (например, V%
) и использовать текст в качестве ввода команды оболочки (например, wc
или pbcopy
)), но я НЕ хочу изменять текущий buffer - я просто хочу увидеть вывод команды (если есть), а затем продолжить редактирование без каких-либо изменений.
Ввод V%!wc
преобразуется в :'<,'>!wc
и переключает блок текста для вывода команды wc
.
Как вы нажимаете кусок текста на произвольную команду оболочки, не влияя на текущий буфер?
Ответы
Ответ 1
Выберите свой блок текста, затем введите следующие ключи: w! sh
Все это должно выглядеть так:
:'<,'>w !sh
Что это. Мне потребовалось всего 8 лет, чтобы узнать это:)
note: ввод: после выбора текста выдает: '<,' > диапазон, указывающий начало и конец выбора.
Обновление 2016: Это действительно одно использование общего типа:
'<,'>w !cli_command
Что в принципе позволяет "отправлять" произвольные части вашего файла внешним командам и просматривать результаты во временном окне vi без изменения вашего буфера. Другие полезные примеры:
'<,'>w !wc
'<,'>w !to_file my_file
Я честно считаю более полезным изменить текущий буфер. Это разнообразие просто:
'<,'>!wc
'<,'>!to_file my_file
Ответ 2
Одна из возможностей заключается в использовании system()
в пользовательской команде, примерно так:
command! -range -nargs=1 SendToCommand <line1>,<line2>call SendToCommand(<q-args>)
function! SendToCommand(UserCommand) range
" Get a list of lines containing the selected range
let SelectedLines = getline(a:firstline,a:lastline)
" Convert to a single string suitable for passing to the command
let ScriptInput = join(SelectedLines, "\n") . "\n"
" Run the command
let result = system(a:UserCommand, ScriptInput)
" Echo the result (could just do "echo system(....)")
echo result
endfunction
Вызовите это с помощью (например):
:'<,'>SendToCommand wc -w
Обратите внимание, что если вы нажмете V%:
, для вас будет введена :'<,'>
.
:help command
:help command-range
:help command-nargs
:help q-args
:help function
:help system()
:help function-range
Ответ 3
Обновление: мой ответ вздор.
Ответ на @pixelearth хорош, но у меня было немного проблем с пониманием того, что он сделал точно, поэтому я написал следующее. Эта последовательность команд позволяет вам выполнить wc -l
по вашему визуальному выбору. wc -l
просто подсчитывает количество переданных ему строк.
- В Vim перейдите в Visual Mode, используя
v
- Выберите несколько строк, опускаясь:
jjjj
- Введите
:
, который Vim переведет на :'<,'>
- Введите
w !wc -l
, теперь ваша полная командная строка должна быть :'<,'>w !wc -l
- Нажмите Enter, чтобы получить результат вашей команды (в этом примере это будет 4)
- Нажмите Enter, чтобы продолжить редактирование.
Я не понимаю, что именно происходит на шагах 3 и 4, но я знаю, что он работает.
Ответ 4
Я знаю, что это не идеальное решение, но если все остальное не удается, вы всегда можете просто нажать u после запуска команды, чтобы отменить изменение буфера.