c9-core/plugins/c9.ide.ace.repl/repl.js

921 wiersze
30 KiB
JavaScript

/* ***** BEGIN LICENSE BLOCK *****
* Distributed under the BSD license:
*
* Copyright (c) 2010, Ajax.org B.V.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Ajax.org B.V. nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
define(function(require, exports, module) {
"use strict";
var dom = require("ace/lib/dom");
var Anchor = require("ace/anchor").Anchor;
var HashHandler = require("ace/keyboard/hash_handler").HashHandler;
var Range = require("ace/range").Range;
var comparePoints = Range.comparePoints;
var ReplCell = require("./repl_cell").ReplCell;
var css = require("ace/requirejs/text!./repl.css");
dom.importCssString(css, "ace_repl");
var replCommands = new HashHandler([{
name: "newLine",
bindKey: { win: "Shift-Return|Alt-Enter", mac: "Shift-Return|Alt-Enter" },
exec: function(editor) {editor.insert("\n");},
scrollIntoView: "cursor"
}, {
name: "eval",
bindKey: "Ctrl-Return|Cmd-Return",
exec: function(editor) {return editor.repl.eval(true);},
scrollIntoView: "cursor"
}, {
name: "evalOrNewLine",
bindKey: "Return",
exec: function(editor) {return editor.repl.eval();},
scrollIntoView: "cursor"
}, {
name: "down",
bindKey: "down",
exec: function(editor) {return editor.repl.navigateHistory(1);},
scrollIntoView: "center-animate"
}, {
name: "up",
bindKey: "up",
exec: function(editor) {return editor.repl.navigateHistory(-1);},
scrollIntoView: "center-animate"
}, {
name: "prevCell",
bindKey: { mac: "cmd-up", win: "ctrl-up" },
exec: function(editor) {return editor.repl.moveByCells(-1, null, "input");},
scrollIntoView: "center-animate"
}, {
name: "nextCell",
bindKey: { mac: "cmd-down", win: "ctrl-down" },
exec: function(editor) {return editor.repl.moveByCells(1, null, "input");},
scrollIntoView: "center-animate"
}, {
name: "firstCell",
bindKey: { mac: "alt-up|ctrl-home", win: "ctrl-home" },
exec: function(editor) {return editor.repl.moveByCells("first", null, "input");},
scrollIntoView: "center-animate"
}, {
name: "lastCell",
bindKey: { mac: "alt-down|ctrl-end", win: "ctrl-end" },
exec: function(editor) {return editor.repl.moveByCells("last", null, "input");},
scrollIntoView: "center-animate"
}, {
name: "clear",
bindKey: { mac: "cmd-k", win: "Alt-k" },
exec: function(editor) {return editor.repl.clear();},
scrollIntoView: "center-animate"
}, {
name: "removeOutputCell",
bindKey: { mac: "Shift-delete", win: "Shift-delete" },
exec: function(editor) {return editor.repl.removeOutputCell();},
scrollIntoView: "cursor"
}, {
name: "newInputCell",
bindKey: { mac: "ctrl-insert", win: "ctrl-insert" },
exec: function(editor) { editor.repl.insertCell();},
scrollIntoView: "center-animate"
}]);
for (var key in replCommands.commands) {
replCommands.commands[key].isRepl = true;
}
/******************************************************/
var Repl = function(session, options) {
options = options || {};
this.history = new History();
this.evaluator = options.evaluator || new Evaluator();
this.session = session;
this._replResize = this._replResize.bind(this);
this.updateCellsOnChange = this.updateCellsOnChange.bind(this);
this.updateWidgets = this.updateWidgets.bind(this);
this.measureWidgets = this.measureWidgets.bind(this);
this.session._changedWidgets = [];
this.detach = this.detach.bind(this);
this.session.on("change", this.updateCellsOnChange);
session.repl = this;
session.replCells = [];
var pos = { row: session.getLength(), column: 0 };
if (!session.getValue() && options.message)
pos = session.insert(pos, options.message);
if (session.getValue())
this.insertCell({ row: 0, column: 0 }, { type: "start" }, true);
var last = this.insertCell(pos, { type: "input" });
this.select(last.range.end);
this.session.on("changeMode", function() {
session.getFoldWidget = function(row) {
if (!session.replCells[row])
return;
if (session.replCells[row + 1])
return;
if (row == session.replCells.length - 1)
return;
if (session.replCells[row].lineWidget)
return;
return "start";
};
session.getFoldWidgetRange = function(row) {
return session.repl.getCellAt(row).range;
};
session.bgTokenizer.$tokenizeRow = session.repl.$tokenizeRow;
session.bgTokenizer.session = session;
});
session.getRowLength = function(row) {
if (this.lineWidgets)
var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
else
h = 0;
if (!this.$useWrapMode || !this.$wrapData[row]) {
return 1 + h;
} else {
return this.$wrapData[row].length + 1 + h;
}
};
session.$getWidgetScreenLength = function() {
var screenRows = 0;
this.lineWidgets.forEach(function(w) {
if (w && w.rowCount)
screenRows += w.rowCount;
});
return screenRows;
};
session.gutterRenderer = this.gutterRenderer;
this.session.setMode(options.mode);
this.$updateSession();
this._addCursorMonitor();
};
(function() {
this.message = "\nWelcome to ace repl!\n";
this.setEvaluator = function(evaluator) {
this.evaluator = evaluator;
};
this.getEvaluator = function() {
return this.evaluator;
};
this._replResize = function(oldSize, renderer) {
var session = renderer.session;
var size = renderer.$size;
var dh = size.scrollerHeight - oldSize.scrollerHeight;
if (dh > 0)
return;
var oldMaxScrollTop = renderer.layerConfig.maxHeight
- oldSize.scrollerHeight + renderer.scrollMargin.v;
var scrollTop = session.getScrollTop();
if (scrollTop > oldMaxScrollTop - renderer.layerConfig.lineHeight) {
session.setScrollTop(scrollTop - dh);
}
};
this.gutterRenderer = {
getText: function(session, row) {
var cell = session.replCells[row];
if (cell)
return cell.prompt || "";
return row + "";
},
getWidth: function(session, lastLineNumber, config) {
var chars = Math.max(lastLineNumber.toString().length, session.maxPromptLength || 0);
return chars * config.characterWidth;
}
};
// hide cursor in non editable cells
this._addCursorMonitor = function() {
this._updateCursorVisibility = this._updateCursorVisibility.bind(this);
this.$cursorChanged = false;
var markDirty = function() {
this.$cursorChanged = true;
}.bind(this);
this.session.selection.on("changeSelection", markDirty);
this.session.selection.on("changeCursor", markDirty);
};
this._updateCursorVisibility = function(e, renderer) {
if (!this.$cursorChanged) return;
this.$cursorChanged = false;
var cell = this.getCurrentCell();
var visible = cell && cell.type === "input";
if (visible != renderer.$cursorLayer.inEditableCell) {
renderer.$cursorLayer.inEditableCell = visible;
renderer.$cursorLayer.element.style.opacity = visible ? "" : "0";
}
};
this.onMouseUp = function(e) {
var editor = e.editor;
if (editor.repl.$mouseTimer)
clearTimeout(editor.repl.$mouseTimer);
editor.repl.$mouseTimer = setTimeout(function() {
var sel = editor.selection;
if (sel.isEmpty() && !sel.rangeCount) {
var cell = editor.repl.getCurrentCell();
if (cell.type != "input") {
var r = cell.getRange();
if (r && (sel.lead.row - r.start.row) / (r.end.row - r.start.row) < 0.1)
cell = editor.repl.getSiblingCell(-1, cell, "input");
if (!cell)
cell = editor.repl.getSiblingCell(1, cell, "input");
if (cell)
editor.repl.select(cell.range.end);
}
}
}, 250);
};
// commands
this.beforeCommand = function(e) {
var editor = e.editor;
var command = e.command;
var cell = editor.repl.getCurrentCell();
if (!editor.curReplOp)
editor.curReplOp = { command: command, cell: cell };
if (command.isRepl)
return;
if (cell && cell.lineWidget) {
editor.repl.moveByCells(-1, cell);
e.preventDefault();
}
if (cell && cell.type != "input") {
if (!command.readOnly)
e.preventDefault();
return;
}
if (!cell)
return;
var op = editor.curReplOp;
if (command.readOnly) {
op.clipSelection = "before";
if (editor.lastReplOp && editor.lastReplOp.command === command) {
// todo allow some commands to go outside of cell
op.clipSelection = "after";
}
} else if (command) {
op.clipSelection = "before";
}
if (op.clipSelection == "before") {
var range = cell.getRange();
editor.repl.$trackedRange = range;
setClipToRange(editor.selection.lead, range);
setClipToRange(editor.selection.anchor, range);
}
};
this.afterCommand = function(e) {
var editor = e.editor;
var op = editor.curReplOp;
editor.curReplOp = null;
editor.lastReplOp = op;
if (!op)
return;
var command = op.command;
if (op.clipSelection == "before") {
setClipToRange(editor.selection.lead, false);
setClipToRange(editor.selection.anchor, false);
} else if (op.clipSelection == "after") {
var range = editor.selection.toOrientedRange();
if (op.cell) {
range.clip(op.cell.getRange());
editor.selection.fromOrientedRange(range);
}
}
editor.repl.$trackedRange = null;
if (!command.readOnly && !command.isRepl)
editor.repl.ensureLastInputCell();
};
this.attach = function(editor) {
if (editor.repl && editor.repl != this)
editor.repl.detach();
if (this.editor == editor)
return;
this.detach();
this.editor = editor;
this.editor.on("changeSession", this.detach);
editor.keyBinding.addKeyboardHandler(replCommands);
editor.commands.on("exec", this.beforeCommand);
editor.commands.on("afterExec", this.afterCommand);
editor.on("mouseup", this.onMouseUp);
editor.repl = this;
// editor.setOption("enableLineWidgets", true);
editor.renderer.on("beforeRender", this.measureWidgets);
editor.renderer.on("afterRender", this.updateWidgets);
editor.renderer.on("afterRender", this._updateCursorVisibility);
editor.renderer.on("resize", this._replResize);
};
this.detach = function(e) {
console.log("detach", this.session.getLength(), e);
if (e && e.session == this.session)
return; // sometimes attach can be called before setSession
var editor = this.editor;
if (!editor)
return;
editor.keyBinding.removeKeyboardHandler(replCommands);
editor.commands.off("exec", this.beforeCommand);
editor.commands.off("afterExec", this.afterCommand);
editor.off("mouseup", this.onMouseUp);
editor.off("changeSession", this.detach);
delete editor.renderer.$gutterLayer.update;
this.editor = null;
editor.repl = null;
editor.renderer.off("beforeRender", this.measureWidgets);
editor.renderer.off("afterRender", this.updateWidgets);
this.session.lineWidgets.forEach(function(w) {
if (w && w.el && w.el.parentNode) {
w._inDocument = false;
w.el.parentNode.removeChild(w.el);
}
});
editor.renderer.off("afterRender", this._updateCursorVisibility);
editor.renderer.off("resize", this._replResize);
};
this.navigateHistory = function(dir) {
var cell = this.getCurrentCell();
if (!cell || cell.type != "input")
return false;
var row = this.editor.getCursorPosition().row;
if (dir == 1 && cell.range.end.row != row)
return false;
else if (dir == -1 && cell.range.start.row != row)
return false;
var val = cell.getValue();
val = this.history.navigateList(dir == -1 ? "prev" : "next", val);
if (typeof val == "string") {
dir = -dir;
if (dir == -1 && val.indexOf("\n") == -1)
dir = 1;
cell.setValue(val, dir);
}
};
this.getCurrentCell = function(returnAdjacent) {
var range = this.editor.getSelectionRange();
var cell = this.getCellAt(range.start);
if (returnAdjacent || cell && cell.range.contains(range.end.row, range.end.column)) {
return cell;
}
};
this.getCellAt = function(pos) {
if (pos == undefined)
pos = { row: this.session.getLength(), column: 0 };
else if (typeof pos == "number")
pos = { row: pos, column: 0 };
var cells = this.session.replCells;
for (var i = pos.row; i > 0; i--) {
if (cells[i])
break;
}
var cell = cells[i];
if (!cell)
return;
cell.row = i;
for (var i = pos.row + 1, l = this.session.getLength(); i < l; i++) {
if (cells[i])
break;
}
cell.endRow = Math.min(i - 1, l - 1);
cell.range = new Range(cell.row, 0, cell.endRow, Number.MAX_VALUE);
return cell;
};
this.getSiblingCell = function(dir, cell, type) {
if (dir == -1) {
var pos = cell.range.clone().start;
pos.row--;
} else {
var pos = cell.range.clone().end;
pos.row++;
}
cell = this.getCellAt(pos);
if (!cell)
return;
if (!type || cell.type == type)
return cell;
return this.getSiblingCell(dir, cell, type);
};
this.moveByCells = function(dir, cell, type) {
if (dir == "first")
cell = this.getFirstCell(type);
else if (dir == "last")
cell = this.getLastCell(type);
else
cell = this.getSiblingCell(dir, cell || this.getCurrentCell(), type);
if (cell)
return this.select(cell.range.end);
};
this.getFirstCell = function(type) {
var cell = this.getCellAt(0);
if (type && cell.type != type)
return this.getSiblingCell(1, cell, type);
return cell;
};
this.getLastCell = function(type) {
var cell = this.getCellAt(null);
if (type && cell.type != type)
return this.getSiblingCell(-1, cell, type);
return cell;
};
this.removeOutputCell = function(cell) {
cell = cell || this.getCurrentCell();
if (cell && cell.type == "input")
cell = cell.output;
if (cell)
this.removeCell(cell);
};
this.removeCell = function(cell) {
var range = cell.getRange().clone();
range.start.row--;
range.start.column = this.session.getLine(range.start.row).length;
this.session.replace(range, "");
};
this.clear = function() {
this.session.setValue("");
this.ensureLastInputCell();
};
this.ensureLastInputCell = function() {
var end = { row: this.session.getLength(), column: 0 };
var cell = this.getCellAt(end);
if (!cell || cell.type != "input") {
this.insertCell(end, { type: "input" }, true);
}
};
this.select = function(pos) {
var sel = this.session.selection;
if (typeof pos.row == "number" && typeof pos.column == "number") {
if (sel.rangeCount)
sel.toSingleRange();
sel.setRange(Range.fromPoints(pos, pos));
}
};
this.eval = function(force, cell) {
cell = cell || this.getCurrentCell();
if (!cell)
return;
if (!force && cell.type != "input")
cell = cell.input || this.getSiblingCell(1, cell) || this.getSiblingCell(-1, cell);
var str = cell.getValue();
if (force || this.evaluator.canEvaluate(str)) {
this.session.getUndoManager().reset();
if (!cell.output || !cell.output.session) {
cell.output = this.insertCell(cell.range.end, { type: "output" });
var newCell = this.getSiblingCell(1, cell.output);
}
this.history.add(str);
cell.output.waiting = true;
cell.output.input = cell;
var self = this;
var success = this.evaluator.evaluate(str, cell.output, function(result) {
cell.output.waiting = false;
if (result !== undefined)
cell.output.setValue(result);
var renderer = self.editor.renderer;
renderer.scrollSelectionIntoView(cell.range.end, cell.range.start);
renderer.scrollCursorIntoView();
});
if (success !== false && newCell && newCell.type != "input") {
newCell = this.insertCell(cell.output.range.end, { type: "input" });
this.session.selection.setRange(newCell.range);
}
if (cell.output.waiting) {
cell.output.setPlaceholder("...");
}
} else
this.editor.insert("\n");
if (this.evaluator.afterEvaluate)
this.evaluator.afterEvaluate(cell, newCell);
};
this.insertCell = function(pos, options, allowSplit) {
pos = pos || this.session.selection.getCursor();
if (!options)
options = { type: "input" };
var cell = !allowSplit && this.getCellAt(pos);
if (cell) {
pos = cell.range.end;
pos = this.session.insert(pos, "\n");
}
var newCell = new ReplCell(options, this.session);
pos.row = Math.max(0, Math.min(pos.row, this.session.getLength() - 1));
var range = Range.fromPoints(pos, pos);
range.end.column = Number.MAX_VALUE;
range.start.column = 0;
newCell.range = range;
newCell.row = range.end.row;
var oldCell = this.session.replCells[pos.row];
if (oldCell)
oldCell.destroy();
this.session.replCells[pos.row] = newCell;
this.$updateSession();
return newCell;
};
this.$updateSession = function() {
var session = this.session;
session.$decorations = [];
var lastType = "";
session.replCells.forEach(function(c, row) {
if (!c) {
if (lastType)
session.$decorations[row] = lastType;
return;
}
var dec = "";
if (c.type == "input") {
dec = "repl_prompt ";
lastType = "repl_dots ";
} else if (c.type == "output") {
dec = "repl_output ";
lastType = "repl_nonum ";
}
if (c && c.waiting)
dec += "waiting ";
session.$decorations[row] = dec;
});
session.addGutterDecoration(0, session.$decorations[0]);
session.lineWidgets = session.replCells.map(function(c) {
return c && c.lineWidget;
});
};
this.updateCellsOnChange = function(delta) {
var startRow = delta.start.row;
var len = delta.end.row - startRow;
var range = this.$trackedRange;
var cells = this.session.replCells;
if (len === 0) {
} else if (delta.action == "remove") {
var removed = cells.splice(startRow + 1, len);
removed.forEach(function(cell) {
if (cell) {
cell.destroy();
}
});
if (range && range.start.row <= startRow && range.end.row >= startRow) {
this.$trackedRange.end.row = Math.max(this.$trackedRange.end.row - len, this.$trackedRange.start.row);
}
if (cells.length <= 1)
this.ensureLastInputCell();
} else {
var args = Array(len);
args.unshift(startRow + 1, 0);
cells.splice.apply(cells, args);
if (range && range.start.row <= startRow && range.end.row >= startRow) {
this.$trackedRange.end.row += len;
}
}
this.$updateSession();
this.session._signal("updateCells");
};
this.$tokenizeRow = function(row) {
var line = this.doc.getLine(row);
var state = this.states[row - 1];
var cell = this.session.replCells[row];
if (!cell && !state) {
cell = this.session.repl.getCellAt(row);
}
if (cell) {
state = cell.tokenizerState || cell.type;
if (!this.tokenizer.regExps[state])
state = "start";
}
var data = this.tokenizer.getLineTokens(line, state, row);
if (this.states[row] + "" !== data.state + "") {
if (!this.states[row] || !this.states[row].cellData)
this.states[row] = data.state;
this.lines[row + 1] = null;
if (this.currentLine > row + 1)
this.currentLine = row + 1;
} else if (this.currentLine == row) {
this.currentLine = row + 1;
}
if (this.session.repl.onTokenizeRow)
data.tokens = this.session.repl.onTokenizeRow(row, data.tokens) || data.tokens;
return this.lines[row] = data.tokens;
};
this.addLineWidget = function(w) {
var renderer = this.editor.renderer;
if (w.html && !w.el) {
w.el = dom.createElement("div");
w.el.innerHTML = w.html;
}
if (w.el) {
dom.addCssClass(w.el, "ace_lineWidgetContainer");
renderer.container.appendChild(w.el);
w._inDocument = true;
}
if (!w.coverGutter) {
w.el.style.zIndex = 3;
}
if (!w.pixelHeight) {
w.pixelHeight = w.el.offsetHeight;
}
if (w.rowCount == null)
w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
this.session._emit("changeFold", { data: { start: { row: w.row }}});
this.$updateSession();
this.updateWidgets(null, renderer);
return w;
};
this.removeLineWidget = function(w) {
w._inDocument = false;
if (w.el && w.el.parentNode)
w.el.parentNode.removeChild(w.el);
if (w.editor && w.editor.destroy) try {
w.editor.destroy();
} catch (e) {}
this.session._emit("changeFold", { data: { start: { row: w.row }}});
this.$updateSession();
};
this.onWidgetChanged = function(w) {
this.session._changedWidgets.push(w);
this.editor && this.editor.renderer.updateFull();
};
this.measureWidgets = function(e, renderer) {
var ws = this.session._changedWidgets;
var config = renderer.layerConfig;
if (!ws || !ws.length) return;
var min = Infinity;
for (var i = 0; i < ws.length; i++) {
var w = ws[i].lineWidget;
if (!w._inDocument) {
w._inDocument = true;
renderer.container.appendChild(w.el);
}
w.h = w.el.offsetHeight;
if (!w.fixedWidth) {
w.w = w.el.offsetWidth;
w.screenWidth = Math.ceil(w.w / config.characterWidth);
}
var rowCount = w.h / config.lineHeight;
if (w.coverLine)
rowCount -= this.session.getRowLineCount(w.row);
if (w.rowCount != rowCount) {
w.rowCount = rowCount;
if (w.row < min)
min = w.row;
}
}
if (min != Infinity) {
this.session._emit("changeFold", { data: { start: { row: min }}});
this.session.lineWidgetWidth = null;
}
this.session._changedWidgets = [];
};
this.updateWidgets = function(e, renderer) {
var config = renderer.layerConfig;
var cells = this.session.replCells;
if (!cells)
return;
var first = Math.min(this.firstRow, config.firstRow);
var last = Math.max(this.lastRow, config.lastRow, cells.length);
while (first > 0 && !cells[first])
first--;
this.firstRow = config.firstRow;
this.lastRow = config.lastRow;
renderer.$cursorLayer.config = config;
for (var i = first; i <= last; i++) {
var c = cells[i];
var w = c && c.lineWidget;
if (!w || !w.el) continue;
if (!w._inDocument) {
w._inDocument = true;
renderer.container.appendChild(w.el);
}
var top = renderer.$cursorLayer.getPixelPosition({ row: i, column: 0 }, true).top;
if (!w.coverLine)
top += config.lineHeight * this.session.getRowLineCount(w.row);
w.el.style.top = top - config.offset + "px";
var left = w.coverGutter ? 0 : renderer.gutterWidth;
if (!w.fixedWidth)
left -= renderer.scrollLeft;
w.el.style.left = left + "px";
if (w.fixedWidth) {
w.el.style.right = renderer.scrollBar.getWidth() + "px";
} else {
w.el.style.right = "";
}
}
};
}).call(Repl.prototype);
var History = function() {
this._data = [];
this._tempData = Object.create(null);
this.position = 0;
};
History.prototype = {
add: function(text) {
if (text && this._data[0] !== text) {
this._data.unshift(text);
}
delete this._tempData[this.position];
this.position = -1;
this._tempData[-1] = "";
return this._data;
},
navigateList: function(type, value) {
var lines = this._data;
if (value && (lines[this.position] != value)) {
this._tempData[this.position] = value;
}
if (type == "next") {
if (this.position <= 0) {
this.position = -1;
return this._tempData[this.position] || "";
}
var next = Math.max(0, this.position - 1);
}
else if (type == "prev")
next = Math.min(lines.length - 1, this.position + 1);
else if (type == "last")
next = Math.max(lines.length - 1, 0);
else if (type == "first")
next = 0;
if (lines[next] && next != this.position) {
this.position = next;
return this._tempData[next] || lines[next];
}
}
};
function clonePos(pos) {
return { row: pos.row, column: pos.column };
}
function setPos(pos, newPos) {
pos.row = newPos.row;
pos.column = newPos.column;
}
function clipPos(pos, range) {
if (comparePoints(pos, range.start) < 0) {
setPos(pos, range.start);
} else if (comparePoints(pos, range.end) > 0) {
setPos(pos, range.end);
}
}
Range.prototype.clip = function(range) {
clipPos(this.start, range);
clipPos(this.end, range);
};
function setClipToRange(anchor, range) {
anchor.$clip_default = Anchor.prototype.$clipPositionToDocument;
if (!range) {
anchor.$clipPositionToDocument = anchor.$clip_default;
return;
}
anchor.$clipPositionToDocument = function(row, column) {
var pos = this.$clip_default(row, column);
clipPos(pos, range);
return pos;
};
}
// dummy example
var Evaluator = function() {
};
(function() {
this.canEvaluate = function(str) {
return !!str.trim();
};
this.evaluate = function(str, cell, cb) {
cb("evaluator is missing!");
};
}).call(Evaluator.prototype);
Repl.fromEditor = function(editor, options) {
// todo different modes for input and output
var repl = new Repl(editor.session, options);
// this should happen on session.changeEditor event
repl.attach(editor);
editor.setOption("showPrintMargin", false);
return repl;
};
exports.Repl = Repl;
});