ocaml / merlin

Context sensitive completion for OCaml in Vim and Emacs
https://ocaml.github.io/merlin/
MIT License
1.57k stars 235 forks source link

Merlin emacs mode does not support project-wide occurrences #1740

Open voodoos opened 5 months ago

voodoos commented 5 months ago

With the support for project wide occurrences approaching, we need to update Merlin clients.

Some attempts was made to update the emacs mode that are buggy right now: it breaks the standard local occurrences queries, doesn't always show the name of the file and sometimes returns error (when the list is too big ?).

Working on this requires an experimental setup with:

The current, fragile patch can be found here: https://github.com/voodoos/merlin/pull/9/commits/141fe8daa884f66a388e3dd48b91fc2a1f823759

voodoos commented 5 months ago

@xvw To tests your changes on a small scale you won't need the custom dune: you can build the index by hand and instruct Merlin to use it:

From the testsuite:

  $ cat >lib.ml <<'EOF'
  > let foo = "bar"
  > let () = print_string foo
  > EOF

  $ cat >main.ml <<'EOF'
  > let () = print_string Lib.foo
  > EOF

  $ ocamlc -bin-annot -bin-annot-occurrences -c lib.ml main.ml

  $ ocaml-index aggregate main.cmt lib.cmt
  $ ocaml-index dump project.ocaml-index
  2 uids:
  {uid: Stdlib.312; locs:
     "print_string": File "lib.ml", line 2, characters 9-21;
     "print_string": File "main.ml", line 1, characters 9-21
   uid: Lib.0; locs:
     "foo": File "lib.ml", line 1, characters 4-7;
     "foo": File "lib.ml", line 2, characters 22-25;
     "Lib.foo": File "main.ml", line 1, characters 22-29
   }, 0 approx shapes: {}, and shapes for CUS .

  $ $MERLIN single occurrences -scope project -identifier-at 1:28 \
  > -index-file project.ocaml-index \
  > -filename main.ml <main.ml
  {
    "class": "return",
    "value": [
      {
        "file": "$TESTCASE_ROOT/lib.ml",
        "start": {
          "line": 1,
          "col": 4
        },
        "end": {
          "line": 1,
          "col": 7
        }
      },
      {
        "file": "$TESTCASE_ROOT/lib.ml",
        "start": {
          "line": 2,
          "col": 22
        },
        "end": {
          "line": 2,
          "col": 25
        }
      },
      {
        "file": "$TESTCASE_ROOT/main.ml",
        "start": {
          "line": 1,
          "col": 26
        },
        "end": {
          "line": 1,
          "col": 29
        }
      }
    ],
    "notifications": []
  }
  1. Build the cmt files with indexes in them with OCaml 5.2 and the -bin-annot -bin-annot-occurrences flags.
  2. Gather the occurrences from all the cmts by running the indexer: ocaml-index aggregate -o the_index_file.index *.cmt
  3. Instruct Merlin to use that index via the emacs merlin-flags command: -index-file ./the_index_file.index or by using a .merlin file with the directive INDEX ./the_index_file.index.

These are still moving parts, if by mistake the latest versions of these tools don't work together you can follow the instructions here for a working 4.14-base version of the feature: https://discuss.ocaml.org/t/ann-preview-play-with-project-wide-occurrences-for-ocaml/13814

The emacs mode should work regardless :-)