Skip to content

Instantly share code, notes, and snippets.

@cloudRoutine
Last active August 29, 2015 14:09
Show Gist options
  • Select an option

  • Save cloudRoutine/3b57cc9ce47609a19c1d to your computer and use it in GitHub Desktop.

Select an option

Save cloudRoutine/3b57cc9ce47609a19c1d to your computer and use it in GitHub Desktop.
Ace Syntax Highlighting F# (revised)
ace.define('ace/mode/fsharp_highlight_rules', function(require, exports, module)
{
"use strict";
var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
var Tokenizer = require("ace/tokenizer").Tokenizer;
var FSharpHighlightRules = function ()
{
var keywords =
// actual keywords
'abstract|and|as|assert|base|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false' +
'|finally|for|fun|function|global|if|in|inherit|inline|interface|internal|lazy|let|let!|match|member|module|mutable|namespace' +
'|new|not|null|of|open|or|override|private|public|rec|return|return!|select|static|struct|then|to|true|try|type|typeof|upcast|use' +
'|use!|val|void|when|while|with|yield|yield!|__SOURCE_DIRECTORY__' +
// OCaml keywords
'|asr|land|lor|lsl|lsr|lxor|mod|sig' +
// future keywords
'|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|include|' +
'|method|mixin|object|parallel|process|protected|pure|sealed|tailcall|trait|virtual|volatile';
var builtinConstants = ("true|false");
var builtinFunctions = (
''
);
var keywordMapper = this.createKeywordMapper({
"variable.language": "this",
"keyword": keywords,
"constant.language": builtinConstants,
"support.function": builtinFunctions
}, "identifier");
var keywordsOnly = this.createKeywordMapper({
"variable.language": "this",
"keyword": keywords,
"constant.language": builtinConstants,
}, "identifier");
var decimalInteger = "(?:(?:[1-9]\\d*)|(?:0))";
var octInteger = "(?:0[oO]?[0-7]+)";
var hexInteger = "(?:0[xX][\\dA-Fa-f]+)";
var binInteger = "(?:0[bB][01]+)";
var integer = "(?:" + decimalInteger + "|" + octInteger + "|" + hexInteger + "|" + binInteger + ")";
var exponent = "(?:[eE][+-]?\\d+)";
var fraction = "(?:\\.\\d+)";
var intPart = "(?:\\d+)";
var pointFloat = "(?:(?:" + intPart + "?" + fraction + ")|(?:" + intPart + "\\.))";
var exponentFloat = "(?:(?:" + pointFloat + "|" + intPart + ")" + exponent + ")";
var floatNumber = "(?:" + exponentFloat + "|" + pointFloat + ")";
var stringSingleOps = "("
this.$rules = {
"start": [
//{ token: "entity.name.type",
// regex: ":\\s+\\'\\w+[\\w|\\d]+",
// next: "entity.name.type" },
{ token: "paren.left", // start of an attribute block
regex: "\\[\\<",
next: "attribute" },
{ // ' in a generic type attribute
token : ["keyword","whitespace","keyword.operator", "text", "keyword.operator","identifier"],
regex : "(type|inherit)(\\s*|\\n*|\\r*)(\\<)(\\s*)(\\')(\\w+\\d*)",
next: "type-name"
},
{ token: ["keyword","whitespace","support.class"], // type declaration
regex: "(type|inherit)(\\s*|\\n*|\\r*)(\\w+[\\d_\\w]*)",
next: "type-name"
},
{ token: ["keyword","whitespace","support.class"], // type declaration
regex: "(type|inherit)(\\s*|\\n*|\\r*)(``\\w+[\\d_\\w]*``)",
next: "type-name"
},
{ token: ["keyword","support.class"], // type declaration
regex: "(type|inherit)((``\\w+(\\d|_|\\w)*``)|\\w+[\\d_\\w]*)",
next: "type-name" },
{
token : ["keyword", "whitespace", "identifier","keyword.operator","entity.name.function", "variable.parameter"],
regex : "(member)"+ "(\\s+)"+ "([a-zA-Z_][a-zA-Z0-9_]*)(\\.)([a-zA-Z_][a-zA-Z0-9_]*)(\\s*[a-zA-Z_][a-zA-Z0-9_]*)",
next: "function-args"
},
{
token : ["keyword", "whitespace","keyword","whitespace", "entity.name.function", "variable.parameter"],
regex : "(let)"+"(\\s+)(inline|private)(\\s+)([a-zA-Z_][a-zA-Z0-9_]*\\b)(\\s*[a-zA-Z_][a-zA-Z0-9_]*\\b)",
next: "function-args"
},
{
token : ["keyword", "whitespace", "entity.name.function", "variable.parameter"],
regex : "(let|inline|private)"+"(\\s+)([a-zA-Z_][a-zA-Z0-9_]*\\b)(\\s*[a-zA-Z_][a-zA-Z0-9_]*\\b)",
next: "function-args"
},
{ // ' in a generic type attribute
token : ["keyword.operator", "text", "keyword.operator","identifier"],
regex : "(\\<)(\\s*)(\\')(\\w+\\d*)"
},
{ // ' in a generic type attribute
token : [ "text", "keyword.operator","identifier"],
regex : "(,\\s*)(\\')(\\w+\\d*)"
},
{ // ' in a function sig
token : [ "keyword.operator","text", "keyword.operator","identifier"],
regex : "(\\:)(\\s*)(\\')(\\w+\\d*)"
},
{ // ' in a function sig
token : [ "keyword.operator","text", "keyword.operator","identifier"],
regex : "(\\-\\>)(\\s*)(\\')(\\w+\\d*)"
},
{ token: "keyword", // type declaration
regex: "namespace",
next: "namespace" },
{ token: "keyword", // type declaration
regex: "module",
next: "module" },
{ token: "comment", // single line
regex: '[\\s*\\S*](\\r|\\n)' },
{ token: "comment",
regex: '\\(\\*.*?\\*\\)\\s*?$' },
{ token: "comment",
regex: '\\(\\*.*',
next: "comment" },
{ token: "comment.documentation",
regex: '///',
next: "comment.documentation" },
{
token:"comment",
regex: "//",
next: "comment.line"
},
{
token: "string", // single line
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
},
{
token: "string.single", // single char
regex: "'.+'"
},
{
token: "string.double", // " string
regex: '"',
next: "qstring"
},
{
token: keywordMapper,
regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
},
{
token: "constant.numeric", // imaginary
regex: "(?:" + floatNumber + "|\\d+)[jJ]\\b"
},
{
token: "constant.numeric", // float
regex: floatNumber
},
{
token: "constant.numeric", // integer
regex: integer + "\\b"
},
{
token: "paren.lbanana",
regex: "\\(\\|",
next: "active-pattern"
},
{
token: "paren.lparen",
regex: "\\(|\\{|\\[\\||\\["
// ^ [| ^ ^ (| ^
},
{
token: "paren.rparen",
regex: "\\|\\)|\\)|\\|\\]|\\}|\\]"
},
{ token: "keyword.operator",
regex: "\\+\\.|\\-\\.|\\*\\.|\\/\\.|#|;;|\\+|\\-|\\*|\\*\\*\\/|\\-\\>" +
"\\/\\/|%|\\<\\<|\\>\\>|\\&|\\||\\^|~|\\<|\\>|\\<=|=\\>|==|!=|\\<\\>|" +
"\\<\\-|=|/|\\:|!|\\." },
{ token: "text",
regex: "\\s+(\\r|\\n)" },
],
"function-args": [
{
token: "line-end",
regex: "$^",
next: "start"
},
{
token: "variable.parameter",
regex: "(\\s*[a-zA-Z_][a-zA-Z0-9_]*\\b)",
next: "function-args"
},
{
token: "keyword.operator",
regex: "\\=",
next: "start"
},
],
"attribute": [
{
token: "entity.other.attribute-name",
regex: "\\w+\\d*",
},
{
token: "string", // single line
regex: '".+"'
},
{
token: "string.single", // single char
regex: "'.+'"
},
{
token: "paren.right",
regex: "\\>\\]",
next: "start"
},
],
"namespace":[
{ token: "support.constant",
regex: "\\w+(\\d|_|\\w)*",
next: "start" },
],
"module":[
{ token: "meta.storage.type",
regex: "\\w+(\\d|_|\\w)*",
next: "start" },
],
"type-name":[
{ // ' in a generic type attribute
token : ["keyword.operator", "text", "keyword.operator","identifier"],
regex : "(\\<)(\\s*)(\\')(\\w+\\d*)"
},
{ // ' in a generic type attribute
token : [ "text", "keyword.operator","identifier"],
regex : "(,\\s*)(\\')(\\w+\\d*)"
},
{ // ' in a generic type attribute 'Type * 'Type
token : [ "keyword.operator","whitespace", "keyword.operator","identifier"],
regex : "(\\*)([\\s\\n\\r]*)(\\')(\\w+\\d*)"
},
{
token: "keyword",
regex: "of"
},
{
token: "keyword.operator",
regex: "\\*|\\>"
},
{
token: ["keyword.operator","whitespace", "keyword.operator","whitespace","entity.other.attribute-name"],
regex: "(\\=)([\\s*$*\\r*\\n*]*)(\\|)(\\s*|\\n*|\\r*)([A-Z]+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token: ["keyword.operator","whitespace", "keyword.operator","whitespace","entity.other.attribute-name"],
regex: "(\\=)([\\s*\\r*\\n*]*$^[\\s*\\r*\\n*]*)(\\|)(\\s*|\\n*|\\r*)([A-Z]+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token: ["whitespace", "keyword.operator","whitespace","entity.other.attribute-name"],
regex: "([\\s*$*\\r*\\n*]*)(\\|)([\\s\\n\\r]*)([A-Z]+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token: ["whitespace", "keyword.operator","whitespace","entity.other.attribute-name"],
regex: "([\\s*$*\\r*\\n*]*)(\\|)([\\s\\n\\r]*)([A-Z]+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token: "keyword.operator",
regex: "\\=",
next:"discriminated-union"
} ,
{
token: keywordMapper,
regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b",
next: "start"
},
{
token: "unit",
regex: "\\(\\s*\\)",
next: "start"
},
],
"discriminated-union":[
//{
// token: "whitespace",
// regex : "[^\\s\\n\\r$]*"
//},
{ // Discriminated Union Case
token : ["whitespace", "keyword.operator","whitespace","entity.other.attribute-name"],
regex : "([\\s\\n\\r]*)(\\|)(\\s*|\\n*|\\r*)([A-Z]+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token : ["whitespace","keyword","whitespace","identifier"],
regex : "([\\s\\n\\r]+)(of)([\\s\\n\\r]+)(\\w+[\\w_\\d]*)",
next: "discriminated-union"
},
{
token : ["whitespace","keyword.operator","whitespace","identifier"],
regex : "([\\s\\n\\r]+)(\\*)([\\s\\n\\r]+)(\\w+[\\w_\\d]*)",
next: "discriminated-union"
},
{ // Discriminated Union Case
token : [ "whitespace", "keyword.operator","whitespace","entity.other.attribute-name","whitespace"],
regex : "(^[\\s\\n\\r]*)(\\|)([\\s\\n\\r]*)([A-Z]+[\\w_\\d]*)([\\s\\n\\r]*$)"
},
{
token: "line-end",
regex: "$^",
next: "start"
},
{
token: keywordMapper,
regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b",
next: "start"
},
],
"active-pattern":[
{
token: "entity.other.attribute-name",
regex: "\\w+\\d*",
},
{
token: "paren.rbanana",
regex: "\\|\\)|\\)",
next: "start"
},
],
"comment": [
{
token: "comment", // closing comment
regex: ".*?\\*\\)",
next: "start"
},
],
"comment.documentation":[
{
token: "comment.documentation", // comment spanning whole line
regex: ".+",
next: "start"
},
],
"comment.line":[
{
token: "comment", // comment spanning whole line
regex: ".+",
next: "start"
},
],
"entity.name.type": [
{
token: "type",
regex: "\\w+[\\w\\d]*",
next: "start"
},
],
"qstring": [
{
token: "string",
regex: '"',
next: "start"
}, {
token: "string",
regex: '.+'
}
]
};
};
oop.inherits(FSharpHighlightRules, TextHighlightRules);
exports.FSharpHighlightRules = FSharpHighlightRules;
});
ace.define('ace/mode/fsharp', function (require, exports, module)
{
"use strict";
var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var Tokenizer = require("../tokenizer").Tokenizer;
var FSharpHighlightRules = require("./fsharp_highlight_rules").FSharpHighlightRules;
var Range = require("../range").Range;
var Mode = function ()
{
this.HighlightRules = FSharpHighlightRules;
};
oop.inherits(Mode, TextMode);
var indenter = /(?:[({[=:]|[-=]>|\b(?:else|try|with))\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.getTokenizer().getLineTokens(line, state).tokens;
if (!(tokens.length && tokens[tokens.length - 1].type === 'comment') &&
state === 'start' && indenter.test(line))
indent += tab;
return indent;
};
this.$id = "ace/mode/fsharp";
}).call(Mode.prototype);
exports.Mode = Mode;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment