Как перенаправить вывод команды ex в текущий буфер или файл?

Как я могу перенаправить или направить вывод команды ex в мой текущий буфер или файл?

Например, я хочу прочитать содержимое всех регистров в текущий буфер, который в режиме ex отображается с помощью :registers.


person Aman Jain    schedule 03.04.2010    source источник
comment
vi.stackexchange.com/a/13881/10254 может представлять интерес, в основном получите ввод, затем запустить команду, захватить и поставить. С функциями vimscript Capture(excmd) PutAfterCapture(command) GetInputCommandThenCaptureAndPut()   -  person qeatzy    schedule 10.10.2017


Ответы (6)


:redir >name_of_registers_file
:registers
:redir END
:r name_of_registers_file
:help redir

Последняя команда очень полезная, так как вариантов перенаправления масса: к переменным, к регистрам, как дописать, дальше рог изобилия.

Я все еще нахожу странным и раздражающим то, что он использует END таким образом, но поскольку все остальное, что может следовать за redir, должно начинаться с символа, отличного от слова, по крайней мере, это не двусмысленно.

PS Насколько я знаю (что довольно далеко в данном случае), нет способа прочитать его непосредственно в буфер: сначала вы должны сохранить его в регистре или переменной. Проверьте справку для различных вариантов того, как это сделать.

PPS Если вы хотите сделать это с помощью переменной — возможно, чтобы инкапсулировать ее в функцию и избежать затирания регистров или глобальных переменных — вам придется преобразовать многострочную строку, которая записывается в переменную, в список. НАПРИМЕР

:call append( '.', split(variable_you_redirected_to, "\n") )

В противном случае (если вы просто сделаете append('.',var)) вы получите ^@ (нулевые значения) вместо новых строк, поскольку это то, что vimscript использует для представления новых строк в строковых переменных.

редактировать: как упоминает @Bill Odom, использование :put =variable_you_redirected_to намного проще, чем сложное выражение append(). Спасибо, Билл!


ПППС

Я написал фрагмент, чтобы сделать этот материал более удобным. Он объявляет функцию Redir(command, target) и команду R.

Команда анализирует последнюю серию символов, отличных от пробела, как цель перенаправления и передает ее функции, которая делает шаблон для перенаправления вывода команды на цель перенаправления.

Команда — это все после R и до последнего пробела.

EG

" Store the vim buffer list in buffer_list.txt
:R ls >buffer_list.txt
" Store error messages emitted by a function being debugged
"   in the 'unnamed register'
:R call FunctionBeingDebugged() @">

При этом есть несколько ограничений: например, вы не сможете писать в имя файла, содержащее пробел. Преимущество этого в том, что вам не нужно цитировать вашу команду. Я разместил его на gist.github.com, и я постараюсь обновлять его, если в конечном итоге улучшу его. Или вы можете раскошелиться самостоятельно‹/ноэвфемизм>!

В любом случае фрагмент доступен здесь. Его можно поместить в файл .vimrc или в файл ~/.vim/plugins.

person intuited    schedule 03.04.2010
comment
Используя функцию Exec @intuited из здесь, такое сопоставление, как :inoremap <C-S-C> <C-R>=Exec("")<Left><Left>, сопоставляет Ctrl+Shift+C (для Command ), чтобы упростить вставку вывода такой команды, как :ls, в текущую точку буфера. - person Evgeni Sergeev; 04.02.2014

@intuited прав; команда redir - это то, что вам нужно. Такой однострочный код вставит вывод :registers в текущий буфер:

redir => m | silent registers | redir END | put=m

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

" redir_messages.vim
"
" Inspired by the TabMessage function/command combo found
" at <http://www.jukie.net/~bart/conf/vimrc>.
"

