Skip to content
This repository was archived by the owner on Apr 24, 2021. It is now read-only.

Commit 59d7a8b

Browse files
committed
Add support for autocomplete of labelled arguments.
Given a context `foo(... ~lab)`, parse backwards to find `foo`, get the type and list of labels, and complete from `lab`.
1 parent 3999139 commit 59d7a8b

File tree

6 files changed

+89
-14
lines changed

6 files changed

+89
-14
lines changed

Changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Fix type hint when hovering over labeled arguments of components (See https://github.com/rescript-lang/rescript-editor-support/issues/63).
66
- Fix issue where values declared with type annotation would not show up in autocomplete, and would show no doc comment on hover. (See https://github.com/rescript-lang/rescript-vscode/issues/72).
77
- Fix hover on definitions inside a react component module, or whenever multiple definitins for the same value exist in the module (See https://github.com/rescript-lang/rescript-editor-support/issues/67).
8+
- Add support for autocomplete of labelled arguments `foo(~label... )`.
89

910
## Release 1.0.5 of rescript-vscode
1011
This [commit](https://github.com/rescript-lang/rescript-editor-support/commit/6bdd10f6af259edc5f9cbe5b9df06836de3ab865) is vendored in [rescript-vscode 1.0.5](https://github.com/rescript-lang/rescript-vscode/releases/tag/1.0.5).

examples/example-project/src/ZZ.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,9 @@ module HoverInsideModuleWithComponent = {
105105
@react.component
106106
let make = () => React.null
107107
}
108+
109+
module Lib = {
110+
let foo = (~age, ~name) => name ++ string_of_int(age)
111+
let next = (~number=0, ~year) => number + year
112+
}
113+

src/rescript-editor-support/NewCompletions.re

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,9 +820,54 @@ let computeCompletions = (~full, ~maybeText, ~package, ~pos, ~state) => {
820820
|> List.filter(decorator => Utils.startsWith(decorator, prefix))
821821
|> List.map(mkDecorator);
822822

823-
| Some((_, _, Some(Clabel(_)))) =>
824-
// not supported yet
825-
[]
823+
| Some((text, offset, Some(Clabel(funPath, prefix)))) =>
824+
let rawOpens = PartialParser.findOpens(text, offset);
825+
let allModules =
826+
package.TopTypes.localModules @ package.dependencyModules;
827+
828+
let getItems = parts =>
829+
getItems(
830+
~full,
831+
~package,
832+
~rawOpens,
833+
~getModule=State.fileForModule(state, ~package),
834+
~allModules,
835+
~pos,
836+
~parts,
837+
);
838+
839+
let labels = {
840+
switch (getItems(funPath)) {
841+
| [(_uri, {SharedTypes.item: Value(typ)}), ..._] =>
842+
let rec getLabels = (t: Types.type_expr) =>
843+
switch (t.desc) {
844+
| Tlink(t1)
845+
| Tsubst(t1) => getLabels(t1)
846+
| Tarrow(Labelled(l) | Optional(l), tArg, tRet, _) => [
847+
(l, tArg),
848+
...getLabels(tRet),
849+
]
850+
| Tarrow(Nolabel, _, tRet, _) => getLabels(tRet)
851+
| _ => []
852+
};
853+
typ |> getLabels;
854+
| _ => []
855+
};
856+
};
857+
858+
let mkLabel = ((name, typ)) =>
859+
mkItem(
860+
~name,
861+
~kind=4,
862+
~detail=typ |> Shared.typeToString,
863+
~docstring=None,
864+
~uri=full.file.uri,
865+
~pos_lnum=fst(pos),
866+
);
867+
868+
labels
869+
|> List.filter(((name, _t)) => Utils.startsWith(name, prefix))
870+
|> List.map(mkLabel);
826871

827872
| Some((_, _, None)) => []
828873
};

src/rescript-editor-support/NotificationHandlers.re

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,6 @@ let getTextDocument = doc => {
99
Some((uri, text));
1010
};
1111

12-
let reloadAllState = state => {
13-
Log.log("RELOADING ALL STATE");
14-
{
15-
...TopTypes.empty(~rootUri=state.rootUri),
16-
documentText: state.documentText,
17-
};
18-
};
19-
2012
let notificationHandlers:
2113
list((string, (state, Json.t) => result(state, string))) = [
2214
(

src/rescript-editor-support/PartialParser.re

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,32 @@ let rec startOfLident = (text, i) =>
6464
};
6565
};
6666

67+
// foo(... ~arg) from ~arg find foo
68+
let findCallFromArgument = (text, offset) => {
69+
let rec loop = (~i, ~nClosed) =>
70+
if (i > 0) {
71+
switch (text.[i]) {
72+
| '(' when nClosed > 0 => loop(~i=i - 1, ~nClosed=nClosed - 1)
73+
74+
| '(' =>
75+
let i1 = skipWhite(text, i - 1);
76+
let i0 = startOfLident(text, i1);
77+
let funLident = String.sub(text, i0, i1 - i0 + 1);
78+
Str.split(Str.regexp_string("."), funLident);
79+
80+
| ')' => loop(~i=i - 1, ~nClosed=nClosed + 1)
81+
82+
| _ => loop(~i=i - 1, ~nClosed)
83+
};
84+
} else {
85+
[];
86+
};
87+
loop(~i=offset, ~nClosed=0);
88+
};
89+
6790
type completable =
6891
| Cdecorator(string)
69-
| Clabel(string)
92+
| Clabel(list(string), string)
7093
| Cpath(list(string))
7194
| Cpipe(string);
7295

@@ -92,7 +115,10 @@ let findCompletable = (text, offset) => {
92115
: (
93116
switch (text.[i]) {
94117
| '>' when i > 0 && text.[i - 1] == '-' => loop(i - 2)
95-
| '~' => Some(Clabel(String.sub(text, i + 1, offset - (i + 1))))
118+
| '~' =>
119+
let labelPrefix = String.sub(text, i + 1, offset - (i + 1));
120+
let funPath = findCallFromArgument(text, i - 1);
121+
Some(Clabel(funPath, labelPrefix));
96122
| '@' => Some(Cdecorator(String.sub(text, i + 1, offset - (i + 1))))
97123
| 'a'..'z'
98124
| 'A'..'Z'

src/rescript-editor-support/RescriptEditorSupport.re

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ let capabilities =
77
("hoverProvider", J.t),
88
(
99
"completionProvider",
10-
J.o([("triggerCharacters", J.l([J.s("."), J.s(">"), J.s("@")]))]),
10+
J.o([
11+
(
12+
"triggerCharacters",
13+
J.l([J.s("."), J.s(">"), J.s("@"), J.s("~")]),
14+
),
15+
]),
1116
),
1217
("definitionProvider", J.t),
1318
("typeDefinitionProvider", J.t),

0 commit comments

Comments
 (0)