如何将 ex 命令输出重定向到当前缓冲区或文件?

发布于 2024-08-27 06:13:26 字数 109 浏览 9 评论 0原文

如何将 ex 命令的输出重定向或通过管道传输到当前缓冲区或文件中?

例如,我想将所有寄存器的内容读入当前缓冲区,在 ex 模式下使用 :registers 显示。

How can I redirect or pipe the output of an ex command into my current buffer or a file?

For example, I want to read the contents of all the registers into the current buffer, which in ex mode is shown using :registers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

感情洁癖 2024-09-03 06:13:26
: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 用来表示字符串变量中的换行符的方式。

编辑:正如 @Bill Odom 提到的,使用 :put =variable_you_redirected_to 比复杂的 append() 表达式容易得多。谢谢,比尔!


PPPS

我写了一个 snippet 来让这些东西更方便。它声明了一个函数 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 中的文件中。

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

The last command is very useful, since there are lots of options for redirection: to variables, to registers, how to append, further cornucopia.

I still find it weird and annoying that it uses END that way, but since everything else that can follow redir has to start with a non-word-character, at least it's not ambiguous.

PS AFAIK (which is pretty far in this case) there's no way to read it directly into the buffer: you have to store it in a register or a variable first. Check the help for the various options of how to do that.

PPS If you do want to do this using a variable —maybe to encapsulate it in a function and avoid clobbering registers or global variables— you'll have to convert the multiline string that gets written to the variable into a list. EG

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

Otherwise (if you just do append('.',var)) you end up with ^@'s (nulls) instead of newlines, since that's what vimscript uses to represent newlines in String variables.

edit: as @Bill Odom mentions, using :put =variable_you_redirected_to is a lot easier than the complicated append() expression. Thanks, Bill!


PPPS

I've written a snippet to make this stuff more convenient. It declares a function Redir(command, target) and a command R.

The command parses the last series of non-space characters as a redirection target and passes that to the function, which does the boilerplate to redirect the command output to the redirection target.

The command is everything after R and before the last space.

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() @">

There are a few limitations with this: for example you won't be able to write to a filename that contains a space. The upside to this is that you don't have to quote your command. I've got it posted on gist.github.com, and I'll try to keep it updated if I end up improving it. Or you can fork it yourself</noeuphemism>!

Anyway the snippet is available here. It can be dropped into a .vimrc file or into a file in ~/.vim/plugins.

凶凌 2024-09-03 06:13:26

@直觉是对的; 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

@intuited is right; the redir command is what you want. A one-liner like this will insert the output of :registers into the current buffer:

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

That's not something you'll want to type very often, however, and it's not exactly amenable to a key map. I found myself doing this fairly often, so I wrote a function and a handful of commands to make it easier. As a bonus, I can now send command output to a new window or new tab as easily as inserting it into the current buffer. Here's the code (with a few command examples at the very end):

" 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
爱给你人给你 2024-09-03 06:13:26
:redir @a
:registers
:redir END
"ap

:redir @a 将所有消息从此处重定向到名为a寄存器。您可以使用要捕获其输出的命令(在您的情况下是 :registers )。 :redir END 结束重定向。 "ap 表示,"a 使用名为 a 的寄存器,p 将所选寄存器的内容放入当前缓冲区。

有关详细信息,请参阅 Vim Tips Wiki 中的捕获 ex 命令输出 :-)

:redir @a
:registers
:redir END
"ap

:redir @a redirects all messages from here on to a register named a. You follow this with your command whose output you want to capture (:registers in your case). :redir END ends the redirection. "ap means, "a uses the register named a and p puts the contents of the selected register into the current buffer.

See Capture ex command output at Vim Tips Wiki for more information :-)

无风消散 2024-09-03 06:13:26

另外,:h :redir

...要获取一个命令的输出 |execute()|可以使用函数。

例如

put = execute('scriptnames')
put = execute('filter /vimfiles/ scriptnames')

In addition, :h :redir:

...To get the output of one command the |execute()| function can be used.

e.g.

put = execute('scriptnames')
put = execute('filter /vimfiles/ scriptnames')
作妖 2024-09-03 06:13:26

没有必要使用临时变量,只要您可以保存当前缓冲区并且可以将消息附加到当前文件的末尾即可。

来自 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!

但这可能不是您想要做的。

It is not necessary to use a temporary variable as long as you can save the current buffer and are ok with appending the messages to the end of the current file.

From the Vim documentation:

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

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

So, to append the messages from :registers to the bottom of the current file, do this:

:write | redir >> % | silent registers | redir END | edit
  1. :write the file so that any changes won't be lost
  2. Begin redirecting output to %, the name of the current file.
  3. Silently run the :registers command.
  4. END redirecting to the file.
  5. :edit the file to see the new changes.

You can also forcefully truncate the current file and replace it with the output messages:

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

But that is probably not what you want to do.

楠木可依 2024-09-03 06:13:26

不幸的是我没有代表,所以我不能将其添加为“Francis Niu”的评论。

execute() 函数看起来是完成此操作的最简单方法,它是在 vim 8 中添加的。

列在 vim 的 github 上的新/扩展功能中。 version8.txt

Unfortunately I have no rep, so I cannot add this as a comment to 'Francis Niu'.

The execute() function looks like the easiest way to accomplish this, and it was added in vim 8 .

Listed in the new/extended features on vim's github. version8.txt

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文