diff --git a/Changes.md b/Changes.md
index fc18cbe2..2fc89758 100644
--- a/Changes.md
+++ b/Changes.md
@@ -3,6 +3,7 @@
- Don't show file path on hover.
- Add autocomplete for props in JSX components.
- Autocomplete: fix issue where `->` autocomplete was overruling `.`. See https://github.com/rescript-lang/rescript-editor-support/issues/99.
+- Add pipe autocomplete for builtin list, array, string, option types. And for string and array literals.
## Release 1.0.6 of rescript-vscode
This [commit](https://github.com/rescript-lang/rescript-editor-support/commit/03ee0d97b250474028d4fb08eac81ddb21ccb082) is vendored in [rescript-vscode 1.0.6](https://github.com/rescript-lang/rescript-vscode/releases/tag/1.0.6).
diff --git a/examples/example-project/src/ZZ.res b/examples/example-project/src/ZZ.res
index 6fd66fcb..6a3c9ddc 100644
--- a/examples/example-project/src/ZZ.res
+++ b/examples/example-project/src/ZZ.res
@@ -79,25 +79,25 @@ let testRecordFields = (gr: gr) => {
}
@ocaml.doc("vr docstring")
-type vr = | V1 | V2
+type vr = V1 | V2
let v1 = V1
module DoubleNested = ModuleWithDocComment.Nested.NestedAgain
-let uncurried = (. x) => x+1;
+let uncurried = (. x) => x + 1
module Inner = {
- type tInner = int;
+ type tInner = int
let vInner = 34
}
-type typeInner = Inner.tInner;
+type typeInner = Inner.tInner
-let valueInner = Inner.vInner;
+let valueInner = Inner.vInner
@ocaml.doc("Doc comment for functionWithTypeAnnotation")
-let functionWithTypeAnnotation : unit => int = () => 1
+let functionWithTypeAnnotation: unit => int = () => 1
module HoverInsideModuleWithComponent = {
let x = 2 // check that hover on x works
@@ -111,14 +111,12 @@ module Lib = {
let next = (~number=0, ~year) => number + year
}
-@ocaml.doc("This module is commented")
-@deprecated("This module is deprecated")
-module Dep : {
- @ocaml.doc("Some doc comment")
- @deprecated("Use customDouble instead")
- let customDouble : int => int
+@ocaml.doc("This module is commented") @deprecated("This module is deprecated")
+module Dep: {
+ @ocaml.doc("Some doc comment") @deprecated("Use customDouble instead")
+ let customDouble: int => int
- let customDouble2 : int => int
+ let customDouble2: int => int
} = {
let customDouble = foo => foo * 2
let customDouble2 = foo => foo * 2
@@ -129,8 +127,19 @@ let cc = Dep.customDouble(11)
module O = {
module Comp = {
@react.component
- let make = (~first="", ~kas=11, ~foo=3, ~second, ~v) => React.string(first ++ second ++ string_of_int(foo))
+ let make = (~first="", ~kas=11, ~foo=3, ~second, ~v) =>
+ React.string(first ++ second ++ string_of_int(foo))
}
}
-let comp =
\ No newline at end of file
+let comp =
+
+let lll = List.make(3, 4)
+
+let abc = "abc"
+
+let arr = [1, 2, 3]
+
+let some7 = Some(7)
+
+
diff --git a/src/NewCompletions.ml b/src/NewCompletions.ml
index 81b60e65..b1bda7d9 100644
--- a/src/NewCompletions.ml
+++ b/src/NewCompletions.ml
@@ -514,7 +514,11 @@ let processCompletable ~findItems ~full ~package ~pos ~rawOpens
->
mkItem ~name ~kind:(kindToInt item) ~deprecated
~detail:(detail name item) ~docstring ~uri ~pos_lnum)
- | Cpipe s -> (
+ | Cpipe (pipe, partialName) -> (
+ let arrayModulePath = ["Js"; "Array2"] in
+ let listModulePath = ["Belt"; "List"] in
+ let optionModulePath = ["Belt"; "Option"] in
+ let stringModulePath = ["Js"; "String2"] in
let getModulePath path =
let rec loop (path : Path.t) =
match path with
@@ -522,10 +526,15 @@ let processCompletable ~findItems ~full ~package ~pos ~rawOpens
| Pdot (p, s, _) -> s :: loop p
| Papply _ -> []
in
- match loop path with _ :: rest -> List.rev rest | [] -> []
+ match path with
+ | Path.Pident id when Ident.name id = "array" -> arrayModulePath
+ | Path.Pident id when Ident.name id = "list" -> listModulePath
+ | Path.Pident id when Ident.name id = "option" -> optionModulePath
+ | Path.Pident id when Ident.name id = "string" -> stringModulePath
+ | _ -> ( match loop path with _ :: rest -> List.rev rest | [] -> [])
in
- let getLhsPath ~lhs ~partialName =
- match [lhs] |> findItems ~exact:true with
+ let getLhsPath ~pipeId ~partialName =
+ match [pipeId] |> findItems ~exact:true with
| (_uri, {SharedTypes.item = Value t}) :: _ ->
let modulePath =
match t.desc with
@@ -537,12 +546,10 @@ let processCompletable ~findItems ~full ~package ~pos ~rawOpens
| _ -> None
in
let lhsPath =
- match Str.split (Str.regexp_string "->") s with
- | [lhs] -> getLhsPath ~lhs ~partialName:""
- | [lhs; partialName] -> getLhsPath ~lhs ~partialName
- | _ ->
- (* Only allow one -> *)
- None
+ match pipe with
+ | PipeId pipeId -> getLhsPath ~pipeId ~partialName
+ | PipeString -> Some (stringModulePath, partialName)
+ | PipeArray -> Some (arrayModulePath, partialName)
in
let removePackageOpens modulePath =
match modulePath with
diff --git a/src/PartialParser.ml b/src/PartialParser.ml
index 16a219a2..12144800 100644
--- a/src/PartialParser.ml
+++ b/src/PartialParser.ml
@@ -109,6 +109,8 @@ let findJsxContext text offset =
in
loop offset
+type pipe = PipeId of string | PipeArray | PipeString
+
type completable =
| Cdecorator of string (** e.g. @module *)
| Clabel of string list * string
@@ -116,7 +118,7 @@ type completable =
| Cpath of string list (** e.g. ["M", "foo"] for M.foo *)
| Cjsx of string list * string
(** E.g. (["M", "Comp"], "id") for foo" *)
+ | Cpipe of pipe * string (** E.g. ("x", "foo") for "x->foo" *)
let isLowercaseIdent id =
let rec loop i =
@@ -132,24 +134,35 @@ let isLowercaseIdent id =
let findCompletable text offset =
let mkPath s =
let len = String.length s in
- let pipeParts = Str.split (Str.regexp_string "->") s in
- if
- (len > 1 && s.[len - 2] = '-' && s.[len - 1] = '>')
- || List.length pipeParts > 1
- then Cpipe s
- else
- let parts = Str.split (Str.regexp_string ".") s in
- let parts =
- match s.[len - 1] = '.' with true -> parts @ [""] | false -> parts
- in
- match parts with
- | [id] when String.lowercase_ascii id = id -> (
- match findJsxContext text (offset - len - 1) with
- | None -> Cpath parts
- | Some componentName ->
- Cjsx (Str.split (Str.regexp_string ".") componentName, id))
- | _ -> Cpath parts
+ let parts = Str.split (Str.regexp_string ".") s in
+ let parts =
+ match s.[len - 1] = '.' with true -> parts @ [""] | false -> parts
+ in
+ match parts with
+ | [id] when String.lowercase_ascii id = id -> (
+ match findJsxContext text (offset - len - 1) with
+ | None -> Cpath parts
+ | Some componentName ->
+ Cjsx (Str.split (Str.regexp_string ".") componentName, id))
+ | _ -> Cpath parts
+ in
+ let mkPipe off partialName =
+ let off = skipWhite text off in
+ let rec loop i =
+ match i < 0 with
+ | true -> Some (PipeId (String.sub text 0 (i - 1)))
+ | false -> (
+ match text.[i] with
+ | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '.' | '_' -> loop (i - 1)
+ | '"' when i == off -> Some PipeString
+ | ']' when i == off -> Some PipeArray
+ | _ -> Some (PipeId (String.sub text (i + 1) (off - i))))
+ in
+ match loop off with
+ | None -> None
+ | Some lhs -> Some (Cpipe (lhs, partialName))
in
+
let suffix i = String.sub text (i + 1) (offset - (i + 1)) in
let rec loop i =
match i < 0 with
@@ -158,7 +171,8 @@ let findCompletable text offset =
match text.[i] with
| '>' when i > 0 && text.[i - 1] = '-' ->
let rest = suffix i in
- if isLowercaseIdent rest then loop (i - 2) else Some (mkPath rest)
+ if isLowercaseIdent rest then mkPipe (i - 2) rest
+ else Some (mkPath rest)
| '~' ->
let labelPrefix = suffix i in
let funPath = findCallFromArgument text (i - 1) in