Closed mnxn closed 4 years ago
I don't know a good solution.
Dune autogenerated merlin files won't work, because they don't include dependencies, that are added in such a custom way.
In emacs you can activate it manually later via M-x merlin-use ⏎ ppx_cstubs.merlin
. But your editor might not provide such an option.
Now I understand that PKG ppx_cstubs.merlin
needs to be in the .merlin
for it to work. I can add it manually, but the obvious problem is that it will be overwritten when dune regenerates the .merlin
file.
I will ask around to see what can be done to generate the PKG directive.
What does ppx_cstubs.merlin
actually do? If there's a need for a library to provide some information to merlin perhaps we should try and think of a good way to do that. I don't mind adding support on the dune side.
My understanding is that this library has two code generators with the following differences:
ppx_cstubs
generates the Ctypes OCaml code that will make the C stubs, but it does not provide useful editor information.
ocamlfind printppx ppx_cstubs
returns nothing
ppx_cstubs.merlin
"produces a correctly typed syntax tree" that provides editor information, but the generated OCaml code can't be used.
ocamlfind printppx ppx_cstubs.merlin
returns -ppx "ppx_cstubs --as-ppx"
The dune example doesn't use the preprocess
field for generation with ppx_cstubs
: https://github.com/fdopen/ppx_cstubs/blob/master/examples/dune-project/src/lib/dune
I tried adding the ppx_cstubs.merlin
ppx flags to the library with (flags -ppx "ppx_cstubs --as-ppx")
, but then the problem is that the correct code from ppx_cstubs
is overwritten by the incorrect code from ppx_cstubs.merlin
and fails to build.
Dune somehow needs to make merlin aware of ppx_cstubs.merlin
without using ppx_cstubs.merlin
to actually generate code.
ppx_cstubs is far slower than an ordinary ppx extension, it creates two output files, and you have to pass many differents flags to it (CFLAGS, dependencies,...). Therefore I've made it an executable that is used like cppo.
ppx_cstubs.merlin
is never used for compiling, it's just there for merlin.
ppx_cstubs does among others:
1) extracts constants from a c files (constants, structs size and offsets, enums, etc.), that are used in 2) and 3). 2) creates a c file with stub code 3) creates an OCaml parse tree
ppx_cstubs.merlin
only does step 3). 2) is skipped and constants from 1) are replaced by dummy values in order to create a syntax tree for merlin. Step 1) would often be too slow for realtime feedback within editors.
If this step is required is for 3)
extracts constants from a c files (constants, structs size and offsets, enums, etc.), that are used in 2) and 3).
Then how can you omit it for 3) in ppx_cstubs.merlin?
Note that if you want your ppx rewriter to behave differently when called from merlin, you can match on the tool_name
parameter. In ppxlib, it's exposed via Ppxlib.Expansion_context.XXX.omp_config
(or simply Ppxlib.Expansion_context.XXX.tool_name` in the latest version of ppxlib).
Then how can you omit it for 3) in ppx_cstubs.merlin?
Dummy values that are semantically wrong, but syntactically correct and produce a properly typed parse tree - enough for merlin.
Note that if you want your ppx rewriter to behave differently when called from merlin, you can match on the
tool_name
parameter.
Thanks for this hint, I didn't know that merlin sets this value. This way it seems feasible.
@mnxn
You can try the next branch with an updated ppx_cstubs.merlin
sub-package.
It can now be added as an additional preprocessing step. See: https://github.com/fdopen/ppx_cstubs/blob/92e66506c9e2222aa6dfa7a45d16124face6ff6f/examples/dune-project/src/lib/dune#L24 When it is called outside merlin, it will just check, if the real preprocessor has been called in an earlier step. When merlin calls it, it will do the dummy preprocessing.
I've tested it under Emacs and with VSCode (and https://marketplace.visualstudio.com/items?itemName=freebroccolo.reasonml ) It seems to work out of the box, once the '.merlin' file was generated by dune.
Works wonderfully with https://github.com/ocamllabs/vscode-ocaml-platform, thank you.
I set up my dune project similar to the example and got the stub generation working well. However, there is minimal editor support when editing the file.
It's not very clear to me how I should be using
ppx_cstubs.merlin
as neither the readme nor user guide provide an example.It would be helpful to have some instructions on how to use
ppx_cstubs.merlin
Thanks.