Как перенаправить вывод команды ex в текущий буфер или файл? - PullRequest
42 голосов
/ 04 апреля 2010

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

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

Ответы [ 6 ]

35 голосов
/ 04 апреля 2010
:redir >name_of_registers_file
:registers
:redir END
:r name_of_registers_file
:help redir

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

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

PS AFAIK (что довольно далеко в данном случае), нет способа прочитать его непосредственно в буфер: сначала нужно сохранить его в регистре или переменной. Обратитесь к справке за информацией о том, как это сделать.

PPS Если вы хотите сделать это, используя переменную - возможно, инкапсулирующую ее в функцию и избегающую засорения регистров или глобальных переменных - вам придется преобразовать многострочную строку, которая записывается в Переменная в список. EG

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

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

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


PPPS

Я написал фрагмент , чтобы сделать этот материал более удобным. Он объявляет функцию 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.

26 голосов
/ 04 апреля 2010

@ интуитивно верно; команда 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
17 голосов
/ 26 ноября 2010
:redir @a
:registers
:redir END
"ap

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

См. Вывод команды Capture ex в Vim Tips Wiki для получения дополнительной информации: -)

4 голосов
/ 05 сентября 2016

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

... Для получения выходных данных одной команды | execute () | можно использовать функцию.

, например

put = execute('scriptnames')
put = execute('filter /vimfiles/ scriptnames')
4 голосов
/ 04 февраля 2015

Нет необходимости использовать временную переменную, если вы можете сохранить текущий буфер и можете добавлять сообщения в конец текущего файла.

Из документации Vim:

:redi[r] >> {file}      Redirect messages to file {file}.  Append if {file}
                        already exists.  {not in Vi}

http://vimdoc.sourceforge.net/htmldoc/various.html#:redir

Итак, чтобы добавить сообщения из :registers в конец текущего файла, сделайте следующее:

:write | redir >> % | silent registers | redir END | edit
  1. :write файл, чтобы любые изменения не были потеряны
  2. Начните перенаправлять вывод в %, имя текущего файла.
  3. Выполнить команду :registers в режиме без вывода сообщений.
  4. END перенаправление в файл.
  5. :edit файл для просмотра новых изменений.

Вы также можете принудительно обрезать текущий файл и заменить его выходными сообщениями:

:redir! > % | silent registers | redir END | edit!

Но это, вероятно, не то, что вы хотите сделать.

3 голосов
/ 08 ноября 2016

К сожалению, у меня нет представителя, поэтому я не могу добавить это как комментарий к 'Francis Niu'.

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

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

...