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

4.17 414 backport #1837

Merged
merged 24 commits into from
Sep 26, 2024
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3b91b41
[B] SOURCE_ROOT, UNIT_NAME and WRAPPING_PREFIX
voodoos Sep 25, 2024
b52d18d
[B] #1795: Fix #1794: Add `-unboxed-types` and `-no-unboxed-types` to…
voodoos Sep 25, 2024
c02a023
[B] #1804 vim: remove references to MerlinPhrase
voodoos Sep 25, 2024
140bb29
[B] #1806 Ignore new Menhir deprecations
voodoos Sep 25, 2024
d0b018d
[B] #1800 Refinement in the presence of optional arguments
voodoos Sep 25, 2024
1f57d7f
[B] #1807 Check always that default args are option
voodoos Sep 25, 2024
463eb71
[B] #1803 Fix ignorance of STDLIB in .merlin
voodoos Sep 25, 2024
2b01e1f
[B] #1745 Expand PPX nodes
voodoos Sep 25, 2024
e1ef844
[B] #1810 Produce a better error message when a flag spec appears mul…
voodoos Sep 25, 2024
d7968d6
[B] #1812 Inlay hint upstreaming
voodoos Sep 25, 2024
3b7f685
[B] #1814 Some UI improvement for `emacs/merlin-search`
voodoos Sep 25, 2024
198d6f5
[B] #1811 Exposes some helper for reducing direct typedtree usage in Lsp
voodoos Sep 25, 2024
db0b37e
[B] #1720 Signature Help
voodoos Sep 25, 2024
681c3c8
Compat with new occurrences api
voodoos Sep 25, 2024
83efbfa
Setup codebase formatting and fix a few comments.
voodoos Sep 25, 2024
e6786db
Format the codebase
voodoos Sep 25, 2024
c6fb925
Add commit to ignored revs
voodoos Sep 25, 2024
19e7220
[B] #1828 Search by type feature, a kind of sherlodoc in Merlin
voodoos Sep 25, 2024
c83e2e3
Promote fixed test after Dune upgrade
voodoos Sep 25, 2024
dc5e372
Silence ld warnings in tests
voodoos Sep 25, 2024
c04d859
Enable github CI
voodoos Sep 25, 2024
b82b038
[B] #1839 Fix ignorance of SOURCE_ROOT directive
voodoos Sep 25, 2024
98616bd
Make deps explicit
patrick-nicodemus Sep 25, 2024
315ccfa
[B] #1841 Document missing commands in PROTOCOL.md
voodoos Sep 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# git config blame.ignoreRevsFile .git-blame-ignore-revs
beb4b4c5ed38984534effc3cc8733db57820bc7b
12 changes: 9 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ name: CI
# events but only for the master branch
on:
push:
branches: [ master ]
branches: [ '414' ]
paths-ignore:
- '**.md'
- '**.txt'
@@ -16,7 +16,7 @@ on:
- 'vim/**'
- '**/emacs-lint.yml'
pull_request:
branches: [ master ]
branches: [ '414' ]
paths-ignore:
- '**.md'
- '**.txt'
@@ -38,7 +38,6 @@ jobs:
os:
- macos-latest
- ubuntu-latest
- windows-latest
ocaml-compiler:
- 4.14.x
# The type of runner that the job will run on
@@ -82,3 +81,10 @@ jobs:
opam exec -- dune clean
opam exec -- dune build
git diff --exit-code


- name: Check that the changes are correctly formatted
if: matrix.os == 'ubuntu-latest'
run: |
opam install ocamlformat.0.26.2
opam exec -- dune build @fmt
11 changes: 11 additions & 0 deletions .ocamlformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version=0.26.2
disable=false

