blob: 68c15fc75792d58c6281d8cfb961c7cc2f19159c [file] [log] [blame] [raw]
define(function (require) {
"use strict";
var CodeMirror = require('codemirror');
require('codemirror/mode/clike/clike');
require('codemirror/mode/d/d');
require('codemirror/mode/go/go');
require('codemirror/mode/rust/rust');
function Editor(hub, state, container, lang, defaultSrc) {
var self = this;
this.id = state.id || hub.nextEditorId();
this.container = container;
var domRoot = container.getElement();
domRoot.html($('#codeEditor').html());
var cmMode;
switch (lang.toLowerCase()) {
default:
cmMode = "text/x-c++src";
break;
case "c":
cmMode = "text/x-c";
break;
case "rust":
cmMode = "text/x-rustsrc";
break;
case "d":
cmMode = "text/x-d";
break;
case "go":
cmMode = "text/x-go";
break;
}
this.editor = CodeMirror.fromTextArea(domRoot.find("textarea")[0], {
lineNumbers: true,
matchBrackets: true,
useCPP: true,
mode: cmMode
});
if (state.src) {
this.editor.setValue(state.src);
} else if (defaultSrc) {
this.editor.setValue(defaultSrc);
}
// With reference to "fix typing '#' in emacs mode"
// https://github.com/mattgodbolt/gcc-explorer/pull/131
this.editor.setOption("extraKeys", {
"Alt-F": false
});
this.editor.on("change", function () {
hub.onEditorChange(self);
self.updateState();
});
function resize() {
self.editor.setSize(domRoot.width(), domRoot.height());
self.editor.refresh();
}
container.on('resize', resize);
container.on('open', resize);
container.on('close', function () {
hub.removeEditor(self);
});
container.setTitle(lang + " source");
}
Editor.prototype.updateState = function () {
this.container.setState({
id: this.id,
src: this.getSource()
});
};
Editor.prototype.getSource = function () {
return this.editor.getValue();
};
Editor.prototype.getId = function () {
return this.id;
};
function makeErrorNode(text) {
var clazz = "error";
if (text.match(/^warning/)) clazz = "warning";
if (text.match(/^note/)) clazz = "note";
var node = $('<div class="' + clazz + ' inline-msg"><span class="icon">!!</span><span class="msg"></span></div>');
node.find(".msg").text(text);
return node[0];
}
function parseLines(lines, callback) {
var re = /^\/tmp\/[^:]+:([0-9]+)(:([0-9]+))?:\s+(.*)/;
$.each(lines.split('\n'), function (_, line) {
line = line.trim();
if (line !== "") {
var match = line.match(re);
if (match) {
callback(parseInt(match[1]), match[4].trim());
} else {
callback(null, line);
}
}
});
}
Editor.prototype.removeWidgets = function (compiler) {
var self = this;
_.each(compiler.editorState.widgets, function (widget) {
self.editor.removeLineWidget(widget);
});
};
Editor.prototype.onCompilerAttach = function (compiler) {
compiler.editorState = {
widgets: []
};
};
Editor.prototype.onCompilerDetach = function (compiler) {
this.removeWidgets(compiler);
compiler.editorState = {};
};
Editor.prototype.onCompileResponse = function (compiler, result) {
var output = (result.stdout || "") + (result.stderr || "");
var self = this;
this.removeWidgets(compiler);
parseLines(output, function (lineNum, msg) {
if (lineNum) {
var widget = self.editor.addLineWidget(
lineNum - 1,
makeErrorNode(msg),
{coverGutter: false, noHScroll: true});
compiler.editorState.widgets.push(widget);
}
});
};
return Editor;
});