function! RedirMessages(msgcmd, destcmd)
"
" Captures the output generated by executing a:msgcmd, then places this
" output in the current buffer.
"
" If the a:destcmd parameter is not empty, a:destcmd is executed
" before the output is put into the buffer. This can be used to open a
" new window, new tab, etc., before :put'ing the output into the
" destination buffer.
"
" Examples:
"
"   " Insert the output of :registers into the current buffer.
"   call RedirMessages('registers', '')
"
"   " Output :registers into the buffer of a new window.
"   call RedirMessages('registers', 'new')
"
"   " Output :registers into a new vertically-split window.
"   call RedirMessages('registers', 'vnew')
"
"   " Output :registers to a new tab.
"   call RedirMessages('registers', 'tabnew')
"
" Commands for common cases are defined immediately after the
" function; see below.
"
    " Redirect messages to a variable.
    "
    redir => message

    " Execute the specified Ex command, capturing any messages
    " that it generates into the message variable.
    "
    silent execute a:msgcmd

    " Turn off redirection.
    "
    redir END

    " If a destination-generating command was specified, execute it to
    " open the destination. (This is usually something like :tabnew or
    " :new, but can be any Ex command.)
    "
    " If no command is provided, output will be placed in the current
    " buffer.
    "
    if strlen(a:destcmd) " destcmd is not an empty string
        silent execute a:destcmd
    endif

    " Place the messages in the destination buffer.
    "
    silent put=message

endfunction

" Create commands to make RedirMessages() easier to use interactively.
" Here are some examples of their use:
"
"   :BufMessage registers
"   :WinMessage ls
"   :TabMessage echo "Key mappings for Control+A:" | map <C-A>
"
command! -nargs=+ -complete=command BufMessage call RedirMessages(<q-args>, ''       )
command! -nargs=+ -complete=command WinMessage call RedirMessages(<q-args>, 'new'    )
command! -nargs=+ -complete=command TabMessage call RedirMessages(<q-args>, 'tabnew' )

" end redir_messages.vim
person Bill Odom    schedule 04.04.2010
comment
Отлично, я не знал, что ты можешь просто :put =var. - person intuited; 12.04.2010
comment
хорошо, я использовал это, чтобы вывести txt-файл с моими сопоставлениями клавиш для справки, но просто переключил его на: redir => m | silent map | redir END | put=m - person Alex Moore-Niemi; 25.04.2015
comment
Я абсолютно угнал это в свою собственную конфигурацию vim. (Конечно, с указанием авторства, чтобы я не подумал, что это написал я.) Спасибо! - person Jon Carter; 26.10.2015
comment
Действительно очень полезно, и именно то, что я искал. - Лично я не хочу, чтобы он продолжал спрашивать, хочу ли я потерять несохраненные изменения, когда я снова закрою окно или вкладку, я не буду сохранять результаты, поэтому я добавил закомментированную альтернативную версию беззвучного выполнения a:destcmd в приведенный выше код дает этот вариант - person lessthanideal; 17.02.2016
comment
В любви, и НАСТОЛЬКО большая часть моей ярости сейчас ослабла. Это тоже попало в мои файлы vimfiles! (Конечно, с соответствующими кредитами, как сказал @JonCarter.) ???? - person Cometsong; 12.04.2018

:redir @a
:registers
:redir END
"ap

:redir @a перенаправляет все сообщения отсюда в регистр с именем a. Вы следуете за этим с помощью своей команды, вывод которой вы хотите захватить (:registers в вашем случае). :redir END завершает перенаправление. "ap означает, что "a использует регистр с именем a, а p помещает содержимое выбранного регистра в текущий буфер.

Дополнительную информацию см. в разделе Захват выходных данных команды ex на вики Vim Tips. :-)

person Ashwin Nanjappa    schedule 26.11.2010
comment
Это короче и более прямолинейно, чем принятый ответ. Если нет обильного вывода, который вы хотите сохранить в файле, это лучшее решение. - person NeilG; 12.02.2020
comment
Из связанного совета Vim, если ваша команда ex на самом деле является внешней (оболочкой) командой, вы можете просто :read !<shell command> и направить вывод прямо в буфер. - person NeilG; 16.07.2021


Кроме того, :h :redir:

...Чтобы получить вывод одной команды, |execute()| можно использовать функцию.

e.g.

put = execute('scriptnames')
put = execute('filter /vimfiles/ scriptnames')
person Francis Niu    schedule 05.09.2016

К сожалению, у меня нет представителя, поэтому я не могу добавить это в качестве комментария к «Фрэнсис Ниу».

Функция execute() кажется самым простым способом сделать это, и она была добавлена ​​в vim 8.

Перечислены в новых/расширенных функциях на github vim. version8.txt

person Erik Olson    schedule 08.11.2016