mirror of
https://github.com/nvim-treesitter/nvim-treesitter.git
synced 2026-07-01 19:17:02 -04:00
feat: add rescript parser and queries (#6671)
This commit is contained in:
parent
7cec6219c4
commit
f97e0de005
12 changed files with 748 additions and 0 deletions
|
|
@ -380,6 +380,7 @@ We are looking for maintainers to add more parsers and to write query files for
|
||||||
- [x] [regex](https://github.com/tree-sitter/tree-sitter-regex) (maintained by @theHamsta)
|
- [x] [regex](https://github.com/tree-sitter/tree-sitter-regex) (maintained by @theHamsta)
|
||||||
- [x] [rego](https://github.com/FallenAngel97/tree-sitter-rego) (maintained by @FallenAngel97)
|
- [x] [rego](https://github.com/FallenAngel97/tree-sitter-rego) (maintained by @FallenAngel97)
|
||||||
- [x] [pip requirements](https://github.com/ObserverOfTime/tree-sitter-requirements) (maintained by @ObserverOfTime)
|
- [x] [pip requirements](https://github.com/ObserverOfTime/tree-sitter-requirements) (maintained by @ObserverOfTime)
|
||||||
|
- [x] [rescript](https://github.com/rescript-lang/tree-sitter-rescript) (maintained by @ribru17)
|
||||||
- [x] [rnoweb](https://github.com/bamonroe/tree-sitter-rnoweb) (maintained by @bamonroe)
|
- [x] [rnoweb](https://github.com/bamonroe/tree-sitter-rnoweb) (maintained by @bamonroe)
|
||||||
- [x] [robot](https://github.com/Hubro/tree-sitter-robot) (maintained by @Hubro)
|
- [x] [robot](https://github.com/Hubro/tree-sitter-robot) (maintained by @Hubro)
|
||||||
- [x] [robots](https://github.com/opa-oz/tree-sitter-robots-txt) (maintained by @opa-oz)
|
- [x] [robots](https://github.com/opa-oz/tree-sitter-robots-txt) (maintained by @opa-oz)
|
||||||
|
|
|
||||||
|
|
@ -620,6 +620,9 @@
|
||||||
"requirements": {
|
"requirements": {
|
||||||
"revision": "5ad9b7581b3334f6ad492847d007f2fac6e6e5f2"
|
"revision": "5ad9b7581b3334f6ad492847d007f2fac6e6e5f2"
|
||||||
},
|
},
|
||||||
|
"rescript": {
|
||||||
|
"revision": "444c127686714b2358622427c3bdba7eb09021c6"
|
||||||
|
},
|
||||||
"rnoweb": {
|
"rnoweb": {
|
||||||
"revision": "1a74dc0ed731ad07db39f063e2c5a6fe528cae7f"
|
"revision": "1a74dc0ed731ad07db39f063e2c5a6fe528cae7f"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1804,6 +1804,14 @@ list.requirements = {
|
||||||
readme_name = "pip requirements",
|
readme_name = "pip requirements",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.rescript = {
|
||||||
|
install_info = {
|
||||||
|
url = "https://github.com/rescript-lang/tree-sitter-rescript",
|
||||||
|
files = { "src/parser.c", "src/scanner.c" },
|
||||||
|
},
|
||||||
|
maintainers = { "@ribru17" },
|
||||||
|
}
|
||||||
|
|
||||||
list.rnoweb = {
|
list.rnoweb = {
|
||||||
install_info = {
|
install_info = {
|
||||||
url = "https://github.com/bamonroe/tree-sitter-rnoweb",
|
url = "https://github.com/bamonroe/tree-sitter-rnoweb",
|
||||||
|
|
|
||||||
12
queries/rescript/folds.scm
Normal file
12
queries/rescript/folds.scm
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
[
|
||||||
|
(block)
|
||||||
|
(function)
|
||||||
|
(module_declaration)
|
||||||
|
(type_declaration)
|
||||||
|
(external_declaration)
|
||||||
|
(call_expression)
|
||||||
|
(switch_expression)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(record)
|
||||||
|
(include_statement)+
|
||||||
|
] @fold
|
||||||
335
queries/rescript/highlights.scm
Normal file
335
queries/rescript/highlights.scm
Normal file
|
|
@ -0,0 +1,335 @@
|
||||||
|
(comment) @comment @spell
|
||||||
|
|
||||||
|
; Identifiers
|
||||||
|
;------------
|
||||||
|
; Escaped identifiers like \"+."
|
||||||
|
((value_identifier) @constant.macro
|
||||||
|
(#lua-match? @constant.macro "^%.*$"))
|
||||||
|
|
||||||
|
(value_identifier) @variable
|
||||||
|
|
||||||
|
[
|
||||||
|
(type_identifier)
|
||||||
|
(unit_type)
|
||||||
|
(list)
|
||||||
|
(list_pattern)
|
||||||
|
] @type
|
||||||
|
|
||||||
|
((type_identifier) @type.builtin
|
||||||
|
(#any-of? @type.builtin "int" "char" "string" "float" "bool" "unit"))
|
||||||
|
|
||||||
|
[
|
||||||
|
(variant_identifier)
|
||||||
|
(polyvar_identifier)
|
||||||
|
] @constructor
|
||||||
|
|
||||||
|
(record_type_field
|
||||||
|
(property_identifier) @property)
|
||||||
|
|
||||||
|
(record_field
|
||||||
|
(property_identifier) @property)
|
||||||
|
|
||||||
|
(object
|
||||||
|
(field
|
||||||
|
(property_identifier) @property))
|
||||||
|
|
||||||
|
(object_type
|
||||||
|
(field
|
||||||
|
(property_identifier) @property))
|
||||||
|
|
||||||
|
(module_identifier) @module
|
||||||
|
|
||||||
|
(member_expression
|
||||||
|
(property_identifier) @variable.member)
|
||||||
|
|
||||||
|
(value_identifier_path
|
||||||
|
(module_identifier)
|
||||||
|
(value_identifier) @variable)
|
||||||
|
|
||||||
|
(record_pattern
|
||||||
|
(value_identifier_path
|
||||||
|
(value_identifier) @variable.member))
|
||||||
|
|
||||||
|
(record_pattern
|
||||||
|
(value_identifier) @variable)
|
||||||
|
|
||||||
|
(labeled_argument
|
||||||
|
label: (value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
; Parameters
|
||||||
|
;----------------
|
||||||
|
(list_pattern
|
||||||
|
(value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
(spread_pattern
|
||||||
|
(value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
; String literals
|
||||||
|
;----------------
|
||||||
|
[
|
||||||
|
(string)
|
||||||
|
(template_string)
|
||||||
|
] @string
|
||||||
|
|
||||||
|
(character) @character
|
||||||
|
|
||||||
|
(escape_sequence) @string.escape
|
||||||
|
|
||||||
|
; Other literals
|
||||||
|
;---------------
|
||||||
|
[
|
||||||
|
(true)
|
||||||
|
(false)
|
||||||
|
] @boolean
|
||||||
|
|
||||||
|
(number) @number
|
||||||
|
|
||||||
|
(polyvar) @constructor
|
||||||
|
|
||||||
|
(polyvar_string) @constructor
|
||||||
|
|
||||||
|
; Functions
|
||||||
|
;----------
|
||||||
|
; parameter(s) in parens
|
||||||
|
(parameter
|
||||||
|
(value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
(labeled_parameter
|
||||||
|
(value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
; single parameter with no parens
|
||||||
|
(function
|
||||||
|
parameter: (value_identifier) @variable.parameter)
|
||||||
|
|
||||||
|
(parameter
|
||||||
|
(tuple_pattern
|
||||||
|
(tuple_item_pattern
|
||||||
|
(value_identifier) @variable.parameter)))
|
||||||
|
|
||||||
|
(parameter
|
||||||
|
(array_pattern
|
||||||
|
(value_identifier) @variable.parameter))
|
||||||
|
|
||||||
|
(parameter
|
||||||
|
(record_pattern
|
||||||
|
(value_identifier) @variable.parameter))
|
||||||
|
|
||||||
|
; function identifier in let binding
|
||||||
|
(let_binding
|
||||||
|
pattern: (value_identifier) @function
|
||||||
|
body: (function))
|
||||||
|
|
||||||
|
; function calls
|
||||||
|
(call_expression
|
||||||
|
function: (value_identifier_path
|
||||||
|
(value_identifier) @function.method.call .))
|
||||||
|
|
||||||
|
(call_expression
|
||||||
|
function: (value_identifier) @function.call)
|
||||||
|
|
||||||
|
; highlight the right-hand side of a pipe operator as a function call
|
||||||
|
(pipe_expression
|
||||||
|
(value_identifier) @function.call .)
|
||||||
|
|
||||||
|
(pipe_expression
|
||||||
|
(value_identifier_path
|
||||||
|
(value_identifier) @function.method.call .) .)
|
||||||
|
|
||||||
|
; Meta
|
||||||
|
;-----
|
||||||
|
(decorator_identifier) @attribute
|
||||||
|
|
||||||
|
(extension_identifier) @keyword
|
||||||
|
|
||||||
|
"%" @keyword
|
||||||
|
|
||||||
|
; Misc
|
||||||
|
;-----
|
||||||
|
(polyvar_type_pattern
|
||||||
|
"#" @constructor)
|
||||||
|
|
||||||
|
[
|
||||||
|
"include"
|
||||||
|
"open"
|
||||||
|
] @keyword.import
|
||||||
|
|
||||||
|
[
|
||||||
|
"private"
|
||||||
|
"mutable"
|
||||||
|
"rec"
|
||||||
|
] @keyword.modifier
|
||||||
|
|
||||||
|
"type" @keyword.type
|
||||||
|
|
||||||
|
[
|
||||||
|
"and"
|
||||||
|
"with"
|
||||||
|
"as"
|
||||||
|
] @keyword.operator
|
||||||
|
|
||||||
|
[
|
||||||
|
"export"
|
||||||
|
"external"
|
||||||
|
"let"
|
||||||
|
"module"
|
||||||
|
"assert"
|
||||||
|
"await"
|
||||||
|
"lazy"
|
||||||
|
"constraint"
|
||||||
|
] @keyword
|
||||||
|
|
||||||
|
"await" @keyword.coroutine
|
||||||
|
|
||||||
|
(function
|
||||||
|
"async" @keyword.coroutine)
|
||||||
|
|
||||||
|
(module_unpack
|
||||||
|
"unpack" @keyword)
|
||||||
|
|
||||||
|
[
|
||||||
|
"if"
|
||||||
|
"else"
|
||||||
|
"switch"
|
||||||
|
"when"
|
||||||
|
] @keyword.conditional
|
||||||
|
|
||||||
|
[
|
||||||
|
"exception"
|
||||||
|
"try"
|
||||||
|
"catch"
|
||||||
|
] @keyword.exception
|
||||||
|
|
||||||
|
(call_expression
|
||||||
|
function: (value_identifier) @keyword.exception
|
||||||
|
(#eq? @keyword.exception "raise"))
|
||||||
|
|
||||||
|
[
|
||||||
|
"for"
|
||||||
|
"in"
|
||||||
|
"to"
|
||||||
|
"downto"
|
||||||
|
"while"
|
||||||
|
] @keyword.repeat
|
||||||
|
|
||||||
|
[
|
||||||
|
"."
|
||||||
|
","
|
||||||
|
"|"
|
||||||
|
":"
|
||||||
|
] @punctuation.delimiter
|
||||||
|
|
||||||
|
[
|
||||||
|
"++"
|
||||||
|
"+"
|
||||||
|
"+."
|
||||||
|
"-"
|
||||||
|
"-."
|
||||||
|
"*"
|
||||||
|
"**"
|
||||||
|
"*."
|
||||||
|
"/."
|
||||||
|
"<="
|
||||||
|
"=="
|
||||||
|
"==="
|
||||||
|
"!"
|
||||||
|
"!="
|
||||||
|
"!=="
|
||||||
|
">="
|
||||||
|
"&&"
|
||||||
|
"||"
|
||||||
|
"="
|
||||||
|
":="
|
||||||
|
"->"
|
||||||
|
"|>"
|
||||||
|
":>"
|
||||||
|
"+="
|
||||||
|
"=>"
|
||||||
|
(uncurry)
|
||||||
|
] @operator
|
||||||
|
|
||||||
|
; Explicitly enclose these operators with binary_expression
|
||||||
|
; to avoid confusion with JSX tag delimiters
|
||||||
|
(binary_expression
|
||||||
|
[
|
||||||
|
"<"
|
||||||
|
">"
|
||||||
|
"/"
|
||||||
|
] @operator)
|
||||||
|
|
||||||
|
[
|
||||||
|
"("
|
||||||
|
")"
|
||||||
|
"{"
|
||||||
|
"}"
|
||||||
|
"["
|
||||||
|
"]"
|
||||||
|
"<"
|
||||||
|
">"
|
||||||
|
] @punctuation.bracket
|
||||||
|
|
||||||
|
(unit
|
||||||
|
[
|
||||||
|
"("
|
||||||
|
")"
|
||||||
|
] @constant.builtin)
|
||||||
|
|
||||||
|
(template_substitution
|
||||||
|
"${" @punctuation.special
|
||||||
|
"}" @punctuation.special) @none
|
||||||
|
|
||||||
|
(polyvar_type
|
||||||
|
[
|
||||||
|
"["
|
||||||
|
"[>"
|
||||||
|
"[<"
|
||||||
|
"]"
|
||||||
|
] @punctuation.bracket)
|
||||||
|
|
||||||
|
[
|
||||||
|
"~"
|
||||||
|
"?"
|
||||||
|
".."
|
||||||
|
"..."
|
||||||
|
] @punctuation.special
|
||||||
|
|
||||||
|
(ternary_expression
|
||||||
|
[
|
||||||
|
"?"
|
||||||
|
":"
|
||||||
|
] @keyword.conditional.ternary)
|
||||||
|
|
||||||
|
; JSX
|
||||||
|
;----------
|
||||||
|
(jsx_identifier) @tag
|
||||||
|
|
||||||
|
(jsx_element
|
||||||
|
open_tag: (jsx_opening_element
|
||||||
|
[
|
||||||
|
"<"
|
||||||
|
">"
|
||||||
|
] @tag.delimiter))
|
||||||
|
|
||||||
|
(jsx_element
|
||||||
|
close_tag: (jsx_closing_element
|
||||||
|
[
|
||||||
|
"<"
|
||||||
|
"/"
|
||||||
|
">"
|
||||||
|
] @tag.delimiter))
|
||||||
|
|
||||||
|
(jsx_self_closing_element
|
||||||
|
[
|
||||||
|
"/"
|
||||||
|
">"
|
||||||
|
"<"
|
||||||
|
] @tag.delimiter)
|
||||||
|
|
||||||
|
(jsx_fragment
|
||||||
|
[
|
||||||
|
">"
|
||||||
|
"<"
|
||||||
|
"/"
|
||||||
|
] @tag.delimiter)
|
||||||
|
|
||||||
|
(jsx_attribute
|
||||||
|
(property_identifier) @tag.attribute)
|
||||||
36
queries/rescript/indents.scm
Normal file
36
queries/rescript/indents.scm
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
[
|
||||||
|
(block)
|
||||||
|
(record_type)
|
||||||
|
(record)
|
||||||
|
(parenthesized_expression)
|
||||||
|
(call_expression)
|
||||||
|
(function_type_parameters)
|
||||||
|
(function)
|
||||||
|
(switch_match)
|
||||||
|
(let_declaration)
|
||||||
|
(jsx_element)
|
||||||
|
(jsx_fragment)
|
||||||
|
(jsx_self_closing_element)
|
||||||
|
(object_type)
|
||||||
|
] @indent.begin
|
||||||
|
|
||||||
|
[
|
||||||
|
"}"
|
||||||
|
")"
|
||||||
|
(jsx_closing_element)
|
||||||
|
] @indent.branch @indent.end
|
||||||
|
|
||||||
|
(jsx_self_closing_element
|
||||||
|
"/" @indent.branch
|
||||||
|
">"? @indent.end)
|
||||||
|
|
||||||
|
; </> is captured as 3 different anonymous nodes
|
||||||
|
(jsx_fragment
|
||||||
|
"<"
|
||||||
|
"<" @indent.branch)
|
||||||
|
|
||||||
|
(jsx_fragment
|
||||||
|
">"
|
||||||
|
">" @indent.end)
|
||||||
|
|
||||||
|
(comment) @indent.auto
|
||||||
33
queries/rescript/injections.scm
Normal file
33
queries/rescript/injections.scm
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
((comment) @injection.content
|
||||||
|
(#set! injection.language "comment"))
|
||||||
|
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "re")
|
||||||
|
(expression_statement
|
||||||
|
(_) @injection.content
|
||||||
|
(#set! injection.language "regex")))
|
||||||
|
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "raw")
|
||||||
|
(expression_statement
|
||||||
|
(_
|
||||||
|
(_) @injection.content
|
||||||
|
(#set! injection.language "javascript"))))
|
||||||
|
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "graphql")
|
||||||
|
(expression_statement
|
||||||
|
(_
|
||||||
|
(_) @injection.content
|
||||||
|
(#set! injection.language "graphql"))))
|
||||||
|
|
||||||
|
(extension_expression
|
||||||
|
(extension_identifier) @_name
|
||||||
|
(#eq? @_name "relay")
|
||||||
|
(expression_statement
|
||||||
|
(_
|
||||||
|
(_) @injection.content
|
||||||
|
(#set! injection.language "graphql"))))
|
||||||
9
queries/rescript/locals.scm
Normal file
9
queries/rescript/locals.scm
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
(switch_expression) @local.scope
|
||||||
|
|
||||||
|
; Definitions
|
||||||
|
;------------
|
||||||
|
(type_declaration) @local.definition.type
|
||||||
|
|
||||||
|
(let_binding) @local.definition.var
|
||||||
|
|
||||||
|
(module_declaration) @local.definition.namespace
|
||||||
23
tests/indent/rescript/basic.res
Normal file
23
tests/indent/rescript/basic.res
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
@genType
|
||||||
|
type person = {
|
||||||
|
name: string,
|
||||||
|
age: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
type renderMe<'a> = React.component<{
|
||||||
|
"randomString": string,
|
||||||
|
"poly": 'a,
|
||||||
|
}>
|
||||||
|
|
||||||
|
@genType.import("./hookExample") @react.component
|
||||||
|
external make: (
|
||||||
|
~person: person,
|
||||||
|
~children: React.element,
|
||||||
|
~renderMe: renderMe<'a>,
|
||||||
|
) => React.element = "makeRenamed"
|
||||||
|
|
||||||
|
@genType.import("./hookExample")
|
||||||
|
external foo: (~person: person) => string = "foo"
|
||||||
|
|
||||||
|
let hi = 'a'
|
||||||
151
tests/indent/rescript/complex.res
Normal file
151
tests/indent/rescript/complex.res
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
let hit = ({hit, children}: DocSearch.hitComponent) => {
|
||||||
|
let toTitle = str =>
|
||||||
|
str->Js.String2.charAt(0)->Js.String2.toUpperCase ++ Js.String2.sliceToEnd(str, ~from=1)
|
||||||
|
|
||||||
|
let description = switch hit.url
|
||||||
|
->Js.String2.split("/")
|
||||||
|
->Js.Array2.sliceFrom(1)
|
||||||
|
->Belt.List.fromArray {
|
||||||
|
| list{"blog" as r | "community" as r, ..._} => r->toTitle
|
||||||
|
| list{"docs", doc, version, ...rest} =>
|
||||||
|
let path = rest->Belt.List.toArray
|
||||||
|
|
||||||
|
let info =
|
||||||
|
path
|
||||||
|
->Js.Array2.slice(~start=0, ~end_=Js.Array2.length(path) - 1)
|
||||||
|
->Js.Array2.map(path =>
|
||||||
|
switch path {
|
||||||
|
| "api" => "API"
|
||||||
|
| other => toTitle(other)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
[doc->toTitle, version->toTitle]->Js.Array2.concat(info)->Js.Array2.joinWith(" / ")
|
||||||
|
| _ => ""
|
||||||
|
}
|
||||||
|
|
||||||
|
<Next.Link href={hit.url} className="flex flex-col w-full">
|
||||||
|
<span className="text-gray-60 captions px-4 pt-3 pb-1 block">
|
||||||
|
{description->React.string}
|
||||||
|
</span>
|
||||||
|
children
|
||||||
|
</Next.Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
let transformItems = (items: DocSearch.transformItems) => {
|
||||||
|
items->Belt.Array.keepMap(item => {
|
||||||
|
let url = try Webapi.URL.make(item.url)->Some catch {
|
||||||
|
| Js.Exn.Error(obj) =>
|
||||||
|
Js.Console.error2(`Failed to parse URL ${item.url}`, obj)
|
||||||
|
None
|
||||||
|
}
|
||||||
|
switch url {
|
||||||
|
| Some({pathname, hash}) => {...item, url: pathname ++ hash}->Some
|
||||||
|
| None => None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@react.component
|
||||||
|
let make = () => {
|
||||||
|
let (state, setState) = React.useState(_ => Inactive)
|
||||||
|
let router = Next.Router.useRouter()
|
||||||
|
|
||||||
|
let version = switch Url.parse(router.route).version {
|
||||||
|
| Version(v) => v
|
||||||
|
| _ => "latest"
|
||||||
|
}
|
||||||
|
|
||||||
|
let handleCloseModal = () => {
|
||||||
|
let () = switch ReactDOM.querySelector(".DocSearch-Modal") {
|
||||||
|
| Some(modal) =>
|
||||||
|
switch ReactDOM.querySelector("body") {
|
||||||
|
| Some(body) =>
|
||||||
|
open Webapi
|
||||||
|
body->Element.classList->ClassList.remove("DocSearch--active")
|
||||||
|
modal->Element.addEventListener("transitionend", () => {
|
||||||
|
setState(_ => Inactive)
|
||||||
|
})
|
||||||
|
| None => setState(_ => Inactive)
|
||||||
|
}
|
||||||
|
| None => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
let isEditableTag = el =>
|
||||||
|
switch el->tagName {
|
||||||
|
| "TEXTAREA" | "SELECT" | "INPUT" => true
|
||||||
|
| _ => false
|
||||||
|
}
|
||||||
|
|
||||||
|
let focusSearch = e => {
|
||||||
|
switch activeElement {
|
||||||
|
| Some(el) if el->isEditableTag || el->isContentEditable => ()
|
||||||
|
| _ =>
|
||||||
|
setState(_ => Active)
|
||||||
|
e->keyboardEventPreventDefault
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let handleGlobalKeyDown = e => {
|
||||||
|
switch e.key {
|
||||||
|
| "/" => focusSearch(e)
|
||||||
|
| "k" if e.ctrlKey || e.metaKey => focusSearch(e)
|
||||||
|
| "Escape" => handleCloseModal()
|
||||||
|
| _ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addKeyboardEventListener("keydown", handleGlobalKeyDown)
|
||||||
|
Some(() => removeKeyboardEventListener("keydown", handleGlobalKeyDown))
|
||||||
|
}, [setState])
|
||||||
|
|
||||||
|
let onClick = _ => {
|
||||||
|
setState(_ => Active)
|
||||||
|
}
|
||||||
|
|
||||||
|
let onClose = React.useCallback(() => {
|
||||||
|
handleCloseModal()
|
||||||
|
}, [setState])
|
||||||
|
|
||||||
|
<>
|
||||||
|
<button onClick type_="button" className="text-gray-60 hover:text-fire-50 p-2">
|
||||||
|
<Icon.MagnifierGlass className="fill-current" />
|
||||||
|
</button>
|
||||||
|
{switch state {
|
||||||
|
| Active =>
|
||||||
|
switch ReactDOM.querySelector("body") {
|
||||||
|
| Some(element) =>
|
||||||
|
ReactDOM.createPortal(
|
||||||
|
<DocSearch
|
||||||
|
apiKey
|
||||||
|
appId
|
||||||
|
indexName
|
||||||
|
onClose
|
||||||
|
searchParameters={facetFilters: ["version:" ++ version]}
|
||||||
|
initialScrollY={window->scrollY}
|
||||||
|
transformItems={transformItems}
|
||||||
|
hitComponent=hit
|
||||||
|
/>
|
||||||
|
element,
|
||||||
|
)
|
||||||
|
| None => React.null
|
||||||
|
}
|
||||||
|
| Inactive => React.null
|
||||||
|
}}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
let comparable = (type key, ~cmp) => {
|
||||||
|
module N = MakeComparable({
|
||||||
|
type t = key
|
||||||
|
let cmp = cmp
|
||||||
|
})
|
||||||
|
module(N: Comparable with type t = key)
|
||||||
|
}
|
||||||
|
|
||||||
|
<Next.Link href={hit.url} className="flex flex-col w-full">
|
||||||
|
<span className="text-gray-60 captions px-4 pt-3 pb-1 block">
|
||||||
|
{description->React.string}
|
||||||
|
children
|
||||||
|
</Next.Link>
|
||||||
104
tests/indent/rescript/conditional.res
Normal file
104
tests/indent/rescript/conditional.res
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
include UseClient
|
||||||
|
include UseQuery
|
||||||
|
include UseMutation
|
||||||
|
include UseSubscription
|
||||||
|
|
||||||
|
type hookResponse<'ret> = Types.Hooks.hookResponse<'ret> = {
|
||||||
|
operation: Types.operation,
|
||||||
|
fetching: bool,
|
||||||
|
data: option<'ret>,
|
||||||
|
error: option<CombinedError.t>,
|
||||||
|
response: Types.Hooks.response<'ret>,
|
||||||
|
extensions: option<Js.Json.t>,
|
||||||
|
stale: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
Js.Array2.slice(~start=0, ~end_=Js.Array2.length(moduleRoute) - 1)
|
||||||
|
|
||||||
|
let pathModule = Path.join([dir, version, `${moduleName}.json`])
|
||||||
|
|
||||||
|
let {Api.LocMsg.row: row, column, shortMsg} = locMsg
|
||||||
|
|
||||||
|
let message = `${"error"->red}: failed to compile examples from ${kind} ${test.id->cyan}\n${errorMessage}`
|
||||||
|
|
||||||
|
let version = (evt->ReactEvent.Form.target)["value"]
|
||||||
|
|
||||||
|
let rehypePlugins =
|
||||||
|
[Rehype.WithOptions([Plugin(Rehype.slug), SlugOption({prefix: slugPrefix ++ "-"})])]->Some
|
||||||
|
|
||||||
|
module Item = {
|
||||||
|
type t = {
|
||||||
|
name: string,
|
||||||
|
sellIn: int,
|
||||||
|
quality: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
let make = (~name, ~sellIn, ~quality): t => {
|
||||||
|
name,
|
||||||
|
sellIn,
|
||||||
|
quality,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateQuality = (items: array<Item.t>) => {
|
||||||
|
items->Js.Array2.map(item => {
|
||||||
|
let newItem = ref(item)
|
||||||
|
|
||||||
|
call(
|
||||||
|
asdf,
|
||||||
|
asdf
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
newItem.contents.name != "Aged Brie" && 5 > 2 &&
|
||||||
|
newItem.contents.name != "Backstage passes to a TAFKAL80ETC concert"
|
||||||
|
) {
|
||||||
|
if newItem.contents.quality > 0 {
|
||||||
|
if newItem.contents.name != "Sulfuras, Hand of Ragnaros" {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality - 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if newItem.contents.quality < 50 {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality + 1}
|
||||||
|
|
||||||
|
if newItem.contents.name == "Backstage passes to a TAFKAL80ETC concert" {
|
||||||
|
if newItem.contents.sellIn < 11 {
|
||||||
|
if newItem.contents.quality < 50 {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality + 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if newItem.contents.sellIn < 6 {
|
||||||
|
if newItem.contents.quality < 50 {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality + 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if newItem.contents.name != "Sulfuras, Hand of Ragnaros" {
|
||||||
|
newItem := {...newItem.contents, sellIn: newItem.contents.sellIn - 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
if newItem.contents.sellIn < 0 {
|
||||||
|
if newItem.contents.name != "Aged Brie" {
|
||||||
|
if newItem.contents.name != "Backstage passes to a TAFKAL80ETC concert" {
|
||||||
|
if newItem.contents.quality > 0 {
|
||||||
|
if newItem.contents.name != "Sulfuras, Hand of Ragnaros" {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality - 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newItem := {
|
||||||
|
...newItem.contents,
|
||||||
|
quality: newItem.contents.quality - newItem.contents.quality,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if newItem.contents.quality < 50 {
|
||||||
|
newItem := {...newItem.contents, quality: newItem.contents.quality + 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newItem.contents
|
||||||
|
})
|
||||||
|
}
|
||||||
33
tests/indent/rescript_spec.lua
Normal file
33
tests/indent/rescript_spec.lua
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
local Runner = require("tests.indent.common").Runner
|
||||||
|
|
||||||
|
local run = Runner:new(it, "tests/indent/rescript", {
|
||||||
|
tabstop = 2,
|
||||||
|
shiftwidth = 2,
|
||||||
|
softtabstop = 0,
|
||||||
|
expandtab = true,
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("indent ReScript:", function()
|
||||||
|
describe("whole file:", function()
|
||||||
|
run:whole_file(".", {})
|
||||||
|
end)
|
||||||
|
|
||||||
|
describe("new line:", function()
|
||||||
|
run:new_line("basic.res", { on_line = 5, text = "x", indent = 0 })
|
||||||
|
run:new_line("basic.res", { on_line = 9, text = '"another": here,', indent = 2 })
|
||||||
|
run:new_line("basic.res", { on_line = 10, text = "}", indent = 0 })
|
||||||
|
run:new_line("basic.res", { on_line = 14, text = "~test: test,", indent = 2 })
|
||||||
|
run:new_line("basic.res", { on_line = 18, text = "x", indent = 0 })
|
||||||
|
|
||||||
|
run:new_line("complex.res", { on_line = 3, text = "x", indent = 2 })
|
||||||
|
run:new_line("complex.res", { on_line = 5, text = "x", indent = 4 })
|
||||||
|
run:new_line("complex.res", { on_line = 17, text = "|", indent = 10 })
|
||||||
|
run:new_line("complex.res", { on_line = 25, text = "x", indent = 2 })
|
||||||
|
run:new_line("complex.res", { on_line = 60, text = "x", indent = 6 })
|
||||||
|
run:new_line("complex.res", { on_line = 120, text = "x", indent = 14 })
|
||||||
|
run:new_line("complex.res", { on_line = 136, text = "x", indent = 2 })
|
||||||
|
|
||||||
|
run:new_line("conditional.res", { on_line = 6, text = "test: bool,", indent = 2 })
|
||||||
|
run:new_line("conditional.res", { on_line = 95, text = "x", indent = 10 })
|
||||||
|
end)
|
||||||
|
end)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue