Skip to content
Open
Changes from 1 commit
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
71c2897
refactor: switch to React Router
jderochervlk Sep 28, 2025
3d46e64
refactor: add order and section to language manual frontmatter
jderochervlk Sep 28, 2025
365d522
Merge branch 'vlk/add-order-and-section-to-manual' of github.com:resc…
jderochervlk Sep 28, 2025
24c9fdc
add react
jderochervlk Sep 28, 2025
bce0ea1
Merge branch 'vlk/add-order-and-section-to-manual' of github.com:resc…
jderochervlk Sep 28, 2025
b3e42b7
improve css loading speed
jderochervlk Sep 28, 2025
62a4916
fix fouc
jderochervlk Sep 28, 2025
2a54652
fix css not loading
jderochervlk Sep 28, 2025
100fb4c
make sure progress is synced
jderochervlk Oct 1, 2025
3b5acdb
language manual
jderochervlk Oct 2, 2025
1217a60
working on tables
jderochervlk Oct 2, 2025
4d28ff6
back out table changes for now
jderochervlk Oct 2, 2025
a39d058
updating blog pages
jderochervlk Oct 3, 2025
06987bb
builds are working
jderochervlk Oct 3, 2025
5282ad2
copy to out folder
jderochervlk Oct 3, 2025
50c193e
add static server
jderochervlk Oct 3, 2025
b0c3673
cleanup some deps
jderochervlk Oct 5, 2025
d167bf2
cleanup some todo comments
jderochervlk Oct 5, 2025
f571352
configure loadmdx
jderochervlk Oct 5, 2025
8c812c6
tables looking good
jderochervlk Oct 5, 2025
96d9032
more mdx work
jderochervlk Oct 5, 2025
4732229
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Oct 5, 2025
565e2d2
move react docs
jderochervlk Oct 7, 2025
009596d
react docs and anchor scrolling
jderochervlk Oct 7, 2025
c23be9b
fixed scrolling on full page nav
jderochervlk Oct 7, 2025
5a5904f
api is rendering
jderochervlk Oct 7, 2025
778f521
api prerender is working
jderochervlk Oct 7, 2025
f566bec
working on api table of contents
jderochervlk Oct 8, 2025
f478604
Initial plan
Copilot Oct 12, 2025
34acb8f
Migrate CodeMirror from v5 to v6 - initial implementation
Copilot Oct 12, 2025
1040aa7
Fix warnings and remove CodeMirror v5 dependency
Copilot Oct 12, 2025
cc339b5
Address code review feedback - fix import paths, error handling, and …
Copilot Oct 12, 2025
8311c48
Fix error validation logic - properly validate both line and column b…
Copilot Oct 12, 2025
6a1b928
Clarify error position indexing in comments - rows are 1-based, colum…
Copilot Oct 12, 2025
87c0785
Fix ReferenceError: createEditor is not defined - call function direc…
Copilot Oct 13, 2025
a631fc4
Format JavaScript files with Prettier
Copilot Oct 13, 2025
5ee2f10
Convert createEditor from raw JavaScript to native ReScript with comp…
Copilot Oct 13, 2025
924e84a
apidocs
jderochervlk Oct 13, 2025
1213a43
use more idiomatic rescript bindings
tsnobip Oct 13, 2025
bc74250
api nav is working
jderochervlk Oct 13, 2025
a90d0a8
trying to fix the inline codeblock
jderochervlk Oct 13, 2025
f8185ff
just remove it for now
jderochervlk Oct 13, 2025
23eaffe
fix &
jderochervlk Oct 13, 2025
31058cb
move syntax pages
jderochervlk Oct 13, 2025
6942b6b
working on blog listing page
jderochervlk Oct 14, 2025
0321c41
working on syntax page
jderochervlk Oct 14, 2025
e997c36
blog listing page is mostly working
jderochervlk Oct 15, 2025
a599198
update to rc.2
jderochervlk Oct 17, 2025
eed9347
blog post is rendering
jderochervlk Oct 17, 2025
bd882a6
fix archived blog posts
jderochervlk Oct 19, 2025
58001ca
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Oct 19, 2025
0a505e7
static builds are working
jderochervlk Oct 19, 2025
9fe79d8
rendering community pages
jderochervlk Oct 19, 2025
f8dc09b
getting close
jderochervlk Oct 20, 2025
91f9442
package search
jderochervlk Oct 20, 2025
b07a66c
syntax lookup
jderochervlk Oct 20, 2025
dc0ad5d
remove package-lock
jderochervlk Oct 20, 2025
654f09e
rebuild package lock
jderochervlk Oct 20, 2025
b7ba93f
fix webapi
jderochervlk Oct 20, 2025
9ce7121
fixes
jderochervlk Oct 20, 2025
14f7bd2
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Oct 20, 2025
0fcf8a8
Merge branch 'copilot/migrate-playground-to-cm-v6' of github.com:resc…
jderochervlk Oct 20, 2025
9272d9d
control panel
jderochervlk Oct 20, 2025
7d7bbdf
fix divider
jderochervlk Oct 20, 2025
f676837
more cleanup
jderochervlk Oct 20, 2025
8f15c78
more style fixes
jderochervlk Oct 20, 2025
89112cc
config cleanup
jderochervlk Oct 20, 2025
b1156d8
delete pages folder
jderochervlk Oct 20, 2025
ec22753
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Oct 21, 2025
0b63251
rebuild package lock and remove .nvmrc
jderochervlk Oct 21, 2025
a5bbc50
try fixing missing types
jderochervlk Oct 22, 2025
219742d
add search
jderochervlk Oct 22, 2025
c9f8095
use npm build
jderochervlk Oct 22, 2025
011e271
fix typo
jderochervlk Oct 22, 2025
7a22a0a
fix package lock webapi version
jderochervlk Oct 22, 2025
0b9887a
run formatter
jderochervlk Oct 22, 2025
ba425b2
rollback codemirror
jderochervlk Oct 23, 2025
201a0ea
back to codemirror 5
jderochervlk Oct 23, 2025
3d650b7
Revert "use more idiomatic rescript bindings"
jderochervlk Oct 23, 2025
ad9b581
back to codemirror 5
jderochervlk Oct 23, 2025
a0ce329
Revert "rollback codemirror"
jderochervlk Oct 23, 2025
7dbe3df
playground is working
jderochervlk Oct 23, 2025
45b99f2
fix background color on dropdown
jderochervlk Oct 23, 2025
3015186
warning table
jderochervlk Oct 23, 2025
d5b111b
docson
jderochervlk Oct 23, 2025
1882fa0
fixed markdown
jderochervlk Oct 23, 2025
3852202
import css
jderochervlk Oct 24, 2025
70aeb1c
remove trailing ;
jderochervlk Oct 24, 2025
ce8576d
add back tests
jderochervlk Oct 24, 2025
7dc4b86
fix doc tests
jderochervlk Oct 24, 2025
0304baa
remove href test
jderochervlk Oct 24, 2025
d48b592
test out redirects
jderochervlk Oct 24, 2025
8547f39
formatting
jderochervlk Oct 24, 2025
11a742f
add 404 page
jderochervlk Oct 24, 2025
91d8860
typo in redirects
jderochervlk Oct 24, 2025
3b0bd2d
fix filename
jderochervlk Oct 24, 2025
20a153b
fix prettier ignore
jderochervlk Oct 24, 2025
113e21b
preconnect to css
jderochervlk Oct 24, 2025
ff62b7b
fix flicker
jderochervlk Oct 24, 2025
9f886db
fix community link
jderochervlk Oct 24, 2025
2d42ed9
Fix community links
jderochervlk Oct 24, 2025
2b785e2
fix search box and docson
jderochervlk Oct 26, 2025
14d00a1
getting meta tags to work
jderochervlk Nov 4, 2025
666f235
meta tags
jderochervlk Nov 4, 2025
20227bb
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Nov 4, 2025
7cf2561
fix image imports after merge
jderochervlk Nov 4, 2025
6880219
formatting
jderochervlk Nov 4, 2025
2074165
align naming for Lazy components
jderochervlk Nov 5, 2025
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
Prev Previous commit
Next Next commit
use more idiomatic rescript bindings
  • Loading branch information
tsnobip committed Oct 13, 2025
commit 1213a4314aa9314ae1efb85013f7b7997c260961
165 changes: 64 additions & 101 deletions src/components/CodeMirror.res
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,14 @@ module CM6 = {
type editorView
type compartment
type effect
type transaction
type languageSupport

type keymapSpec

module Extension = {
type t = extension
external fromArray: array<t> => t = "%identity"
}

module Text = {
type t
type line
Expand All @@ -111,40 +115,42 @@ module CM6 = {
}

module EditorState = {
@module("@codemirror/state") @scope("EditorState")
external create: {"doc": string, "extensions": array<extension>} => editorState = "create"
type createConfig = {doc: string, extensions: array<extension>}

@module("@codemirror/state") @scope("EditorState") @val
external readOnly: {"of": bool => extension} = "readOnly"
@module("@codemirror/state") @scope("EditorState")
external create: createConfig => editorState = "create"

module ReadOnly = {
@module("@codemirror/state") @scope(("EditorState", "readOnly")) @val
external of_: bool => extension = "of"
}
@get external doc: editorState => Text.t = "doc"
}

module Compartment = {
@module("@codemirror/state") @new
external make: unit => compartment = "Compartment"

@send external of_: (compartment, extension) => extension = "of"
external create: unit => compartment = "Compartment"
@send external make: (compartment, extension) => extension = "of"
@send external reconfigure: (compartment, extension) => effect = "reconfigure"
}

module EditorView = {
type createConfig = {state: editorState, parent: WebAPI.DOMAPI.element}
@module("@codemirror/view") @new
external create: {"state": editorState, "parent": WebAPI.DOMAPI.element} => editorView =
"EditorView"
external create: createConfig => editorView = "EditorView"

@send external destroy: editorView => unit = "destroy"
@get external state: editorView => editorState = "state"
@get external dom: editorView => WebAPI.DOMAPI.htmlElement = "dom"

type change = {from: int, to: int, insert: string}
type dispatchArg = {changes: change}
@send
external dispatch: (
editorView,
{"changes": {"from": int, "to": int, "insert": string}},
) => unit = "dispatch"
external dispatch: (editorView, dispatchArg) => unit = "dispatch"

type dispatchEffectsArg = {effects: effect}
@send
external dispatchEffects: (editorView, {"effects": effect}) => unit = "dispatch"
external dispatchEffects: (editorView, dispatchEffectsArg) => unit = "dispatch"

@module("@codemirror/view") @scope("EditorView") @val
external lineWrapping: extension = "lineWrapping"
Expand All @@ -169,8 +175,8 @@ module CM6 = {
@get external view: update => editorView = "view"
@get external docChanged: update => bool = "docChanged"

@module("@codemirror/view") @scope("EditorView")
external of_: (update => unit) => extension = "updateListener"
@module("@codemirror/view") @scope(("EditorView", "updateListener"))
external of_: (update => unit) => extension = "of"
}
}

Expand All @@ -197,16 +203,18 @@ module CM6 = {
@module("@codemirror/language")
external bracketMatching: unit => extension = "bracketMatching"

type syntaxConfig = {fallback: bool}

@module("@codemirror/language")
external syntaxHighlighting: (extension, {"fallback": bool}) => extension = "syntaxHighlighting"
external syntaxHighlighting: (extension, syntaxConfig) => extension = "syntaxHighlighting"

@module("@lezer/highlight") @val
@module("@codemirror/language") @val
external defaultHighlightStyle: extension = "defaultHighlightStyle"
}

module Keymap = {
@module("@codemirror/state")
external of_: array<keymapSpec> => extension = "keymap"
@module("@codemirror/view") @scope("keymap") @val
external of_: array<keymapSpec> => extension = "of"
}

module Lint = {
Expand All @@ -228,7 +236,7 @@ module CM6 = {

module JavaScript = {
@module("@codemirror/lang-javascript")
external javascript: unit => languageSupport = "javascript"
external javascript: unit => extension = "javascript"
}

module Vim = {
Expand All @@ -237,11 +245,11 @@ module CM6 = {
}

module CustomLanguages = {
@module("../plugins/cm6-rescript-mode") @val
external rescriptLanguage: languageSupport = "rescriptLanguage"
@module("../../plugins/cm6-rescript-mode.js") @val
external rescriptLanguage: extension = "rescriptLanguage"

@module("../plugins/cm6-reason-mode") @val
external reasonLanguage: languageSupport = "reasonLanguage"
@module("../../plugins/cm6-reason-mode.js") @val
external reasonLanguage: extension = "reasonLanguage"
}
}

Expand All @@ -268,7 +276,7 @@ type editorConfig = {
maxHeight: option<string>,
}

let createLinterExtension = (errors: array<Error.t>, lintConf: CM6.compartment): CM6.extension => {
let createLinterExtension = (errors: array<Error.t>): CM6.extension => {
let linterSource = (view: CM6.editorView): array<CM6.Lint.diagnostic> => {
if Array.length(errors) === 0 {
[]
Expand Down Expand Up @@ -296,7 +304,7 @@ let createLinterExtension = (errors: array<Error.t>, lintConf: CM6.compartment):
message: err.text,
}

Array.push(diagnostics, diagnostic)->ignore
Array.push(diagnostics, diagnostic)
} catch {
| _ => Console.warn("Error creating lint marker")
}
Expand All @@ -306,7 +314,7 @@ let createLinterExtension = (errors: array<Error.t>, lintConf: CM6.compartment):
}
}

CM6.Compartment.of_(lintConf, CM6.Lint.linter(linterSource))
CM6.Lint.linter(linterSource)
}

let createEditor = (config: editorConfig): editorInstance => {
Expand All @@ -318,41 +326,41 @@ let createEditor = (config: editorConfig): editorInstance => {
}

// Setup compartments for dynamic config
let languageConf = CM6.Compartment.make()
let readOnlyConf = CM6.Compartment.make()
let keymapConf = CM6.Compartment.make()
let lintConf = CM6.Compartment.make()
let languageConf = CM6.Compartment.create()
let readOnlyConf = CM6.Compartment.create()
let keymapConf = CM6.Compartment.create()
let lintConf = CM6.Compartment.create()

// Basic extensions
let extensions = [
CM6.Compartment.of_(languageConf, (Obj.magic(language): CM6.extension)),
CM6.Compartment.make(languageConf, (language: CM6.extension)),
CM6.Commands.history(),
CM6.EditorView.drawSelection(),
CM6.EditorView.dropCursor(),
CM6.Language.bracketMatching(),
CM6.Search.highlightSelectionMatches(),
CM6.Language.syntaxHighlighting(CM6.Language.defaultHighlightStyle, {"fallback": true}),
CM6.Language.syntaxHighlighting(CM6.Language.defaultHighlightStyle, {fallback: true}),
]

// Add optional extensions
if config.lineNumbers {
Array.push(extensions, CM6.EditorView.lineNumbers())->ignore
Array.push(extensions, CM6.EditorView.highlightActiveLineGutter())->ignore
Array.push(extensions, CM6.EditorView.lineNumbers())
Array.push(extensions, CM6.EditorView.highlightActiveLineGutter())
}

if !config.readOnly {
Array.push(extensions, CM6.EditorView.highlightActiveLine())->ignore
Array.push(extensions, CM6.EditorView.highlightActiveLine())
}

if config.lineWrapping {
Array.push(extensions, CM6.EditorView.lineWrapping)->ignore
Array.push(extensions, CM6.EditorView.lineWrapping)
}

// Add readonly conf
Array.push(
extensions,
CM6.Compartment.of_(readOnlyConf, CM6.EditorState.readOnly["of"](config.readOnly)),
)->ignore
CM6.Compartment.make(readOnlyConf, CM6.EditorState.ReadOnly.of_(config.readOnly)),
)

// Add keymap
let keymapExtension = if config.keyMap === "vim" {
Expand All @@ -362,17 +370,16 @@ let createEditor = (config: editorConfig): editorInstance => {
let searchKeymapExt = CM6.Keymap.of_(CM6.Search.searchKeymap)
// Return vim extension combined with keymap extensions
// We need to wrap them in an array and convert to extension
let combined = Array.concat([vimExt], [defaultKeymapExt, historyKeymapExt, searchKeymapExt])
(Obj.magic(combined): CM6.extension)
/* combine extensions into a JS array value */
[vimExt, defaultKeymapExt, historyKeymapExt, searchKeymapExt]->CM6.Extension.fromArray
} else {
let defaultKeymapExt = CM6.Keymap.of_(CM6.Commands.defaultKeymap)
let historyKeymapExt = CM6.Keymap.of_(CM6.Commands.historyKeymap)
let searchKeymapExt = CM6.Keymap.of_(CM6.Search.searchKeymap)
// Return combined keymap extensions
let combined = [defaultKeymapExt, historyKeymapExt, searchKeymapExt]
(Obj.magic(combined): CM6.extension)
// Return combined keymap extensions as a JS array
[defaultKeymapExt, historyKeymapExt, searchKeymapExt]->CM6.Extension.fromArray
}
Array.push(extensions, CM6.Compartment.of_(keymapConf, keymapExtension))->ignore
Array.push(extensions, CM6.Compartment.make(keymapConf, keymapExtension))

// Add change listener
switch config.onChange {
Expand All @@ -384,24 +391,18 @@ let createEditor = (config: editorConfig): editorInstance => {
onChange(newValue)
}
})
Array.push(extensions, updateListener)->ignore
Array.push(extensions, updateListener)
| None => ()
}

// Add linter for errors
Array.push(extensions, createLinterExtension(config.errors, lintConf))->ignore
Array.push(extensions, CM6.Lint.lintGutter())->ignore
// Add linter for errors (wrap the raw linter extension in the compartment)
Array.push(extensions, CM6.Compartment.make(lintConf, createLinterExtension(config.errors)))
Array.push(extensions, CM6.Lint.lintGutter())

// Create editor
let state = CM6.EditorState.create({
"doc": config.initialValue,
"extensions": extensions,
})
let state = CM6.EditorState.create({doc: config.initialValue, extensions})

let view = CM6.EditorView.create({
"state": state,
"parent": config.parent,
})
let view = CM6.EditorView.create({state, parent: config.parent})

// Apply custom styling
let dom = CM6.EditorView.dom(view)
Expand Down Expand Up @@ -429,13 +430,7 @@ let editorSetValue = (instance: editorInstance, value: string): unit => {
let doc = CM6.EditorView.state(instance.view)->CM6.EditorState.doc
CM6.EditorView.dispatch(
instance.view,
{
"changes": {
"from": 0,
"to": CM6.Text.toString(doc)->String.length,
"insert": value,
},
},
{changes: {from: 0, to: CM6.Text.toString(doc)->String.length, insert: value}},
)
}

Expand All @@ -456,47 +451,15 @@ let editorSetMode = (instance: editorInstance, mode: string): unit => {

CM6.EditorView.dispatchEffects(
instance.view,
{
"effects": CM6.Compartment.reconfigure(
instance.languageConf,
(Obj.magic(language): CM6.extension),
),
},
)
}

let editorSetKeyMap = (instance: editorInstance, keyMap: string): unit => {
let keymapExtension = if keyMap === "vim" {
let vimExt = CM6.Vim.vim()
let defaultKeymapExt = CM6.Keymap.of_(CM6.Commands.defaultKeymap)
let historyKeymapExt = CM6.Keymap.of_(CM6.Commands.historyKeymap)
let searchKeymapExt = CM6.Keymap.of_(CM6.Search.searchKeymap)
let combined = Array.concat([vimExt], [defaultKeymapExt, historyKeymapExt, searchKeymapExt])
(Obj.magic(combined): CM6.extension)
} else {
let defaultKeymapExt = CM6.Keymap.of_(CM6.Commands.defaultKeymap)
let historyKeymapExt = CM6.Keymap.of_(CM6.Commands.historyKeymap)
let searchKeymapExt = CM6.Keymap.of_(CM6.Search.searchKeymap)
let combined = [defaultKeymapExt, historyKeymapExt, searchKeymapExt]
(Obj.magic(combined): CM6.extension)
}

CM6.EditorView.dispatchEffects(
instance.view,
{
"effects": CM6.Compartment.reconfigure(instance.keymapConf, keymapExtension),
},
{effects: CM6.Compartment.reconfigure(instance.languageConf, (language: CM6.extension))},
)
}

let editorSetErrors = (instance: editorInstance, errors: array<Error.t>): unit => {
CM6.EditorView.dispatchEffects(
instance.view,
{
"effects": CM6.Compartment.reconfigure(
instance.lintConf,
createLinterExtension(errors, instance.lintConf),
),
effects: CM6.Compartment.reconfigure(instance.lintConf, createLinterExtension(errors)),
},
)
}
Expand Down