Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dune] Merlin's PPX invocations does not match Dune's #1292

Open
voodoos opened this issue Mar 25, 2021 · 9 comments
Open

[dune] Merlin's PPX invocations does not match Dune's #1292

voodoos opened this issue Mar 25, 2021 · 9 comments

Comments

@voodoos
Copy link
Collaborator

voodoos commented Mar 25, 2021

Context

Merlin associates with each ppx command line a workdir value which represents the directory in witch the ppx executable will be started by Merlin. This configuration value is not given to Merlin but inferred from the folder containing the configuration. That is, for .merlin based configuration, that folder was always the one containing the .merlin.

This was not a perfect solution as it does not reflect the true running folder of the ppxes when Dune builds a project, but it was a best effort solution which seems to work in most cases.

Issue

This best-effort broke when switching to the Dune-based configuration reader because Merlin considered the folder in which the external configuration reader is started to be the workdir. However, unlike dot-merlin-reader, the dune ocaml-merlin process starting folder might not be the one with the dune file.

The issue notably appears when using ppx_expect and was reported by @jeremiedimino. After investigating it turns out that ppx_expect should not attempt to compute the hash off the file when called by Merlin and Jérémie opened an issue.

Other ppxes that need to interact with files from the sources might be equally broken right now.

Food for thought

This issue is a good opportunity to make Merlin ppx behavior closer to Dune's in term of workdir and execution environment. However this need changes to both sides and might not happen immediately. This raises two questions:

  1. How can we have Merlin replicate more precisely the environnement and conditions of executions of ppxes by Dune ?
  2. Meanwhile, should we issue a quick fix to restore the previous, less-broken, behavior ?

For 1. Dune would need to forward more information to merlin, especially the workdir which appears to always be the root of the current context folder in _build. We also need Dune to provide the filename to use for locations.

For 2. the fix is ready but it is adding more noise to the codebase for use cases that may be illegitimate (for example ppx_expect should not do what it is doing when invoked in Merlin). However the patch does "solve" the current issue and could always be reverted when a cleaner approach is merged.

@voodoos
Copy link
Collaborator Author

voodoos commented Mar 25, 2021

cc @emillon @jeremiedimino

@ghost
Copy link

ghost commented Mar 25, 2021

The changes for 1 seems simple on the Dune side, and it seems fine to put them in a 2.8.5 release.

@voodoos
Copy link
Collaborator Author

voodoos commented Mar 26, 2021

They are indeed simple but they require changes on both sides. That means we should add a new conflict between dune and merlin.

If we don't merlin will report some "unknown configuration directive" to the user if dune attempts to pass more info.

I guess we don't want to add such constraints on a patch release like Dune 2.8.5 ?

@ghost
Copy link

ghost commented Mar 26, 2021

I guess we don't want to add such constraints on a patch release like Dune 2.8.5 ?

It depends. Is the protocol between Dune and merlin public/versioned at this point? Or do we still consider that it is in-development mode? If that's the later, adding such a constraint seems fine to me. The new information is not part of the public API, so we are not really adding a new feature.

BTW, both of the choices you proposed seems fine to me. I just wanted to point out that we could do 1 without too much ceremony, in case you don't want to add a hack in merlin.

@voodoos
Copy link
Collaborator Author

voodoos commented Mar 31, 2021

We finally decided to merge #1284 and restore the original behaviour.
We will work on a more robust solution in the future.

(As far as I'm aware there are no plans to make the merlin/dune protocol public yet)

voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:
      + improve prefixing of generated constructors in Destruct by filtering
        opened modules (ocaml/merlin#1277)
      + make the destruct command more resilient to ill-typed expressions and
        when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
    - introduce a new AST node for holes (`_`), allow correct typing of these
      holes and add a new `holes` command that returns the locations of all
      holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - Windows: system command variant: do not open a window console when
      launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
      between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
    - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
      navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
    - emacs: modernization of the elisp code and conformance with coding
      guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover constructor disambiguation and record fields (ocaml/merlin#1276)
    - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:
      + improve prefixing of generated constructors in Destruct by filtering
        opened modules (ocaml/merlin#1277)
      + make the destruct command more resilient to ill-typed expressions and
        when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
    - introduce a new AST node for holes (`_`), allow correct typing of these
      holes and add a new `holes` command that returns the locations of all
      holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - Windows: system command variant: do not open a window console when
      launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
      between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
    - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
      navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
    - emacs: modernization of the elisp code and conformance with coding
      guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover constructor disambiguation and record fields (ocaml/merlin#1276)
    - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:
      + improve prefixing of generated constructors in Destruct by filtering
        opened modules (ocaml/merlin#1277)
      + make the destruct command more resilient to ill-typed expressions and
        when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
    - introduce a new AST node for holes (`_`), allow correct typing of these
      holes and add a new `holes` command that returns the locations of all
      holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - Windows: system command variant: do not open a window console when
      launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
      between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
    - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
      navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
    - emacs: modernization of the elisp code and conformance with coding
      guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover constructor disambiguation and record fields (ocaml/merlin#1276)
    - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
    CHANGES:

    Tue Apr 12 11:44:22 AM CET 2021

      + merlin binary
        - external configuration reading:
          + use relative paths to communicate with Dune when possible. This solves
            issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
            fixes ocaml/merlin#1288)
          + make the `workdir` configuration value when using the
            `dune ocaml-merlin` configuration provider the same as when using
            `dot-merlin-reader` so that ppxes behaves in the same way as before
            (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
        - destruct:
          + improve prefixing of generated constructors in Destruct by filtering
            opened modules (ocaml/merlin#1277)
          + make the destruct command more resilient to ill-typed expressions and
            when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
        - reintroduce some record recovery and improve completion (ocaml/merlin#1276)
        - introduce a new AST node for holes (`_`), allow correct typing of these
          holes and add a new `holes` command that returns the locations of all
          holes in the current file along with their types (ocaml/merlin#1242, ocaml/merlin#1289)
        - Mppx: don't restore cookies after invocation. Ppx are invoked only once
          so there is no need to manage cookies. This small change should increase
          performance and should not change any other behavior (ocaml/merlin#1309)
        - Windows: system command variant: do not open a window console when
          launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
        - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
      + editor modes
        - vim: Add `MerlinNextHole` and `MerlinPreviousHole` commands to navigate
          between holes. Jump to the first hole after destruct (ocaml/merlin#1287, ocaml/merlin#1303)
        - emacs: Add `merlin-next-hole` and `merlin-previous-hole` commands to
          navigate holes. Jump to the first hole after calling destruct. (ocaml/merlin#1291)
        - emacs: modernization of the elisp code and conformance with coding
          guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
        - vim & emacs : new client-side "merlin use package" commands, restoring
          previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
      + test suite
        - cover constructor disambiguation and record fields (ocaml/merlin#1276)
        - cover the new `holes` command and AST node (ocaml/merlin#1242, ocaml/merlin#1289)
        - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
voodoos added a commit to voodoos/opam-repository that referenced this issue Apr 13, 2021
CHANGES:

Tue Apr 12 11:44:22 AM CET 2021

  + merlin binary
    - external configuration reading:
      + use relative paths to communicate with Dune when possible. This solves
        issues related to symlinks on Unix and improve Windows support (ocaml/merlin#1271,
        fixes ocaml/merlin#1288)
      + make the `workdir` configuration value when using the
        `dune ocaml-merlin` configuration provider the same as when using
        `dot-merlin-reader` so that ppxes behaves in the same way as before
        (ocaml/merlin#1284, fixes ocaml/dune#4479, discussion in ocaml/merlin#1292)
    - destruct:  make the destruct command more resilient to ill-typed
      expressions and when called without nodes (ocaml/merlin#1304, fixes ocaml/merlin#1300)
    - Mppx: don't restore cookies after invocation. Ppx are invoked only once
      so there is no need to manage cookies. This small change should increase
      performance and should not change any other behavior (ocaml/merlin#1309)
    - windows:
      + system command variant: do not open a window console when
        launching a ppx (ocaml/merlin#1270, fixes ocaml/merlin#714)
      + fix Emacs hanging when starting Merlin (ocaml/merlin#1263)
      + fix path canonicalization (ocaml/merlin#1254)
    - fix same file documentation bug (ocaml/merlin#1265 by @ulugbekna, fixes ocaml/merlin#1261)
  + editor modes
    - emacs:
      + modernization of the elisp code and conformance with coding
        guidelines (ocaml/merlin#1247, ocaml/merlin#1310 by Steve Purcell )
      + use opam var where applicable (ocaml/merlin#1310)
      + fix "wrong number of argument" (ocaml/merlin#1250 by @atharvashukla, fixes ocaml/merlin#1234)
      + fix for Neovim's CursorMoved semantics (ocaml/merlin#1213 by @ddickstein)
    - vim & emacs : new client-side "merlin use package" commands, restoring
      previous behavior (ocaml/merlin#1272, fixes ocaml/merlin#1191)
  + test suite
    - cover the document fix (ocaml/merlin#1265, ocaml/merlin#1315)
@voodoos
Copy link
Collaborator Author

voodoos commented Apr 13, 2021

Dune's PR ocaml/dune#4478 has a test that illustrates the fact that, as it expected, the current behaviour does not work when the ppx is defined in a subdir stanza.

@voodoos
Copy link
Collaborator Author

voodoos commented Apr 15, 2021

Related issue: #1114

@rgrinberg
Copy link
Member

Personally, I think it's time to address the versioning issue and for all. There's a couple of new motivators:

  1. We are looking to increase the sophistication of interaction between dune and merlin for a much better user experience.
  2. We have a real rpc protocol in dune with a principled versioning mechanism (thanks @cwong-ocaml). Let's just reuse that.

In practice, I think this would mean freezing the current implementation and redoing it on top of rpc.

@jeremiedimino that's indeed an issue with ppx_expect, but is there a mechanism for other ppx's to handle this correctly? I.e. can they detect they're running in merlin mode?

@ghost
Copy link

ghost commented Nov 1, 2021

@jeremiedimino that's indeed an issue with ppx_expect, but is there a mechanism for other ppx's to handle this correctly? I.e. can they detect they're running in merlin mode?

They can look at tool_name and check if it's "merlin". This is what ppx_expect does now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants