ocaml - 使用 Merlin 打印文件的模块签名

标签 ocaml bucklescript merlin

使用 Merlin 2.5.4,在我的项目中打印 OCaml 文件签名的正确方法是什么?例如,假设我有:

(* foo.ml *)
let x = 1

我想要得到:

val x : int

正确的命令(或命令序列)是什么?

我尝试过的:

我暂时将文件包装在子模块中:module Foo = struct let x = 1 end,然后运行:

$ ocamlmerlin
["type","expression","Foo","at",{"line":1,"col":7}]

但我得到:

["error",{"start":{"line":1,"col":0},"end":{"line":1,"col":3},"type":"type","sub":[],"valid":true,"message":"Error: Unbound constructor Foo"}]

这是有道理的,因为我实际上没有提到我正在查询哪个文件,查询 ( https://github.com/ocaml/merlin/blob/master/doc/dev/OLD-PROTOCOL.md#type-checking ) 也不允许我这样做。

E 我应该提到,我使用的是 BuckleScript,而不是 ocamlc,并且 ocamlc -i 仅在我指定的情况下才有效我的模块及其所有模块依赖项;我正在寻找能够自动管理这些依赖项的东西。

最佳答案

让 Merlin 输出模块的推断签名的一种方法是向其提供一系列命令(如其协议(protocol) https://github.com/ocaml/merlin/blob/master/doc/dev/OLD-PROTOCOL.md#type-checking 中所述),这些命令首先定义模块,然后请求其签名。我们可以准备一个包含这一系列命令的临时文件,并将其作为标准输入提供给 Merlin。

棘手的部分是:用正确的命令包装输入;在输入文件中转义双引号字符,这样它们就不会与 Merlin 的输入格式混合;并解开输出以放弃 Merlin 的协议(protocol)格式。以下是关键命令:

it=~/tmp/it

echo '["tell","start","end","module It = struct' >$it
sed 's/"/\\"/g' ${1%i} >>$it
echo ' end let () = ()"]' >>$it
echo '["type","expression","It","at","end"]' >>$it

ocamlmerlin <$it | sed -e '/^\["return",true\]$/d' -e 's/^\["return","sig *//' -e 's/ *end"\]$//' -e 's/\\"/"/g' -e 's/\\n/\
/g' | sed -e '/^ *$/d' -e 's/^  //'

注意事项:

  • 上面假设 Unix-y 系统具有 touchsed,并且命令路径中还有 ocamlmerlin
  • Merlin 不会在其输出中保留 OCaml 属性 ([@...])
  • 仅适用于 OCaml 语法,但可以适应 Reason 语法

更完整的脚本可以在 https://gist.github.com/yawaramin/b86557ae81cbd019fcb9e071abe594de 找到。 .

关于ocaml - 使用 Merlin 打印文件的模块签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900407/

相关文章:

vim - 在 vim 中获取 ocamlmerlin 自动完成功能

nullable - 处理 Js.Nullable 的正确方法是什么?

function - 试图理解 OCaml 中的这段代码

ocaml - ocaml定义函数 'a -> ' b

list - 将元组转换为列表的 Ocaml 函数

ocaml - 带有可选和可变字段的记录

string - 将字符串拆分为字符列表的最简单方法是什么?

emacs - Merlin 提示同一个项目中缺少一个模块

ocaml - 如何在 OCaml 中使用 #use 指令包含其他源文件?