|
| 1 | +# Supported syntaxes |
| 2 | + |
| 3 | +Melange supports two syntaxes: [OCaml |
| 4 | +syntax](https://ocamlpro.github.io/ocaml-cheat-sheets/ocaml-lang.pdf) (the |
| 5 | +default) and [Reason syntax](https://reasonml.github.io/). You can toggle |
| 6 | +between them by using the "Syntax" widget in the top left corner of this page. |
| 7 | +Try clicking on it now to see the two different versions of the following code |
| 8 | +snippet: |
| 9 | + |
| 10 | +```ocaml |
| 11 | +module Speech = struct |
| 12 | + type utterance |
| 13 | +
|
| 14 | + external makeUtterance : string -> utterance = "SpeechSynthesisUtterance" |
| 15 | + [@@mel.new] |
| 16 | +
|
| 17 | + external speak : utterance -> unit = "speechSynthesis.speak" |
| 18 | +end |
| 19 | +
|
| 20 | +module App = struct |
| 21 | + let style = |
| 22 | + ReactDOM.Style.make ~fontSize:"1em" ~border:"1px solid white" |
| 23 | + ~borderRadius:"0.5em" ~padding:"1em" () |
| 24 | +
|
| 25 | + let make () = |
| 26 | + (button ~style |
| 27 | + ~onClick:(fun _ -> |
| 28 | + "Hello ReasonReact" |> Speech.makeUtterance |> Speech.speak) |
| 29 | + ~children:[ React.string "Say hello" ] |
| 30 | + () [@JSX]) |
| 31 | + [@@react.component] |
| 32 | +end |
| 33 | +
|
| 34 | +let () = |
| 35 | + match ReactDOM.querySelector "#preview" with |
| 36 | + | None -> Js.log "Failed to start React: couldn't find the #preview element" |
| 37 | + | Some root -> |
| 38 | + let root = ReactDOM.Client.createRoot root in |
| 39 | + ReactDOM.Client.render root (App.createElement ~children:[] () [@JSX]) |
| 40 | +``` |
| 41 | +```reasonml |
| 42 | +module Speech = { |
| 43 | + type utterance; |
| 44 | +
|
| 45 | + [@mel.new] |
| 46 | + external makeUtterance: string => utterance = "SpeechSynthesisUtterance"; |
| 47 | +
|
| 48 | + external speak: utterance => unit = "speechSynthesis.speak"; |
| 49 | +}; |
| 50 | +
|
| 51 | +module App = { |
| 52 | + let style = |
| 53 | + ReactDOM.Style.make( |
| 54 | + ~fontSize="1em", |
| 55 | + ~border="1px solid white", |
| 56 | + ~borderRadius="0.5em", |
| 57 | + ~padding="1em", |
| 58 | + (), |
| 59 | + ); |
| 60 | +
|
| 61 | + [@react.component] |
| 62 | + let make = () => |
| 63 | + <button |
| 64 | + style |
| 65 | + onClick={_ => |
| 66 | + "Hello ReasonReact" |> Speech.makeUtterance |> Speech.speak |
| 67 | + }> |
| 68 | + {React.string("Say hello")} |
| 69 | + </button>; |
| 70 | +}; |
| 71 | +
|
| 72 | +let () = |
| 73 | + switch (ReactDOM.querySelector("#preview")) { |
| 74 | + | None => |
| 75 | + Js.log("Failed to start React: couldn't find the #preview element") |
| 76 | + | Some(root) => |
| 77 | + let root = ReactDOM.Client.createRoot(root); |
| 78 | + ReactDOM.Client.render(root, <App />); |
| 79 | + }; |
| 80 | +``` |
| 81 | + |
| 82 | +As you can see, Reason syntax resembles JavaScript and supports JSX, so it is |
| 83 | +more approachable to JavaScript and TypeScript developers. |
| 84 | + |
| 85 | +## Installation |
| 86 | + |
| 87 | +### Reason syntax |
| 88 | + |
| 89 | +To install Reason syntax support add `reason` to the `depends` section of the |
| 90 | +`<project-name>.opam` file in your project's root directory: |
| 91 | + |
| 92 | +```opam |
| 93 | +depends: [ |
| 94 | + "ocaml" |
| 95 | + "reason" {>= "3.10.0"} # [!code ++] |
| 96 | + "dune" {>= "3.9"} |
| 97 | + "melange" {>= "2.0.0"} |
| 98 | + "reason-react" {>= "0.13.0"} |
| 99 | + "reason-react-ppx" |
| 100 | + "opam-check-npm-deps" {with-dev-setup} |
| 101 | + "ocaml-lsp-server" {with-dev-setup} |
| 102 | + "dot-merlin-reader" {with-setup} |
| 103 | + "odoc" {with-doc} |
| 104 | +] |
| 105 | +``` |
| 106 | + |
| 107 | +On the command line, run[^1] |
| 108 | + |
| 109 | +```bash |
| 110 | +opam install -y . --deps-only |
| 111 | +``` |
| 112 | + |
| 113 | +Note that Reason support is already set up for you in |
| 114 | +[melange-opam-template](https://github.com/melange-re/melange-opam-template). |
| 115 | + |
| 116 | +### OCaml syntax |
| 117 | + |
| 118 | +OCaml syntax is supported by default, but to get formatting support, you should |
| 119 | +add `ocamlformat` to the `depends` section of the `<project-name>.opam` file in |
| 120 | +your project's root directory: |
| 121 | + |
| 122 | +```opam |
| 123 | +depends: [ |
| 124 | + "ocaml" |
| 125 | + "dune" {>= "3.9"} |
| 126 | + "melange" {>= "2.0.0"} |
| 127 | + "reason-react" {>= "0.13.0"} |
| 128 | + "reason-react-ppx" |
| 129 | + "ocamlformat" {with-dev-setup} # [!code ++] |
| 130 | + "opam-check-npm-deps" {with-dev-setup} |
| 131 | + "ocaml-lsp-server" {with-dev-setup} |
| 132 | + "dot-merlin-reader" {with-setup} |
| 133 | + "odoc" {with-doc} |
| 134 | +] |
| 135 | +``` |
| 136 | + |
| 137 | +On the command line, run[^2] |
| 138 | + |
| 139 | +```bash |
| 140 | +opam install -y . --deps-only --with-dev-setup |
| 141 | +``` |
| 142 | + |
| 143 | +## VS Code configuration |
| 144 | + |
| 145 | +First, make sure you've already [installed and configured OCaml Platform VS Code |
| 146 | +extension](getting-started#editor-integration). |
| 147 | + |
| 148 | +### Reason syntax |
| 149 | + |
| 150 | +1. To enable format-on-save in VS Code, open your [User Settings JSON |
| 151 | + file](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) |
| 152 | + and add this snippet: |
| 153 | + |
| 154 | + ```json |
| 155 | + "[reason]": { |
| 156 | + "editor.formatOnSave": true |
| 157 | + }, |
| 158 | + ``` |
| 159 | + |
| 160 | +1. To control how the Reason formatter breaks up long lines, you can also add |
| 161 | + this snippet: |
| 162 | + |
| 163 | + ```json |
| 164 | + "ocaml.server.extraEnv": { |
| 165 | + "REFMT_PRINT_WIDTH": "120" |
| 166 | + }, |
| 167 | + ``` |
| 168 | + |
| 169 | + In the snippet above, the print width is set to 120 characters, but you can |
| 170 | + use any number you prefer. If you don't set this, the default is 80. |
| 171 | + |
| 172 | +### OCaml syntax |
| 173 | + |
| 174 | +1. Add `.ocamlformat` to your project's root directory. If you want to change |
| 175 | + the print width, add this to the file: |
| 176 | + |
| 177 | + ```ini |
| 178 | + m=120 |
| 179 | + ``` |
| 180 | + |
| 181 | + In the snippet above, the print width is set to 120 characters, but you can |
| 182 | + use any number you prefer. If you don't set this, the default is 80. |
| 183 | +1. To enable format-on-save in VS Code, open your [User Settings JSON |
| 184 | + file](https://code.visualstudio.com/docs/getstarted/settings#_settingsjson) |
| 185 | + and add this snippet: |
| 186 | + |
| 187 | + ```json |
| 188 | + "[ocaml]": { |
| 189 | + "editor.formatOnSave": true |
| 190 | + }, |
| 191 | + ``` |
| 192 | + |
| 193 | +## Other editors |
| 194 | + |
| 195 | +For Reason syntax, check out [Editor |
| 196 | +Plugins](https://reasonml.github.io/docs/en/editor-plugins) page from Reason |
| 197 | +documentation. |
| 198 | + |
| 199 | +For OCaml syntax, check out the [Editor |
| 200 | +Setup](https://ocamlverse.net/content/editor_setup.html) page from OCamlverse. |
| 201 | + |
| 202 | +## Formatters |
| 203 | + |
| 204 | +You can run this command to check the format of all your OCaml source files: |
| 205 | + |
| 206 | +```bash |
| 207 | +dune build @fmt |
| 208 | +``` |
| 209 | + |
| 210 | +If Reason syntax support is installed, it will automatically check the format of |
| 211 | +all Reason sources files (`.re` and `.rei`). |
| 212 | + |
| 213 | +To automatically fix the formatting, run this: |
| 214 | + |
| 215 | +```bash |
| 216 | +dune build @fmt --auto-promote |
| 217 | +``` |
| 218 | + |
| 219 | +[^1]: Alternatively, you can first run `opam install -y reason` and then add the |
| 220 | + appropriate entry to your `<project-name>.opam` file. |
| 221 | + |
| 222 | +[^2]: Alternatively, you can first run `opam install -y ocamlformat` and then |
| 223 | + add the appropriate entry to your `<project-name>.opam` file. |
0 commit comments