Skip to content

feat(merlin): allow multiple configurations per file - #15493

Open
anmonteiro wants to merge 1 commit into
ocaml:mainfrom
anmonteiro:anmonteiro/refactor-merlin-groups
Open

feat(merlin): allow multiple configurations per file#15493
anmonteiro wants to merge 1 commit into
ocaml:mainfrom
anmonteiro:anmonteiro/refactor-merlin-groups

Conversation

@anmonteiro

@anmonteiro anmonteiro commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

breaks out just the config part from #14821

@anmonteiro anmonteiro added merlin Merlin editor support and its interface with dune single-context-universal labels Jul 13, 2026
@rgrinberg

Copy link
Copy Markdown
Member

How is this going to work on the merlin side? The client is going to flip between the two configs?

@anmonteiro

Copy link
Copy Markdown
Collaborator Author

My plan was to add a new protocol directive in Merlin to query the multiple configurations per file, so that we could flip between each at will / select a default.

I've got a working prototype which seems to work well, and I'm curious about your take?

@rgrinberg

Copy link
Copy Markdown
Member

I find it hard it to imagine needing to switch the configs outside of some #ifdef. Inside of some #ifdef, I'd hope/expect the config to be switched automatically for me. For things like auto-completion, I'd expect merlin to return an intersection of common results for me so that i can't accidentally introduce non-portable code. None of these things are relevant to this PR though. Just wondering what the end result is going to look like.

@anmonteiro

Copy link
Copy Markdown
Collaborator Author

@rgrinberg this is more relevant to the case of single context universal libraries. Let me illustrate it with an example:

(library
 (name foo)
 (libraries promise)
 (melange.libraries promise.js))

In the case above, assuming both libraries expose a top-level Promise module, X may use Promise.all, Promise.x, etc.

When the editor is in OCaml mode, go-to-definition should find the OCaml library; conversely, in Melange mode, it should jump to the promise.js source.

@rgrinberg

Copy link
Copy Markdown
Member

For goto definition, the lsp protocol is allowed to return more than one result. So I would expect it to just return both locations to and allow the user to choose. So it should still not be necessary to switch between modes.

@anmonteiro

Copy link
Copy Markdown
Collaborator Author

what about type definitions, etc? i think my point is that, with single context, there can essentially be 2 very distinct libraries with the same name, different preprocessing, different library dependencies, etc.

I'm not tied to this specific approach, but I couldn't think of a way to express all of that (incl. pps) in a way that finds the "common" diagnostics. What am I missing?

@rgrinberg

Copy link
Copy Markdown
Member

Type definitions are allowed to return more than on result as well. It is true that the underlying libraries can be entirely different, but I'm arguing that a user should see a unified front:

  1. The user is editing the "portable" part of the library. In which case he should only see suggestions that are the lowest common denominator that is available to both backends (or some sort of greying out of unavailable identifiers?). Queries like go-to definition etc should go through both backends and be normalized, deduplicated, and presented to the user. The user should select the backend once he is presented with options.

  2. The user is editing the "non portable" part of the library. In which case, there should be transparent selection to the appropriate backend.

  3. For things like diagnostics, I would expect to always see the diagnostics for both backends. Some effort to de-duplicate them (either in the editor, or directly in lsp) would be appreciated as well.

To summarize, there's not too many explicit backend selection opportunities for the user in such a workflow. There's still plenty going on under the hood automatically, but it's not a flag that the user has to toggle all the time.

@anmonteiro

Copy link
Copy Markdown
Collaborator Author

Interesting -- I'll take this away and think about it.

  1. It sounds like there may be a path forward without generating 2 configurations for Merlin?
  2. I'm not too familiar on what information we'd have to expose in the .merlin-conf files in this case for the Merlin protocol to get e.g. 2 results for go-to-definition, 2 results for type definitions, etc.

Maybe I'm mixing things up -- what responsibilities should Dune have in this case? e.g. How do I express that 2 different PPX generate different code according to the compilation mode?

@rgrinberg

Copy link
Copy Markdown
Member

As I mentioned, my comments aren't directly relevant to this PR. Something similar to what is done here is needed regardless of what is presented to the user.

My comments are more relevant to the protocol lsp and Merlin use to talk to dune, and how well equipped are Merlin and Lsp themselves to handle such a multi modal setup.

@anmonteiro

Copy link
Copy Markdown
Collaborator Author

OK sorry, I think I just misunderstood a lot of what you were saying.

Let me try again:

  1. It sounds like this PR, or a version of it, may be needed so that we can inform Merlin / LSP of the different artifacts in each compilation mode
  2. The end user experience I was thinking about -- switching between a few modes, might not provide the best experience, and your suggestion is that returning multiple results / deduplicating correctly will be way better.

@anmonteiro
anmonteiro force-pushed the anmonteiro/refactor-merlin-groups branch from 8a825df to 863ea62 Compare July 15, 2026 04:26
anmonteiro added a commit that referenced this pull request Jul 19, 2026
Adds expected-failure cram coverage for mode-specific Merlin lookup and
missing Melange configurations in mixed-mode libraries.

Related to #15493.

Signed-off-by: Antonio Nuno Monteiro <anmonteiro@gmail.com>
Signed-off-by: Antonio Nuno Monteiro <anmonteiro@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merlin Merlin editor support and its interface with dune single-context-universal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants