VIM学习笔记 作业(job)

在传统的单线程模式下,运行外部命令时,将中断用户当前的编辑操作,并等待命令完成才可以返回vim。

自8.0版本起,包含+channel和+job特性的Vim将可以支持异步操作。Vim使用作业(job)来启动进程,并利用通道(channel)和其他进程通信。

利用异步支持,可以在后台进行复杂耗时的操作(比如使用外部grep工具查找文本),不必等待外部命令结束即可返回Vim,而不中断前台的正常编辑。在外部命令结束运行时,可以通过回调函数来处理输出结果。

job_start_version

例如使用:!ls外部命令,将在屏幕底部列示目录内容,并等待用户按回车键以返回常规模式,此时用户无法进行其它操作:

shell_cmd_ls

启动作业

使用job_start()函数,可以异步执行命令,其格式为:

job_start({command} [, {options}])

其中:command,用于指定需要运行的外部系统命令;options,是包含多个键值的字典选项,用于配置和控制作业的行为。

使用以下命令,可以启动作业以执行外部命令,并立刻返回常规模式,不影响用户的后续操作:

:call job_start('ls')

作业选项

作业采用管道(pipe)将外部命令与vim联接起来,并与标准输入(stdin)、标准输出(stdout)和标准错误(stderr)输出进行交互。

在使用job_start()函数启动作业时,可以注册一个或多个回调函数来处理特定的信息。如果希望静默执行命令,而不关心输出信息,那么也可以不注册任何回调函数。

使用"callback"选项,可以同时捕获标准输出与标准错误输出;也可以分别使用"out_cb"或"err_cb"选项,来单独捕获标准输出或标准错误输出。

首先定义用于捕获输出的回调函数:

func! MyHandler (channel, msg)
    echomsg a:msg
endfunc

通过"callback"选项,指定回调函数来处理stdout和stderr的内容:

let job = job_start ('ls', {"callback": "MyHandler"})

通过"out_cb"选项,指定回调函数来处理stdout的内容:

let job = job_start ('ls', {"out_cb": "MyHandler"})

通过"err_cb"选项,指定回调函数来处理stderr的内容:

let job = job_start ('ls', {"err_cb": "ErrHandler"})

在以上回调函数中使用了:echomsg命令,因此随后可以使用:message命令来查看信息历史,以确认命令执行结果:

job_start_ls_messages

使用"in_io"、"out_io"或"err_io"选项,可以将作业管道重定向到文件或缓冲区。

使用以下命令,可以将标准输出重定向至指定缓冲区:

:let job = job_start('ls', {'out_io': 'buffer', 'out_name': 'mybuffer'})

使用以下命令,则可以打开缓冲区查看输出信息:

:sbuf mybuffer

请注意,首行包含了“Reading from channel output...”的说明文字:

job_start_ls_out_io

使用以下任一命令,均可以将标准输出重定向至指定文件:

:let job = job_start('ls -al', {'out_io': 'file', 'out_name': '/tmp/file.txt'})

:call job_start(["/bin/sh", "-c", "ls -al > /tmp/file.txt"])

使用以下命令,可以查看作业选项的帮助信息:

:help job-options

作业状态

使用job_status()函数,可以返回指定作业的状态:

:echo job_status(job)

状态描述
run作业运行中
fail作业无法启动
dead作业启动后结束或被终止

使用job_info()函数,则可返回指定作业的详细信息:

:echo job_info(job)

job_info

函数将返回包含详细信息的字典:

描述
statusjob_status()返回值
cmd启动作业的命令行参数列表
stoponexitVim结束时给作业发信号(缺省是 "term")
channeljob_getchannel()返回值
process进程ID
tty_in终端输入名,如果没有则为空
tty_out终端输出名,如果没有则为空
exitval"status" 为 "dead" 时才有效
exit_cb退出时调用的函数
termsig终止程序的信号(仅用于Unix)
仅当"status"为"dead"时才有意义
tty_type使用的虚拟控制台类型(仅用于MS-Windows)
可选值是"winpty"或"conpty"

停止作业

使用job_stop()函数,可以停止指定的作业:

:call job_stop(job)

作业实例

实例1:启动Apache HTTP Server服务

:let job = job_start('apachectl start')

使用以下命令载入首页内容,以确认服务启动成功:

:silent r ! curl localhost

实例2:在位置列表中显示命令输出

function! s:on_find(chan, msg)
      lgetexpr split(a:msg, '')
endfunction

call job_start('find . -print0', {
      \ 'out_mode': 'raw',
      \ 'callback': function('<SID>on_find')
      \ })

使用以下命令,执行包含以上命令的脚本:

:so %

使用以下命令,将在位置列表(location list)中显示外部find命令输出的文件列表:

:lopen

job_start_out_mode_raw

使用以下命令,可以查看关于作业的帮助信息:

:help job

函数小结
job_start()启动作业
job_status()显示作业状态
job_info()显示作业的详细信息
job_stop()停止作业

Ver: 2.0 | YYQ<上一篇 | 目录 下一篇>