break-cases=fit-or-vertical
doc-comments=before
cases-exp-indent=2
dock-collection-brackets=false
# Preserve begin/end
exp-grouping=preserve
module-item-spacing=preserve
parse-docstrings=false
1 change: 1 addition & 0 deletions .ocamlformat-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
upstream/**
15 changes: 15 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
unreleased
==========

+ merlin binary
- A new `WRAPPING_PREFIX` configuration directive that can be used to tell Merlin
what to append to the current unit name in the presence of wrapping (#1788)
- Add `-unboxed-types` and `-no-unboxed-types` as ocaml ignored flags (#1795, fixes #1794)
- destruct: Refinement in the presence of optional arguments (#1800 #1807, fixes #1770)
- Implement new expand-node command for expanding PPX annotations (#1745)
- Implement new inlay-hints command for adding hints on a sourcetree (#1812)
- Add `signature-help` command (#1720)
- Implement new search-by-type command for searching values by types (#1828)
+ editor modes
- vim: fix python-3.12 syntax warnings in merlin.py (#1798)
- vim: Dead code / doc removal for previously deleted MerlinPhrase command (#1804)
- emacs: Improve the way that result of polarity search is displayed (#1814)
- emacs: Add `merlin-search-by-type`, `merlin-search-by-polarity` and change the
behaviour of `merlin-search` to switch between `by-type` or `by-polarity`
depending on the query (#1828)

merlin 4.16
===========
161 changes: 154 additions & 7 deletions doc/dev/PROTOCOL.md
Original file line number Diff line number Diff line change
@@ -388,11 +388,13 @@ shape =

### `type-enclosing -position <position> [ -expression <string> ] [ -cursor <int> ] [verbosity <smart|int>] [ -index <int> ]`

-position <position> Position to complete
-expression <string> Expression to type
-cursor <int> Position of the cursor inside expression
-index <int> Only print type of <index>'th result
-verbosity <smart|int> Verbosity level
```
-position <position> Position to complete
-expression <string> Expression to type
-cursor <int> Position of the cursor inside expression
-index <int> Only print type of <index>'th result
-verbosity <smart|int> Verbosity level
```

Returns a list of type information for all expressions at given position, sorted by increasing size.
That is asking for type enlosing around `2` in `string_of_int 2` will return the types of `2 : int` and `string_of_int 2 : string`.
@@ -420,11 +422,156 @@ The result is returned as a list of:

### `type-expression -position <position> -expression <string>`

-position <position> Position to complete
-expression <string> Expression to type
```
-position <position> Position to complete
-expression <string> Expression to type
```

Returns the type of the expression when typechecked in the environment around the specified position.

### `search-by-polarity -position <position> -query <string>`

```
-position <position> Position to search
-query <string> The query
```

Returns a list (in the form of a completion list) of values matching the query. A query is defined by polarity (and does not support type parameters). Arguments are prefixed with `-` and the return type is prefixed with `+`. For example, to find a function that takes a string and returns an integer: `-string +int`. `-list +option` will returns every definition that take a list an option.

### `search-by-type -position <position> -query <string> -limit <int> -with-doc <bool>`

```
-position <position> Position to search
-query <string> The query
-limit <int> The maximum-size of the result set
-with-doc <bool> If true, values' documentation will be included in the result
```

Returns a list of values matching the query. A query is a type expression, ie: `string -> int option` will search every definition that take a string and returns an option of int. It is also possible to search by polarity.

The result is returned as a list of:
```javascript
{
'file': filename, // the file where the definition is defined
'start': position,
'end': position,
'name': string, // the name of the definition
'type': string, // the type of the definition
'cost': int, // the cost/distance of the definition and the query
'doc': string | null // the docstring of the definition
}
```

### `refactor-open -postion <position> -action <qualify|unqualify>`

```
-position <position> Position to refactor open
-action <qualify|unqualify> Direction of rewriting
```

Returns a list of `content` and `location` (the position referenced by the `location` must be replaced by the `content`).

The result is returned as a list of:

```javascript
{
'start': position, // the start of the region to be substituted
'end': position, // the end of the region to be substituted
'content' string // the content of the substitution
}
```

### `syntax-document -position <position>`

-position <position> The position of the keyword to be documented

Returns the string `No documentation found` (if the position does not refer to any keyword) or the following object:

```javascript
{
'name': string, // the name of the keyword under the position
'description': string, // the description of the keyword under the position
'url': string // a reference link in the OCaml manual
}
```

### `expand-ppx -position <position>`

-position <position> The position where to expand the ppx preprocessors

Returns the string `No PPX deriver/extension node found on this position` (if the position does not refer to any keyword) or the following object:

```javascript
{
'code': string, // the generated code by a ppx
'deriver': {
'start': position, // the start of the region expanded by the ppx
'end': position, // the end of the region expanded by the ppx
}
}
```

### `locate-type -position <position>`

-position <position> The position of the type to be located

Returns the location of the type at the given position.
If the type cannot be located (because the cursor is already at the right position, or because it is a referenced built-in type, or because the type cannot be found), the result is a string explaining why it cannot be located.
The type is defined in the same file, and the result will be the following object:

```javascript
{
'pos': {
'start': position, // the start of the region where the type is defined
'end': position // the end of the region where the type is defined
}
}
```

The type is described in another file, and the result will be the following object:

```javascript
{
'file': string, // the file where the type is defined
'pos': {
'start': position, // the start of the region where the type is defined
'end': position // the end of the region where the type is defined
}
}
```

### `signature-help -position <position>`

-position <position> The position where to request additional information for signature help

This command is essentially useful for an LSP server, as it can be used to return information additional to the completion of a function and its parameters.
If no help is found, the command returns an empty object, otherwise it returns a structured object with signatures and active parameters.
You can find more information here <https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_signatureHelp>

### `inlay-hints -start <position> -end <position> -let-binding <bool> -pattern-binding <bool> -avoid-ghost <bool>`

```
-start <position> the start of the region where to activate the inlay-hints
-end <position> the end of the region where to activate the inlay-hints
-let-binding <bool> activate for `let-bindings
-pattern-binding <bool> activate for `pattern-bindings
-avoid-ghost <bool> deactivate for node attached with a ghost location (mainly for tests)
```

This command is essentially useful for an LSP server, and returns the list of inlay hints for a given region in a list of the following object:

```javascript
{
'pos': {
'start': position, // the start of the region where the hint should be attached
'end': position // the end of the region where the hint should be attached
},
'label': string // the value fo the hint
}
```

You can find more information here <https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint_resolve>

### `check-configuration`


2 changes: 1 addition & 1 deletion dune-project
Original file line number Diff line number Diff line change
@@ -3,6 +3,6 @@
(using menhir 2.0)

(cram enable)
(formatting disabled)
(formatting (enabled_for ocaml))
(implicit_transitive_deps false)
(use_standard_c_and_cxx_flags true)
76 changes: 60 additions & 16 deletions emacs/merlin.el
Original file line number Diff line number Diff line change
@@ -1090,26 +1090,70 @@ An ocaml atom is any string containing [a-z_0-9A-Z`.]."
(cons (if bounds (car bounds) (point))
(point))))

;;;;;;;;;;;;;;;;;;;;;
;; POLARITY SEARCH ;;
;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;
;; SEARCH ;;
;;;;;;;;;;;;

(defun merlin--search (query)
(merlin-call "search-by-polarity"
"-query" query
"-position" (merlin-unmake-point (point))))
(merlin-call "search-by-type"
"-query" query
"-position" (merlin-unmake-point (point))))

(defun merlin--search-format-key (name type doc)
(let ((plain-name (string-remove-prefix "Stdlib__" name)))
(concat
(propertize plain-name 'face (intern "font-lock-function-name-face"))
" : "
(propertize type 'face (intern "font-lock-doc-face"))
" "
(propertize doc 'face (intern "font-lock-comment-face")))))

(defun merlin--get-documentation-line-from-entry (entry)
(let* ((doc-entry (cdr (assoc 'doc entry)))
(doc (if (eq doc-entry 'null) "" doc-entry))
(doc-lines (split-string doc "[\r\n]+")))
(car doc-lines)))

(defun merlin--search-entry-to-completion-entry (entry)
(let ((value-name (cdr (assoc 'name entry)))
(value-hole (cdr (assoc 'constructible entry)))
(value-type (cdr (assoc 'type entry)))
(value-docs (merlin--get-documentation-line-from-entry entry)))
(let ((key (merlin--search-format-key value-name value-type value-docs))
(value value-hole))
(cons key value))))

(defun merlin--search-select-completion-result (choices selected)
(alist-get selected choices nil nil #'equal))

(defun merlin--search-substitute-constructible (elt)
(progn
(when (region-active-p)
(delete-region (region-beginning) (region-end)))
(insert (concat "(" elt ")"))))

(defun merlin--search-completion-presort (choices)
(lambda (string pred action)
(if (eq action 'metadata)
'(metadata (display-sort-function . identity)
(cycle-sort-function . identity))
(complete-with-action action choices string pred))))

(defun merlin-search (query)
(interactive "sSearch pattern: ")
(let* ((result (merlin--search query))
(entries (cdr (assoc 'entries result)))
(transform
(lambda (entry)
(let ((text (merlin-completion-entry-text "" entry))
(desc (merlin-completion-entry-short-description entry)))
(vector (concat text " : " desc)
`(lambda () (insert ,text)))))))
(popup-menu (easy-menu-create-menu "Results" (mapcar transform entries)))))
"Search values by types or polarity"
(interactive "sSearch query: ")
(let* ((entries (merlin--search query))
(choices
(mapcar #'merlin--search-entry-to-completion-entry entries)))
(let ((constructible
(merlin--search-select-completion-result
choices
(completing-read (concat "Candidates: ")
(merlin--search-completion-presort choices)
nil nil nil t))))
(merlin--search-substitute-constructible constructible))))


;;;;;;;;;;;;;;;;;
;; TYPE BUFFER ;;
1 change: 1 addition & 0 deletions merlin-lib.opam
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ depends: [
"ocaml" {>= "4.14" & < "4.15"}
"dune" {>= "2.9.0"}
"csexp" {>= "1.5.1"}
"alcotest" {with-test}
"menhir" {dev & >= "20201216"}
"menhirLib" {dev & >= "20201216"}
"menhirSdk" {dev & >= "20201216"}
Loading