:mzscheme :mz
:[range]mz[scheme] {stmt}
执行 MzScheme 语句 {stmt}。
:[range]mz[scheme] << [trim] [{endmarker}]
{script}
{endmarker}
执行内联的 MzScheme 脚本 {script}。
注意: 如果编译时没有加入 MzScheme 特性,此命令不能工
作。要避免错误,见 script-here 。
如果 "<<" 之后省略了 [endmarker],{script} 结束后必须
加上一个句号 '.',类似于 :append 和 :insert 命令。
详见 :let-heredoc 。
:mzfile :mzf
:[range]mzf[ile] {file} 执行 {file} 文件里的 MzScheme 脚本。
以上命令本质上在做同样一件事 - 执行一段 MzScheme 代码。并将 "当前范围" 设为给
定的行范围。
:mzscheme 执行的代码来自命令行。
:mzfile 执行的代码来自给定文件的内容。
MzScheme 接口定义从 exn 派生的 exn:vim 异常。若干 Vim 错误会抛出此异常。
编译时,MzScheme 接口会记住当前 MzScheme collection 路径。要指定额外路径,可用
"current-library-collection-paths" 参数,例如,要附加 (cons) 用户局部 MzScheme
collection 路径:
:mz << EOF
(current-library-collection-paths
(cons
(build-path (find-system-path 'addon-dir) (version) "collects")
(current-library-collection-paths)))
EOF
所有功能由 vimext 模块提供。
无需显式导入 (import) exn:vim。
为了避免和 MzScheme 冲突,require 模块时请考虑使用 prefix。例如:
:mzscheme (require (prefix vim- vimext))
以下例子都使用此命名方案。
mzscheme-sandbox
在沙盘 sandbox 里执行时,对一些文件系统和 Vim 接口过程的访问会受到限制。
:mzscheme (display "Hello")
:mz (display (string-append "使用 MzScheme 版本 " (version)))
:mzscheme (require (prefix vim- vimext)) ; 用于 MzScheme < 4.x
:mzscheme (require (prefix-in vim- 'vimext)) ; MzScheme 4.x
:mzscheme (vim-set-buff-line 10 "这是第 #10 行")
要查看正在运行的 MzScheme 版本:
:mzscheme (display (version))
内联脚本示例:
function! <SID>SetFirstLine()
:mz << EOF
(display "!!!")
(require (prefix vim- vimext))
; 更新的版本需用 (require (prefix-in vim- 'vimext))
(vim-set-buff-line 1 "这是第 #1 行")
(vim-beep)
EOF
endfunction
nmap <F9> :call <SID>SetFirstLine() <CR>
文件执行:
:mzfile supascript.scm
Vim 异常处理:
:mz << EOF
(require (prefix vim- vimext))
; 更新的版本需用 (require (prefix-in vim- 'vimext))
(with-handlers
([exn:vim? (lambda (e) (display (exn-message e)))])
(vim-eval "无意义字符串"))
EOF
自动实例化 vimext 模块 (可放入 vimrc ):
function! MzRequire()
:redir => l:mzversion
:mz (version)
:redir END
if strpart(l:mzversion, 1, 1) < "4"
" MzScheme 版本号 < 4.x:
:mz (require (prefix vim- vimext))
else
" 更新的版本:
:mz (require (prefix-in vim- 'vimext))
endif
endfunction
if has("mzscheme")
silent call MzRequire()
endif
MzScheme 接口提供线程支持。它们和操作系统的线程相互独立,因此有必要进行调度。
'mzquantum' 选项决定 Vim 轮询可用 MzScheme 线程的时间间隔。
备注
Vim 控制台版本在进行线程调度时,通常不如 GUI 版本可靠。
(command {command-string}) 执行 Vim ":Ex" 风格的命令。
(eval {expr-string}) 计算 vim 表达式,并将结果返回为对应的
MzScheme 对象: Vim 的 List 对应 Scheme
列表, Dictionary 对应哈希表, Funcref
对应函数 (另见 mzscheme-funcref )
注意 这和 MzScheme 自带的 eval 有冲突,可
以使用模块限定符来避免。
(range-start) 传递给 Scheme 命令的范围的开始行
(range-end) 和结束行。
(beep) 响铃
(get-option {option-name} [buffer-or-window])
获取 Vim 选项值 (局部或全局值,见
set-option )。
(set-option {string} [buffer-or-window])
设置 Vim 选项。字符串 {string} 必须为用于
设置 Vim 选项的命令形式 (optname=optval 或
optname+=optval 等)。给出 {buffer} 或
{window} 时,会设置相应的局部选项。在
{buffer-or-window} 的位置也可用符号
'global,此时会用 :setglobal 来设置全局
选项。
缓冲区 mzscheme-buffer
(buff? {object}) 对象是否为缓冲区?
(buff-valid? {object}) 对象是否为合法的缓冲区 (也就是,对应真正
Vim 缓冲区)?
(get-buff-line {linenr} [buffer])
获取缓冲区中的指定行。
(set-buff-line {linenr} {string} [buffer])
设置缓冲区中的指定行。{string} 为 #f 或
null 时,删除该行。 [buffer] 参数可选。省
略时默认使用当前缓冲区。
(get-buff-line-list {start} {end} [buffer])
获取缓冲区中的多行列表。{start} 和 {end}
从 1 开始计数,且为闭区间 (两者都包含)。
(set-buff-line-list {start} {end} {string-list} [buffer])
设置缓冲区的多行内容列表。{string-list} 为
#f 或 null 时,删除所选范围中的所有行。如
果列表长度小于 {end}-{start},不足部分对应
的行被删除。
(get-buff-name [buffer]) 获取缓冲区名。
(get-buff-num [buffer]) 获取缓冲区的编号。
(get-buff-size [buffer]) 获取缓冲区的总行数。
(insert-buff-line-list {linenr} {string/string-list} [buffer])
在缓冲区第 {linenr} 行之后插入多行内容列
表。{linenr} 为 0 时,从缓冲区开头插入。
(curr-buff) 获取当前缓冲区。可用 MzScheme 接口的其他过
程来修改该缓冲区。
(buff-count) 获取编辑器中缓冲区的总数。
(get-next-buff [buffer]) 获取下一个缓冲区。
(get-prev-buff [buffer]) 获取前一个缓冲区。如果没有更多缓冲区,返回
#f。
(open-buff {filename}) 打开新缓冲区 (并编辑指定文件名)。
(get-buff-by-name {buffername}) 根据文件名获取缓冲区,如果没有相应的缓冲
区,返回 #f。
(get-buff-by-num {buffernum}) 根据缓冲区号获取缓冲区,如果没有相应的缓冲
区,返回 #f。
窗口 mzscheme-window
(win? {object}) 对象是否为窗口?
(win-valid? {object}) 对象是否为合法的窗口 (也就是,对应真正 Vim
窗口)?
(curr-win) 获取当前窗口。
(win-count) 获取窗口总数。
(get-win-num [window]) 获取窗口的编号。
(get-win-by-num {windownum}) 根据窗口号获取窗口。
(get-win-buffer [window]) 获取窗口中包含的缓冲区。
(get-win-height [window]) 获取窗口高度。
(set-win-height {height} [window])
设置窗口高度。
(get-win-width [window]) 获取窗口宽度。
(set-win-width {width} [window])
设置窗口宽度。
(get-win-list [buffer]) 获取包含缓冲区的所有窗口的列表。
(get-cursor [window]) 获取窗口光标位置,以组对 (行号 . 列号) 形
式出现。
(set-cursor (line . col) [window])
设置光标位置。
Vim 中的 mzeval() 函数提供了反向接口,它用于计算 MzScheme 表达式,并将计算结
果返回给 Vim 脚本。
MzScheme 接口允许在 Schema 里使用 Funcref 直接调用 Vim 函数。例如:
function! MyAdd2(arg)
return a:arg + 2
endfunction
mz (define f2 (vim-eval "function(\"MyAdd2\")"))
mz (f2 7)
或 :
:mz (define indent (vim-eval "function('indent')"))
" 返回 Vim 第 12 行的缩进量
:mz (indent 12)
MS-Windows 上,可动态调入 MzScheme 库。此时 :version 输出会包含
+mzscheme/dyn 。
此时,Vim 仅在必要时才会寻找 MzScheme DLL 文件。不使用 MzScheme 接口时,就不需
要库文件。因此,即使没有这些 DLL 文件,仍然可以使用 Vim。
注意 较新版本的 MzScheme (Racket) 要求在较早的时间点通过 scheme_main_setup 进
行 (蹦床式的) 初始化。此时,Vim 在启动时总会载入 MzScheme DLL (只要可能)。但这
会减慢 Vim 启动速度。
要使用 MzScheme 接口,必须确保 MzScheme DLL 位于系统搜索路径中。可以在控制台窗
口里输入 "path",查看当前使用的搜索路径。
MS-Windows 上,可用 'mzschemadll' 和 'mzschemagcdll' 选项指定载入库名。选项初
始值在编译时提供。
DLL 的版本号必须匹配 Vim 编译时所使用的 MzScheme 版本。以 MzScheme 209 版本为
例,上述两选项的名字分别为 "libmzsch209_000.dll" 和 "libmzgc209_000.dll"。要查
看编译时使用的版本,可察看 ":version" 命令的输出中 "编译方式" 信息里的
-DDYNAMIC_MZSCH_DLL= "..." 和 -DDYNAMIC_MZGC_DLL="..." 部分的内容。
例如,假定 MzScheme (Racket) 安装在 C:\Racket63,可能需要设置以下的环境变量:
PATH=%PATH%;C:\Racket63\lib
PLTCOLLECTS=C:\Racket63\collects
PLTCONFIGDIR=C:\Racket63\etc
Vim 的 if_mzsch 核心部分需要 "racket/base" 模块 (如果不存在,"scheme/base" 作
为后备),测试需要 "r5rs" 模块,Vim 编译时则需要 "raco ctool" 命令。如果
MzScheme 没有提供这些模块,可以通过 MzScheme 的 raco 命令安装:
raco pkg install scheme-lib # scheme/base 模块
raco pkg install r5rs-lib # r5rs 模块
raco pkg install cext-lib # raco ctool 命令
vim:tw=78:ts=8:noet:sts=4:ft=help:norl: