Skip to content

Commit ed49719

Browse files
committed
Add binding for Microsoft's Monaco editor
1 parent 55f1de6 commit ed49719

File tree

7 files changed

+131
-7
lines changed

7 files changed

+131
-7
lines changed

package-lock.json

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
"dependencies": {
1212
"bootstrap": "^5.0.2",
1313
"graphviz-react": "^1.2.0",
14+
"monaco-editor": "^0.25.2",
1415
"react": "^17.0.2",
1516
"react-dom": "^17.0.2"
1617
},
1718
"devDependencies": {
1819
"autoprefixer": "^10.3.1",
1920
"css-loader": "^5.2.6",
21+
"file-loader": "^6.2.0",
2022
"html-webpack-plugin": "^5.3.2",
2123
"postcss": "^8.3.5",
2224
"postcss-loader": "^6.1.1",

src/bindings/dune

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@
33
(deps errorBoundary.mli)
44
(action
55
(run %{bin:gen_js_api} -o %{targets} %{deps})))
6+
7+
(rule
8+
(targets monaco.ml)
9+
(deps monaco.mli)
10+
(action
11+
(run %{bin:gen_js_api} -o %{targets} %{deps})))

src/bindings/monaco.mli

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Editor : sig
2+
module ITextModel : sig
3+
type t = private Ojs.t
4+
5+
val id : t -> string
6+
end
7+
8+
val create_model : value:string -> ?language:string -> unit -> ITextModel.t
9+
[@@js.global "monaco.editor.createModel"]
10+
11+
module IStandaloneCodeEditor : sig
12+
type t = private Ojs.t
13+
14+
val set_value : t -> string -> unit [@@js.call]
15+
end
16+
17+
module IStandaloneEditorConstructionOptions : sig
18+
type t = { model : ITextModel.t; read_only : bool }
19+
end
20+
21+
val create :
22+
dom_element:React.Dom.domElement ->
23+
?options:IStandaloneEditorConstructionOptions.t ->
24+
unit ->
25+
IStandaloneCodeEditor.t
26+
[@@js.global "monaco.editor.create"]
27+
end

src/static-requires.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@ var prismJs = require("./static/prism.js");
22
var prismCss = require("./static/prism.css");
33

44
require('./stylesheet.scss');
5+
6+
joo_global_object.monaco = require('monaco-editor/esm/vs/editor/editor.api');
7+
require('monaco-editor/esm/vs/basic-languages/cpp/cpp.contribution');

src/ui/editor/gvCodeEditor.re

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
open Batteries;
2+
3+
module Dom = React.Dom;
4+
module Js = Js_of_ocaml.Js;
5+
6+
module Editor = Monaco.Editor;
7+
module IStandaloneCodeEditor = Editor.IStandaloneCodeEditor;
8+
9+
[@react.component]
10+
let make = (~value=?, ~read_only=?) => {
11+
let (value, read_only) = Utils.fix_opt_args2(value, read_only);
12+
let value = Option.default("", value);
13+
let read_only = Option.default(false, read_only);
14+
15+
let editor = React.useRef(None);
16+
17+
React.useEffect1(
18+
() => {
19+
editor
20+
|> React.Ref.current
21+
|> Option.may(e => IStandaloneCodeEditor.set_value(e, value));
22+
None;
23+
},
24+
[|value|],
25+
);
26+
27+
let ref =
28+
Dom.Ref.callbackDomRef(
29+
Js.Opt.iter(_, dom_element =>
30+
if (editor |> React.Ref.current |> Option.is_none) {
31+
let model = Editor.create_model(~value, ~language="c", ());
32+
Editor.create(~dom_element, ~options={model, read_only}, ())
33+
|> Option.some
34+
|> React.Ref.setCurrent(editor);
35+
}
36+
),
37+
);
38+
39+
<div ref style={Dom.Style.make(~height="600px", ())} />;
40+
};

webpack.config.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ module.exports = {
1313
'css-loader',
1414
{
1515
loader: 'postcss-loader',
16-
options: { postcssOptions: { plugins: ['autoprefixer'] } }
16+
options: { postcssOptions: { plugins: ['autoprefixer'] } },
1717
},
18-
'sass-loader'
19-
]
20-
}
21-
]
18+
'sass-loader',
19+
],
20+
},
21+
{
22+
test: /\.ttf$/,
23+
use: 'file-loader',
24+
},
25+
],
2226
},
2327
plugins: [new HtmlWebpackPlugin({ template: 'public/index.html' })],
2428
resolve: { fallback: { child_process: false, constants: false, fs: false, tty: false } },
2529
devServer: {
26-
contentBase: path.resolve(__dirname, 'public')
27-
}
30+
contentBase: path.resolve(__dirname, 'public'),
31+
},
2832
};

0 commit comments

Comments
 (0)