Skip to content

Commit

Permalink
context: improve cursor position detection
Browse files Browse the repository at this point in the history
  • Loading branch information
voodoos committed May 2, 2024
1 parent ab56eea commit 9f8cbf4
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ merlin NEXT_VERSION
fixes #1661)
- Ignore SIGPIPE in the Merlin server process (#1746)
- Fix lexing of quoted strings in comments (#1754, fixes #1753)
- Improve cursor position detection in longidents (#1756)

merlin 4.14
===========
Expand Down
14 changes: 12 additions & 2 deletions src/analysis/context.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,17 @@ let cursor_on_longident_end
match lid with
| Longident.Lident _ -> true
| _ ->
let end_offset = loc.loc_end.pos_cnum in
let cstr_name_size = String.length name in
let end_offset =
loc.loc_end.pos_cnum in
let cstr_name_size =
(* FIXME: this is britle, but lids don't have precise enough location
information to handle these cases correctly. *)
let name_lenght = String.length name in
if Pprintast.needs_parens name then
name_lenght + 2
else
name_lenght
in
let constr_pos =
{ loc.loc_end
with pos_cnum = end_offset - cstr_name_size }
Expand Down Expand Up @@ -107,6 +116,7 @@ let inspect_expression ~cursor ~lid e : t =
else Module_path
| Texp_ident (p, lid_loc, _) ->
let name = Path.last p in
log ~title:"inspect_context" "name is: [%s]" name;
if name = "*type-error*" then
(* For type_enclosing: it is enough to return Module_path here.
- If the cursor was on the end of the lid typing should fail anyway
Expand Down
1 change: 1 addition & 0 deletions src/ocaml/parsing/pprintast.mli
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ val tyvar: Format.formatter -> string -> unit
(* merlin *)
val case_list : Format.formatter -> Parsetree.case list -> unit
val protect_ident : Format.formatter -> string -> unit
val needs_parens : string -> bool
32 changes: 25 additions & 7 deletions tests/test-dirs/type-enclosing/need-parens.t
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
FIXME: locate on `M.(|+)` should work:
Locate on `M.(|+)` should work:
$ $MERLIN single locate -position 2:11 -filename test.ml <<'EOF' | \
> jq '.value'
> module M = struct let (+) a b = a + b end
> let _ = M.(+)
> EOF
"Not in environment 'M.+'"
{
"file": "test.ml",
"pos": {
"line": 1,
"col": 22
}
}

Locate on `M.(+|)` should work:
$ $MERLIN single locate -position 2:12 -filename test.ml <<'EOF' | \
Expand All @@ -21,7 +27,7 @@ Locate on `M.(+|)` should work:
}

And need spaces:
FIXME: locate on `M.(| * )` should work:
Locate on `M.(| * )` should work:
$ $MERLIN single locate -position 2:11 -filename test.ml <<'EOF' | \
> jq '.value'
> module M = struct let ( * ) a b = a + b end
Expand All @@ -36,19 +42,31 @@ FIXME: locate on `M.(| * )` should work:
}

And need spaces:
FIXME: locate on `M.( |* )` should work:
Locate on `M.( |* )` should work:
$ $MERLIN single locate -position 2:12 -filename test.ml <<'EOF' | \
> jq '.value'
> module M = struct let ( * ) a b = a + b end
> let _ = M.( * )
> EOF
"Not in environment 'M.*'"
{
"file": "test.ml",
"pos": {
"line": 1,
"col": 22
}
}

And need spaces:
FIXME: locate on `M.( *| )` should work:
Locate on `M.( *| )` should work:
$ $MERLIN single locate -position 2:13 -filename test.ml <<'EOF' | \
> jq '.value'
> module M = struct let ( * ) a b = a + b end
> let _ = M.( * )
> EOF
"Not in environment 'M.*'"
{
"file": "test.ml",
"pos": {
"line": 1,
"col": 22
}
}

0 comments on commit 9f8cbf4

Please sign in to comment.