Merge branch 'master' into worker
This commit is contained in:
commit
faa155a20f
48 changed files with 1842 additions and 1340 deletions
25
.gitmodules
vendored
25
.gitmodules
vendored
|
|
@ -1,30 +1,9 @@
|
|||
[submodule "tool/support/node-o3-xml"]
|
||||
path = tool/support/node-o3-xml
|
||||
url = git://github.com/ajaxorg/node-o3-xml.git
|
||||
[submodule "tool/support/async"]
|
||||
path = tool/support/async
|
||||
url = git://github.com/fjakobs/async.js.git
|
||||
[submodule "support/requirejs"]
|
||||
path = support/requirejs
|
||||
url = git://github.com/jrburke/requirejs.git
|
||||
[submodule "support/node-o3-xml"]
|
||||
path = support/node-o3-xml
|
||||
url = git://github.com/ajaxorg/node-o3-xml.git
|
||||
[submodule "support/async"]
|
||||
path = support/async
|
||||
url = git://github.com/fjakobs/async.js.git
|
||||
[submodule "support/jsdom"]
|
||||
path = support/jsdom
|
||||
url = git://github.com/tmpvar/jsdom.git
|
||||
[submodule "support/node-htmlparser"]
|
||||
path = support/node-htmlparser
|
||||
url = git://github.com/tautologistics/node-htmlparser.git
|
||||
[submodule "support/cockpit"]
|
||||
path = support/cockpit
|
||||
url = git://github.com/mozilla/cockpit.git
|
||||
url = git://github.com/ajaxorg/cockpit.git
|
||||
[submodule "support/pilot"]
|
||||
path = support/pilot
|
||||
url = git://github.com/ajaxorg/pilot.git
|
||||
[submodule "support/dryice"]
|
||||
path = support/dryice
|
||||
url = git://github.com/mozilla/dryice.git
|
||||
url = git://github.com/ajaxorg/pilot.git
|
||||
5
Makefile.dryice.js
Normal file → Executable file
5
Makefile.dryice.js
Normal file → Executable file
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/env node
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
|
@ -44,7 +45,7 @@ var aceHome = __dirname;
|
|||
var pilot = copy.createDataObject();
|
||||
copy({
|
||||
source: [ {
|
||||
root: aceHome + '/support/cockpit/support/pilot/lib',
|
||||
root: aceHome + '/support/pilot/lib',
|
||||
include: /.*\.js$/,
|
||||
exclude: /tests?\//
|
||||
} ],
|
||||
|
|
@ -137,7 +138,7 @@ copy({
|
|||
// Create the compressed and uncompressed output files
|
||||
copy({
|
||||
source: data,
|
||||
filter: copy.filter.uglifyjs,
|
||||
//filter: copy.filter.uglifyjs,
|
||||
dest: 'build/ace.js'
|
||||
});
|
||||
copy({
|
||||
|
|
|
|||
72
Readme.md
72
Readme.md
|
|
@ -1,6 +1,70 @@
|
|||
ACE (Ajax.org Code Editor)
|
||||
==========================
|
||||
Ace (Ajax.org Cloud9 Editor)
|
||||
============================
|
||||
|
||||
ACE is a standalone code editor written in JavaScript. It can be easily embedded in any web page and JavaScript application. It is currently used as the editor component of the [Cloud9 IDE](http://cloud9ide.com).
|
||||
Ace is a standalone code editor written in JavaScript. Our goal is to create a web based code editor that matches and extends the features, usability and performance of existing native editors such as TextMate, Vim or Eclipse. It can be easily embedded in any web page and JavaScript application. Ace is developed as the primary editor for [Cloud9 IDE](http://www.cloud9ide.com/) and the successor of the Mozilla Skywriter (Bespin) Project.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Syntax highlighting
|
||||
* Auto indentation and outdent
|
||||
* An optional command line
|
||||
* Work with huge documents (100,000 lines and more are no problem)
|
||||
* Fully customizable key bindings including VI and Emacs modes
|
||||
* Themes (TextMate themes can be imported)
|
||||
* Search and replace with regular expressions
|
||||
* Highlight matching parentheses
|
||||
* Toggle between soft tabs and real tabs
|
||||
* Displays hidden characters
|
||||
|
||||
Take Ace for a spin!
|
||||
--------------------
|
||||
|
||||
Check out the Ace live [demo](http://ajaxorg.github.com/ace/editor-build.html) or get a [Cloud9 IDE account](http://run.cloud9ide.com) to experience Ace while editing one of your own GitHub projects.
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
Previously known as “Bespin” or lately “Skywriter” it’s now known as Ace (Ajax.org Cloud9 Editor)! Bespin and Ace started as two independent projects both aiming to build a no compromise code editor component for the web. Bespin started as part of Mozilla Labs and was based on the canvas tag, while Ace is the Editor component of the Cloud9 IDE and is using the DOM for rendering. After the release of Ace at JSConf.eu 2010 in Berlin the Skywriter team decided to merge Ace with a simplified version of Skywriter's plugin system and some of Skywriter's extensibility points. All these changes have been merged back to Ace now, which supersedes Skywriter. Both Ajax.org and Mozilla are actively developing and maintaining Ace.
|
||||
|
||||
Getting the code
|
||||
----------------
|
||||
|
||||
Ace is a community project. We actively encourage and support contributions. The Ace source code is hosted on GitHub. It is released under the Mozilla tri-license (MPL/GPL/LGPL). This is the same license used by Firefox. This license is friendly to all kinds of projects, whether open source or not. Take charge of your editor and add your favorite language highlighting and keybindings!
|
||||
|
||||
git clone git://github.com/ajaxorg/ace.git
|
||||
git submodule update --init --recursive
|
||||
|
||||
Running Ace
|
||||
-----------
|
||||
|
||||
After the checkout Ace works out of the box. No build step is required. Simply open 'editor.html' in any browser except Google Chrome. Google Chrome doesn't allow XMLHTTPRequests from files loaded from disc (i.e. with a file:/// URL). To open the Ace in Chrome simply start the bundled mini HTTP server:
|
||||
|
||||
./static.py
|
||||
|
||||
The editor can then be opened at http://localhost:9999/editor.html.
|
||||
|
||||
Package Ace
|
||||
-----------
|
||||
|
||||
To package Ace we use the dryice build tool developed by the Mozilla Skywriter team. To install dryice and all its dependencies simply call:
|
||||
|
||||
npm link .
|
||||
|
||||
Afterwards Ace can by build by calling
|
||||
|
||||
./Makefile.dryice.js
|
||||
|
||||
The packaged Ace will be put in the 'build' folder.
|
||||
|
||||
Running the Unit Tests
|
||||
----------------------
|
||||
|
||||
The Ace unit tests run on node.js. Before the first run a couple of node mudules have to be installed. The easiest way to do this is by using the node package manager (npm). In the Ace base directory simply call
|
||||
|
||||
npm link .
|
||||
|
||||
To run the tests call:
|
||||
|
||||
node lib/ace/test/all.js
|
||||
|
||||
Checkout the [demo](http://ajaxorg.github.com/ace/editor-build.html)!
|
||||
|
|
|
|||
|
|
@ -51,20 +51,20 @@ var ace = {
|
|||
var env = require("pilot/environment").create();
|
||||
var catalog = require("pilot/plugin_manager").catalog;
|
||||
catalog.startupPlugins({ env: env }).then(function() {
|
||||
var Document = require("ace/document").Document;
|
||||
var EditSession = require("ace/edit_session").EditSession;
|
||||
var JavaScriptMode = require("ace/mode/javascript").Mode;
|
||||
var UndoManager = require("ace/undomanager").UndoManager;
|
||||
var Editor = require("ace/editor").Editor;
|
||||
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
|
||||
var theme = require("ace/theme/textmate");
|
||||
|
||||
var doc = new Document(el.innerHTML);
|
||||
var doc = new EditSession(el.innerHTML);
|
||||
el.innerHTML = '';
|
||||
doc.setMode(new JavaScriptMode());
|
||||
doc.setUndoManager(new UndoManager());
|
||||
env.document = doc;
|
||||
env.editor = new Editor(new Renderer(el, theme));
|
||||
env.editor.setDocument(doc);
|
||||
env.editor.setSession(doc);
|
||||
env.editor.resize();
|
||||
window.addEventListener("resize", function() {
|
||||
env.editor.resize();
|
||||
|
|
|
|||
|
|
@ -88,6 +88,6 @@ function define(module, payload) {
|
|||
return;
|
||||
}
|
||||
|
||||
console.log('defining module: ' + module + ' as a ' + typeof payload);
|
||||
// console.log('defining module: ' + module + ' as a ' + typeof payload);
|
||||
require.modules[module] = payload;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ exports.launch = function(env) {
|
|||
var event = require("pilot/event");
|
||||
var Editor = require("ace/editor").Editor;
|
||||
var Renderer = require("ace/virtual_renderer").VirtualRenderer;
|
||||
var theme = require("ace/theme/textmate");
|
||||
var Document = require("ace/document").Document;
|
||||
var theme = require("ace/theme/textmate");
|
||||
var EditSession = require("ace/edit_session").EditSession;
|
||||
var JavaScriptMode = require("ace/mode/javascript").Mode;
|
||||
var CssMode = require("ace/mode/css").Mode;
|
||||
var HtmlMode = require("ace/mode/html").Mode;
|
||||
|
|
@ -63,26 +63,26 @@ exports.launch = function(env) {
|
|||
|
||||
var docs = {};
|
||||
|
||||
docs.js = new Document(document.getElementById("jstext").innerHTML);
|
||||
docs.js = new EditSession(document.getElementById("jstext").innerHTML);
|
||||
docs.js.setMode(new JavaScriptMode());
|
||||
docs.js.setUndoManager(new UndoManager());
|
||||
|
||||
var worker = new WorkerClient("../..", ["ace", "pilot"], "ace/worker/demo", "Demo");
|
||||
worker.send("juhu");
|
||||
|
||||
docs.css = new Document(document.getElementById("csstext").innerHTML);
|
||||
docs.css = new EditSession(document.getElementById("csstext").innerHTML);
|
||||
docs.css.setMode(new CssMode());
|
||||
docs.css.setUndoManager(new UndoManager());
|
||||
|
||||
docs.html = new Document(document.getElementById("htmltext").innerHTML);
|
||||
docs.html = new EditSession(document.getElementById("htmltext").innerHTML);
|
||||
docs.html.setMode(new HtmlMode());
|
||||
docs.html.setUndoManager(new UndoManager());
|
||||
|
||||
docs.python = new Document(document.getElementById("pythontext").innerHTML);
|
||||
docs.python = new EditSession(document.getElementById("pythontext").innerHTML);
|
||||
docs.python.setMode(new PythonMode());
|
||||
docs.python.setUndoManager(new UndoManager());
|
||||
|
||||
docs.php = new Document(document.getElementById("phptext").innerHTML);
|
||||
docs.php = new EditSession(document.getElementById("phptext").innerHTML);
|
||||
docs.php.setMode(new PhpMode());
|
||||
docs.php.setUndoManager(new UndoManager());
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ exports.launch = function(env) {
|
|||
|
||||
var modeEl = document.getElementById("mode");
|
||||
function setMode() {
|
||||
env.editor.getDocument().setMode(modes[modeEl.value] || modes.text);
|
||||
env.editor.getSession().setMode(modes[modeEl.value] || modes.text);
|
||||
}
|
||||
modeEl.onchange = setMode;
|
||||
setMode();
|
||||
|
|
@ -125,7 +125,7 @@ exports.launch = function(env) {
|
|||
var docEl = document.getElementById("doc");
|
||||
function onDocChange() {
|
||||
var doc = docs[docEl.value];
|
||||
env.editor.setDocument(doc);
|
||||
env.editor.setSession(doc);
|
||||
|
||||
var mode = doc.getMode();
|
||||
if (mode instanceof JavaScriptMode) {
|
||||
|
|
@ -245,7 +245,7 @@ exports.launch = function(env) {
|
|||
env.editor.onTextInput(reader.result);
|
||||
|
||||
modeEl.value = mode;
|
||||
env.editor.getDocument().setMode(modes[mode]);
|
||||
env.editor.getSession().setMode(modes[mode]);
|
||||
};
|
||||
reader.readAsText(file);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,11 +197,11 @@ echo $output;
|
|||
|
||||
<input id="cockpitInput" type="text"/>
|
||||
|
||||
<script src="build/demo/require.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="build/demo/boot.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="demo/require.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="demo/boot.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script type="text/javascript">
|
||||
require("demo/boot");
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -38,40 +38,33 @@
|
|||
define(function(require, exports, module) {
|
||||
|
||||
var oop = require("pilot/oop");
|
||||
var lang = require("pilot/lang");
|
||||
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||
var Selection = require("ace/selection").Selection;
|
||||
var TextMode = require("ace/mode/text").Mode;
|
||||
var Range = require("ace/range").Range;
|
||||
|
||||
var NO_CHANGE_DELTAS = {};
|
||||
|
||||
var Document = function(text, mode) {
|
||||
|
||||
this.modified = true;
|
||||
var Document = function(text) {
|
||||
this.$lines = [];
|
||||
this.selection = new Selection(this);
|
||||
this.$breakpoints = [];
|
||||
|
||||
this.listeners = [];
|
||||
if (mode) {
|
||||
this.setMode(mode);
|
||||
}
|
||||
|
||||
if (Array.isArray(text)) {
|
||||
this.$insertLines(0, text);
|
||||
this.insertLines(0, text);
|
||||
} else {
|
||||
this.$insert({row: 0, column: 0}, text);
|
||||
this.insert({row: 0, column:0}, text);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.$undoManager = null;
|
||||
|
||||
this.setValue = function(text) {
|
||||
var len = this.getLength();
|
||||
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
|
||||
this.insertLines(0, this.$split(text));
|
||||
};
|
||||
|
||||
this.getValue = function() {
|
||||
return this.$lines.join(this.getNewLineCharacter());
|
||||
};
|
||||
|
||||
// check for IE split bug
|
||||
if ("aaa".split(/a/).length == 0)
|
||||
this.$split = function(text) {
|
||||
|
|
@ -82,125 +75,7 @@ var Document = function(text, mode) {
|
|||
return text.split(/\r\n|\r|\n/);
|
||||
};
|
||||
|
||||
this.setValue = function(text) {
|
||||
var args = [0, this.$lines.length];
|
||||
args.push.apply(args, this.$split(text));
|
||||
this.$lines.splice.apply(this.$lines, args);
|
||||
this.modified = true;
|
||||
this.fireChangeEvent(0);
|
||||
};
|
||||
|
||||
this.toString = function() {
|
||||
return this.$lines.join(this.$getNewLineCharacter());
|
||||
};
|
||||
|
||||
this.getValue = this.toString;
|
||||
|
||||
this.getSelection = function() {
|
||||
return this.selection;
|
||||
};
|
||||
|
||||
this.fireChangeEvent = function(firstRow, lastRow) {
|
||||
var data = {
|
||||
firstRow: firstRow,
|
||||
lastRow: lastRow
|
||||
};
|
||||
this._dispatchEvent("change", { data: data});
|
||||
};
|
||||
|
||||
this.setUndoManager = function(undoManager) {
|
||||
this.$undoManager = undoManager;
|
||||
this.$deltas = [];
|
||||
|
||||
if (this.$informUndoManager) {
|
||||
this.$informUndoManager.cancel();
|
||||
}
|
||||
|
||||
if (undoManager) {
|
||||
var self = this;
|
||||
this.$informUndoManager = lang.deferredCall(function() {
|
||||
if (self.$deltas.length > 0)
|
||||
undoManager.execute({
|
||||
action : "aceupdate",
|
||||
args : [self.$deltas, self]
|
||||
});
|
||||
self.$deltas = [];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.$defaultUndoManager = {
|
||||
undo: function() {},
|
||||
redo: function() {}
|
||||
};
|
||||
|
||||
this.getUndoManager = function() {
|
||||
return this.$undoManager || this.$defaultUndoManager;
|
||||
},
|
||||
|
||||
this.getTabString = function() {
|
||||
if (this.getUseSoftTabs()) {
|
||||
return lang.stringRepeat(" ", this.getTabSize());
|
||||
} else {
|
||||
return "\t";
|
||||
}
|
||||
};
|
||||
|
||||
this.$useSoftTabs = true;
|
||||
this.setUseSoftTabs = function(useSoftTabs) {
|
||||
if (this.$useSoftTabs === useSoftTabs) return;
|
||||
|
||||
this.$useSoftTabs = useSoftTabs;
|
||||
};
|
||||
|
||||
this.getUseSoftTabs = function() {
|
||||
return this.$useSoftTabs;
|
||||
};
|
||||
|
||||
this.$tabSize = 4;
|
||||
this.setTabSize = function(tabSize) {
|
||||
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
|
||||
|
||||
this.modified = true;
|
||||
this.$tabSize = tabSize;
|
||||
this._dispatchEvent("changeTabSize");
|
||||
};
|
||||
|
||||
this.getTabSize = function() {
|
||||
return this.$tabSize;
|
||||
};
|
||||
|
||||
this.isTabStop = function(position) {
|
||||
return this.$useSoftTabs && (position.column % this.$tabSize == 0);
|
||||
};
|
||||
|
||||
this.getBreakpoints = function() {
|
||||
return this.$breakpoints;
|
||||
};
|
||||
|
||||
this.setBreakpoints = function(rows) {
|
||||
this.$breakpoints = [];
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
this.$breakpoints[rows[i]] = true;
|
||||
}
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.clearBreakpoints = function() {
|
||||
this.$breakpoints = [];
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.setBreakpoint = function(row) {
|
||||
this.$breakpoints[row] = true;
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.clearBreakpoint = function(row) {
|
||||
delete this.$breakpoints[row];
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.$detectNewLine = function(text) {
|
||||
var match = text.match(/^.*?(\r?\n)/m);
|
||||
if (match) {
|
||||
|
|
@ -210,41 +85,7 @@ var Document = function(text, mode) {
|
|||
}
|
||||
};
|
||||
|
||||
this.tokenRe = /^[\w\d]+/g;
|
||||
this.nonTokenRe = /^[^\w\d]+/g;
|
||||
|
||||
this.getWordRange = function(row, column) {
|
||||
var line = this.getLine(row);
|
||||
|
||||
var inToken = false;
|
||||
if (column > 0) {
|
||||
inToken = !!line.charAt(column - 1).match(this.tokenRe);
|
||||
}
|
||||
|
||||
if (!inToken) {
|
||||
inToken = !!line.charAt(column).match(this.tokenRe);
|
||||
}
|
||||
|
||||
var re = inToken ? this.tokenRe : this.nonTokenRe;
|
||||
|
||||
var start = column;
|
||||
if (start > 0) {
|
||||
do {
|
||||
start--;
|
||||
}
|
||||
while (start >= 0 && line.charAt(start).match(re));
|
||||
start++;
|
||||
}
|
||||
|
||||
var end = column;
|
||||
while (end < line.length && line.charAt(end).match(re)) {
|
||||
end++;
|
||||
}
|
||||
|
||||
return new Range(row, start, row, end);
|
||||
};
|
||||
|
||||
this.$getNewLineCharacter = function() {
|
||||
this.getNewLineCharacter = function() {
|
||||
switch (this.$newLineMode) {
|
||||
case "windows":
|
||||
return "\r\n";
|
||||
|
|
@ -268,66 +109,9 @@ var Document = function(text, mode) {
|
|||
this.getNewLineMode = function() {
|
||||
return this.$newLineMode;
|
||||
};
|
||||
|
||||
this.$mode = null;
|
||||
this.setMode = function(mode) {
|
||||
if (this.$mode === mode) return;
|
||||
|
||||
this.$mode = mode;
|
||||
this._dispatchEvent("changeMode");
|
||||
};
|
||||
|
||||
this.getMode = function() {
|
||||
if (!this.$mode) {
|
||||
this.$mode = new TextMode();
|
||||
}
|
||||
return this.$mode;
|
||||
};
|
||||
|
||||
this.$scrollTop = 0;
|
||||
this.setScrollTopRow = function(scrollTopRow) {
|
||||
if (this.$scrollTop === scrollTopRow) return;
|
||||
|
||||
this.$scrollTop = scrollTopRow;
|
||||
this._dispatchEvent("changeScrollTop");
|
||||
};
|
||||
|
||||
this.getScrollTopRow = function() {
|
||||
return this.$scrollTop;
|
||||
};
|
||||
|
||||
this.getWidth = function() {
|
||||
this.$computeWidth();
|
||||
return this.width;
|
||||
};
|
||||
|
||||
this.getScreenWidth = function() {
|
||||
this.$computeWidth();
|
||||
return this.screenWidth;
|
||||
};
|
||||
|
||||
this.$computeWidth = function() {
|
||||
if (this.modified) {
|
||||
this.modified = false;
|
||||
|
||||
var lines = this.$lines;
|
||||
var longestLine = 0;
|
||||
var longestScreenLine = 0;
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
for ( var i = 0; i < lines.length; i++) {
|
||||
var len = lines[i].length;
|
||||
longestLine = Math.max(longestLine, len);
|
||||
|
||||
lines[i].replace("\t", function(m) {
|
||||
len += tabSize-1;
|
||||
return m;
|
||||
});
|
||||
longestScreenLine = Math.max(longestScreenLine, len);
|
||||
}
|
||||
this.width = longestLine;
|
||||
this.screenWidth = longestScreenLine;
|
||||
}
|
||||
|
||||
this.isNewLine = function(text) {
|
||||
return (text == "\r\n" || text == "\r" || text == "\n");
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -337,17 +121,17 @@ var Document = function(text, mode) {
|
|||
return this.$lines[row] || "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a line as it is displayed on screen. Tabs are replaced by spaces.
|
||||
*/
|
||||
this.getDisplayLine = function(row) {
|
||||
var tab = new Array(this.getTabSize()+1).join(" ");
|
||||
return this.$lines[row].replace(/\t/g, tab);
|
||||
};
|
||||
|
||||
this.getLines = function(firstRow, lastRow) {
|
||||
return this.$lines.slice(firstRow, lastRow+1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns all lines in the document as string array. Warning: The caller
|
||||
* should not modify this array!
|
||||
*/
|
||||
this.getAllLines = function() {
|
||||
return this.$lines;
|
||||
};
|
||||
|
||||
this.getLength = function() {
|
||||
return this.$lines.length;
|
||||
|
|
@ -363,480 +147,243 @@ var Document = function(text, mode) {
|
|||
lines.push(this.$lines[range.start.row].substring(range.start.column));
|
||||
lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
|
||||
lines.push(this.$lines[range.end.row].substring(0, range.end.column));
|
||||
return lines.join(this.$getNewLineCharacter());
|
||||
return lines.join(this.getNewLineCharacter());
|
||||
}
|
||||
};
|
||||
|
||||
this.findMatchingBracket = function(position) {
|
||||
if (position.column == 0) return null;
|
||||
|
||||
var charBeforeCursor = this.getLine(position.row).charAt(position.column-1);
|
||||
if (charBeforeCursor == "") return null;
|
||||
|
||||
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
|
||||
if (!match) {
|
||||
return null;
|
||||
this.$clipPosition = function(position) {
|
||||
var length = this.getLength();
|
||||
if (position.row >= length) {
|
||||
position.row = Math.max(0, length - 1);
|
||||
position.column = this.getLine(length-1).length;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
if (match[1]) {
|
||||
return this.$findClosingBracket(match[1], position);
|
||||
} else {
|
||||
return this.$findOpeningBracket(match[2], position);
|
||||
}
|
||||
};
|
||||
|
||||
this.$brackets = {
|
||||
")": "(",
|
||||
"(": ")",
|
||||
"]": "[",
|
||||
"[": "]",
|
||||
"{": "}",
|
||||
"}": "{"
|
||||
};
|
||||
|
||||
this.$findOpeningBracket = function(bracket, position) {
|
||||
var openBracket = this.$brackets[bracket];
|
||||
|
||||
var column = position.column - 2;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
|
||||
while (true) {
|
||||
while(column >= 0) {
|
||||
var ch = line.charAt(column);
|
||||
if (ch == openBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (ch == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column -= 1;
|
||||
}
|
||||
row -=1;
|
||||
if (row < 0) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = line.length-1;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.$findClosingBracket = function(bracket, position) {
|
||||
var closingBracket = this.$brackets[bracket];
|
||||
|
||||
var column = position.column;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var lineCount = this.getLength();
|
||||
|
||||
while (true) {
|
||||
while(column < line.length) {
|
||||
var ch = line.charAt(column);
|
||||
if (ch == closingBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (ch == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column += 1;
|
||||
}
|
||||
row +=1;
|
||||
if (row >= lineCount) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = 0;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.insert = function(position, text, fromUndo) {
|
||||
var end = this.$insert(position, text, fromUndo);
|
||||
this.fireChangeEvent(position.row, position.row == end.row ? position.row
|
||||
: undefined);
|
||||
return end;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param rows Array[Integer] sorted list of rows
|
||||
*/
|
||||
this.multiRowInsert = function(rows, column, text) {
|
||||
var lines = this.$lines;
|
||||
|
||||
for (var i=rows.length-1; i>=0; i--) {
|
||||
var row = rows[i];
|
||||
if (row >= lines.length)
|
||||
continue;
|
||||
|
||||
var diff = column - lines[row].length;
|
||||
if ( diff > 0) {
|
||||
var padded = lang.stringRepeat(" ", diff) + text;
|
||||
var offset = -diff;
|
||||
}
|
||||
else {
|
||||
padded = text;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var end = this.$insert({row: row, column: column+offset}, padded, false);
|
||||
}
|
||||
|
||||
if (end) {
|
||||
this.fireChangeEvent(rows[0], rows[rows.length-1] + end.row - rows[0]);
|
||||
return {
|
||||
rows: end.row - rows[0],
|
||||
columns: end.column - column
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {
|
||||
rows: 0,
|
||||
columns: 0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.$insertLines = function(row, lines, fromUndo) {
|
||||
if (lines.length == 0)
|
||||
return;
|
||||
|
||||
var args = [row, 0];
|
||||
args.push.apply(args, lines);
|
||||
this.$lines.splice.apply(this.$lines, args);
|
||||
|
||||
var nl = this.$getNewLineCharacter();
|
||||
var delta = {
|
||||
action: "insertText",
|
||||
range: new Range(row, 0, row + lines.length, 0),
|
||||
text: lines.join(nl) + nl
|
||||
};
|
||||
if (!fromUndo && this.$undoManager) {
|
||||
this.$deltas.push(delta);
|
||||
this.$informUndoManager.schedule();
|
||||
}
|
||||
|
||||
if (fromUndo !== NO_CHANGE_DELTAS) {
|
||||
this._dispatchEvent("changeDelta", { data: delta });
|
||||
}
|
||||
},
|
||||
|
||||
this.$insert = function(position, text, fromUndo) {
|
||||
this.insert = function(position, text) {
|
||||
if (text.length == 0)
|
||||
return position;
|
||||
|
||||
this.modified = true;
|
||||
if (this.$lines.length <= 1) {
|
||||
|
||||
position = this.$clipPosition(position);
|
||||
|
||||
if (this.getLength() <= 1)
|
||||
this.$detectNewLine(text);
|
||||
}
|
||||
|
||||
var newLines = this.$split(text);
|
||||
|
||||
if (this.$isNewLine(text)) {
|
||||
var line = this.$lines[position.row] || "";
|
||||
this.$lines[position.row] = line.substring(0, position.column);
|
||||
this.$lines.splice(position.row + 1, 0, line.substring(position.column));
|
||||
|
||||
var end = {
|
||||
row : position.row + 1,
|
||||
column : 0
|
||||
};
|
||||
if (this.isNewLine(text)) {
|
||||
var end = this.insertNewLine(position);
|
||||
}
|
||||
else if (newLines.length == 1) {
|
||||
var line = this.$lines[position.row] || "";
|
||||
this.$lines[position.row] = line.substring(0, position.column) + text
|
||||
+ line.substring(position.column);
|
||||
|
||||
var end = {
|
||||
row : position.row,
|
||||
column : position.column + text.length
|
||||
};
|
||||
var end = this.insertInLine(position, text);
|
||||
}
|
||||
else {
|
||||
var line = this.$lines[position.row] || "";
|
||||
var firstLine = line.substring(0, position.column) + newLines[0];
|
||||
var lastLine = newLines[newLines.length - 1] + line.substring(position.column);
|
||||
|
||||
this.$lines[position.row] = firstLine;
|
||||
this.$insertLines(position.row + 1, [lastLine], NO_CHANGE_DELTAS);
|
||||
|
||||
if (newLines.length > 2) {
|
||||
this.$insertLines(position.row + 1, newLines.slice(1, -1), NO_CHANGE_DELTAS);
|
||||
}
|
||||
|
||||
var end = {
|
||||
row : position.row + newLines.length - 1,
|
||||
column : newLines[newLines.length - 1].length
|
||||
};
|
||||
var end = this.insertInLine(position, newLines[0]);
|
||||
this.insertNewLine(end);
|
||||
if (newLines.length > 2)
|
||||
this.insertLines(position.row+1, newLines.slice(1, newLines.length-1));
|
||||
|
||||
var end = this.insertInLine({row: position.row + newLines.length - 1, column: 0}, newLines[newLines.length-1]);
|
||||
}
|
||||
|
||||
return end;
|
||||
};
|
||||
|
||||
this.insertLines = function(row, lines) {
|
||||
if (lines.length == 0)
|
||||
return {row: row, column: 0};
|
||||
|
||||
var args = [row, 0];
|
||||
args.push.apply(args, lines);
|
||||
this.$lines.splice.apply(this.$lines, args);
|
||||
|
||||
var range = new Range(row, 0, row + lines.length - 1, 0);
|
||||
var delta = {
|
||||
action: "insertLines",
|
||||
range: range,
|
||||
lines: lines
|
||||
};
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
return range.end;
|
||||
},
|
||||
|
||||
this.insertNewLine = function(position) {
|
||||
position = this.$clipPosition(position);
|
||||
var line = this.$lines[position.row] || "";
|
||||
this.$lines[position.row] = line.substring(0, position.column);
|
||||
this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
|
||||
|
||||
var end = {
|
||||
row : position.row + 1,
|
||||
column : 0
|
||||
};
|
||||
|
||||
var delta = {
|
||||
action: "insertText",
|
||||
range: Range.fromPoints(position, end),
|
||||
text: this.getNewLineCharacter()
|
||||
};
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
|
||||
return end;
|
||||
};
|
||||
|
||||
this.insertInLine = function(position, text) {
|
||||
if (text.length == 0)
|
||||
return position;
|
||||
|
||||
var line = this.$lines[position.row] || "";
|
||||
this.$lines[position.row] = line.substring(0, position.column) + text
|
||||
+ line.substring(position.column);
|
||||
|
||||
var end = {
|
||||
row : position.row,
|
||||
column : position.column + text.length
|
||||
};
|
||||
|
||||
var delta = {
|
||||
action: "insertText",
|
||||
range: Range.fromPoints(position, end),
|
||||
text: text
|
||||
};
|
||||
if (!fromUndo && this.$undoManager) {
|
||||
this.$deltas.push(delta);
|
||||
this.$informUndoManager.schedule();
|
||||
}
|
||||
this._dispatchEvent("changeDelta", { data: delta });
|
||||
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
|
||||
return end;
|
||||
};
|
||||
|
||||
this.$isNewLine = function(text) {
|
||||
return (text == "\r\n" || text == "\r" || text == "\n");
|
||||
};
|
||||
this.remove = function(range) {
|
||||
// clip to document
|
||||
range.start = this.$clipPosition(range.start);
|
||||
range.end = this.$clipPosition(range.end);
|
||||
|
||||
this.remove = function(range, fromUndo) {
|
||||
if (range.isEmpty())
|
||||
return range.start;
|
||||
|
||||
this.$remove(range, fromUndo);
|
||||
|
||||
this.fireChangeEvent(range.start.row, range.isMultiLine() ? undefined : range.start.row);
|
||||
|
||||
return range.start;
|
||||
};
|
||||
|
||||
this.multiRowRemove = function(rows, range) {
|
||||
if (range.start.row !== rows[0])
|
||||
throw new TypeError("range must start in the first row!");
|
||||
|
||||
var height = range.end.row - rows[0];
|
||||
for (var i=rows.length-1; i>=0; i--) {
|
||||
var row = rows[i];
|
||||
if (row >= this.$lines.length)
|
||||
continue;
|
||||
|
||||
var end = this.$remove(new Range(row, range.start.column, row+height, range.end.column), false);
|
||||
}
|
||||
|
||||
if (end) {
|
||||
if (height < 0)
|
||||
this.fireChangeEvent(rows[0]+height, undefined);
|
||||
else
|
||||
this.fireChangeEvent(rows[0], height == 0 ? rows[rows.length-1] : undefined);
|
||||
}
|
||||
};
|
||||
|
||||
this.$remove = function(range, fromUndo) {
|
||||
if (range.isEmpty())
|
||||
return;
|
||||
|
||||
var delta = {
|
||||
action: "removeText",
|
||||
range: range.clone(),
|
||||
text: this.getTextRange(range)
|
||||
};
|
||||
if (!fromUndo && this.$undoManager) {
|
||||
this.$deltas.push(delta);
|
||||
this.$informUndoManager.schedule();
|
||||
}
|
||||
|
||||
this.modified = true;
|
||||
|
||||
var firstRow = range.start.row;
|
||||
var lastRow = range.end.row;
|
||||
|
||||
var row = this.getLine(firstRow).substring(0, range.start.column)
|
||||
+ this.getLine(lastRow).substring(range.end.column);
|
||||
|
||||
if (row != "")
|
||||
this.$lines.splice(firstRow, lastRow - firstRow + 1, row);
|
||||
else
|
||||
this.$lines.splice(firstRow, lastRow - firstRow + 1, "");
|
||||
|
||||
this._dispatchEvent("changeDelta", { data: delta });
|
||||
if (range.isMultiLine()) {
|
||||
|
||||
// TODO removeInLine can be optimized away!
|
||||
this.removeInLine(lastRow, 0, range.end.column);
|
||||
if (lastRow - firstRow >= 2)
|
||||
this.removeLines(firstRow + 1, lastRow - 1);
|
||||
this.removeInLine(firstRow, range.start.column, this.$lines[firstRow].length);
|
||||
this.removeNewLine(range.start.row);
|
||||
}
|
||||
else {
|
||||
this.removeInLine(firstRow, range.start.column, range.end.column);
|
||||
}
|
||||
return range.start;
|
||||
};
|
||||
|
||||
this.undoChanges = function(deltas) {
|
||||
this.selection.clearSelection();
|
||||
for (var i=deltas.length-1; i>=0; i--) {
|
||||
var delta = deltas[i];
|
||||
if (delta.action == "insertText") {
|
||||
this.remove(delta.range, true);
|
||||
this.selection.moveCursorToPosition(delta.range.start);
|
||||
} else {
|
||||
this.insert(delta.range.start, delta.text, true);
|
||||
this.selection.clearSelection();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
this.redoChanges = function(deltas) {
|
||||
this.selection.clearSelection();
|
||||
for (var i=0; i<deltas.length; i++) {
|
||||
var delta = deltas[i];
|
||||
if (delta.action == "insertText") {
|
||||
this.insert(delta.range.start, delta.text, true);
|
||||
this.selection.setSelectionRange(delta.range);
|
||||
} else {
|
||||
this.remove(delta.range, true);
|
||||
this.selection.moveCursorToPosition(delta.range.start);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
this.removeInLine = function(row, startColumn, endColumn) {
|
||||
if (startColumn == endColumn)
|
||||
return;
|
||||
|
||||
var range = new Range(row, startColumn, row, endColumn);
|
||||
var line = this.getLine(row);
|
||||
var removed = line.substring(startColumn, endColumn);
|
||||
var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
|
||||
this.$lines.splice(row, 1, newLine);
|
||||
|
||||
var delta = {
|
||||
action: "removeText",
|
||||
range: range,
|
||||
text: removed
|
||||
};
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
return range.start;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a range of full lines
|
||||
*
|
||||
* @param firstRow {Integer} The first row to be removed
|
||||
* @param lastRow {Integer} The last row to be removed
|
||||
* @return {String[]} The removed lines
|
||||
*/
|
||||
this.removeLines = function(firstRow, lastRow) {
|
||||
var range = new Range(firstRow, 0, lastRow, this.$lines[lastRow].length);
|
||||
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
|
||||
|
||||
var delta = {
|
||||
action: "removeLines",
|
||||
range: range,
|
||||
nl: this.getNewLineCharacter(),
|
||||
lines: removed
|
||||
};
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
return removed;
|
||||
};
|
||||
|
||||
this.removeNewLine = function(row) {
|
||||
var firstLine = this.getLine(row);
|
||||
var secondLine = this.getLine(row+1);
|
||||
|
||||
var range = new Range(row, firstLine.length, row+1, 0);
|
||||
var line = firstLine + secondLine;
|
||||
|
||||
this.$lines.splice(row, 2, line);
|
||||
|
||||
var delta = {
|
||||
action: "removeText",
|
||||
range: range,
|
||||
text: this.getNewLineCharacter()
|
||||
};
|
||||
this._dispatchEvent("change", { data: delta });
|
||||
};
|
||||
|
||||
this.replace = function(range, text) {
|
||||
// Shortcut: Nothing to replace in this case.
|
||||
if (text.length == 0 && range.isEmpty()) {
|
||||
if (text.length == 0 && range.isEmpty())
|
||||
return range.start;
|
||||
} else
|
||||
|
||||
// Shortcut: If the text we want to insert is the same as it is already
|
||||
// in the document, we don't have to replace anything.
|
||||
if (text == this.getTextRange(range)) {
|
||||
if (text == this.getTextRange(range))
|
||||
return range.end;
|
||||
}
|
||||
|
||||
this.$remove(range);
|
||||
|
||||
this.remove(range);
|
||||
if (text) {
|
||||
var end = this.$insert(range.start, text);
|
||||
var end = this.insert(range.start, text);
|
||||
}
|
||||
else {
|
||||
end = range.start;
|
||||
}
|
||||
|
||||
var lastRemoved = range.end.column == 0 ? range.end.column - 1
|
||||
: range.end.column;
|
||||
this.fireChangeEvent(range.start.row, lastRemoved == end.row ? lastRemoved
|
||||
: undefined);
|
||||
|
||||
|
||||
return end;
|
||||
};
|
||||
|
||||
this.indentRows = function(startRow, endRow, indentString) {
|
||||
indentString = indentString.replace("\t", this.getTabString());
|
||||
for (var row=startRow; row<=endRow; row++) {
|
||||
this.$insert({row: row, column:0}, indentString);
|
||||
}
|
||||
this.fireChangeEvent(startRow, endRow);
|
||||
return indentString.length;
|
||||
};
|
||||
|
||||
this.outdentRows = function (range) {
|
||||
var rowRange = range.collapseRows();
|
||||
var deleteRange = new Range(0, 0, 0, 0);
|
||||
var size = this.getTabSize();
|
||||
|
||||
for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
|
||||
var line = this.getLine(i);
|
||||
|
||||
this.applyDeltas = function(deltas) {
|
||||
for (var i=0; i<deltas.length; i++) {
|
||||
var delta = deltas[i];
|
||||
var range = delta.range;
|
||||
|
||||
deleteRange.start.row = i;
|
||||
deleteRange.end.row = i;
|
||||
for (var j = 0; j < size; ++j)
|
||||
if (line.charAt(j) != ' ')
|
||||
break;
|
||||
if (j < size && line.charAt(j) == '\t') {
|
||||
deleteRange.start.column = j;
|
||||
deleteRange.end.column = j + 1;
|
||||
} else {
|
||||
deleteRange.start.column = 0;
|
||||
deleteRange.end.column = j;
|
||||
}
|
||||
if (i == range.start.row)
|
||||
range.start.column -= deleteRange.end.column - deleteRange.start.column;
|
||||
if (i == range.end.row)
|
||||
range.end.column -= deleteRange.end.column - deleteRange.start.column;
|
||||
this.$remove(deleteRange);
|
||||
}
|
||||
this.fireChangeEvent(range.start.row, range.end.row);
|
||||
return range;
|
||||
}
|
||||
|
||||
this.moveLinesUp = function(firstRow, lastRow) {
|
||||
if (firstRow <= 0) return 0;
|
||||
|
||||
var removed = this.$lines.slice(firstRow, lastRow + 1);
|
||||
this.$remove(new Range(firstRow-1, this.$lines[firstRow-1].length, lastRow, this.$lines[lastRow].length));
|
||||
this.$insertLines(firstRow - 1, removed);
|
||||
|
||||
this.fireChangeEvent(firstRow - 1, lastRow);
|
||||
return -1;
|
||||
if (delta.action == "insertLines")
|
||||
this.insertLines(range.start.row, delta.lines)
|
||||
else if (delta.action == "insertText")
|
||||
this.insert(range.start, delta.text)
|
||||
else if (delta.action == "removeLines")
|
||||
this.removeLines(range.start.row, range.end.row)
|
||||
else if (delta.action == "removeText")
|
||||
this.remove(range)
|
||||
}
|
||||
};
|
||||
|
||||
this.moveLinesDown = function(firstRow, lastRow) {
|
||||
if (lastRow >= this.$lines.length-1) return 0;
|
||||
|
||||
var removed = this.$lines.slice(firstRow, lastRow + 1);
|
||||
this.$remove(new Range(firstRow, 0, lastRow + 1, 0));
|
||||
this.$insertLines(firstRow+1, removed);
|
||||
|
||||
this.fireChangeEvent(firstRow, lastRow + 1);
|
||||
return 1;
|
||||
};
|
||||
|
||||
this.duplicateLines = function(firstRow, lastRow) {
|
||||
var firstRow = this.$clipRowToDocument(firstRow);
|
||||
var lastRow = this.$clipRowToDocument(lastRow);
|
||||
|
||||
var lines = this.getLines(firstRow, lastRow);
|
||||
this.$insertLines(firstRow, lines);
|
||||
|
||||
var addedRows = lastRow - firstRow + 1;
|
||||
this.fireChangeEvent(firstRow);
|
||||
|
||||
return addedRows;
|
||||
};
|
||||
|
||||
this.$clipRowToDocument = function(row) {
|
||||
return Math.max(0, Math.min(row, this.$lines.length-1));
|
||||
};
|
||||
|
||||
this.documentToScreenColumn = function(row, docColumn) {
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
var screenColumn = 0;
|
||||
var remaining = docColumn;
|
||||
|
||||
var line = this.getLine(row).split("\t");
|
||||
for (var i=0; i<line.length; i++) {
|
||||
var len = line[i].length;
|
||||
if (remaining > len) {
|
||||
remaining -= (len + 1);
|
||||
screenColumn += len + tabSize;
|
||||
}
|
||||
else {
|
||||
screenColumn += remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return screenColumn;
|
||||
};
|
||||
|
||||
this.screenToDocumentColumn = function(row, screenColumn) {
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
var docColumn = 0;
|
||||
var remaining = screenColumn;
|
||||
|
||||
var line = this.getLine(row).split("\t");
|
||||
for (var i=0; i<line.length; i++) {
|
||||
var len = line[i].length;
|
||||
if (remaining >= len + tabSize) {
|
||||
remaining -= (len + tabSize);
|
||||
docColumn += (len + 1);
|
||||
}
|
||||
else if (remaining > len){
|
||||
docColumn += len;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
docColumn += remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return docColumn;
|
||||
|
||||
this.revertDeltas = function(deltas) {
|
||||
for (var i=deltas.length-1; i>=0; i--) {
|
||||
var delta = deltas[i];
|
||||
var range = delta.range;
|
||||
|
||||
if (delta.action == "insertLines")
|
||||
this.removeLines(range.start.row, range.end.row)
|
||||
else if (delta.action == "insertText")
|
||||
this.remove(range)
|
||||
else if (delta.action == "removeLines")
|
||||
this.insertLines(range.start.row, delta.lines)
|
||||
else if (delta.action == "removeText")
|
||||
this.insert(range.start, delta.text)
|
||||
}
|
||||
};
|
||||
|
||||
}).call(Document.prototype);
|
||||
|
|
|
|||
642
lib/ace/edit_session.js
Normal file
642
lib/ace/edit_session.js
Normal file
|
|
@ -0,0 +1,642 @@
|
|||
/* ***** 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):
|
||||
* Fabian Jakobs <fabian 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 lang = require("pilot/lang");
|
||||
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||
var Selection = require("ace/selection").Selection;
|
||||
var TextMode = require("ace/mode/text").Mode;
|
||||
var Range = require("ace/range").Range;
|
||||
var Document = require("ace/document").Document;
|
||||
|
||||
var NO_CHANGE_DELTAS = {};
|
||||
|
||||
var EditSession = function(text, mode) {
|
||||
this.$modified = true;
|
||||
this.selection = new Selection(this);
|
||||
this.$breakpoints = [];
|
||||
|
||||
this.listeners = [];
|
||||
if (mode) {
|
||||
this.setMode(mode);
|
||||
}
|
||||
|
||||
if (text instanceof Document) {
|
||||
this.setDocument(text)
|
||||
} else {
|
||||
this.setDocument(new Document(text));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
oop.implement(this, EventEmitter);
|
||||
|
||||
this.setDocument = function(doc) {
|
||||
if (this.doc)
|
||||
throw new Error("Document is already set");
|
||||
|
||||
this.doc = doc;
|
||||
doc.on("change", this.onChange.bind(this));
|
||||
};
|
||||
|
||||
this.getDocument = function() {
|
||||
return this.doc;
|
||||
};
|
||||
|
||||
this.onChange = function(e) {
|
||||
var delta = e.data;
|
||||
this.$modified = true;
|
||||
if (!this.$fromUndo && this.$undoManager) {
|
||||
this.$deltas.push(delta);
|
||||
this.$informUndoManager.schedule();
|
||||
}
|
||||
this._dispatchEvent("change", e);
|
||||
};
|
||||
|
||||
this.setValue = function(text) {
|
||||
this.doc.setValue(text);
|
||||
this.$deltas = [];
|
||||
};
|
||||
|
||||
this.getValue =
|
||||
this.toString = function() {
|
||||
return this.doc.getValue();
|
||||
};
|
||||
|
||||
this.getSelection = function() {
|
||||
return this.selection;
|
||||
};
|
||||
|
||||
this.setUndoManager = function(undoManager) {
|
||||
this.$undoManager = undoManager;
|
||||
this.$deltas = [];
|
||||
|
||||
if (this.$informUndoManager) {
|
||||
this.$informUndoManager.cancel();
|
||||
}
|
||||
|
||||
if (undoManager) {
|
||||
var self = this;
|
||||
this.$informUndoManager = lang.deferredCall(function() {
|
||||
if (self.$deltas.length > 0)
|
||||
undoManager.execute({
|
||||
action : "aceupdate",
|
||||
args : [self.$deltas, self]
|
||||
});
|
||||
self.$deltas = [];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.$defaultUndoManager = {
|
||||
undo: function() {},
|
||||
redo: function() {}
|
||||
};
|
||||
|
||||
this.getUndoManager = function() {
|
||||
return this.$undoManager || this.$defaultUndoManager;
|
||||
},
|
||||
|
||||
this.getTabString = function() {
|
||||
if (this.getUseSoftTabs()) {
|
||||
return lang.stringRepeat(" ", this.getTabSize());
|
||||
} else {
|
||||
return "\t";
|
||||
}
|
||||
};
|
||||
|
||||
this.$useSoftTabs = true;
|
||||
this.setUseSoftTabs = function(useSoftTabs) {
|
||||
if (this.$useSoftTabs === useSoftTabs) return;
|
||||
|
||||
this.$useSoftTabs = useSoftTabs;
|
||||
};
|
||||
|
||||
this.getUseSoftTabs = function() {
|
||||
return this.$useSoftTabs;
|
||||
};
|
||||
|
||||
this.$tabSize = 4;
|
||||
this.setTabSize = function(tabSize) {
|
||||
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
|
||||
|
||||
this.$modified = true;
|
||||
this.$tabSize = tabSize;
|
||||
this._dispatchEvent("changeTabSize");
|
||||
};
|
||||
|
||||
this.getTabSize = function() {
|
||||
return this.$tabSize;
|
||||
};
|
||||
|
||||
this.isTabStop = function(position) {
|
||||
return this.$useSoftTabs && (position.column % this.$tabSize == 0);
|
||||
};
|
||||
|
||||
this.getBreakpoints = function() {
|
||||
return this.$breakpoints;
|
||||
};
|
||||
|
||||
this.setBreakpoints = function(rows) {
|
||||
this.$breakpoints = [];
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
this.$breakpoints[rows[i]] = true;
|
||||
}
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.clearBreakpoints = function() {
|
||||
this.$breakpoints = [];
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.setBreakpoint = function(row) {
|
||||
this.$breakpoints[row] = true;
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.clearBreakpoint = function(row) {
|
||||
delete this.$breakpoints[row];
|
||||
this._dispatchEvent("changeBreakpoint", {});
|
||||
};
|
||||
|
||||
this.$detectNewLine = function(text) {
|
||||
var match = text.match(/^.*?(\r?\n)/m);
|
||||
if (match) {
|
||||
this.$autoNewLine = match[1];
|
||||
} else {
|
||||
this.$autoNewLine = "\n";
|
||||
}
|
||||
};
|
||||
|
||||
this.tokenRe = /^[\w\d]+/g;
|
||||
this.nonTokenRe = /^[^\w\d]+/g;
|
||||
|
||||
this.getWordRange = function(row, column) {
|
||||
var line = this.getLine(row);
|
||||
|
||||
var inToken = false;
|
||||
if (column > 0) {
|
||||
inToken = !!line.charAt(column - 1).match(this.tokenRe);
|
||||
}
|
||||
|
||||
if (!inToken) {
|
||||
inToken = !!line.charAt(column).match(this.tokenRe);
|
||||
}
|
||||
|
||||
var re = inToken ? this.tokenRe : this.nonTokenRe;
|
||||
|
||||
var start = column;
|
||||
if (start > 0) {
|
||||
do {
|
||||
start--;
|
||||
}
|
||||
while (start >= 0 && line.charAt(start).match(re));
|
||||
start++;
|
||||
}
|
||||
|
||||
var end = column;
|
||||
while (end < line.length && line.charAt(end).match(re)) {
|
||||
end++;
|
||||
}
|
||||
|
||||
return new Range(row, start, row, end);
|
||||
};
|
||||
|
||||
this.setNewLineMode = function(newLineMode) {
|
||||
this.doc.setNewLineMode(newLineMode);
|
||||
};
|
||||
|
||||
this.getNewLineMode = function() {
|
||||
return this.doc.getNewLineMode();
|
||||
};
|
||||
|
||||
this.$mode = null;
|
||||
this.setMode = function(mode) {
|
||||
if (this.$mode === mode) return;
|
||||
|
||||
this.$mode = mode;
|
||||
this._dispatchEvent("changeMode");
|
||||
};
|
||||
|
||||
this.getMode = function() {
|
||||
if (!this.$mode) {
|
||||
this.$mode = new TextMode();
|
||||
}
|
||||
return this.$mode;
|
||||
};
|
||||
|
||||
this.$scrollTop = 0;
|
||||
this.setScrollTopRow = function(scrollTopRow) {
|
||||
if (this.$scrollTop === scrollTopRow) return;
|
||||
|
||||
this.$scrollTop = scrollTopRow;
|
||||
this._dispatchEvent("changeScrollTop");
|
||||
};
|
||||
|
||||
this.getScrollTopRow = function() {
|
||||
return this.$scrollTop;
|
||||
};
|
||||
|
||||
this.getWidth = function() {
|
||||
this.$computeWidth();
|
||||
return this.width;
|
||||
};
|
||||
|
||||
this.getScreenWidth = function() {
|
||||
this.$computeWidth();
|
||||
return this.screenWidth;
|
||||
};
|
||||
|
||||
this.$computeWidth = function() {
|
||||
if (this.$modified) {
|
||||
this.$modified = false;
|
||||
|
||||
var lines = this.doc.getAllLines();
|
||||
var longestLine = 0;
|
||||
var longestScreenLine = 0;
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
for ( var i = 0; i < lines.length; i++) {
|
||||
var len = lines[i].length;
|
||||
longestLine = Math.max(longestLine, len);
|
||||
|
||||
lines[i].replace(/\t/g, function(m) {
|
||||
len += tabSize-1;
|
||||
return m;
|
||||
});
|
||||
longestScreenLine = Math.max(longestScreenLine, len);
|
||||
}
|
||||
this.width = longestLine;
|
||||
this.screenWidth = longestScreenLine;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a verbatim copy of the given line as it is in the document
|
||||
*/
|
||||
this.getLine = function(row) {
|
||||
return this.doc.getLine(row);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a line as it is displayed on screen. Tabs are replaced by spaces.
|
||||
*/
|
||||
this.getDisplayLine = function(row) {
|
||||
var tab = new Array(this.getTabSize()+1).join(" ");
|
||||
return this.doc.getLine(row).replace(/\t/g, tab);
|
||||
};
|
||||
|
||||
this.getLines = function(firstRow, lastRow) {
|
||||
return this.doc.getLines(firstRow, lastRow);
|
||||
};
|
||||
|
||||
this.getLength = function() {
|
||||
return this.doc.getLength();
|
||||
};
|
||||
|
||||
this.getTextRange = function(range) {
|
||||
return this.doc.getTextRange(range);
|
||||
};
|
||||
|
||||
this.findMatchingBracket = function(position) {
|
||||
if (position.column == 0) return null;
|
||||
|
||||
var charBeforeCursor = this.getLine(position.row).charAt(position.column-1);
|
||||
if (charBeforeCursor == "") return null;
|
||||
|
||||
var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (match[1]) {
|
||||
return this.$findClosingBracket(match[1], position);
|
||||
} else {
|
||||
return this.$findOpeningBracket(match[2], position);
|
||||
}
|
||||
};
|
||||
|
||||
this.$brackets = {
|
||||
")": "(",
|
||||
"(": ")",
|
||||
"]": "[",
|
||||
"[": "]",
|
||||
"{": "}",
|
||||
"}": "{"
|
||||
};
|
||||
|
||||
this.$findOpeningBracket = function(bracket, position) {
|
||||
var openBracket = this.$brackets[bracket];
|
||||
|
||||
var column = position.column - 2;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
|
||||
while (true) {
|
||||
while(column >= 0) {
|
||||
var ch = line.charAt(column);
|
||||
if (ch == openBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (ch == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column -= 1;
|
||||
}
|
||||
row -=1;
|
||||
if (row < 0) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = line.length-1;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.$findClosingBracket = function(bracket, position) {
|
||||
var closingBracket = this.$brackets[bracket];
|
||||
|
||||
var column = position.column;
|
||||
var row = position.row;
|
||||
var depth = 1;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var lineCount = this.getLength();
|
||||
|
||||
while (true) {
|
||||
while(column < line.length) {
|
||||
var ch = line.charAt(column);
|
||||
if (ch == closingBracket) {
|
||||
depth -= 1;
|
||||
if (depth == 0) {
|
||||
return {row: row, column: column};
|
||||
}
|
||||
}
|
||||
else if (ch == bracket) {
|
||||
depth +=1;
|
||||
}
|
||||
column += 1;
|
||||
}
|
||||
row +=1;
|
||||
if (row >= lineCount) break;
|
||||
|
||||
var line = this.getLine(row);
|
||||
var column = 0;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.insert = function(position, text) {
|
||||
return this.doc.insert(position, text);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param rows Array[Integer] sorted list of rows
|
||||
*/
|
||||
this.multiRowInsert = function(rows, column, text) {
|
||||
for (var i=rows.length-1; i>=0; i--) {
|
||||
var row = rows[i];
|
||||
if (row >= this.doc.getLength())
|
||||
continue;
|
||||
|
||||
var diff = column - this.doc.getLine(row).length;
|
||||
if ( diff > 0) {
|
||||
var padded = lang.stringRepeat(" ", diff) + text;
|
||||
var offset = -diff;
|
||||
}
|
||||
else {
|
||||
padded = text;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
var end = this.insert({row: row, column: column+offset}, padded);
|
||||
}
|
||||
|
||||
return {
|
||||
rows: end ? end.row - rows[0] : 0,
|
||||
columns: end ? end.column - column : 0
|
||||
}
|
||||
};
|
||||
|
||||
this.remove = function(range) {
|
||||
return this.doc.remove(range);
|
||||
};
|
||||
|
||||
this.multiRowRemove = function(rows, range) {
|
||||
if (range.start.row !== rows[0])
|
||||
throw new TypeError("range must start in the first row!");
|
||||
|
||||
var height = range.end.row - rows[0];
|
||||
for (var i=rows.length-1; i>=0; i--) {
|
||||
var row = rows[i];
|
||||
if (row >= this.doc.getLength())
|
||||
continue;
|
||||
|
||||
var end = this.remove(new Range(row, range.start.column, row+height, range.end.column));
|
||||
}
|
||||
};
|
||||
|
||||
this.undoChanges = function(deltas) {
|
||||
if (!deltas.length)
|
||||
return;
|
||||
|
||||
this.$fromUndo = true;
|
||||
this.doc.revertDeltas(deltas);
|
||||
this.$fromUndo = false;
|
||||
|
||||
// update the selection
|
||||
var firstDelta = deltas[0];
|
||||
var lastDelta = deltas[deltas.length-1];
|
||||
|
||||
this.selection.clearSelection();
|
||||
if (firstDelta.action == "insertText" || firstDelta.action == "insertLines")
|
||||
this.selection.moveCursorToPosition(firstDelta.range.start);
|
||||
if (firstDelta.action == "removeText" || firstDelta.action == "removeLines")
|
||||
this.selection.setSelectionRange(Range.fromPoints(firstDelta.range.start, lastDelta.range.end));
|
||||
},
|
||||
|
||||
this.redoChanges = function(deltas) {
|
||||
if (!deltas.length)
|
||||
return;
|
||||
|
||||
this.$fromUndo = true;
|
||||
this.doc.applyDeltas(deltas);
|
||||
this.$fromUndo = false;
|
||||
|
||||
// update the selection
|
||||
var firstDelta = deltas[0];
|
||||
var lastDelta = deltas[deltas.length-1];
|
||||
|
||||
this.selection.clearSelection();
|
||||
if (firstDelta.action == "insertText" || firstDelta.action == "insertLines")
|
||||
this.selection.setSelectionRange(Range.fromPoints(firstDelta.range.start, lastDelta.range.end));
|
||||
if (firstDelta.action == "removeText" || firstDelta.action == "removeLines")
|
||||
this.selection.moveCursorToPosition(firstDelta.range.start);
|
||||
},
|
||||
|
||||
this.replace = function(range, text) {
|
||||
return this.doc.replace(range, text);
|
||||
};
|
||||
|
||||
this.indentRows = function(startRow, endRow, indentString) {
|
||||
indentString = indentString.replace(/\t/g, this.getTabString());
|
||||
for (var row=startRow; row<=endRow; row++) {
|
||||
this.insert({row: row, column:0}, indentString);
|
||||
}
|
||||
return indentString.length;
|
||||
};
|
||||
|
||||
this.outdentRows = function (range) {
|
||||
var rowRange = range.collapseRows();
|
||||
var deleteRange = new Range(0, 0, 0, 0);
|
||||
var size = this.getTabSize();
|
||||
|
||||
for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
|
||||
var line = this.getLine(i);
|
||||
|
||||
deleteRange.start.row = i;
|
||||
deleteRange.end.row = i;
|
||||
for (var j = 0; j < size; ++j)
|
||||
if (line.charAt(j) != ' ')
|
||||
break;
|
||||
if (j < size && line.charAt(j) == '\t') {
|
||||
deleteRange.start.column = j;
|
||||
deleteRange.end.column = j + 1;
|
||||
} else {
|
||||
deleteRange.start.column = 0;
|
||||
deleteRange.end.column = j;
|
||||
}
|
||||
if (i == range.start.row)
|
||||
range.start.column -= deleteRange.end.column - deleteRange.start.column;
|
||||
if (i == range.end.row)
|
||||
range.end.column -= deleteRange.end.column - deleteRange.start.column;
|
||||
this.remove(deleteRange);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
this.moveLinesUp = function(firstRow, lastRow) {
|
||||
if (firstRow <= 0) return 0;
|
||||
|
||||
var removed = this.doc.removeLines(firstRow, lastRow);
|
||||
this.doc.insertLines(firstRow - 1, removed);
|
||||
return -1;
|
||||
};
|
||||
|
||||
this.moveLinesDown = function(firstRow, lastRow) {
|
||||
if (lastRow >= this.doc.getLength()-1) return 0;
|
||||
|
||||
var removed = this.doc.removeLines(firstRow, lastRow);
|
||||
this.doc.insertLines(firstRow+1, removed);
|
||||
return 1;
|
||||
};
|
||||
|
||||
this.duplicateLines = function(firstRow, lastRow) {
|
||||
var firstRow = this.$clipRowToDocument(firstRow);
|
||||
var lastRow = this.$clipRowToDocument(lastRow);
|
||||
|
||||
var lines = this.getLines(firstRow, lastRow);
|
||||
this.doc.insertLines(firstRow, lines);
|
||||
|
||||
var addedRows = lastRow - firstRow + 1;
|
||||
return addedRows;
|
||||
};
|
||||
|
||||
this.$clipRowToDocument = function(row) {
|
||||
return Math.max(0, Math.min(row, this.doc.getLength()-1));
|
||||
};
|
||||
|
||||
this.documentToScreenColumn = function(row, docColumn) {
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
var screenColumn = 0;
|
||||
var remaining = docColumn;
|
||||
|
||||
var line = this.getLine(row).split("\t");
|
||||
for (var i=0; i<line.length; i++) {
|
||||
var len = line[i].length;
|
||||
if (remaining > len) {
|
||||
remaining -= (len + 1);
|
||||
screenColumn += len + tabSize;
|
||||
}
|
||||
else {
|
||||
screenColumn += remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return screenColumn;
|
||||
};
|
||||
|
||||
this.screenToDocumentColumn = function(row, screenColumn) {
|
||||
var tabSize = this.getTabSize();
|
||||
|
||||
var docColumn = 0;
|
||||
var remaining = screenColumn;
|
||||
|
||||
var line = this.getLine(row).split("\t");
|
||||
for (var i=0; i<line.length; i++) {
|
||||
var len = line[i].length;
|
||||
if (remaining >= len + tabSize) {
|
||||
remaining -= (len + tabSize);
|
||||
docColumn += (len + 1);
|
||||
}
|
||||
else if (remaining > len){
|
||||
docColumn += len;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
docColumn += remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return docColumn;
|
||||
};
|
||||
|
||||
}).call(EditSession.prototype);
|
||||
|
||||
exports.EditSession = EditSession;
|
||||
});
|
||||
|
|
@ -42,13 +42,13 @@ var event = require("pilot/event");
|
|||
var lang = require("pilot/lang");
|
||||
var TextInput = require("ace/keyboard/textinput").TextInput;
|
||||
var KeyBinding = require("ace/keyboard/keybinding").KeyBinding;
|
||||
var Document = require("ace/document").Document;
|
||||
var EditSession = require("ace/edit_session").EditSession;
|
||||
var Search = require("ace/search").Search;
|
||||
var BackgroundTokenizer = require("ace/background_tokenizer").BackgroundTokenizer;
|
||||
var Range = require("ace/range").Range;
|
||||
var EventEmitter = require("pilot/event_emitter").EventEmitter;
|
||||
|
||||
var Editor =function(renderer, doc) {
|
||||
var Editor =function(renderer, session) {
|
||||
var container = renderer.getContainerElement();
|
||||
this.container = container;
|
||||
this.renderer = renderer;
|
||||
|
|
@ -78,7 +78,7 @@ var Editor =function(renderer, doc) {
|
|||
wrap: true
|
||||
});
|
||||
|
||||
this.setDocument(doc || new Document(""));
|
||||
this.setSession(session || new EditSession(""));
|
||||
this.focus();
|
||||
};
|
||||
|
||||
|
|
@ -118,38 +118,38 @@ var Editor =function(renderer, doc) {
|
|||
return this.keyBinding.getKeyboardHandler();
|
||||
}
|
||||
|
||||
this.setDocument = function(doc) {
|
||||
if (this.doc == doc) return;
|
||||
this.setSession = function(session) {
|
||||
if (this.session == session) return;
|
||||
|
||||
if (this.doc) {
|
||||
this.doc.removeEventListener("change", this.$onDocumentChange);
|
||||
this.doc.removeEventListener("changeMode", this.$onDocumentModeChange);
|
||||
this.doc.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
this.doc.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
if (this.session) {
|
||||
this.session.removeEventListener("change", this.$onDocumentChange);
|
||||
this.session.removeEventListener("changeMode", this.$onDocumentModeChange);
|
||||
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
|
||||
var selection = this.doc.getSelection();
|
||||
var selection = this.session.getSelection();
|
||||
selection.removeEventListener("changeCursor", this.$onCursorChange);
|
||||
selection.removeEventListener("changeSelection", this.$onSelectionChange);
|
||||
|
||||
this.doc.setScrollTopRow(this.renderer.getScrollTopRow());
|
||||
this.session.setScrollTopRow(this.renderer.getScrollTopRow());
|
||||
}
|
||||
|
||||
this.doc = doc;
|
||||
this.session = session;
|
||||
|
||||
this.$onDocumentChange = this.onDocumentChange.bind(this);
|
||||
doc.addEventListener("change", this.$onDocumentChange);
|
||||
this.renderer.setDocument(doc);
|
||||
session.addEventListener("change", this.$onDocumentChange);
|
||||
this.renderer.setSession(session);
|
||||
|
||||
this.$onDocumentModeChange = this.onDocumentModeChange.bind(this);
|
||||
doc.addEventListener("changeMode", this.$onDocumentModeChange);
|
||||
session.addEventListener("changeMode", this.$onDocumentModeChange);
|
||||
|
||||
this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer);
|
||||
doc.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
|
||||
|
||||
this.$onDocumentChangeBreakpoint = this.onDocumentChangeBreakpoint.bind(this);
|
||||
this.doc.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
this.session.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
|
||||
|
||||
this.selection = doc.getSelection();
|
||||
this.selection = session.getSelection();
|
||||
this.$desiredColumn = 0;
|
||||
|
||||
this.$onCursorChange = this.onCursorChange.bind(this);
|
||||
|
|
@ -159,18 +159,18 @@ var Editor =function(renderer, doc) {
|
|||
this.selection.addEventListener("changeSelection", this.$onSelectionChange);
|
||||
|
||||
this.onDocumentModeChange();
|
||||
this.bgTokenizer.setDocument(doc);
|
||||
this.bgTokenizer.setDocument(session.getDocument());
|
||||
this.bgTokenizer.start(0);
|
||||
|
||||
this.onCursorChange();
|
||||
this.onSelectionChange();
|
||||
this.onDocumentChangeBreakpoint();
|
||||
this.renderer.scrollToRow(doc.getScrollTopRow());
|
||||
this.renderer.scrollToRow(session.getScrollTopRow());
|
||||
this.renderer.updateFull();
|
||||
};
|
||||
|
||||
this.getDocument = function() {
|
||||
return this.doc;
|
||||
this.getSession = function() {
|
||||
return this.session;
|
||||
};
|
||||
|
||||
this.getSelection = function() {
|
||||
|
|
@ -201,7 +201,7 @@ var Editor =function(renderer, doc) {
|
|||
setTimeout(function() {
|
||||
self.$highlightPending = false;
|
||||
|
||||
var pos = self.doc.findMatchingBracket(self.getCursorPosition());
|
||||
var pos = self.session.findMatchingBracket(self.getCursorPosition());
|
||||
if (pos) {
|
||||
var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
|
||||
self.$bracketHighlight = self.renderer.addMarker(range, "ace_bracket");
|
||||
|
|
@ -228,9 +228,15 @@ var Editor =function(renderer, doc) {
|
|||
};
|
||||
|
||||
this.onDocumentChange = function(e) {
|
||||
var data = e.data;
|
||||
this.bgTokenizer.start(data.firstRow);
|
||||
this.renderer.updateLines(data.firstRow, data.lastRow);
|
||||
var delta = e.data;
|
||||
var range = delta.range;
|
||||
|
||||
this.bgTokenizer.start(range.start.row);
|
||||
if (range.start.row == range.end.row)
|
||||
var lastRow = range.end.row;
|
||||
else
|
||||
lastRow = Infinity;
|
||||
this.renderer.updateLines(range.start.row, lastRow);
|
||||
|
||||
// update cursor because tab characters can influence the cursor position
|
||||
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
|
||||
|
|
@ -280,11 +286,11 @@ var Editor =function(renderer, doc) {
|
|||
};
|
||||
|
||||
this.onDocumentChangeBreakpoint = function() {
|
||||
this.renderer.setBreakpoints(this.doc.getBreakpoints());
|
||||
this.renderer.setBreakpoints(this.session.getBreakpoints());
|
||||
};
|
||||
|
||||
this.onDocumentModeChange = function() {
|
||||
var mode = this.doc.getMode();
|
||||
var mode = this.session.getMode();
|
||||
if (this.mode == mode)
|
||||
return;
|
||||
|
||||
|
|
@ -308,7 +314,7 @@ var Editor =function(renderer, doc) {
|
|||
var pageY = event.getDocumentY(e);
|
||||
|
||||
var pos = this.renderer.screenToTextCoordinates(pageX, pageY);
|
||||
pos.row = Math.max(0, Math.min(pos.row, this.doc.getLength()-1));
|
||||
pos.row = Math.max(0, Math.min(pos.row, this.session.getLength()-1));
|
||||
|
||||
if (event.getButton(e) != 0) {
|
||||
if (this.selection.isEmpty()) {
|
||||
|
|
@ -345,7 +351,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
var cursor = self.renderer.screenToTextCoordinates(mousePageX, mousePageY);
|
||||
cursor.row = Math.max(0, Math.min(cursor.row, self.doc.getLength()-1));
|
||||
cursor.row = Math.max(0, Math.min(cursor.row, self.session.getLength()-1));
|
||||
|
||||
if (self.$clickSelection) {
|
||||
if (self.$clickSelection.contains(cursor.row, cursor.column)) {
|
||||
|
|
@ -394,7 +400,7 @@ var Editor =function(renderer, doc) {
|
|||
|
||||
this.getCopyText = function() {
|
||||
if (!this.selection.isEmpty()) {
|
||||
return this.doc.getTextRange(this.getSelectionRange());
|
||||
return this.session.getTextRange(this.getSelectionRange());
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
|
|
@ -406,7 +412,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
if (!this.selection.isEmpty()) {
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.moveCursorToPosition(this.session.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
}
|
||||
};
|
||||
|
|
@ -416,28 +422,28 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
var cursor = this.getCursorPosition();
|
||||
text = text.replace("\t", this.doc.getTabString());
|
||||
text = text.replace("\t", this.session.getTabString());
|
||||
|
||||
// remove selected text
|
||||
if (!this.selection.isEmpty()) {
|
||||
var cursor = this.doc.remove(this.getSelectionRange());
|
||||
var cursor = this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
} else if (this.$overwrite){
|
||||
var range = new Range.fromPoints(cursor, cursor);
|
||||
range.end.column += text.length;
|
||||
this.doc.remove(range);
|
||||
this.session.remove(range);
|
||||
}
|
||||
|
||||
this.clearSelection();
|
||||
|
||||
var lineState = this.bgTokenizer.getState(cursor.row);
|
||||
var shouldOutdent = this.mode.checkOutdent(lineState, this.doc.getLine(cursor.row), text);
|
||||
var line = this.doc.getLine(cursor.row);
|
||||
var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.doc.getTabString());
|
||||
var end = this.doc.insert(cursor, text);
|
||||
var shouldOutdent = this.mode.checkOutdent(lineState, this.session.getLine(cursor.row), text);
|
||||
var line = this.session.getLine(cursor.row);
|
||||
var lineIndent = this.mode.getNextLineIndent(lineState, line.slice(0, cursor.column), this.session.getTabString());
|
||||
var end = this.session.insert(cursor, text);
|
||||
|
||||
/* TODO: This shortcut is somehow broken
|
||||
if (!shouldOutdent && line != this.doc.getLine(row) && text != "\n") {
|
||||
if (!shouldOutdent && line != this.session.getLine(row) && text != "\n") {
|
||||
this.moveCursorToPosition(end);
|
||||
this.renderer.scrollCursorIntoView();
|
||||
return;
|
||||
|
|
@ -447,13 +453,13 @@ var Editor =function(renderer, doc) {
|
|||
var lineState = this.bgTokenizer.getState(cursor.row);
|
||||
// multi line insert
|
||||
if (cursor.row !== end.row) {
|
||||
var size = this.doc.getTabSize(),
|
||||
var size = this.session.getTabSize(),
|
||||
minIndent = Number.MAX_VALUE;
|
||||
|
||||
for (var row = cursor.row + 1; row <= end.row; ++row) {
|
||||
var indent = 0;
|
||||
|
||||
line = this.doc.getLine(row);
|
||||
line = this.session.getLine(row);
|
||||
for (var i = 0; i < line.length; ++i)
|
||||
if (line.charAt(i) == '\t')
|
||||
indent += size;
|
||||
|
|
@ -468,18 +474,18 @@ var Editor =function(renderer, doc) {
|
|||
for (var row = cursor.row + 1; row <= end.row; ++row) {
|
||||
var outdent = minIndent;
|
||||
|
||||
line = this.doc.getLine(row);
|
||||
line = this.session.getLine(row);
|
||||
for (var i = 0; i < line.length && outdent > 0; ++i)
|
||||
if (line.charAt(i) == '\t')
|
||||
outdent -= size;
|
||||
else if (line.charAt(i) == ' ')
|
||||
outdent -= 1;
|
||||
this.doc.replace(new Range(row, 0, row, line.length), line.substr(i));
|
||||
this.session.replace(new Range(row, 0, row, line.length), line.substr(i));
|
||||
}
|
||||
end.column += this.doc.indentRows(cursor.row + 1, end.row, lineIndent);
|
||||
end.column += this.session.indentRows(cursor.row + 1, end.row, lineIndent);
|
||||
} else {
|
||||
if (shouldOutdent) {
|
||||
end.column += this.mode.autoOutdent(lineState, this.doc, cursor.row);
|
||||
end.column += this.mode.autoOutdent(lineState, this.session, cursor.row);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -595,7 +601,7 @@ var Editor =function(renderer, doc) {
|
|||
if (this.selection.isEmpty()) {
|
||||
this.selection.selectRight();
|
||||
}
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.moveCursorToPosition(this.session.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
|
|
@ -606,7 +612,7 @@ var Editor =function(renderer, doc) {
|
|||
if (this.selection.isEmpty())
|
||||
this.selection.selectLeft();
|
||||
|
||||
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
|
||||
this.moveCursorToPosition(this.session.remove(this.getSelectionRange()));
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
|
|
@ -614,21 +620,21 @@ var Editor =function(renderer, doc) {
|
|||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
var doc = this.doc,
|
||||
range = this.getSelectionRange();
|
||||
var session = this.session;
|
||||
var range = this.getSelectionRange();
|
||||
|
||||
if (range.start.row < range.end.row || range.start.column < range.end.column) {
|
||||
var rows = this.$getSelectedRows();
|
||||
var count = doc.indentRows(rows.first, rows.last, "\t");
|
||||
var count = session.indentRows(rows.first, rows.last, "\t");
|
||||
|
||||
this.selection.shiftSelection(count);
|
||||
} else {
|
||||
var indentString;
|
||||
|
||||
if (this.doc.getUseSoftTabs()) {
|
||||
var size = doc.getTabSize(),
|
||||
if (this.session.getUseSoftTabs()) {
|
||||
var size = session.getTabSize(),
|
||||
position = this.getCursorPosition(),
|
||||
column = doc.documentToScreenColumn(position.row, position.column),
|
||||
column = session.documentToScreenColumn(position.row, position.column),
|
||||
count = (size - column % size);
|
||||
|
||||
indentString = lang.stringRepeat(" ", count);
|
||||
|
|
@ -642,8 +648,8 @@ var Editor =function(renderer, doc) {
|
|||
if (this.$readOnly)
|
||||
return;
|
||||
|
||||
var selection = this.doc.getSelection();
|
||||
var range = this.doc.outdentRows(selection.getRange());
|
||||
var selection = this.session.getSelection();
|
||||
var range = this.session.outdentRows(selection.getRange());
|
||||
|
||||
selection.setSelectionRange(range, selection.isBackwards());
|
||||
this.$updateDesiredColumn();
|
||||
|
|
@ -655,7 +661,7 @@ var Editor =function(renderer, doc) {
|
|||
|
||||
var state = this.bgTokenizer.getState(this.getCursorPosition().row);
|
||||
var rows = this.$getSelectedRows()
|
||||
var addedColumns = this.mode.toggleCommentLines(state, this.doc, rows.first, rows.last);
|
||||
var addedColumns = this.mode.toggleCommentLines(state, this.session, rows.first, rows.last);
|
||||
this.selection.shiftSelection(addedColumns);
|
||||
};
|
||||
|
||||
|
|
@ -667,7 +673,7 @@ var Editor =function(renderer, doc) {
|
|||
this.selection.setSelectionAnchor(rows.last+1, 0);
|
||||
this.selection.selectTo(rows.first, 0);
|
||||
|
||||
this.doc.remove(this.getSelectionRange());
|
||||
this.session.remove(this.getSelectionRange());
|
||||
this.clearSelection();
|
||||
};
|
||||
|
||||
|
|
@ -676,7 +682,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.doc.moveLinesDown(firstRow, lastRow);
|
||||
return this.session.moveLinesDown(firstRow, lastRow);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -685,7 +691,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.doc.moveLinesUp(firstRow, lastRow);
|
||||
return this.session.moveLinesUp(firstRow, lastRow);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -694,7 +700,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
this.doc.duplicateLines(firstRow, lastRow);
|
||||
this.session.duplicateLines(firstRow, lastRow);
|
||||
return 0;
|
||||
});
|
||||
};
|
||||
|
|
@ -704,7 +710,7 @@ var Editor =function(renderer, doc) {
|
|||
return;
|
||||
|
||||
this.$moveLines(function(firstRow, lastRow) {
|
||||
return this.doc.duplicateLines(firstRow, lastRow);
|
||||
return this.session.duplicateLines(firstRow, lastRow);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -798,7 +804,7 @@ var Editor =function(renderer, doc) {
|
|||
this.gotoPageDown = function() {
|
||||
var row = this.getPageDownRow(),
|
||||
column = Math.min(this.getCursorPosition().column,
|
||||
this.doc.getLine(row).length);
|
||||
this.session.getLine(row).length);
|
||||
|
||||
this.scrollToRow(row);
|
||||
this.getSelection().moveCursorTo(row, column);
|
||||
|
|
@ -807,7 +813,7 @@ var Editor =function(renderer, doc) {
|
|||
this.gotoPageUp = function() {
|
||||
var row = this.getPageUpRow(),
|
||||
column = Math.min(this.getCursorPosition().column,
|
||||
this.doc.getLine(row).length);
|
||||
this.session.getLine(row).length);
|
||||
|
||||
this.scrollToRow(row);
|
||||
this.getSelection().moveCursorTo(row, column);
|
||||
|
|
@ -874,7 +880,7 @@ var Editor =function(renderer, doc) {
|
|||
|
||||
if (this.$desiredColumn) {
|
||||
var cursor = this.getCursorPosition();
|
||||
var column = this.doc.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
||||
var column = this.session.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
||||
this.selection.moveCursorTo(cursor.row, column);
|
||||
}
|
||||
};
|
||||
|
|
@ -885,14 +891,14 @@ var Editor =function(renderer, doc) {
|
|||
|
||||
if (this.$desiredColumn) {
|
||||
var cursor = this.getCursorPosition();
|
||||
var column = this.doc.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
||||
var column = this.session.screenToDocumentColumn(cursor.row, this.$desiredColumn);
|
||||
this.selection.moveCursorTo(cursor.row, column);
|
||||
}
|
||||
};
|
||||
|
||||
this.$updateDesiredColumn = function() {
|
||||
var cursor = this.getCursorPosition();
|
||||
this.$desiredColumn = this.doc.documentToScreenColumn(cursor.row, cursor.column);
|
||||
this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column);
|
||||
};
|
||||
|
||||
this.navigateLeft = function(times) {
|
||||
|
|
@ -957,7 +963,7 @@ var Editor =function(renderer, doc) {
|
|||
if (options)
|
||||
this.$search.set(options);
|
||||
|
||||
var range = this.$search.find(this.doc);
|
||||
var range = this.$search.find(this.session);
|
||||
this.$tryReplace(range, replacement);
|
||||
if (range !== null)
|
||||
this.selection.setSelectionRange(range);
|
||||
|
|
@ -969,7 +975,7 @@ var Editor =function(renderer, doc) {
|
|||
this.$search.set(options);
|
||||
}
|
||||
|
||||
var ranges = this.$search.findAll(this.doc);
|
||||
var ranges = this.$search.findAll(this.session);
|
||||
if (!ranges.length)
|
||||
return;
|
||||
|
||||
|
|
@ -984,10 +990,10 @@ var Editor =function(renderer, doc) {
|
|||
},
|
||||
|
||||
this.$tryReplace = function(range, replacement) {
|
||||
var input = this.doc.getTextRange(range);
|
||||
var input = this.session.getTextRange(range);
|
||||
var replacement = this.$search.replace(input, replacement);
|
||||
if (replacement !== null) {
|
||||
range.end = this.doc.replace(range, replacement);
|
||||
range.end = this.session.replace(range, replacement);
|
||||
return range;
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -1024,13 +1030,13 @@ var Editor =function(renderer, doc) {
|
|||
|
||||
this.$find = function(backwards) {
|
||||
if (!this.selection.isEmpty()) {
|
||||
this.$search.set({needle: this.doc.getTextRange(this.getSelectionRange())});
|
||||
this.$search.set({needle: this.session.getTextRange(this.getSelectionRange())});
|
||||
}
|
||||
|
||||
if (typeof backwards != "undefined")
|
||||
this.$search.set({backwards: backwards});
|
||||
|
||||
var range = this.$search.find(this.doc);
|
||||
var range = this.$search.find(this.session);
|
||||
if (range) {
|
||||
this.gotoLine(range.end.row+1, range.end.column);
|
||||
this.$updateDesiredColumn();
|
||||
|
|
@ -1039,11 +1045,11 @@ var Editor =function(renderer, doc) {
|
|||
};
|
||||
|
||||
this.undo = function() {
|
||||
this.doc.getUndoManager().undo();
|
||||
this.session.getUndoManager().undo();
|
||||
};
|
||||
|
||||
this.redo = function() {
|
||||
this.doc.getUndoManager().redo();
|
||||
this.session.getUndoManager().redo();
|
||||
};
|
||||
|
||||
}).call(Editor.prototype);
|
||||
|
|
|
|||
|
|
@ -52,14 +52,14 @@ var Cursor = function(parentEl) {
|
|||
|
||||
(function() {
|
||||
|
||||
this.setDocument = function(doc) {
|
||||
this.doc = doc;
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
};
|
||||
|
||||
this.setCursor = function(position, overwrite) {
|
||||
this.position = {
|
||||
row : position.row,
|
||||
column : this.doc.documentToScreenColumn(position.row, position.column)
|
||||
column : this.session.documentToScreenColumn(position.row, position.column)
|
||||
};
|
||||
if (overwrite) {
|
||||
dom.addCssClass(this.cursor, "ace_overwrite");
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@ var Marker = function(parentEl) {
|
|||
|
||||
(function() {
|
||||
|
||||
this.setDocument = function(doc) {
|
||||
this.doc = doc;
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
};
|
||||
|
||||
this.addMarker = function(range, clazz, type) {
|
||||
|
|
@ -105,7 +105,7 @@ var Marker = function(parentEl) {
|
|||
|
||||
// selection start
|
||||
var row = range.start.row;
|
||||
var lineRange = new Range(row, range.start.column, row, this.doc.getLine(row).length);
|
||||
var lineRange = new Range(row, range.start.column, row, this.session.getLine(row).length);
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
||||
|
||||
// selection end
|
||||
|
|
@ -116,13 +116,13 @@ var Marker = function(parentEl) {
|
|||
for (var row = range.start.row + 1; row < range.end.row; row++) {
|
||||
lineRange.start.row = row;
|
||||
lineRange.end.row = row;
|
||||
lineRange.end.column = this.doc.getLine(row).length; // account for endofline characters
|
||||
lineRange.end.column = this.session.getLine(row).length; // account for endofline characters
|
||||
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1);
|
||||
}
|
||||
};
|
||||
|
||||
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
|
||||
var range = range.toScreenRange(this.doc);
|
||||
var range = range.toScreenRange(this.session);
|
||||
|
||||
// from selection start to the end of the line
|
||||
var height = layerConfig.lineHeight;
|
||||
|
|
@ -164,7 +164,7 @@ var Marker = function(parentEl) {
|
|||
};
|
||||
|
||||
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength) {
|
||||
var range = range.toScreenRange(this.doc);
|
||||
var range = range.toScreenRange(this.session);
|
||||
|
||||
var height = layerConfig.lineHeight;
|
||||
var width = Math.round((range.end.column + (extraLength || 0) - range.start.column) * layerConfig.characterWidth);
|
||||
|
|
|
|||
|
|
@ -125,8 +125,8 @@ var Text = function(parentEl) {
|
|||
return size;
|
||||
};
|
||||
|
||||
this.setDocument = function(doc) {
|
||||
this.doc = doc;
|
||||
this.setSession = function(session) {
|
||||
this.session = session;
|
||||
};
|
||||
|
||||
this.showInvisibles = false;
|
||||
|
|
@ -139,7 +139,7 @@ var Text = function(parentEl) {
|
|||
};
|
||||
|
||||
this.$computeTabString = function() {
|
||||
var tabSize = this.doc.getTabSize();
|
||||
var tabSize = this.session.getTabSize();
|
||||
if (this.showInvisibles) {
|
||||
var halfTab = (tabSize) / 2;
|
||||
this.$tabString = "<span class='ace_invisible'>"
|
||||
|
|
@ -280,7 +280,7 @@ var Text = function(parentEl) {
|
|||
};
|
||||
|
||||
if (this.showInvisibles) {
|
||||
if (row !== this.doc.getLength() - 1) {
|
||||
if (row !== this.session.getLength() - 1) {
|
||||
stringBuilder.push("<span class='ace_invisible'>" + this.EOL_CHAR + "</span>");
|
||||
} else {
|
||||
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
|
||||
|
|
|
|||
|
|
@ -110,8 +110,6 @@ var XmlHighlightRules = function() {
|
|||
};
|
||||
};
|
||||
|
||||
/fd/g
|
||||
|
||||
oop.inherits(XmlHighlightRules, TextHighlightRules);
|
||||
|
||||
exports.XmlHighlightRules = XmlHighlightRules;
|
||||
|
|
|
|||
|
|
@ -67,14 +67,14 @@ Search.SELECTION = 2;
|
|||
return lang.copyObject(this.$options);
|
||||
};
|
||||
|
||||
this.find = function(doc) {
|
||||
this.find = function(session) {
|
||||
if (!this.$options.needle)
|
||||
return null;
|
||||
|
||||
if (this.$options.backwards) {
|
||||
var iterator = this.$backwardMatchIterator(doc);
|
||||
var iterator = this.$backwardMatchIterator(session);
|
||||
} else {
|
||||
iterator = this.$forwardMatchIterator(doc);
|
||||
iterator = this.$forwardMatchIterator(session);
|
||||
}
|
||||
|
||||
var firstRange = null;
|
||||
|
|
@ -86,14 +86,14 @@ Search.SELECTION = 2;
|
|||
return firstRange;
|
||||
};
|
||||
|
||||
this.findAll = function(doc) {
|
||||
this.findAll = function(session) {
|
||||
if (!this.$options.needle)
|
||||
return [];
|
||||
|
||||
if (this.$options.backwards) {
|
||||
var iterator = this.$backwardMatchIterator(doc);
|
||||
var iterator = this.$backwardMatchIterator(session);
|
||||
} else {
|
||||
iterator = this.$forwardMatchIterator(doc);
|
||||
iterator = this.$forwardMatchIterator(session);
|
||||
}
|
||||
|
||||
var ranges = [];
|
||||
|
|
@ -118,13 +118,13 @@ Search.SELECTION = 2;
|
|||
}
|
||||
};
|
||||
|
||||
this.$forwardMatchIterator = function(doc) {
|
||||
this.$forwardMatchIterator = function(session) {
|
||||
var re = this.$assembleRegExp();
|
||||
var self = this;
|
||||
|
||||
return {
|
||||
forEach: function(callback) {
|
||||
self.$forwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
self.$forwardLineIterator(session).forEach(function(line, startIndex, row) {
|
||||
if (startIndex) {
|
||||
line = line.substring(startIndex);
|
||||
}
|
||||
|
|
@ -152,13 +152,13 @@ Search.SELECTION = 2;
|
|||
};
|
||||
};
|
||||
|
||||
this.$backwardMatchIterator = function(doc) {
|
||||
this.$backwardMatchIterator = function(session) {
|
||||
var re = this.$assembleRegExp();
|
||||
var self = this;
|
||||
|
||||
return {
|
||||
forEach: function(callback) {
|
||||
self.$backwardLineIterator(doc).forEach(function(line, startIndex, row) {
|
||||
self.$backwardLineIterator(session).forEach(function(line, startIndex, row) {
|
||||
if (startIndex) {
|
||||
line = line.substring(startIndex);
|
||||
}
|
||||
|
|
@ -208,20 +208,20 @@ Search.SELECTION = 2;
|
|||
return re;
|
||||
};
|
||||
|
||||
this.$forwardLineIterator = function(doc) {
|
||||
this.$forwardLineIterator = function(session) {
|
||||
var searchSelection = this.$options.scope == Search.SELECTION;
|
||||
|
||||
var range = doc.getSelection().getRange();
|
||||
var start = doc.getSelection().getCursor();
|
||||
var range = session.getSelection().getRange();
|
||||
var start = session.getSelection().getCursor();
|
||||
|
||||
var firstRow = searchSelection ? range.start.row : 0;
|
||||
var firstColumn = searchSelection ? range.start.column : 0;
|
||||
var lastRow = searchSelection ? range.end.row : doc.getLength() - 1;
|
||||
var lastRow = searchSelection ? range.end.row : session.getLength() - 1;
|
||||
|
||||
var wrap = this.$options.wrap;
|
||||
|
||||
function getLine(row) {
|
||||
var line = doc.getLine(row);
|
||||
var line = session.getLine(row);
|
||||
if (searchSelection && row == range.end.row) {
|
||||
line = line.substring(0, range.end.column);
|
||||
}
|
||||
|
|
@ -264,15 +264,15 @@ Search.SELECTION = 2;
|
|||
};
|
||||
};
|
||||
|
||||
this.$backwardLineIterator = function(doc) {
|
||||
this.$backwardLineIterator = function(session) {
|
||||
var searchSelection = this.$options.scope == Search.SELECTION;
|
||||
|
||||
var range = doc.getSelection().getRange();
|
||||
var range = session.getSelection().getRange();
|
||||
var start = searchSelection ? range.end : range.start;
|
||||
|
||||
var firstRow = searchSelection ? range.start.row : 0;
|
||||
var firstColumn = searchSelection ? range.start.column : 0;
|
||||
var lastRow = searchSelection ? range.end.row : doc.getLength() - 1;
|
||||
var lastRow = searchSelection ? range.end.row : session.getLength() - 1;
|
||||
|
||||
var wrap = this.$options.wrap;
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ Search.SELECTION = 2;
|
|||
forEach : function(callback) {
|
||||
var row = start.row;
|
||||
|
||||
var line = doc.getLine(row).substring(0, start.column);
|
||||
var line = session.getLine(row).substring(0, start.column);
|
||||
var startIndex = 0;
|
||||
var stop = false;
|
||||
|
||||
|
|
@ -303,7 +303,7 @@ Search.SELECTION = 2;
|
|||
if (row == start.row)
|
||||
stop = true;
|
||||
|
||||
line = doc.getLine(row);
|
||||
line = session.getLine(row);
|
||||
if (searchSelection) {
|
||||
if (row == firstRow)
|
||||
startIndex = firstColumn;
|
||||
|
|
|
|||
|
|
@ -37,11 +37,12 @@
|
|||
|
||||
require("../../../support/paths");
|
||||
|
||||
var async = require("async");
|
||||
var async = require("asyncjs");
|
||||
|
||||
async.concat(
|
||||
require("./change_document_test"),
|
||||
require("./document_test"),
|
||||
require("./edit_session_test"),
|
||||
require("./event_emitter_test"),
|
||||
require("./navigation_test"),
|
||||
require("./range_test"),
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ define(function(require, exports, module) {
|
|||
|
||||
require("./mockdom");
|
||||
|
||||
var Document = require("../document").Document,
|
||||
var EditSession = require("../edit_session").EditSession,
|
||||
Editor = require("../editor").Editor,
|
||||
Text = require("../mode/text").Mode,
|
||||
JavaScriptMode = require("../mode/javascript").Mode,
|
||||
|
|
@ -47,18 +47,20 @@ var Document = require("../document").Document,
|
|||
assert = require("./assertions");
|
||||
|
||||
var Test = {
|
||||
setUp : function() {
|
||||
this.doc1 = new Document(["abc", "def"].join("\n"));
|
||||
this.doc2 = new Document(["ghi", "jkl"].join("\n"));
|
||||
|
||||
setUp : function(next) {
|
||||
this.session1 = new EditSession(["abc", "def"]);
|
||||
this.session2 = new EditSession(["ghi", "jkl"]);
|
||||
this.editor = new Editor(new MockRenderer());
|
||||
next();
|
||||
},
|
||||
|
||||
"test: change document" : function() {
|
||||
this.editor.setDocument(this.doc1);
|
||||
assert.equal(this.editor.getDocument(), this.doc1);
|
||||
this.editor.setSession(this.session1);
|
||||
assert.equal(this.editor.getSession(), this.session1);
|
||||
|
||||
this.editor.setDocument(this.doc2);
|
||||
assert.equal(this.editor.getDocument(), this.doc2);
|
||||
this.editor.setSession(this.session2);
|
||||
assert.equal(this.editor.getSession(), this.session2);
|
||||
},
|
||||
|
||||
"test: only changes to the new document should have effect" : function() {
|
||||
|
|
@ -67,24 +69,24 @@ var Test = {
|
|||
called = true;
|
||||
};
|
||||
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session1);
|
||||
this.editor.setSession(this.session2);
|
||||
|
||||
this.doc1.duplicateLines(0, 0);
|
||||
this.session1.duplicateLines(0, 0);
|
||||
assert.notOk(called);
|
||||
|
||||
this.doc2.duplicateLines(0, 0);
|
||||
this.session2.duplicateLines(0, 0);
|
||||
assert.ok(called);
|
||||
},
|
||||
|
||||
"test: should use cursor of new document" : function() {
|
||||
this.doc1.getSelection().moveCursorTo(0, 1);
|
||||
this.doc2.getSelection().moveCursorTo(1, 0);
|
||||
this.session1.getSelection().moveCursorTo(0, 1);
|
||||
this.session2.getSelection().moveCursorTo(1, 0);
|
||||
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setSession(this.session1);
|
||||
assert.position(this.editor.getCursorPosition(), 0, 1);
|
||||
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session2);
|
||||
assert.position(this.editor.getCursorPosition(), 1, 0);
|
||||
},
|
||||
|
||||
|
|
@ -93,28 +95,28 @@ var Test = {
|
|||
called = true;
|
||||
};
|
||||
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session1);
|
||||
this.editor.setSession(this.session2);
|
||||
assert.position(this.editor.getCursorPosition(), 0, 0);
|
||||
|
||||
var called = false;
|
||||
this.doc1.getSelection().moveCursorTo(0, 1);
|
||||
this.session1.getSelection().moveCursorTo(0, 1);
|
||||
assert.position(this.editor.getCursorPosition(), 0, 0);
|
||||
assert.notOk(called);
|
||||
|
||||
this.doc2.getSelection().moveCursorTo(1, 1);
|
||||
this.session2.getSelection().moveCursorTo(1, 1);
|
||||
assert.position(this.editor.getCursorPosition(), 1, 1);
|
||||
assert.ok(called);
|
||||
},
|
||||
|
||||
"test: should use selection of new document" : function() {
|
||||
this.doc1.getSelection().selectTo(0, 1);
|
||||
this.doc2.getSelection().selectTo(1, 0);
|
||||
this.session1.getSelection().selectTo(0, 1);
|
||||
this.session2.getSelection().selectTo(1, 0);
|
||||
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setSession(this.session1);
|
||||
assert.position(this.editor.getSelection().getSelectionLead(), 0, 1);
|
||||
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session2);
|
||||
assert.position(this.editor.getSelection().getSelectionLead(), 1, 0);
|
||||
},
|
||||
|
||||
|
|
@ -123,16 +125,16 @@ var Test = {
|
|||
called = true;
|
||||
};
|
||||
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session1);
|
||||
this.editor.setSession(this.session2);
|
||||
assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);
|
||||
|
||||
var called = false;
|
||||
this.doc1.getSelection().selectTo(0, 1);
|
||||
this.session1.getSelection().selectTo(0, 1);
|
||||
assert.position(this.editor.getSelection().getSelectionLead(), 0, 0);
|
||||
assert.notOk(called);
|
||||
|
||||
this.doc2.getSelection().selectTo(1, 1);
|
||||
this.session2.getSelection().selectTo(1, 1);
|
||||
assert.position(this.editor.getSelection().getSelectionLead(), 1, 1);
|
||||
assert.ok(called);
|
||||
},
|
||||
|
|
@ -141,19 +143,19 @@ var Test = {
|
|||
this.editor.onDocumentModeChange = function() {
|
||||
called = true;
|
||||
};
|
||||
this.editor.setDocument(this.doc1);
|
||||
this.editor.setDocument(this.doc2);
|
||||
this.editor.setSession(this.session1);
|
||||
this.editor.setSession(this.session2);
|
||||
|
||||
var called = false;
|
||||
this.doc1.setMode(new Text());
|
||||
this.session1.setMode(new Text());
|
||||
assert.notOk(called);
|
||||
|
||||
this.doc2.setMode(new JavaScriptMode());
|
||||
this.session2.setMode(new JavaScriptMode());
|
||||
assert.ok(called);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = require("async/test").testcase(Test);
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
|
|
|
|||
|
|
@ -35,259 +35,252 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
define(function(require, exports, module) {
|
||||
|
||||
var Document = require("../document").Document,
|
||||
UndoManager = require("../undomanager").UndoManager,
|
||||
MockRenderer = require("./mockrenderer"),
|
||||
Range = require("../range").Range,
|
||||
assert = require("./assertions"),
|
||||
async = require("async");
|
||||
async = require("asyncjs");
|
||||
|
||||
var Test = {
|
||||
|
||||
"test: find matching opening bracket" : function() {
|
||||
var doc = new Document(["(()(", "())))"]);
|
||||
"test: insert text in line" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 3}), 0, 1);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 2}), 1, 0);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 3}), 0, 3);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 4}), 0, 0);
|
||||
assert.equal(doc.findMatchingBracket({row: 1, column: 5}), null);
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insert({row: 0, column: 1}, "juhu");
|
||||
assert.equal(doc.getValue(), ["1juhu2", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1juhu2", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert new line" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insertNewLine({row: 0, column: 1});
|
||||
assert.equal(doc.getValue(), ["1", "2", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1", "2", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert lines at the beginning" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insertLines(0, ["aa", "bb"]);
|
||||
assert.equal(doc.getValue(), ["aa", "bb", "12", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["aa", "bb", "12", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert lines at the end" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insertLines(2, ["aa", "bb"]);
|
||||
assert.equal(doc.getValue(), ["12", "34", "aa", "bb"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert lines in the middle" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insertLines(1, ["aa", "bb"]);
|
||||
assert.equal(doc.getValue(), ["12", "aa", "bb", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "aa", "bb", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert multi line string at the start" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insert({row: 0, column: 0}, "aa\nbb\ncc");
|
||||
assert.equal(doc.getValue(), ["aa", "bb", "cc12", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["aa", "bb", "cc12", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert multi line string at the end" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insert({row: 2, column: 0}, "aa\nbb\ncc");
|
||||
assert.equal(doc.getValue(), ["12", "34aa", "bb", "cc"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34aa", "bb", "cc"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert multi line string in the middle" : function() {
|
||||
var doc = new Document(["12", "34"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.insert({row: 0, column: 1}, "aa\nbb\ncc");
|
||||
assert.equal(doc.getValue(), ["1aa", "bb", "cc2", "34"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12", "34"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1aa", "bb", "cc2", "34"].join("\n"));
|
||||
},
|
||||
|
||||
"test: delete in line" : function() {
|
||||
var doc = new Document(["1234", "5678"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.remove(new Range(0, 1, 0, 3));
|
||||
assert.equal(doc.getValue(), ["14", "5678"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1234", "5678"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["14", "5678"].join("\n"));
|
||||
},
|
||||
|
||||
"test: find matching closing bracket" : function() {
|
||||
var doc = new Document(["(()(", "())))"]);
|
||||
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 1}), 1, 1);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 1}), 1, 1);
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 4}), 1, 2);
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 2}), 0, 2);
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 1}), 1, 3);
|
||||
assert.equal(doc.findMatchingBracket({row: 0, column: 0}), null);
|
||||
"test: delete new line" : function() {
|
||||
var doc = new Document(["1234", "5678"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.remove(new Range(0, 4, 1, 0));
|
||||
assert.equal(doc.getValue(), ["12345678"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1234", "5678"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12345678"].join("\n"));
|
||||
},
|
||||
|
||||
"test: match different bracket types" : function() {
|
||||
var doc = new Document(["({[", ")]}"]);
|
||||
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 1}), 1, 0);
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 2}), 1, 2);
|
||||
assert.position(doc.findMatchingBracket({row: 0, column: 3}), 1, 1);
|
||||
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 1}), 0, 0);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 2}), 0, 2);
|
||||
assert.position(doc.findMatchingBracket({row: 1, column: 3}), 0, 1);
|
||||
|
||||
"test: delete multi line range line" : function() {
|
||||
var doc = new Document(["1234", "5678", "abcd"]);
|
||||
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.remove(new Range(0, 2, 2, 2));
|
||||
assert.equal(doc.getValue(), ["12cd"].join("\n"));
|
||||
|
||||
var d = deltas.concat();
|
||||
doc.revertDeltas(d);
|
||||
assert.equal(doc.getValue(), ["1234", "5678", "abcd"].join("\n"));
|
||||
|
||||
doc.applyDeltas(d);
|
||||
assert.equal(doc.getValue(), ["12cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: move lines down" : function() {
|
||||
var doc = new Document(["a1", "a2", "a3", "a4"]);
|
||||
|
||||
"test: delete full lines" : function() {
|
||||
var doc = new Document(["1234", "5678", "abcd"]);
|
||||
|
||||
doc.moveLinesDown(0, 1);
|
||||
assert.equal(doc.toString(), ["a3", "a1", "a2", "a4"].join("\n"));
|
||||
var deltas = [];
|
||||
doc.on("change", function(e) { deltas.push(e.data); });
|
||||
|
||||
doc.moveLinesDown(1, 2);
|
||||
assert.equal(doc.toString(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
doc.moveLinesDown(2, 3);
|
||||
assert.equal(doc.toString(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
doc.moveLinesDown(2, 2);
|
||||
assert.equal(doc.toString(), ["a3", "a4", "a2", "a1"].join("\n"));
|
||||
doc.remove(new Range(1, 0, 3, 0));
|
||||
assert.equal(doc.getValue(), ["1234", ""].join("\n"));
|
||||
},
|
||||
|
||||
"test: move lines up" : function() {
|
||||
var doc = new Document(["a1", "a2", "a3", "a4"]);
|
||||
|
||||
doc.moveLinesUp(2, 3);
|
||||
assert.equal(doc.toString(), ["a1", "a3", "a4", "a2"].join("\n"));
|
||||
|
||||
"test: remove lines should return the removed lines" : function() {
|
||||
var doc = new Document(["1234", "5678", "abcd"]);
|
||||
|
||||
doc.moveLinesUp(1, 2);
|
||||
assert.equal(doc.toString(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
doc.moveLinesUp(0, 1);
|
||||
assert.equal(doc.toString(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
doc.moveLinesUp(2, 2);
|
||||
assert.equal(doc.toString(), ["a3", "a1", "a4", "a2"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate lines" : function() {
|
||||
var doc = new Document(["1", "2", "3", "4"]);
|
||||
|
||||
doc.duplicateLines(1, 2);
|
||||
assert.equal(doc.toString(), ["1", "2", "3", "2", "3", "4"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate last line" : function() {
|
||||
var doc = new Document(["1", "2", "3"]);
|
||||
|
||||
doc.duplicateLines(2, 2);
|
||||
assert.equal(doc.toString(), ["1", "2", "3", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate first line" : function() {
|
||||
var doc = new Document(["1", "2", "3"]);
|
||||
|
||||
doc.duplicateLines(0, 0);
|
||||
assert.equal(doc.toString(), ["1", "1", "2", "3"].join("\n"));
|
||||
var removed = doc.removeLines(1, 2);
|
||||
assert.equal(removed.join("\n"), ["5678", "abcd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: should handle unix style new lines" : function() {
|
||||
var doc = new Document(["1", "2", "3"]);
|
||||
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: should handle windows style new lines" : function() {
|
||||
var doc = new Document(["1", "2", "3"].join("\r\n"));
|
||||
|
||||
doc.setNewLineMode("unix");
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: set new line mode to 'windows' should use '\r\n' as new lines": function() {
|
||||
var doc = new Document(["1", "2", "3"].join("\n"));
|
||||
doc.setNewLineMode("windows");
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\r\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\r\n"));
|
||||
},
|
||||
|
||||
"test: set new line mode to 'unix' should use '\n' as new lines": function() {
|
||||
var doc = new Document(["1", "2", "3"].join("\r\n"));
|
||||
|
||||
doc.setNewLineMode("unix");
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: set new line mode to 'auto' should detect the incoming nl type": function() {
|
||||
var doc = new Document(["1", "2", "3"].join("\n"));
|
||||
|
||||
doc.setNewLineMode("auto");
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\n"));
|
||||
|
||||
var doc = new Document(["1", "2", "3"].join("\r\n"));
|
||||
|
||||
doc.setNewLineMode("auto");
|
||||
assert.equal(doc.toString(), ["1", "2", "3"].join("\r\n"));
|
||||
assert.equal(doc.getValue(), ["1", "2", "3"].join("\r\n"));
|
||||
|
||||
doc.replace(new Range(0, 0, 2, 1), ["4", "5", "6"].join("\n"));
|
||||
assert.equal(["4", "5", "6"].join("\n"), doc.toString());
|
||||
},
|
||||
|
||||
"test: convert document to screen coordinates" : function() {
|
||||
var doc = new Document("01234\t567890\t1234");
|
||||
doc.setTabSize(4);
|
||||
|
||||
assert.equal(doc.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(doc.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(doc.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(doc.documentToScreenColumn(0, 6), 9);
|
||||
assert.equal(doc.documentToScreenColumn(0, 12), 15);
|
||||
assert.equal(doc.documentToScreenColumn(0, 13), 19);
|
||||
|
||||
doc.setTabSize(2);
|
||||
|
||||
assert.equal(doc.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(doc.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(doc.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(doc.documentToScreenColumn(0, 6), 7);
|
||||
assert.equal(doc.documentToScreenColumn(0, 12), 13);
|
||||
assert.equal(doc.documentToScreenColumn(0, 13), 15);
|
||||
},
|
||||
|
||||
"test: convert document to scrren coordinates with leading tabs": function() {
|
||||
var doc = new Document("\t\t123");
|
||||
doc.setTabSize(4);
|
||||
|
||||
assert.equal(doc.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(doc.documentToScreenColumn(0, 1), 4);
|
||||
assert.equal(doc.documentToScreenColumn(0, 2), 8);
|
||||
assert.equal(doc.documentToScreenColumn(0, 3), 9);
|
||||
},
|
||||
|
||||
"test: convert screen to document coordinates" : function() {
|
||||
var doc = new Document("01234\t567890\t1234");
|
||||
doc.setTabSize(4);
|
||||
|
||||
assert.equal(doc.screenToDocumentColumn(0, 0), 0);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 4), 4);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 5), 5);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 6), 5);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 7), 5);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 8), 5);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 9), 6);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 15), 12);
|
||||
assert.equal(doc.screenToDocumentColumn(0, 19), 13);
|
||||
},
|
||||
|
||||
"test: insert text in multiple rows": function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
|
||||
var inserted = doc.multiRowInsert([0, 1, 2], 2, "juhu 1");
|
||||
assert.equal(inserted.rows, 0);
|
||||
assert.equal(inserted.columns, 6);
|
||||
|
||||
assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: undo insert text in multiple rows": function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
|
||||
var undoManager = new UndoManager();
|
||||
doc.setUndoManager(undoManager);
|
||||
|
||||
doc.multiRowInsert([0, 1, 2], 2, "juhu 1");
|
||||
doc.$informUndoManager.call();
|
||||
assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
|
||||
undoManager.undo();
|
||||
assert.equal(doc.toString(), ["12", "", "abcd"].join("\n"));
|
||||
|
||||
undoManager.redo();
|
||||
assert.equal(doc.toString(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert new line in multiple rows": function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
|
||||
var inserted = doc.multiRowInsert([0, 1, 2], 2, "\n");
|
||||
assert.equal(inserted.rows, 1);
|
||||
assert.equal(doc.toString(), ["12\n", " \n", "ab\ncd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert multi line text in multiple rows": function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
|
||||
var inserted = doc.multiRowInsert([0, 1, 2], 2, "juhu\n12");
|
||||
assert.equal(inserted.rows, 1);
|
||||
assert.equal(doc.toString(), ["12juhu\n12", " juhu\n12", "abjuhu\n12cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: remove right in multiple rows" : function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
|
||||
doc.multiRowRemove([0, 1, 2], new Range(0, 2, 0, 3));
|
||||
assert.equal(doc.toString(), ["12", "", "abd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: undo remove right in multiple rows" : function() {
|
||||
var doc = new Document(["12", "", "abcd"]);
|
||||
var undoManager = new UndoManager();
|
||||
doc.setUndoManager(undoManager);
|
||||
|
||||
doc.multiRowRemove([0, 1, 2], new Range(0, 1, 0, 3));
|
||||
doc.$informUndoManager.call();
|
||||
assert.equal(doc.toString(), ["1", "", "ad"].join("\n"));
|
||||
|
||||
undoManager.undo();
|
||||
assert.equal(doc.toString(), ["12", "", "abcd"].join("\n"));
|
||||
|
||||
undoManager.redo();
|
||||
assert.equal(doc.toString(), ["1", "", "ad"].join("\n"));
|
||||
assert.equal(["4", "5", "6"].join("\n"), doc.getValue());
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = require("async/test").testcase(Test);
|
||||
});
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
|
||||
if (module === require.main) {
|
||||
require("../../../support/paths");
|
||||
|
|
|
|||
275
lib/ace/test/edit_session_test.js
Normal file
275
lib/ace/test/edit_session_test.js
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
/* ***** 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):
|
||||
* Fabian Jakobs <fabian 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 EditSession = require("ace/edit_session").EditSession,
|
||||
UndoManager = require("ace/undomanager").UndoManager,
|
||||
MockRenderer = require("./mockrenderer"),
|
||||
Range = require("ace/range").Range,
|
||||
assert = require("./assertions"),
|
||||
async = require("asyncjs");
|
||||
|
||||
var Test = {
|
||||
|
||||
"test: find matching opening bracket" : function() {
|
||||
var session = new EditSession(["(()(", "())))"]);
|
||||
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 3}), 0, 1);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 2}), 1, 0);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 3);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 4}), 0, 0);
|
||||
assert.equal(session.findMatchingBracket({row: 1, column: 5}), null);
|
||||
},
|
||||
|
||||
"test: find matching closing bracket" : function() {
|
||||
var session = new EditSession(["(()(", "())))"]);
|
||||
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 4}), 1, 2);
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 2}), 0, 2);
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 3);
|
||||
assert.equal(session.findMatchingBracket({row: 0, column: 0}), null);
|
||||
},
|
||||
|
||||
"test: match different bracket types" : function() {
|
||||
var session = new EditSession(["({[", ")]}"]);
|
||||
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 0);
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 2}), 1, 2);
|
||||
assert.position(session.findMatchingBracket({row: 0, column: 3}), 1, 1);
|
||||
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 1}), 0, 0);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 2}), 0, 2);
|
||||
assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 1);
|
||||
},
|
||||
|
||||
"test: move lines down" : function() {
|
||||
var session = new EditSession(["a1", "a2", "a3", "a4"]);
|
||||
|
||||
session.moveLinesDown(0, 1);
|
||||
assert.equal(session.getValue(), ["a3", "a1", "a2", "a4"].join("\n"));
|
||||
|
||||
session.moveLinesDown(1, 2);
|
||||
assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
session.moveLinesDown(2, 3);
|
||||
assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
session.moveLinesDown(2, 2);
|
||||
assert.equal(session.getValue(), ["a3", "a4", "a2", "a1"].join("\n"));
|
||||
},
|
||||
|
||||
"test: move lines up" : function() {
|
||||
var session = new EditSession(["a1", "a2", "a3", "a4"]);
|
||||
|
||||
session.moveLinesUp(2, 3);
|
||||
assert.equal(session.getValue(), ["a1", "a3", "a4", "a2"].join("\n"));
|
||||
|
||||
session.moveLinesUp(1, 2);
|
||||
assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
session.moveLinesUp(0, 1);
|
||||
assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
|
||||
|
||||
session.moveLinesUp(2, 2);
|
||||
assert.equal(session.getValue(), ["a3", "a1", "a4", "a2"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate lines" : function() {
|
||||
var session = new EditSession(["1", "2", "3", "4"]);
|
||||
|
||||
session.duplicateLines(1, 2);
|
||||
assert.equal(session.getValue(), ["1", "2", "3", "2", "3", "4"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate last line" : function() {
|
||||
var session = new EditSession(["1", "2", "3"]);
|
||||
|
||||
session.duplicateLines(2, 2);
|
||||
assert.equal(session.getValue(), ["1", "2", "3", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: duplicate first line" : function() {
|
||||
var session = new EditSession(["1", "2", "3"]);
|
||||
|
||||
session.duplicateLines(0, 0);
|
||||
assert.equal(session.getValue(), ["1", "1", "2", "3"].join("\n"));
|
||||
},
|
||||
|
||||
"test: convert document to screen coordinates" : function() {
|
||||
var session = new EditSession("01234\t567890\t1234");
|
||||
session.setTabSize(4);
|
||||
|
||||
assert.equal(session.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(session.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(session.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 9);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 15);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 19);
|
||||
|
||||
session.setTabSize(2);
|
||||
|
||||
assert.equal(session.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(session.documentToScreenColumn(0, 4), 4);
|
||||
assert.equal(session.documentToScreenColumn(0, 5), 5);
|
||||
assert.equal(session.documentToScreenColumn(0, 6), 7);
|
||||
assert.equal(session.documentToScreenColumn(0, 12), 13);
|
||||
assert.equal(session.documentToScreenColumn(0, 13), 15);
|
||||
},
|
||||
|
||||
"test: convert document to scrren coordinates with leading tabs": function() {
|
||||
var session = new EditSession("\t\t123");
|
||||
session.setTabSize(4);
|
||||
|
||||
assert.equal(session.documentToScreenColumn(0, 0), 0);
|
||||
assert.equal(session.documentToScreenColumn(0, 1), 4);
|
||||
assert.equal(session.documentToScreenColumn(0, 2), 8);
|
||||
assert.equal(session.documentToScreenColumn(0, 3), 9);
|
||||
},
|
||||
|
||||
"test: convert screen to document coordinates" : function() {
|
||||
var session = new EditSession("01234\t567890\t1234");
|
||||
session.setTabSize(4);
|
||||
|
||||
assert.equal(session.screenToDocumentColumn(0, 0), 0);
|
||||
assert.equal(session.screenToDocumentColumn(0, 4), 4);
|
||||
assert.equal(session.screenToDocumentColumn(0, 5), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 6), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 7), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 8), 5);
|
||||
assert.equal(session.screenToDocumentColumn(0, 9), 6);
|
||||
assert.equal(session.screenToDocumentColumn(0, 15), 12);
|
||||
assert.equal(session.screenToDocumentColumn(0, 19), 13);
|
||||
},
|
||||
|
||||
"test: insert text in multiple rows": function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
|
||||
var inserted = session.multiRowInsert([0, 1, 2], 2, "juhu 1");
|
||||
assert.equal(inserted.rows, 0);
|
||||
assert.equal(inserted.columns, 6);
|
||||
|
||||
assert.equal(session.getValue(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: undo insert text in multiple rows": function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
|
||||
var undoManager = new UndoManager();
|
||||
session.setUndoManager(undoManager);
|
||||
|
||||
session.multiRowInsert([0, 1, 2], 2, "juhu 1");
|
||||
session.$informUndoManager.call();
|
||||
assert.equal(session.getValue(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
|
||||
undoManager.undo();
|
||||
assert.equal(session.getValue(), ["12", "", "abcd"].join("\n"));
|
||||
|
||||
undoManager.redo();
|
||||
assert.equal(session.getValue(), ["12juhu 1", " juhu 1", "abjuhu 1cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert new line in multiple rows": function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
|
||||
var inserted = session.multiRowInsert([0, 1, 2], 2, "\n");
|
||||
assert.equal(inserted.rows, 1);
|
||||
assert.equal(session.getValue(), ["12\n", " \n", "ab\ncd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: insert multi line text in multiple rows": function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
|
||||
var inserted = session.multiRowInsert([0, 1, 2], 2, "juhu\n12");
|
||||
assert.equal(inserted.rows, 1);
|
||||
assert.equal(session.getValue(), ["12juhu\n12", " juhu\n12", "abjuhu\n12cd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: remove right in multiple rows" : function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
|
||||
session.multiRowRemove([0, 1, 2], new Range(0, 2, 0, 3));
|
||||
assert.equal(session.getValue(), ["12", "", "abd"].join("\n"));
|
||||
},
|
||||
|
||||
"test: undo remove right in multiple rows" : function() {
|
||||
var session = new EditSession(["12", "", "abcd"]);
|
||||
var undoManager = new UndoManager();
|
||||
session.setUndoManager(undoManager);
|
||||
|
||||
session.multiRowRemove([0, 1, 2], new Range(0, 1, 0, 3));
|
||||
session.$informUndoManager.call();
|
||||
assert.equal(session.getValue(), ["1", "", "ad"].join("\n"));
|
||||
|
||||
undoManager.undo();
|
||||
assert.equal(session.getValue(), ["12", "", "abcd"].join("\n"));
|
||||
|
||||
undoManager.redo();
|
||||
assert.equal(session.getValue(), ["1", "", "ad"].join("\n"));
|
||||
},
|
||||
|
||||
"test get longest line" : function() {
|
||||
var session = new EditSession(["12"]);
|
||||
session.setTabSize(4);
|
||||
assert.equal(session.getWidth(), 2);
|
||||
assert.equal(session.getScreenWidth(), 2);
|
||||
|
||||
session.doc.insertNewLine(0);
|
||||
session.doc.insertLines(1, ["123"]);
|
||||
assert.equal(session.getWidth(), 3);
|
||||
assert.equal(session.getScreenWidth(), 3);
|
||||
|
||||
session.doc.insertNewLine(0);
|
||||
session.doc.insertLines(1, ["\t\t"]);
|
||||
assert.equal(session.getWidth(), 3);
|
||||
assert.equal(session.getScreenWidth(), 8);
|
||||
|
||||
session.setTabSize(2);
|
||||
assert.equal(session.getWidth(), 3);
|
||||
assert.equal(session.getScreenWidth(), 4);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = require("asyncjs/test").testcase(Test);
|
||||
});
|
||||
|
||||
if (module === require.main) {
|
||||
require("../../../support/paths");
|
||||
exports.exec()
|
||||
}
|
||||
|
|
@ -60,7 +60,7 @@ var Test = {
|
|||
}
|
||||
};
|
||||
|
||||
module.exports = require("async/test").testcase(Test)
|
||||
module.exports = require("asyncjs/test").testcase(Test)
|
||||
|
||||
if (module === require.main)
|
||||
module.exports.exec()
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue