Skip to content

Commit

Permalink
Implemented OCaml mode for Ace
Browse files Browse the repository at this point in the history
  • Loading branch information
sergi committed Apr 29, 2011
1 parent b8ab958 commit 60f8f1b
Show file tree
Hide file tree
Showing 4 changed files with 486 additions and 0 deletions.
11 changes: 11 additions & 0 deletions demo/demo.js
Expand Up @@ -59,6 +59,7 @@ exports.launch = function(env) {
var CCPPMode = require("ace/mode/c_cpp").Mode;
var CoffeeMode = require("ace/mode/coffee").Mode;
var PerlMode = require("ace/mode/perl").Mode;
var OcamlMode = require("ace/mode/ocaml").Mode;
var SvgMode = require("ace/mode/svg").Mode;
var TextileMode = require("ace/mode/textile").Mode;
var TextMode = require("ace/mode/text").Mode;
Expand Down Expand Up @@ -136,6 +137,10 @@ exports.launch = function(env) {
docs.perl.setMode(new PerlMode());
docs.perl.setUndoManager(new UndoManager());

docs.ocaml = new EditSession(document.getElementById("ocamltext").innerHTML);
docs.ocaml.setMode(new OcamlMode());
docs.ocaml.setUndoManager(new UndoManager());

docs.svg = new EditSession(document.getElementById("svgtext").innerHTML.replace("&lt;", "<"));
docs.svg.setMode(new SvgMode());
docs.svg.setUndoManager(new UndoManager());
Expand All @@ -162,6 +167,7 @@ exports.launch = function(env) {
c_cpp: new CCPPMode(),
coffee: new CoffeeMode(),
perl: new PerlMode(),
ocaml: new OcamlMode(),
csharp: new CSharpMode()
};

Expand Down Expand Up @@ -210,6 +216,9 @@ exports.launch = function(env) {
else if (mode instanceof PerlMode) {
modeEl.value = "perl";
}
else if (mode instanceof OcamlMode) {
modeEl.value = "ocaml";
}
else if (mode instanceof CSharpMode) {
modeEl.value = "csharp";
}
Expand Down Expand Up @@ -373,6 +382,8 @@ exports.launch = function(env) {
mode = "coffee";
} else if (/^.*\.(pl|pm)$/i.test(file.name)) {
mode = "perl";
} else if (/^.*\.(ml|mli)$/i.test(file.name)) {
mode = "ocaml";
}

env.editor.onTextInput(reader.result);
Expand Down
22 changes: 22 additions & 0 deletions index.html
Expand Up @@ -26,6 +26,7 @@
<option value="csharp">C# Document</option>
<option value="c_cpp">C++ Document</option>
<option value="svg">SVG Document</option>
<option value="ocaml">OCaml Document</option>
<option value="textile">Textile Document</option>
<option value="plain">Text Document</option>
</select>
Expand Down Expand Up @@ -99,6 +100,7 @@
<option value="c_cpp">C/C++</option>
<option value="coffee">CoffeeScript</option>
<option value="perl">Perl</option>
<option value="ocaml">OCaml</option>
<option value="csharp">C-Sharp</option>
<option value="svg">SVG</option>
<option value="textile">Textile</option>
Expand Down Expand Up @@ -335,6 +337,26 @@ <h1 style="color:red">Juhu Kinners</h1>

</script>

<script type="text/editor" id="ocamltext">(*
* Example of early return implementation taken from
* http://ocaml.janestreet.com/?q=node/91
*)

let with_return (type t) (f : _ -> t) =
let module M =
struct exception Return of t end
in
let return = { return = (fun x -> raise (M.Return x)); } in
try f return with M.Return x -> x


(* Function that uses the 'early return' functionality provided by `with_return` *)
let sum_until_first_negative list =
with_return (fun r ->
List.fold list ~init:0 ~f:(fun acc x ->
if x >= 0 then acc + x else r.return acc))
</script>

<script type="text/editor" id="svgtext"><svg
width="800" height="600"
xmlns="http://www.w3.org/2000/svg"
Expand Down
102 changes: 102 additions & 0 deletions lib/ace/mode/ocaml.js
@@ -0,0 +1,102 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Ajax.org Code Editor (ACE).
*
* The Initial Developer of the Original Code is
* Ajax.org B.V.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Sergi Mansilla <sergi AT ajax DOT org>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {

var oop = require("pilot/oop");
var TextMode = require("ace/mode/text").Mode;
var Tokenizer = require("ace/tokenizer").Tokenizer;
var OcamlHighlightRules = require("ace/mode/ocaml_highlight_rules").OcamlHighlightRules;
var MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
var Range = require("ace/range").Range;

var Mode = function() {
this.$tokenizer = new Tokenizer(new OcamlHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
};
oop.inherits(Mode, TextMode);

var indenter = /(?:[({[=:]|[-=]>|\b(?:else|try|with(?:\s*[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?))\s*$/;

(function() {

this.toggleCommentLines = function(state, doc, startRow, endRow) {
var i, line;
var outdent = true;
var re = /^\s*\(\*(.*)\*\)/;

for (i=startRow; i<= endRow; i++) {
if (!re.test(doc.getLine(i))) {
outdent = false;
break;
}
}

var range = new Range(0, 0, 0, 0);
for (i=startRow; i<= endRow; i++) {
line = doc.getLine(i);
range.start.row = i;
range.end.row = i;
range.end.column = line.length;

doc.replace(range, outdent ? line.match(re)[1] : "(*" + line + "*)");
}
};

this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
var tokens = this.$tokenizer.getLineTokens(line, state).tokens;

if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&
state === 'start' && indenter.test(line))
indent += tab;
return indent;
};

this.checkOutdent = function(state, line, input) {
return this.$outdent.checkOutdent(line, input);
};

this.autoOutdent = function(state, doc, row) {
this.$outdent.autoOutdent(doc, row);
};

}).call(Mode.prototype);

exports.Mode = Mode;
});

0 comments on commit 60f8f1b

Please sign in to comment.