Merge pull request #1274 from ajaxorg/folding
preserve folds when dragging or moving lines
This commit is contained in:
commit
4ab6cab5d9
16 changed files with 594 additions and 500 deletions
2
build
2
build
|
|
@ -1 +1 @@
|
||||||
Subproject commit 75ba742f4f00cefadfef1ae451cfb2a4280ad367
|
Subproject commit 1e3407af692eaf661800083897c73d46d0a4bc46
|
||||||
|
|
@ -295,6 +295,7 @@ exports.commands = [{
|
||||||
name: "selecttomatching",
|
name: "selecttomatching",
|
||||||
bindKey: bindKey("Ctrl-Shift-P", null),
|
bindKey: bindKey("Ctrl-Shift-P", null),
|
||||||
exec: function(editor) { editor.jumpToMatching(true); },
|
exec: function(editor) { editor.jumpToMatching(true); },
|
||||||
|
multiSelectAction: "forEach",
|
||||||
readOnly: true
|
readOnly: true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -315,7 +316,7 @@ exports.commands = [{
|
||||||
name: "removeline",
|
name: "removeline",
|
||||||
bindKey: bindKey("Ctrl-D", "Command-D"),
|
bindKey: bindKey("Ctrl-D", "Command-D"),
|
||||||
exec: function(editor) { editor.removeLines(); },
|
exec: function(editor) { editor.removeLines(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEachLine"
|
||||||
}, {
|
}, {
|
||||||
name: "duplicateSelection",
|
name: "duplicateSelection",
|
||||||
bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
|
bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
|
||||||
|
|
@ -325,12 +326,12 @@ exports.commands = [{
|
||||||
name: "sortlines",
|
name: "sortlines",
|
||||||
bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
|
bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
|
||||||
exec: function(editor) { editor.sortLines(); },
|
exec: function(editor) { editor.sortLines(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEachLine"
|
||||||
}, {
|
}, {
|
||||||
name: "togglecomment",
|
name: "togglecomment",
|
||||||
bindKey: bindKey("Ctrl-/", "Command-/"),
|
bindKey: bindKey("Ctrl-/", "Command-/"),
|
||||||
exec: function(editor) { editor.toggleCommentLines(); },
|
exec: function(editor) { editor.toggleCommentLines(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEachLine"
|
||||||
}, {
|
}, {
|
||||||
name: "modifyNumberUp",
|
name: "modifyNumberUp",
|
||||||
bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
|
bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
|
||||||
|
|
@ -418,12 +419,12 @@ exports.commands = [{
|
||||||
name: "blockoutdent",
|
name: "blockoutdent",
|
||||||
bindKey: bindKey("Ctrl-[", "Ctrl-["),
|
bindKey: bindKey("Ctrl-[", "Ctrl-["),
|
||||||
exec: function(editor) { editor.blockOutdent(); },
|
exec: function(editor) { editor.blockOutdent(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEachLine"
|
||||||
},{
|
},{
|
||||||
name: "blockindent",
|
name: "blockindent",
|
||||||
bindKey: bindKey("Ctrl-]", "Ctrl-]"),
|
bindKey: bindKey("Ctrl-]", "Ctrl-]"),
|
||||||
exec: function(editor) { editor.blockIndent(); },
|
exec: function(editor) { editor.blockIndent(); },
|
||||||
multiSelectAction: "forEach"
|
multiSelectAction: "forEachLine"
|
||||||
}, {
|
}, {
|
||||||
name: "insertstring",
|
name: "insertstring",
|
||||||
exec: function(editor, str) { editor.insert(str); },
|
exec: function(editor, str) { editor.insert(str); },
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Ajax.org B.V.
|
* Copyright (c) 2010, Ajax.org B.V.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* * Neither the name of Ajax.org B.V. nor the
|
* * Neither the name of Ajax.org B.V. nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
|
@ -31,9 +31,9 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var config = require("./config");
|
|
||||||
var oop = require("./lib/oop");
|
var oop = require("./lib/oop");
|
||||||
var lang = require("./lib/lang");
|
var lang = require("./lib/lang");
|
||||||
|
var config = require("./config");
|
||||||
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
var EventEmitter = require("./lib/event_emitter").EventEmitter;
|
||||||
var Selection = require("./selection").Selection;
|
var Selection = require("./selection").Selection;
|
||||||
var TextMode = require("./mode/text").Mode;
|
var TextMode = require("./mode/text").Mode;
|
||||||
|
|
@ -41,18 +41,15 @@ var Range = require("./range").Range;
|
||||||
var Document = require("./document").Document;
|
var Document = require("./document").Document;
|
||||||
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
|
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
|
||||||
var SearchHighlight = require("./search_highlight").SearchHighlight;
|
var SearchHighlight = require("./search_highlight").SearchHighlight;
|
||||||
var config = require("./config");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* Stores all the data about [[Editor `Editor`]] state providing easy way to change editors state.
|
|
||||||
*
|
|
||||||
* `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s.
|
* `EditSession` can be attached to only one [[Document `Document`]]. Same `Document` can be attached to several `EditSession`s.
|
||||||
* @class EditSession
|
* @class EditSession
|
||||||
**/
|
**/
|
||||||
|
|
||||||
// events
|
//{ events
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Emitted when the document changes.
|
* Emitted when the document changes.
|
||||||
|
|
@ -96,19 +93,19 @@ var config = require("./config");
|
||||||
* @param {Object} e An object containing one property, `"data"`, that contains information about the changing rows
|
* @param {Object} e An object containing one property, `"data"`, that contains information about the changing rows
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
/**
|
/**
|
||||||
* Emitted when the current mode changes.
|
* Emitted when the current mode changes.
|
||||||
*
|
*
|
||||||
* @event changeMode
|
* @event changeMode
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
/**
|
/**
|
||||||
* Emitted when the wrap mode changes.
|
* Emitted when the wrap mode changes.
|
||||||
*
|
*
|
||||||
* @event changeWrapMode
|
* @event changeWrapMode
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
/**
|
/**
|
||||||
* Emitted when the wrapping limit changes.
|
* Emitted when the wrapping limit changes.
|
||||||
*
|
*
|
||||||
* @event changeWrapLimit
|
* @event changeWrapLimit
|
||||||
|
|
@ -132,7 +129,7 @@ var config = require("./config");
|
||||||
*
|
*
|
||||||
* @param {Number} scrollLeft The new scroll left value
|
* @param {Number} scrollLeft The new scroll left value
|
||||||
**/
|
**/
|
||||||
|
//}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -150,18 +147,14 @@ var EditSession = function(text, mode) {
|
||||||
this.$backMarkers = {};
|
this.$backMarkers = {};
|
||||||
this.$markerId = 1;
|
this.$markerId = 1;
|
||||||
this.$undoSelect = true;
|
this.$undoSelect = true;
|
||||||
|
|
||||||
this.$foldData = [];
|
this.$foldData = [];
|
||||||
this.$foldData.toString = function() {
|
this.$foldData.toString = function() {
|
||||||
var str = "";
|
return this.join("\n");
|
||||||
this.forEach(function(foldLine) {
|
|
||||||
str += "\n" + foldLine.toString();
|
|
||||||
});
|
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
this.on("changeFold", this.onChangeFold.bind(this));
|
this.on("changeFold", this.onChangeFold.bind(this));
|
||||||
this.$onChange = this.onChange.bind(this);
|
this.$onChange = this.onChange.bind(this);
|
||||||
|
|
||||||
if (typeof text != "object" || !text.getLine)
|
if (typeof text != "object" || !text.getLine)
|
||||||
text = new Document(text);
|
text = new Document(text);
|
||||||
|
|
||||||
|
|
@ -200,13 +193,13 @@ var EditSession = function(text, mode) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the `Document` associated with this session.
|
* Returns the `Document` associated with this session.
|
||||||
* @return {Document}
|
* @return {Document}
|
||||||
**/
|
**/
|
||||||
this.getDocument = function() {
|
this.getDocument = function() {
|
||||||
return this.doc;
|
return this.doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Number} row The row to work with
|
* @param {Number} row The row to work with
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
@ -299,19 +292,19 @@ var EditSession = function(text, mode) {
|
||||||
this.getUndoManager().reset();
|
this.getUndoManager().reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current [[Document `Document`]] as a string.
|
* Returns the current [[Document `Document`]] as a string.
|
||||||
* @method toString
|
* @method toString
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
* @alias EditSession.getValue
|
* @alias EditSession.getValue
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current [[Document `Document`]] as a string.
|
* Returns the current [[Document `Document`]] as a string.
|
||||||
* @method getValue
|
* @method getValue
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
* @alias EditSession.toString
|
* @alias EditSession.toString
|
||||||
**/
|
**/
|
||||||
this.getValue =
|
this.getValue =
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
|
|
@ -325,7 +318,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.selection;
|
return this.selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:BackgroundTokenizer.getState}
|
* {:BackgroundTokenizer.getState}
|
||||||
* @param {Number} row The row to start at
|
* @param {Number} row The row to start at
|
||||||
*
|
*
|
||||||
|
|
@ -335,7 +328,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.bgTokenizer.getState(row);
|
return this.bgTokenizer.getState(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.
|
* Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.
|
||||||
* @param {Number} row The row to start at
|
* @param {Number} row The row to start at
|
||||||
*
|
*
|
||||||
|
|
@ -489,7 +482,7 @@ var EditSession = function(text, mode) {
|
||||||
|
|
||||||
this.$overwrite = false;
|
this.$overwrite = false;
|
||||||
/**
|
/**
|
||||||
* Pass in `true` to enable overwrites in your session, or `false` to disable.
|
* Pass in `true` to enable overwrites in your session, or `false` to disable.
|
||||||
*
|
*
|
||||||
* If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
|
* If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
|
||||||
*
|
*
|
||||||
|
|
@ -543,7 +536,7 @@ var EditSession = function(text, mode) {
|
||||||
this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
|
this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
|
||||||
this._emit("changeBreakpoint", {});
|
this._emit("changeBreakpoint", {});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of numbers, indicating which rows have breakpoints.
|
* Returns an array of numbers, indicating which rows have breakpoints.
|
||||||
* @returns {[Number]}
|
* @returns {[Number]}
|
||||||
|
|
@ -641,7 +634,7 @@ var EditSession = function(text, mode) {
|
||||||
* @param {Object} marker object with update method
|
* @param {Object} marker object with update method
|
||||||
* @param {Boolean} inFront Set to `true` to establish a front marker
|
* @param {Boolean} inFront Set to `true` to establish a front marker
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @return {Object} The added marker
|
* @return {Object} The added marker
|
||||||
**/
|
**/
|
||||||
this.addDynamicMarker = function(marker, inFront) {
|
this.addDynamicMarker = function(marker, inFront) {
|
||||||
|
|
@ -698,7 +691,7 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
this.$searchHighlight.setRegexp(re);
|
this.$searchHighlight.setRegexp(re);
|
||||||
}
|
}
|
||||||
|
|
||||||
// experimental
|
// experimental
|
||||||
this.highlightLines = function(startRow, endRow, clazz, inFront) {
|
this.highlightLines = function(startRow, endRow, clazz, inFront) {
|
||||||
if (typeof endRow != "number") {
|
if (typeof endRow != "number") {
|
||||||
|
|
@ -707,12 +700,12 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
if (!clazz)
|
if (!clazz)
|
||||||
clazz = "ace_step";
|
clazz = "ace_step";
|
||||||
|
|
||||||
var range = new Range(startRow, 0, endRow, Infinity);
|
var range = new Range(startRow, 0, endRow, Infinity);
|
||||||
range.id = this.addMarker(range, clazz, "fullLine", inFront);
|
range.id = this.addMarker(range, clazz, "fullLine", inFront);
|
||||||
return range;
|
return range;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Error:
|
* Error:
|
||||||
* {
|
* {
|
||||||
|
|
@ -747,7 +740,7 @@ var EditSession = function(text, mode) {
|
||||||
this.setAnnotations([]);
|
this.setAnnotations([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `text` contains either the newline (`\n`) or carriage-return ('\r') characters, `$autoNewLine` stores that value.
|
* If `text` contains either the newline (`\n`) or carriage-return ('\r') characters, `$autoNewLine` stores that value.
|
||||||
* @param {String} text A block of text
|
* @param {String} text A block of text
|
||||||
*
|
*
|
||||||
|
|
@ -778,7 +771,7 @@ var EditSession = function(text, mode) {
|
||||||
|
|
||||||
if (!inToken)
|
if (!inToken)
|
||||||
inToken = !!line.charAt(column).match(this.tokenRe);
|
inToken = !!line.charAt(column).match(this.tokenRe);
|
||||||
|
|
||||||
if (inToken)
|
if (inToken)
|
||||||
var re = this.tokenRe;
|
var re = this.tokenRe;
|
||||||
else if (/^\s+$/.test(line.slice(column-1, column+1)))
|
else if (/^\s+$/.test(line.slice(column-1, column+1)))
|
||||||
|
|
@ -820,7 +813,7 @@ var EditSession = function(text, mode) {
|
||||||
return wordRange;
|
return wordRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:Document.setNewLineMode.desc}
|
* {:Document.setNewLineMode.desc}
|
||||||
* @param {String} newLineMode {:Document.setNewLineMode.param}
|
* @param {String} newLineMode {:Document.setNewLineMode.param}
|
||||||
*
|
*
|
||||||
|
|
@ -831,7 +824,7 @@ var EditSession = function(text, mode) {
|
||||||
this.doc.setNewLineMode(newLineMode);
|
this.doc.setNewLineMode(newLineMode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns the current new line mode.
|
* Returns the current new line mode.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
|
|
@ -958,7 +951,6 @@ var EditSession = function(text, mode) {
|
||||||
this.$worker = null;
|
this.$worker = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.$startWorker = function() {
|
this.$startWorker = function() {
|
||||||
if (typeof Worker !== "undefined" && !require.noWorker) {
|
if (typeof Worker !== "undefined" && !require.noWorker) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -1068,7 +1060,7 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a verbatim copy of the given line as it is in the document
|
* Returns a verbatim copy of the given line as it is in the document
|
||||||
* @param {Number} row The row to retrieve from
|
* @param {Number} row The row to retrieve from
|
||||||
*
|
*
|
||||||
|
|
@ -1080,7 +1072,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.doc.getLine(row);
|
return this.doc.getLine(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
|
* Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
|
||||||
* @param {Number} firstRow The first row index to retrieve
|
* @param {Number} firstRow The first row index to retrieve
|
||||||
* @param {Number} lastRow The final row index to retrieve
|
* @param {Number} lastRow The final row index to retrieve
|
||||||
|
|
@ -1092,7 +1084,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.doc.getLines(firstRow, lastRow);
|
return this.doc.getLines(firstRow, lastRow);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of rows in the document.
|
* Returns the number of rows in the document.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
**/
|
**/
|
||||||
|
|
@ -1100,7 +1092,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.doc.getLength();
|
return this.doc.getLength();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:Document.getTextRange.desc}
|
* {:Document.getTextRange.desc}
|
||||||
* @param {Range} range The range to work with
|
* @param {Range} range The range to work with
|
||||||
*
|
*
|
||||||
|
|
@ -1110,7 +1102,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.doc.getTextRange(range || this.selection.getRange());
|
return this.doc.getTextRange(range || this.selection.getRange());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a block of `text` and the indicated `position`.
|
* Inserts a block of `text` and the indicated `position`.
|
||||||
* @param {Object} position The position {row, column} to start inserting at
|
* @param {Object} position The position {row, column} to start inserting at
|
||||||
* @param {String} text A chunk of text to insert
|
* @param {String} text A chunk of text to insert
|
||||||
|
|
@ -1122,7 +1114,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.doc.insert(position, text);
|
return this.doc.insert(position, text);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the `range` from the document.
|
* Removes the `range` from the document.
|
||||||
* @param {Range} range A specified Range to remove
|
* @param {Range} range A specified Range to remove
|
||||||
* @returns {Object} The new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
|
* @returns {Object} The new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
|
||||||
|
|
@ -1139,7 +1131,7 @@ var EditSession = function(text, mode) {
|
||||||
* @param {Array} deltas An array of previous changes
|
* @param {Array} deltas An array of previous changes
|
||||||
* @param {Boolean} dontSelect [If `true`, doesn't select the range of where the change occured]{: #dontSelect}
|
* @param {Boolean} dontSelect [If `true`, doesn't select the range of where the change occured]{: #dontSelect}
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
**/
|
**/
|
||||||
this.undoChanges = function(deltas, dontSelect) {
|
this.undoChanges = function(deltas, dontSelect) {
|
||||||
|
|
@ -1210,7 +1202,7 @@ var EditSession = function(text, mode) {
|
||||||
this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
|
this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
|
||||||
function isInsert(delta) {
|
function isInsert(delta) {
|
||||||
var insert =
|
var insert =
|
||||||
delta.action == "insertText" || delta.action == "insertLines";
|
delta.action === "insertText" || delta.action === "insertLines";
|
||||||
return isUndo ? !insert : insert;
|
return isUndo ? !insert : insert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1261,16 +1253,16 @@ var EditSession = function(text, mode) {
|
||||||
return range;
|
return range;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces a range in the document with the new `text`.
|
* Replaces a range in the document with the new `text`.
|
||||||
*
|
*
|
||||||
* @param {Range} range A specified Range to replace
|
* @param {Range} range A specified Range to replace
|
||||||
* @param {String} text The new text to use as a replacement
|
* @param {String} text The new text to use as a replacement
|
||||||
* @returns {Object} An object containing the final row and column, like this:
|
* @returns {Object} An object containing the final row and column, like this:
|
||||||
* ```
|
* ```
|
||||||
* {row: endRow, column: 0}
|
* {row: endRow, column: 0}
|
||||||
* ```
|
* ```
|
||||||
* If the text and range are empty, this function returns an object containing the current `range.start` value.
|
* If the text and range are empty, this function returns an object containing the current `range.start` value.
|
||||||
* If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
|
* If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
|
@ -1295,32 +1287,44 @@ var EditSession = function(text, mode) {
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.moveText = function(fromRange, toPosition) {
|
this.moveText = function(fromRange, toPosition, copy) {
|
||||||
var text = this.getTextRange(fromRange);
|
var text = this.getTextRange(fromRange);
|
||||||
this.remove(fromRange);
|
var folds = this.getFoldsInRange(fromRange);
|
||||||
|
|
||||||
var toRow = toPosition.row;
|
var toRange = Range.fromPoints(toPosition, toPosition);
|
||||||
var toColumn = toPosition.column;
|
if (!copy) {
|
||||||
|
this.remove(fromRange);
|
||||||
// Make sure to update the insert location, when text is removed in
|
var rowDiff = fromRange.start.row - fromRange.end.row;
|
||||||
// front of the chosen point of insertion.
|
var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
|
||||||
if (!fromRange.isMultiLine() && fromRange.start.row == toRow &&
|
if (collDiff) {
|
||||||
fromRange.end.column < toColumn)
|
if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
|
||||||
toColumn -= text.length;
|
toRange.start.column += collDiff;
|
||||||
|
if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
|
||||||
if (fromRange.isMultiLine() && fromRange.end.row < toRow) {
|
toRange.end.column += collDiff;
|
||||||
var lines = this.doc.$split(text);
|
}
|
||||||
toRow -= lines.length - 1;
|
if (rowDiff && toRange.start.row >= fromRange.end.row) {
|
||||||
|
toRange.start.row += rowDiff;
|
||||||
|
toRange.end.row += rowDiff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var endRow = toRow + fromRange.end.row - fromRange.start.row;
|
|
||||||
var endColumn = fromRange.isMultiLine() ?
|
|
||||||
fromRange.end.column :
|
|
||||||
toColumn + fromRange.end.column - fromRange.start.column;
|
|
||||||
|
|
||||||
var toRange = new Range(toRow, toColumn, endRow, endColumn);
|
|
||||||
|
|
||||||
this.insert(toRange.start, text);
|
this.insert(toRange.start, text);
|
||||||
|
if (folds.length) {
|
||||||
|
var oldStart = fromRange.start;
|
||||||
|
var newStart = toRange.start;
|
||||||
|
var rowDiff = newStart.row - oldStart.row;
|
||||||
|
var collDiff = newStart.column - oldStart.column;
|
||||||
|
this.addFolds(folds.map(function(x) {
|
||||||
|
x = x.clone();
|
||||||
|
if (x.start.row == oldStart.row)
|
||||||
|
x.start.column += collDiff;
|
||||||
|
if (x.end.row == oldStart.row)
|
||||||
|
x.end.column += collDiff;
|
||||||
|
x.start.row += rowDiff;
|
||||||
|
x.end.row += rowDiff;
|
||||||
|
return x;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
return toRange;
|
return toRange;
|
||||||
};
|
};
|
||||||
|
|
@ -1371,7 +1375,39 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
this.$moveLines = function(firstRow, lastRow, dir) {
|
||||||
|
firstRow = this.getRowFoldStart(firstRow);
|
||||||
|
lastRow = this.getRowFoldEnd(lastRow);
|
||||||
|
if (dir < 0) {
|
||||||
|
var row = this.getRowFoldStart(firstRow + dir);
|
||||||
|
if (row < 0) return 0;
|
||||||
|
var diff = row-firstRow;
|
||||||
|
} else if (dir > 0) {
|
||||||
|
var row = this.getRowFoldEnd(lastRow + dir);
|
||||||
|
if (row > this.doc.getLength()-1) return 0;
|
||||||
|
var diff = row-lastRow;
|
||||||
|
} else {
|
||||||
|
firstRow = this.$clipRowToDocument(firstRow);
|
||||||
|
lastRow = this.$clipRowToDocument(lastRow);
|
||||||
|
var diff = lastRow - firstRow + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
|
||||||
|
var folds = this.getFoldsInRange(range).map(function(x){
|
||||||
|
x = x.clone();
|
||||||
|
x.start.row += diff;
|
||||||
|
x.end.row += diff;
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
|
||||||
|
var lines = dir == 0
|
||||||
|
? this.doc.getLines(firstRow, lastRow)
|
||||||
|
: this.doc.removeLines(firstRow, lastRow);
|
||||||
|
this.doc.insertLines(firstRow+diff, lines);
|
||||||
|
folds.length && this.addFolds(folds);
|
||||||
|
return diff;
|
||||||
|
};
|
||||||
|
/**
|
||||||
* Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`.
|
* Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`.
|
||||||
* @param {Number} firstRow The starting row to move up
|
* @param {Number} firstRow The starting row to move up
|
||||||
* @param {Number} lastRow The final row to move up
|
* @param {Number} lastRow The final row to move up
|
||||||
|
|
@ -1381,29 +1417,19 @@ var EditSession = function(text, mode) {
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.moveLinesUp = function(firstRow, lastRow) {
|
this.moveLinesUp = function(firstRow, lastRow) {
|
||||||
if (firstRow <= 0) return 0;
|
return this.$moveLines(firstRow, lastRow, -1);
|
||||||
|
|
||||||
var removed = this.doc.removeLines(firstRow, lastRow);
|
|
||||||
this.doc.insertLines(firstRow - 1, removed);
|
|
||||||
return -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shifts all the lines in the document down one, starting from `firstRow` and ending at `lastRow`.
|
* Shifts all the lines in the document down one, starting from `firstRow` and ending at `lastRow`.
|
||||||
* @param {Number} firstRow The starting row to move down
|
* @param {Number} firstRow The starting row to move down
|
||||||
* @param {Number} lastRow The final row to move down
|
* @param {Number} lastRow The final row to move down
|
||||||
* @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.
|
* @returns {Number} If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
* @related Document.insertLines
|
* @related Document.insertLines
|
||||||
**/
|
**/
|
||||||
this.moveLinesDown = function(firstRow, lastRow) {
|
this.moveLinesDown = function(firstRow, lastRow) {
|
||||||
if (lastRow >= this.doc.getLength()-1) return 0;
|
return this.$moveLines(firstRow, lastRow, 1);
|
||||||
|
|
||||||
var removed = this.doc.removeLines(firstRow, lastRow);
|
|
||||||
this.doc.insertLines(firstRow+1, removed);
|
|
||||||
return 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1415,14 +1441,7 @@ var EditSession = function(text, mode) {
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.duplicateLines = function(firstRow, lastRow) {
|
this.duplicateLines = function(firstRow, lastRow) {
|
||||||
var firstRow = this.$clipRowToDocument(firstRow);
|
return this.$moveLines(firstRow, lastRow, 0);
|
||||||
var lastRow = this.$clipRowToDocument(lastRow);
|
|
||||||
|
|
||||||
var lines = this.getLines(firstRow, lastRow);
|
|
||||||
this.doc.insertLines(firstRow, lines);
|
|
||||||
|
|
||||||
var addedRows = lastRow - firstRow + 1;
|
|
||||||
return addedRows;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1546,12 +1565,12 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This should generally only be called by the renderer when a resize is detected.
|
* This should generally only be called by the renderer when a resize is detected.
|
||||||
* @param {Number} desiredLimit The new wrap limit
|
* @param {Number} desiredLimit The new wrap limit
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
**/
|
**/
|
||||||
this.adjustWrapLimit = function(desiredLimit) {
|
this.adjustWrapLimit = function(desiredLimit) {
|
||||||
|
|
@ -2000,7 +2019,7 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the position (on screen) for the last character in the provided screen row.
|
* Returns the position (on screen) for the last character in the provided screen row.
|
||||||
* @param {Number} screenRow The screen row to check
|
* @param {Number} screenRow The screen row to check
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
|
|
@ -2012,21 +2031,21 @@ var EditSession = function(text, mode) {
|
||||||
return this.documentToScreenColumn(pos.row, pos.column);
|
return this.documentToScreenColumn(pos.row, pos.column);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the given document row and column, this returns the column position of the last screen row.
|
* For the given document row and column, this returns the column position of the last screen row.
|
||||||
* @param {Number} docRow
|
* @param {Number} docRow
|
||||||
*
|
*
|
||||||
* @param {Number} docColumn
|
* @param {Number} docColumn
|
||||||
**/
|
**/
|
||||||
this.getDocumentLastRowColumn = function(docRow, docColumn) {
|
this.getDocumentLastRowColumn = function(docRow, docColumn) {
|
||||||
var screenRow = this.documentToScreenRow(docRow, docColumn);
|
var screenRow = this.documentToScreenRow(docRow, docColumn);
|
||||||
return this.getScreenLastRowColumn(screenRow);
|
return this.getScreenLastRowColumn(screenRow);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the given document row and column, this returns the document position of the last row.
|
* For the given document row and column, this returns the document position of the last row.
|
||||||
* @param {Number} docRow
|
* @param {Number} docRow
|
||||||
* @param {Number} docColumn
|
* @param {Number} docColumn
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
@ -2035,7 +2054,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
|
return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the given row, this returns the split data.
|
* For the given row, this returns the split data.
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
**/
|
**/
|
||||||
|
|
@ -2051,7 +2070,7 @@ var EditSession = function(text, mode) {
|
||||||
* The distance to the next tab stop at the specified screen column.
|
* The distance to the next tab stop at the specified screen column.
|
||||||
* @param {Number} screenColumn The screen column to check
|
* @param {Number} screenColumn The screen column to check
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
**/
|
**/
|
||||||
this.getScreenTabSize = function(screenColumn) {
|
this.getScreenTabSize = function(screenColumn) {
|
||||||
|
|
@ -2068,7 +2087,7 @@ var EditSession = function(text, mode) {
|
||||||
return this.screenToDocumentPosition(screenRow, screenColumn).column;
|
return this.screenToDocumentPosition(screenRow, screenColumn).column;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts characters coordinates on the screen to characters coordinates within the document. [This takes into account code folding, word wrap, tab size, and any other visual modifications.]{: #conversionConsiderations}
|
* Converts characters coordinates on the screen to characters coordinates within the document. [This takes into account code folding, word wrap, tab size, and any other visual modifications.]{: #conversionConsiderations}
|
||||||
* @param {Number} screenRow The screen row to check
|
* @param {Number} screenRow The screen row to check
|
||||||
* @param {Number} screenColumn The screen column to check
|
* @param {Number} screenColumn The screen column to check
|
||||||
|
|
@ -2117,7 +2136,7 @@ var EditSession = function(text, mode) {
|
||||||
foldStart = foldLine ? foldLine.start.row : Infinity;
|
foldStart = foldLine ? foldLine.start.row : Infinity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doCache) {
|
if (doCache) {
|
||||||
this.$docRowCache.push(docRow);
|
this.$docRowCache.push(docRow);
|
||||||
this.$screenRowCache.push(row);
|
this.$screenRowCache.push(row);
|
||||||
|
|
@ -2162,7 +2181,7 @@ var EditSession = function(text, mode) {
|
||||||
return {row: docRow, column: docColumn};
|
return {row: docRow, column: docColumn};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts document coordinates to screen coordinates. {:conversionConsiderations}
|
* Converts document coordinates to screen coordinates. {:conversionConsiderations}
|
||||||
* @param {Number} docRow The document row to check
|
* @param {Number} docRow The document row to check
|
||||||
* @param {Number} docColumn The document column to check
|
* @param {Number} docColumn The document column to check
|
||||||
|
|
@ -2381,9 +2400,9 @@ config.defineOptions(EditSession.prototype, "session", {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
this.setUseWrapMode(false);
|
this.setUseWrapMode(false);
|
||||||
} else {
|
} else {
|
||||||
var col = typeof value == "number" && value;
|
var col = typeof value == "number" ? value : null;
|
||||||
this.setUseWrapMode(true);
|
this.setUseWrapMode(true);
|
||||||
this.setWrapLimitRange(value, value);
|
this.setWrapLimitRange(col, col);
|
||||||
}
|
}
|
||||||
this.$wrap = value;
|
this.$wrap = value;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var Range = require("../range").Range;
|
||||||
|
var RangeList = require("../range_list").RangeList;
|
||||||
|
var oop = require("../lib/oop")
|
||||||
/*
|
/*
|
||||||
* Simple fold-data struct.
|
* Simple fold-data struct.
|
||||||
**/
|
**/
|
||||||
|
|
@ -42,9 +45,11 @@ var Fold = exports.Fold = function(range, placeholder) {
|
||||||
this.end = range.end;
|
this.end = range.end;
|
||||||
|
|
||||||
this.sameRow = range.start.row == range.end.row;
|
this.sameRow = range.start.row == range.end.row;
|
||||||
this.subFolds = [];
|
this.subFolds = this.ranges = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
oop.inherits(Fold, RangeList);
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
|
|
@ -64,17 +69,21 @@ var Fold = exports.Fold = function(range, placeholder) {
|
||||||
this.subFolds.forEach(function(subFold) {
|
this.subFolds.forEach(function(subFold) {
|
||||||
fold.subFolds.push(subFold.clone());
|
fold.subFolds.push(subFold.clone());
|
||||||
});
|
});
|
||||||
|
fold.collapseChildren = this.collapseChildren;
|
||||||
return fold;
|
return fold;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.addSubFold = function(fold) {
|
this.addSubFold = function(fold) {
|
||||||
if (this.range.isEqual(fold))
|
if (this.range.isEqual(fold))
|
||||||
return this;
|
return;
|
||||||
|
|
||||||
if (!this.range.containsRange(fold))
|
if (!this.range.containsRange(fold))
|
||||||
throw "A fold can't intersect already existing fold" + fold.range + this.range;
|
throw "A fold can't intersect already existing fold" + fold.range + this.range;
|
||||||
|
|
||||||
var row = fold.range.start.row, column = fold.range.start.column;
|
// transform fold to local coordinates
|
||||||
|
consumeRange(fold, this.start);
|
||||||
|
|
||||||
|
var row = fold.start.row, column = fold.start.column;
|
||||||
for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
|
for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
|
||||||
cmp = this.subFolds[i].range.compare(row, column);
|
cmp = this.subFolds[i].range.compare(row, column);
|
||||||
if (cmp != 1)
|
if (cmp != 1)
|
||||||
|
|
@ -102,7 +111,30 @@ var Fold = exports.Fold = function(range, placeholder) {
|
||||||
|
|
||||||
return fold;
|
return fold;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.restoreRange = function(range) {
|
||||||
|
return restoreRange(range, this.start);
|
||||||
|
};
|
||||||
|
|
||||||
}).call(Fold.prototype);
|
}).call(Fold.prototype);
|
||||||
|
|
||||||
|
function consumePoint(point, anchor) {
|
||||||
|
point.row -= anchor.row;
|
||||||
|
if (point.row == 0)
|
||||||
|
point.column -= anchor.column;
|
||||||
|
}
|
||||||
|
function consumeRange(range, anchor) {
|
||||||
|
consumePoint(range.start, anchor);
|
||||||
|
consumePoint(range.end, anchor);
|
||||||
|
}
|
||||||
|
function restorePoint(point, anchor) {
|
||||||
|
if (point.row == 0)
|
||||||
|
point.column += anchor.column;
|
||||||
|
point.row += anchor.row;
|
||||||
|
}
|
||||||
|
function restoreRange(range, anchor) {
|
||||||
|
restorePoint(range.start, anchor);
|
||||||
|
restorePoint(range.end, anchor);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -192,13 +192,13 @@ function FoldLine(foldData, folds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.split = function(row, column) {
|
this.split = function(row, column) {
|
||||||
var fold = this.getNextFoldTo(row, column).fold,
|
var fold = this.getNextFoldTo(row, column).fold;
|
||||||
folds = this.folds;
|
var folds = this.folds;
|
||||||
var foldData = this.foldData;
|
var foldData = this.foldData;
|
||||||
|
|
||||||
if (!fold) {
|
if (!fold)
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
var i = folds.indexOf(fold);
|
var i = folds.indexOf(fold);
|
||||||
var foldBefore = folds[i - 1];
|
var foldBefore = folds[i - 1];
|
||||||
this.end.row = foldBefore.end.row;
|
this.end.row = foldBefore.end.row;
|
||||||
|
|
|
||||||
|
|
@ -118,11 +118,6 @@ function Folding() {
|
||||||
|
|
||||||
function addFold(fold) {
|
function addFold(fold) {
|
||||||
folds.push(fold);
|
folds.push(fold);
|
||||||
if (!fold.subFolds)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (var i = 0; i < fold.subFolds.length; i++)
|
|
||||||
addFold(fold.subFolds[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < foldLines.length; i++)
|
for (var i = 0; i < foldLines.length; i++)
|
||||||
|
|
@ -265,9 +260,10 @@ function Folding() {
|
||||||
|
|
||||||
if (placeholder instanceof Fold)
|
if (placeholder instanceof Fold)
|
||||||
fold = placeholder;
|
fold = placeholder;
|
||||||
else
|
else {
|
||||||
fold = new Fold(range, placeholder);
|
fold = new Fold(range, placeholder);
|
||||||
|
fold.collapseChildren = range.collapseChildren;
|
||||||
|
}
|
||||||
this.$clipRangeToDocument(fold.range);
|
this.$clipRangeToDocument(fold.range);
|
||||||
|
|
||||||
var startRow = fold.start.row;
|
var startRow = fold.start.row;
|
||||||
|
|
@ -297,7 +293,9 @@ function Folding() {
|
||||||
// Remove the folds from fold data.
|
// Remove the folds from fold data.
|
||||||
this.removeFolds(folds);
|
this.removeFolds(folds);
|
||||||
// Add the removed folds as subfolds on the new fold.
|
// Add the removed folds as subfolds on the new fold.
|
||||||
fold.subFolds = folds;
|
folds.forEach(function(subFold) {
|
||||||
|
fold.addSubFold(subFold);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < foldData.length; i++) {
|
for (var i = 0; i < foldData.length; i++) {
|
||||||
|
|
@ -306,8 +304,7 @@ function Folding() {
|
||||||
foldLine.addFold(fold);
|
foldLine.addFold(fold);
|
||||||
added = true;
|
added = true;
|
||||||
break;
|
break;
|
||||||
}
|
} else if (startRow == foldLine.end.row) {
|
||||||
else if (startRow == foldLine.end.row) {
|
|
||||||
foldLine.addFold(fold);
|
foldLine.addFold(fold);
|
||||||
added = true;
|
added = true;
|
||||||
if (!fold.sameRow) {
|
if (!fold.sameRow) {
|
||||||
|
|
@ -320,8 +317,7 @@ function Folding() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
} else if (endRow <= foldLine.start.row) {
|
||||||
else if (endRow <= foldLine.start.row) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -414,10 +410,14 @@ function Folding() {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.expandFold = function(fold) {
|
this.expandFold = function(fold) {
|
||||||
this.removeFold(fold);
|
this.removeFold(fold);
|
||||||
fold.subFolds.forEach(function(fold) {
|
fold.subFolds.forEach(function(subFold) {
|
||||||
this.addFold(fold);
|
fold.restoreRange(subFold);
|
||||||
|
this.addFold(subFold);
|
||||||
}, this);
|
}, this);
|
||||||
|
if (fold.collapseChildren > 0) {
|
||||||
|
this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
|
||||||
|
}
|
||||||
fold.subFolds = [];
|
fold.subFolds = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -429,9 +429,10 @@ function Folding() {
|
||||||
|
|
||||||
this.unfold = function(location, expandInner) {
|
this.unfold = function(location, expandInner) {
|
||||||
var range, folds;
|
var range, folds;
|
||||||
if (location == null)
|
if (location == null) {
|
||||||
range = new Range(0, 0, this.getLength(), 0);
|
range = new Range(0, 0, this.getLength(), 0);
|
||||||
else if (typeof location == "number")
|
expandInner = true;
|
||||||
|
} else if (typeof location == "number")
|
||||||
range = new Range(location, 0, location, this.getLine(location).length);
|
range = new Range(location, 0, location, this.getLine(location).length);
|
||||||
else if ("row" in location)
|
else if ("row" in location)
|
||||||
range = Range.fromPoints(location, location);
|
range = Range.fromPoints(location, location);
|
||||||
|
|
@ -464,6 +465,11 @@ function Folding() {
|
||||||
return foldLine ? foldLine.end.row : docRow;
|
return foldLine ? foldLine.end.row : docRow;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getRowFoldStart = function(docRow, startFoldRow) {
|
||||||
|
var foldLine = this.getFoldLine(docRow, startFoldRow);
|
||||||
|
return foldLine ? foldLine.start.row : docRow;
|
||||||
|
};
|
||||||
|
|
||||||
this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
|
this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
|
||||||
if (startRow == null) {
|
if (startRow == null) {
|
||||||
startRow = foldLine.start.row;
|
startRow = foldLine.start.row;
|
||||||
|
|
@ -480,20 +486,20 @@ function Folding() {
|
||||||
var textLine = "";
|
var textLine = "";
|
||||||
|
|
||||||
foldLine.walk(function(placeholder, row, column, lastColumn) {
|
foldLine.walk(function(placeholder, row, column, lastColumn) {
|
||||||
if (row < startRow) {
|
if (row < startRow)
|
||||||
return;
|
return;
|
||||||
} else if (row == startRow) {
|
if (row == startRow) {
|
||||||
if (column < startColumn) {
|
if (column < startColumn)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
lastColumn = Math.max(startColumn, lastColumn);
|
lastColumn = Math.max(startColumn, lastColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (placeholder != null) {
|
if (placeholder != null) {
|
||||||
textLine += placeholder;
|
textLine += placeholder;
|
||||||
} else {
|
} else {
|
||||||
textLine += doc.getLine(row).substring(lastColumn, column);
|
textLine += doc.getLine(row).substring(lastColumn, column);
|
||||||
}
|
}
|
||||||
}.bind(this), endRow, endColumn);
|
}, endRow, endColumn);
|
||||||
return textLine;
|
return textLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -535,26 +541,22 @@ function Folding() {
|
||||||
if (fold) {
|
if (fold) {
|
||||||
this.expandFold(fold);
|
this.expandFold(fold);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (bracketPos = this.findMatchingBracket(cursor)) {
|
||||||
else if (bracketPos = this.findMatchingBracket(cursor)) {
|
|
||||||
if (range.comparePoint(bracketPos) == 1) {
|
if (range.comparePoint(bracketPos) == 1) {
|
||||||
range.end = bracketPos;
|
range.end = bracketPos;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
range.start = bracketPos;
|
range.start = bracketPos;
|
||||||
range.start.column++;
|
range.start.column++;
|
||||||
range.end.column--;
|
range.end.column--;
|
||||||
}
|
}
|
||||||
}
|
} else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
|
||||||
else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
|
|
||||||
if (range.comparePoint(bracketPos) == 1)
|
if (range.comparePoint(bracketPos) == 1)
|
||||||
range.end = bracketPos;
|
range.end = bracketPos;
|
||||||
else
|
else
|
||||||
range.start = bracketPos;
|
range.start = bracketPos;
|
||||||
|
|
||||||
range.start.column++;
|
range.start.column++;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
|
range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -562,8 +564,7 @@ function Folding() {
|
||||||
if (tryToUnfold && folds.length) {
|
if (tryToUnfold && folds.length) {
|
||||||
this.expandFolds(folds);
|
this.expandFolds(folds);
|
||||||
return;
|
return;
|
||||||
}
|
} else if (folds.length == 1 ) {
|
||||||
else if (folds.length == 1 ) {
|
|
||||||
fold = folds[0];
|
fold = folds[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -619,7 +620,9 @@ function Folding() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.foldAll = function(startRow, endRow) {
|
this.foldAll = function(startRow, endRow, depth) {
|
||||||
|
if (depth == undefined)
|
||||||
|
depth = 100000; // JSON.stringify doesn't hanle Infinity
|
||||||
var foldWidgets = this.foldWidgets;
|
var foldWidgets = this.foldWidgets;
|
||||||
endRow = endRow || this.getLength();
|
endRow = endRow || this.getLength();
|
||||||
for (var row = startRow || 0; row < endRow; row++) {
|
for (var row = startRow || 0; row < endRow; row++) {
|
||||||
|
|
@ -630,13 +633,16 @@ function Folding() {
|
||||||
|
|
||||||
var range = this.getFoldWidgetRange(row);
|
var range = this.getFoldWidgetRange(row);
|
||||||
// sometimes range can be incompatible with existing fold
|
// sometimes range can be incompatible with existing fold
|
||||||
// wouldn't it be better for addFold to return null istead of throwing?
|
// TODO change addFold to return null istead of throwing
|
||||||
if (range && range.end.row <= endRow) try {
|
if (range && range.end.row <= endRow) try {
|
||||||
this.addFold("...", range);
|
var fold = this.addFold("...", range);
|
||||||
|
fold.collapseChildren = depth;
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
|
row = range.end.row;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// structured folding
|
||||||
this.$foldStyles = {
|
this.$foldStyles = {
|
||||||
"manual": 1,
|
"manual": 1,
|
||||||
"markbegin": 1,
|
"markbegin": 1,
|
||||||
|
|
@ -661,7 +667,6 @@ function Folding() {
|
||||||
this.$setFolding(mode);
|
this.$setFolding(mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
// structured folding
|
|
||||||
this.$setFolding = function(foldMode) {
|
this.$setFolding = function(foldMode) {
|
||||||
if (this.$foldMode == foldMode)
|
if (this.$foldMode == foldMode)
|
||||||
return;
|
return;
|
||||||
|
|
@ -685,21 +690,46 @@ function Folding() {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.getParentFoldRangeData = function (row, ignoreCurrent) {
|
||||||
|
var fw = this.foldWidgets;
|
||||||
|
if (!fw || (ignoreCurrent && fw[row]))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
var i = row - 1, firstRange;
|
||||||
|
while (i >= 0) {
|
||||||
|
var c = fw[i];
|
||||||
|
if (c == null)
|
||||||
|
c = fw[i] = this.getFoldWidget(i);
|
||||||
|
|
||||||
|
if (c == "start") {
|
||||||
|
var range = this.getFoldWidgetRange(i);
|
||||||
|
if (!firstRange)
|
||||||
|
firstRange = range;
|
||||||
|
if (range && range.end.row >= row)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
range: i !== -1 && range,
|
||||||
|
firstRange: firstRange
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.onFoldWidgetClick = function(row, e) {
|
this.onFoldWidgetClick = function(row, e) {
|
||||||
e = e.domEvent;
|
|
||||||
var type = this.getFoldWidget(row);
|
var type = this.getFoldWidget(row);
|
||||||
var line = this.getLine(row);
|
var line = this.getLine(row);
|
||||||
var onlySubfolds = e.shiftKey;
|
e = e.domEvent;
|
||||||
var addSubfolds = onlySubfolds || e.ctrlKey || e.altKey || e.metaKey;
|
var children = e.shiftKey;
|
||||||
var fold;
|
var all = e.ctrlKey || e.metaKey;
|
||||||
|
var siblings = e.altKey;
|
||||||
|
|
||||||
if (type == "end")
|
var dir = type === "end" ? -1 : 1;
|
||||||
fold = this.getFoldAt(row, 0, -1);
|
var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
|
||||||
else
|
|
||||||
fold = this.getFoldAt(row, line.length, 1);
|
|
||||||
|
|
||||||
if (fold) {
|
if (fold) {
|
||||||
if (addSubfolds)
|
if (children || all)
|
||||||
this.removeFold(fold);
|
this.removeFold(fold);
|
||||||
else
|
else
|
||||||
this.expandFold(fold);
|
this.expandFold(fold);
|
||||||
|
|
@ -707,28 +737,35 @@ function Folding() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var range = this.getFoldWidgetRange(row);
|
var range = this.getFoldWidgetRange(row);
|
||||||
if (range) {
|
// sometimes singleline folds can be missed by the code above
|
||||||
// sometimes singleline folds can be missed by the code above
|
if (range && !range.isMultiLine()) {
|
||||||
if (!range.isMultiLine()) {
|
fold = this.getFoldAt(range.start.row, range.start.column, 1);
|
||||||
fold = this.getFoldAt(range.start.row, range.start.column, 1);
|
if (fold && range.isEqual(fold.range)) {
|
||||||
if (fold && range.isEqual(fold.range)) {
|
this.removeFold(fold);
|
||||||
this.removeFold(fold);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!onlySubfolds)
|
|
||||||
this.addFold("...", range);
|
|
||||||
|
|
||||||
if (addSubfolds)
|
|
||||||
this.foldAll(range.start.row + 1, range.end.row);
|
|
||||||
} else {
|
|
||||||
if (addSubfolds)
|
|
||||||
this.foldAll(row + 1, this.getLength());
|
|
||||||
(e.target || e.srcElement).className += " ace_invalid"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (siblings) {
|
||||||
|
var data = this.getParentFoldRangeData(row);
|
||||||
|
if (data.range) {
|
||||||
|
var startRow = data.range.start.row + 1;
|
||||||
|
var endRow = data.range.end.row;
|
||||||
|
}
|
||||||
|
this.foldAll(startRow, endRow, all ? 10000 : 0);
|
||||||
|
} else if (children) {
|
||||||
|
var endRow = range ? range.end.row : this.getLength();
|
||||||
|
this.foldAll(row + 1, range.end.row, all ? 10000 : 0);
|
||||||
|
} else if (range) {
|
||||||
|
if (all)
|
||||||
|
range.collapseChildren = 10000;
|
||||||
|
this.addFold("...", range);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!range)
|
||||||
|
(e.target || e.srcElement).className += " ace_invalid"
|
||||||
};
|
};
|
||||||
|
|
||||||
this.updateFoldWidgets = function(e) {
|
this.updateFoldWidgets = function(e) {
|
||||||
var delta = e.data;
|
var delta = e.data;
|
||||||
var range = delta.range;
|
var range = delta.range;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Ajax.org B.V.
|
* Copyright (c) 2010, Ajax.org B.V.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* * Neither the name of Ajax.org B.V. nor the
|
* * Neither the name of Ajax.org B.V. nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
|
@ -51,9 +51,9 @@ var config = require("./config");
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* The main entry point into the Ace functionality.
|
* The main entry point into the Ace functionality.
|
||||||
*
|
*
|
||||||
* The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
|
* The `Editor` manages the [[EditSession]] (which manages [[Document]]s), as well as the [[VirtualRenderer]], which draws everything to the screen.
|
||||||
*
|
*
|
||||||
* Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
|
* Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
|
||||||
* @class Editor
|
* @class Editor
|
||||||
|
|
@ -100,7 +100,7 @@ var Editor = function(renderer, session) {
|
||||||
* Sets a new key handler, such as "vim" or "windows".
|
* Sets a new key handler, such as "vim" or "windows".
|
||||||
* @param {String} keyboardHandler The new key handler
|
* @param {String} keyboardHandler The new key handler
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setKeyboardHandler = function(keyboardHandler) {
|
this.setKeyboardHandler = function(keyboardHandler) {
|
||||||
if (typeof keyboardHandler == "string" && keyboardHandler) {
|
if (typeof keyboardHandler == "string" && keyboardHandler) {
|
||||||
|
|
@ -116,11 +116,11 @@ var Editor = function(renderer, session) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the keyboard handler, such as "vim" or "windows".
|
* Returns the keyboard handler, such as "vim" or "windows".
|
||||||
*
|
*
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.getKeyboardHandler = function() {
|
this.getKeyboardHandler = function() {
|
||||||
return this.keyBinding.getKeyboardHandler();
|
return this.keyBinding.getKeyboardHandler();
|
||||||
|
|
@ -247,7 +247,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.session;
|
return this.session;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current document to `val`.
|
* Sets the current document to `val`.
|
||||||
* @param {String} val The new value to set for the document
|
* @param {String} val The new value to set for the document
|
||||||
* @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end
|
* @param {Number} cursorPos Where to set the new value. `undefined` or 0 is selectAll, -1 is at the document start, and 1 is at the end
|
||||||
|
|
@ -268,7 +268,7 @@ var Editor = function(renderer, session) {
|
||||||
return val;
|
return val;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current session's content.
|
* Returns the current session's content.
|
||||||
*
|
*
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
|
|
@ -279,7 +279,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns the currently highlighted selection.
|
* Returns the currently highlighted selection.
|
||||||
* @returns {String} The highlighted selection
|
* @returns {String} The highlighted selection
|
||||||
**/
|
**/
|
||||||
|
|
@ -287,11 +287,11 @@ var Editor = function(renderer, session) {
|
||||||
return this.selection;
|
return this.selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:VirtualRenderer.onResize}
|
* {:VirtualRenderer.onResize}
|
||||||
* @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
|
* @param {Boolean} force If `true`, recomputes the size, even if the height and width haven't changed
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @related VirtualRenderer.onResize
|
* @related VirtualRenderer.onResize
|
||||||
**/
|
**/
|
||||||
this.resize = function(force) {
|
this.resize = function(force) {
|
||||||
|
|
@ -308,9 +308,9 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.setTheme(theme);
|
this.renderer.setTheme(theme);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:VirtualRenderer.getTheme}
|
* {:VirtualRenderer.getTheme}
|
||||||
*
|
*
|
||||||
* @returns {String} The set theme
|
* @returns {String} The set theme
|
||||||
* @related VirtualRenderer.getTheme
|
* @related VirtualRenderer.getTheme
|
||||||
**/
|
**/
|
||||||
|
|
@ -322,14 +322,14 @@ var Editor = function(renderer, session) {
|
||||||
* {:VirtualRenderer.setStyle}
|
* {:VirtualRenderer.setStyle}
|
||||||
* @param {String} style A class name
|
* @param {String} style A class name
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @related VirtualRenderer.setStyle
|
* @related VirtualRenderer.setStyle
|
||||||
**/
|
**/
|
||||||
this.setStyle = function(style) {
|
this.setStyle = function(style) {
|
||||||
this.renderer.setStyle(style);
|
this.renderer.setStyle(style);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:VirtualRenderer.unsetStyle}
|
* {:VirtualRenderer.unsetStyle}
|
||||||
* @related VirtualRenderer.unsetStyle
|
* @related VirtualRenderer.unsetStyle
|
||||||
**/
|
**/
|
||||||
|
|
@ -340,8 +340,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Set a new font size (in pixels) for the editor text.
|
* Set a new font size (in pixels) for the editor text.
|
||||||
* @param {String} size A font size ( _e.g._ "12px")
|
* @param {String} size A font size ( _e.g._ "12px")
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setFontSize = function(size) {
|
this.setFontSize = function(size) {
|
||||||
if (typeof size == "number")
|
if (typeof size == "number")
|
||||||
|
|
@ -375,7 +375,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Brings the current `textInput` into focus.
|
* Brings the current `textInput` into focus.
|
||||||
**/
|
**/
|
||||||
this.focus = function() {
|
this.focus = function() {
|
||||||
|
|
@ -398,7 +398,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Blurs the current `textInput`.
|
* Blurs the current `textInput`.
|
||||||
**/
|
**/
|
||||||
this.blur = function() {
|
this.blur = function() {
|
||||||
|
|
@ -407,9 +407,9 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted once the editor comes into focus.
|
* Emitted once the editor comes into focus.
|
||||||
* @event focus
|
* @event focus
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.onFocus = function() {
|
this.onFocus = function() {
|
||||||
if (this.$isFocused)
|
if (this.$isFocused)
|
||||||
|
|
@ -423,8 +423,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Emitted once the editor has been blurred.
|
* Emitted once the editor has been blurred.
|
||||||
* @event blur
|
* @event blur
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.onBlur = function() {
|
this.onBlur = function() {
|
||||||
if (!this.$isFocused)
|
if (!this.$isFocused)
|
||||||
|
|
@ -440,12 +440,12 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted whenever the document is changed.
|
* Emitted whenever the document is changed.
|
||||||
* @event change
|
* @event change
|
||||||
* @param {Object} e Contains a single property, `data`, which has the delta of changes
|
* @param {Object} e Contains a single property, `data`, which has the delta of changes
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.onDocumentChange = function(e) {
|
this.onDocumentChange = function(e) {
|
||||||
var delta = e.data;
|
var delta = e.data;
|
||||||
|
|
@ -473,14 +473,14 @@ var Editor = function(renderer, session) {
|
||||||
this.onScrollTopChange = function() {
|
this.onScrollTopChange = function() {
|
||||||
this.renderer.scrollToY(this.session.getScrollTop());
|
this.renderer.scrollToY(this.session.getScrollTop());
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onScrollLeftChange = function() {
|
this.onScrollLeftChange = function() {
|
||||||
this.renderer.scrollToX(this.session.getScrollLeft());
|
this.renderer.scrollToX(this.session.getScrollLeft());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when the selection changes.
|
* Emitted when the selection changes.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.onCursorChange = function() {
|
this.onCursorChange = function() {
|
||||||
this.$cursorChange();
|
this.$cursorChange();
|
||||||
|
|
@ -508,7 +508,7 @@ var Editor = function(renderer, session) {
|
||||||
session.$highlightLineMarker = null;
|
session.$highlightLineMarker = null;
|
||||||
} else if (!session.$highlightLineMarker && highlight) {
|
} else if (!session.$highlightLineMarker && highlight) {
|
||||||
var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
|
var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
|
||||||
range.id = session.addMarker(range, "ace_active-line", "screenLine");
|
range.id = session.addMarker(range, "ace_active-line", "screenLine");
|
||||||
session.$highlightLineMarker = range;
|
session.$highlightLineMarker = range;
|
||||||
} else if (highlight) {
|
} else if (highlight) {
|
||||||
session.$highlightLineMarker.start.row = highlight.row;
|
session.$highlightLineMarker.start.row = highlight.row;
|
||||||
|
|
@ -536,7 +536,7 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
|
var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp()
|
||||||
this.session.highlight(re);
|
this.session.highlight(re);
|
||||||
|
|
||||||
this._emit("changeSelection");
|
this._emit("changeSelection");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -616,10 +616,10 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when text is copied.
|
* Emitted when text is copied.
|
||||||
* @event copy
|
* @event copy
|
||||||
* @param {String} text The copied text
|
* @param {String} text The copied text
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -665,7 +665,7 @@ var Editor = function(renderer, session) {
|
||||||
**/
|
**/
|
||||||
this.onPaste = function(text) {
|
this.onPaste = function(text) {
|
||||||
// todo this should change when paste becomes a command
|
// todo this should change when paste becomes a command
|
||||||
if (this.$readOnly)
|
if (this.$readOnly)
|
||||||
return;
|
return;
|
||||||
this._emit("paste", text);
|
this._emit("paste", text);
|
||||||
this.insert(text);
|
this.insert(text);
|
||||||
|
|
@ -679,8 +679,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Inserts `text` into wherever the cursor is pointing.
|
* Inserts `text` into wherever the cursor is pointing.
|
||||||
* @param {String} text The new text to add
|
* @param {String} text The new text to add
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.insert = function(text) {
|
this.insert = function(text) {
|
||||||
var session = this.session;
|
var session = this.session;
|
||||||
|
|
@ -780,10 +780,10 @@ var Editor = function(renderer, session) {
|
||||||
this.keyBinding.onCommandKey(e, hashId, keyCode);
|
this.keyBinding.onCommandKey(e, hashId, keyCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
|
* Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
|
||||||
* @param {Boolean} overwrite Defines wheter or not to set overwrites
|
* @param {Boolean} overwrite Defines wheter or not to set overwrites
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @related EditSession.setOverwrite
|
* @related EditSession.setOverwrite
|
||||||
**/
|
**/
|
||||||
|
|
@ -791,7 +791,7 @@ var Editor = function(renderer, session) {
|
||||||
this.session.setOverwrite(overwrite);
|
this.session.setOverwrite(overwrite);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if overwrites are enabled; `false` otherwise.
|
* Returns `true` if overwrites are enabled; `false` otherwise.
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related EditSession.getOverwrite
|
* @related EditSession.getOverwrite
|
||||||
|
|
@ -800,7 +800,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.session.getOverwrite();
|
return this.session.getOverwrite();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of overwrite to the opposite of whatever it currently is.
|
* Sets the value of overwrite to the opposite of whatever it currently is.
|
||||||
* @related EditSession.toggleOverwrite
|
* @related EditSession.toggleOverwrite
|
||||||
**/
|
**/
|
||||||
|
|
@ -861,7 +861,7 @@ var Editor = function(renderer, session) {
|
||||||
this.getSelectionStyle = function() {
|
this.getSelectionStyle = function() {
|
||||||
return this.getOption("selectionStyle");
|
return this.getOption("selectionStyle");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether or not the current line should be highlighted.
|
* Determines whether or not the current line should be highlighted.
|
||||||
* @param {Boolean} shouldHighlight Set to `true` to highlight the current line
|
* @param {Boolean} shouldHighlight Set to `true` to highlight the current line
|
||||||
|
|
@ -911,7 +911,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
|
* If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
|
||||||
* @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
|
* @param {Boolean} showInvisibles Specifies whether or not to show invisible characters
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setShowInvisibles = function(showInvisibles) {
|
this.setShowInvisibles = function(showInvisibles) {
|
||||||
this.renderer.setShowInvisibles(showInvisibles);
|
this.renderer.setShowInvisibles(showInvisibles);
|
||||||
|
|
@ -936,7 +936,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
|
* If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
|
||||||
* @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
|
* @param {Boolean} showPrintMargin Specifies whether or not to show the print margin
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setShowPrintMargin = function(showPrintMargin) {
|
this.setShowPrintMargin = function(showPrintMargin) {
|
||||||
this.renderer.setShowPrintMargin(showPrintMargin);
|
this.renderer.setShowPrintMargin(showPrintMargin);
|
||||||
|
|
@ -970,7 +970,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
|
* If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
|
||||||
* @param {Boolean} readOnly Specifies whether the editor can be modified or not
|
* @param {Boolean} readOnly Specifies whether the editor can be modified or not
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setReadOnly = function(readOnly) {
|
this.setReadOnly = function(readOnly) {
|
||||||
this.setOption("readOnly", readOnly);
|
this.setOption("readOnly", readOnly);
|
||||||
|
|
@ -987,7 +987,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}
|
* Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}
|
||||||
* @param {Boolean} enabled Enables or disables behaviors
|
* @param {Boolean} enabled Enables or disables behaviors
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setBehavioursEnabled = function (enabled) {
|
this.setBehavioursEnabled = function (enabled) {
|
||||||
this.setOption("behavioursEnabled", enabled);
|
this.setOption("behavioursEnabled", enabled);
|
||||||
|
|
@ -995,7 +995,7 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
|
* Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.getBehavioursEnabled = function () {
|
this.getBehavioursEnabled = function () {
|
||||||
|
|
@ -1006,7 +1006,7 @@ var Editor = function(renderer, session) {
|
||||||
* Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
|
* Specifies whether to use wrapping behaviors or not, i.e. automatically wrapping the selection with characters such as brackets
|
||||||
* when such a character is typed in.
|
* when such a character is typed in.
|
||||||
* @param {Boolean} enabled Enables or disables wrapping behaviors
|
* @param {Boolean} enabled Enables or disables wrapping behaviors
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.setWrapBehavioursEnabled = function (enabled) {
|
this.setWrapBehavioursEnabled = function (enabled) {
|
||||||
this.setOption("wrapBehavioursEnabled", enabled);
|
this.setOption("wrapBehavioursEnabled", enabled);
|
||||||
|
|
@ -1046,7 +1046,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
|
* Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
|
||||||
* @param {String} dir The direction of the deletion to occur, either "left" or "right"
|
* @param {String} dir The direction of the deletion to occur, either "left" or "right"
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.remove = function(dir) {
|
this.remove = function(dir) {
|
||||||
if (this.selection.isEmpty()){
|
if (this.selection.isEmpty()){
|
||||||
|
|
@ -1191,7 +1191,7 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts an indentation into the current cursor position or indents the selected lines.
|
* Inserts an indentation into the current cursor position or indents the selected lines.
|
||||||
*
|
*
|
||||||
* @related EditSession.indentRows
|
* @related EditSession.indentRows
|
||||||
**/
|
**/
|
||||||
this.indent = function() {
|
this.indent = function() {
|
||||||
|
|
@ -1261,7 +1261,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Given the currently selected range, this function either comments all the lines, or uncomments all of them.
|
* Given the currently selected range, this function either comments all the lines, or uncomments all of them.
|
||||||
**/
|
**/
|
||||||
this.toggleCommentLines = function() {
|
this.toggleCommentLines = function() {
|
||||||
|
|
@ -1293,7 +1293,7 @@ var Editor = function(renderer, session) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the character before the cursor is a number, this functions changes its value by `amount`.
|
* If the character before the cursor is a number, this functions changes its value by `amount`.
|
||||||
* @param {Number} amount The value to change the numeral by (can be negative to decrease value)
|
* @param {Number} amount The value to change the numeral by (can be negative to decrease value)
|
||||||
|
|
@ -1318,14 +1318,14 @@ var Editor = function(renderer, session) {
|
||||||
|
|
||||||
var t = parseFloat(nr.value);
|
var t = parseFloat(nr.value);
|
||||||
t *= Math.pow(10, decimals);
|
t *= Math.pow(10, decimals);
|
||||||
|
|
||||||
|
|
||||||
if(fp !== nr.end && column < fp){
|
if(fp !== nr.end && column < fp){
|
||||||
amount *= Math.pow(10, nr.end - column - 1);
|
amount *= Math.pow(10, nr.end - column - 1);
|
||||||
} else {
|
} else {
|
||||||
amount *= Math.pow(10, nr.end - column);
|
amount *= Math.pow(10, nr.end - column);
|
||||||
}
|
}
|
||||||
|
|
||||||
t += amount;
|
t += amount;
|
||||||
t /= Math.pow(10, decimals);
|
t /= Math.pow(10, decimals);
|
||||||
var nnr = t.toFixed(decimals);
|
var nnr = t.toFixed(decimals);
|
||||||
|
|
@ -1340,8 +1340,8 @@ var Editor = function(renderer, session) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all the lines in the current selection
|
* Removes all the lines in the current selection
|
||||||
* @related EditSession.remove
|
* @related EditSession.remove
|
||||||
**/
|
**/
|
||||||
|
|
@ -1367,17 +1367,16 @@ var Editor = function(renderer, session) {
|
||||||
var row = range.start.row;
|
var row = range.start.row;
|
||||||
doc.duplicateLines(row, row);
|
doc.duplicateLines(row, row);
|
||||||
} else {
|
} else {
|
||||||
var reverse = sel.isBackwards()
|
var point = reverse ? range.start : range.end;
|
||||||
var point = sel.isBackwards() ? range.start : range.end;
|
|
||||||
var endPoint = doc.insert(point, doc.getTextRange(range), false);
|
var endPoint = doc.insert(point, doc.getTextRange(range), false);
|
||||||
range.start = point;
|
range.start = point;
|
||||||
range.end = endPoint;
|
range.end = endPoint;
|
||||||
|
|
||||||
sel.setSelectionRange(range, reverse)
|
sel.setSelectionRange(range, reverse)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shifts all the selected lines down one row.
|
* Shifts all the selected lines down one row.
|
||||||
*
|
*
|
||||||
* @returns {Number} On success, it returns -1.
|
* @returns {Number} On success, it returns -1.
|
||||||
|
|
@ -1389,7 +1388,7 @@ var Editor = function(renderer, session) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shifts all the selected lines up one row.
|
* Shifts all the selected lines up one row.
|
||||||
* @returns {Number} On success, it returns -1.
|
* @returns {Number} On success, it returns -1.
|
||||||
* @related EditSession.moveLinesDown
|
* @related EditSession.moveLinesDown
|
||||||
|
|
@ -1400,28 +1399,25 @@ var Editor = function(renderer, session) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
|
* Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
|
||||||
* ```json
|
* ```json
|
||||||
* { row: newRowLocation, column: newColumnLocation }
|
* { row: newRowLocation, column: newColumnLocation }
|
||||||
* ```
|
* ```
|
||||||
* @param {Range} fromRange The range of text you want moved within the document
|
* @param {Range} fromRange The range of text you want moved within the document
|
||||||
* @param {Object} toPosition The location (row and column) where you want to move the text to
|
* @param {Object} toPosition The location (row and column) where you want to move the text to
|
||||||
*
|
*
|
||||||
* @returns {Range} The new range where the text was moved to.
|
* @returns {Range} The new range where the text was moved to.
|
||||||
* @related EditSession.moveText
|
* @related EditSession.moveText
|
||||||
**/
|
**/
|
||||||
this.moveText = function(range, toPosition) {
|
this.moveText = function(range, toPosition) {
|
||||||
if (this.$readOnly)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return this.session.moveText(range, toPosition);
|
return this.session.moveText(range, toPosition);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies all the selected lines up one row.
|
* Copies all the selected lines up one row.
|
||||||
* @returns {Number} On success, returns 0.
|
* @returns {Number} On success, returns 0.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.copyLinesUp = function() {
|
this.copyLinesUp = function() {
|
||||||
this.$moveLines(function(firstRow, lastRow) {
|
this.$moveLines(function(firstRow, lastRow) {
|
||||||
|
|
@ -1430,7 +1426,7 @@ var Editor = function(renderer, session) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies all the selected lines down one row.
|
* Copies all the selected lines down one row.
|
||||||
* @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
|
* @returns {Number} On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
|
||||||
* @related EditSession.duplicateLines
|
* @related EditSession.duplicateLines
|
||||||
|
|
@ -1446,29 +1442,43 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.
|
* Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.
|
||||||
* @param {Function} mover A method to call on each selected row
|
* @param {Function} mover A method to call on each selected row
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.$moveLines = function(mover) {
|
this.$moveLines = function(mover) {
|
||||||
var rows = this.$getSelectedRows();
|
|
||||||
var selection = this.selection;
|
var selection = this.selection;
|
||||||
if (!selection.isMultiLine()) {
|
if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
|
||||||
var range = selection.getRange();
|
var range = selection.toOrientedRange();
|
||||||
var reverse = selection.isBackwards();
|
var rows = this.$getSelectedRows(range);
|
||||||
}
|
var linesMoved = mover.call(this, rows.first, rows.last);
|
||||||
|
range.moveBy(linesMoved, 0);
|
||||||
var linesMoved = mover.call(this, rows.first, rows.last);
|
selection.fromOrientedRange(range);
|
||||||
|
} else {
|
||||||
if (range) {
|
var ranges = selection.rangeList.ranges;
|
||||||
range.start.row += linesMoved;
|
selection.rangeList.detach(this.session);
|
||||||
range.end.row += linesMoved;
|
|
||||||
selection.setSelectionRange(range, reverse);
|
for (var i = ranges.length; i--; ) {
|
||||||
}
|
var rangeIndex = i;
|
||||||
else {
|
var rows = ranges[i].collapseRows();
|
||||||
selection.setSelectionAnchor(rows.last+linesMoved+1, 0);
|
var last = rows.end.row;
|
||||||
selection.$moveSelection(function() {
|
var first = rows.start.row;
|
||||||
selection.moveCursorTo(rows.first+linesMoved, 0);
|
while (i--) {
|
||||||
});
|
var rows = ranges[i].collapseRows();
|
||||||
|
if (first - rows.end.row <= 1)
|
||||||
|
first = rows.end.row;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
var linesMoved = mover.call(this, first, last);
|
||||||
|
while (rangeIndex >= i) {
|
||||||
|
ranges[rangeIndex].moveBy(linesMoved, 0);
|
||||||
|
rangeIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selection.fromOrientedRange(selection.ranges[0]);
|
||||||
|
selection.rangeList.attach(this.session);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1502,7 +1512,7 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.hideComposition();
|
this.renderer.hideComposition();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:VirtualRenderer.getFirstVisibleRow}
|
* {:VirtualRenderer.getFirstVisibleRow}
|
||||||
*
|
*
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
|
|
@ -1512,7 +1522,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.renderer.getFirstVisibleRow();
|
return this.renderer.getFirstVisibleRow();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:VirtualRenderer.getLastVisibleRow}
|
* {:VirtualRenderer.getLastVisibleRow}
|
||||||
*
|
*
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
|
|
@ -1525,7 +1535,7 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Indicates if the row is currently visible on the screen.
|
* Indicates if the row is currently visible on the screen.
|
||||||
* @param {Number} row The row to check
|
* @param {Number} row The row to check
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isRowVisible = function(row) {
|
this.isRowVisible = function(row) {
|
||||||
|
|
@ -1535,8 +1545,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Indicates if the entire row is currently visible on the screen.
|
* Indicates if the entire row is currently visible on the screen.
|
||||||
* @param {Number} row The row to check
|
* @param {Number} row The row to check
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isRowFullyVisible = function(row) {
|
this.isRowFullyVisible = function(row) {
|
||||||
|
|
@ -1618,7 +1628,7 @@ var Editor = function(renderer, session) {
|
||||||
this.$moveByPage(-1);
|
this.$moveByPage(-1);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the editor to the specified row.
|
* Moves the editor to the specified row.
|
||||||
* @related VirtualRenderer.scrollToRow
|
* @related VirtualRenderer.scrollToRow
|
||||||
**/
|
**/
|
||||||
|
|
@ -1626,14 +1636,14 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.scrollToRow(row);
|
this.renderer.scrollToRow(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
|
* Scrolls to a line. If `center` is `true`, it puts the line in middle of screen (or attempts to).
|
||||||
* @param {Number} line The line to scroll to
|
* @param {Number} line The line to scroll to
|
||||||
* @param {Boolean} center If `true`
|
* @param {Boolean} center If `true`
|
||||||
* @param {Boolean} animate If `true` animates scrolling
|
* @param {Boolean} animate If `true` animates scrolling
|
||||||
* @param {Function} callback Function to be called when the animation has finished
|
* @param {Function} callback Function to be called when the animation has finished
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @related VirtualRenderer.scrollToLine
|
* @related VirtualRenderer.scrollToLine
|
||||||
**/
|
**/
|
||||||
this.scrollToLine = function(line, center, animate, callback) {
|
this.scrollToLine = function(line, center, animate, callback) {
|
||||||
|
|
@ -1652,9 +1662,9 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.alignCursor(pos, 0.5);
|
this.renderer.alignCursor(pos, 0.5);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current position of the cursor.
|
* Gets the current position of the cursor.
|
||||||
* @returns {Object} An object that looks something like this:
|
* @returns {Object} An object that looks something like this:
|
||||||
*
|
*
|
||||||
* ```json
|
* ```json
|
||||||
* { row: currRow, column: currCol }
|
* { row: currRow, column: currCol }
|
||||||
|
|
@ -1666,7 +1676,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.selection.getCursor();
|
return this.selection.getCursor();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the screen position of the cursor.
|
* Returns the screen position of the cursor.
|
||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
* @related EditSession.documentToScreenPosition
|
* @related EditSession.documentToScreenPosition
|
||||||
|
|
@ -1675,7 +1685,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.session.documentToScreenPosition(this.getCursorPosition());
|
return this.session.documentToScreenPosition(this.getCursorPosition());
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:Selection.getRange}
|
* {:Selection.getRange}
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
* @related Selection.getRange
|
* @related Selection.getRange
|
||||||
|
|
@ -1685,7 +1695,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects all the text in editor.
|
* Selects all the text in editor.
|
||||||
* @related Selection.selectAll
|
* @related Selection.selectAll
|
||||||
**/
|
**/
|
||||||
|
|
@ -1695,7 +1705,7 @@ var Editor = function(renderer, session) {
|
||||||
this.$blockScrolling -= 1;
|
this.$blockScrolling -= 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:Selection.clearSelection}
|
* {:Selection.clearSelection}
|
||||||
* @related Selection.clearSelection
|
* @related Selection.clearSelection
|
||||||
**/
|
**/
|
||||||
|
|
@ -1703,7 +1713,7 @@ var Editor = function(renderer, session) {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
|
* Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
|
||||||
* @param {Number} row The new row number
|
* @param {Number} row The new row number
|
||||||
* @param {Number} column The new column number
|
* @param {Number} column The new column number
|
||||||
|
|
@ -1715,10 +1725,10 @@ var Editor = function(renderer, session) {
|
||||||
this.selection.moveCursorTo(row, column);
|
this.selection.moveCursorTo(row, column);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor to the position indicated by `pos.row` and `pos.column`.
|
* Moves the cursor to the position indicated by `pos.row` and `pos.column`.
|
||||||
* @param {Object} pos An object with two properties, row and column
|
* @param {Object} pos An object with two properties, row and column
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @related Selection.moveCursorToPosition
|
* @related Selection.moveCursorToPosition
|
||||||
**/
|
**/
|
||||||
|
|
@ -1726,7 +1736,7 @@ var Editor = function(renderer, session) {
|
||||||
this.selection.moveCursorToPosition(pos);
|
this.selection.moveCursorToPosition(pos);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor's row and column to the next matching bracket.
|
* Moves the cursor's row and column to the next matching bracket.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
@ -1746,7 +1756,7 @@ var Editor = function(renderer, session) {
|
||||||
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
|
if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
|
||||||
range = this.session.getBracketRange(pos);
|
range = this.session.getBracketRange(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = range && range.cursor || pos;
|
pos = range && range.cursor || pos;
|
||||||
if (pos) {
|
if (pos) {
|
||||||
if (select) {
|
if (select) {
|
||||||
|
|
@ -1766,7 +1776,7 @@ var Editor = function(renderer, session) {
|
||||||
* @param {Number} lineNumber The line number to go to
|
* @param {Number} lineNumber The line number to go to
|
||||||
* @param {Number} column A column number to go to
|
* @param {Number} column A column number to go to
|
||||||
* @param {Boolean} animate If `true` animates scolling
|
* @param {Boolean} animate If `true` animates scolling
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.gotoLine = function(lineNumber, column, animate) {
|
this.gotoLine = function(lineNumber, column, animate) {
|
||||||
this.selection.clearSelection();
|
this.selection.clearSelection();
|
||||||
|
|
@ -1780,7 +1790,7 @@ var Editor = function(renderer, session) {
|
||||||
this.scrollToLine(lineNumber - 1, true, animate);
|
this.scrollToLine(lineNumber - 1, true, animate);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves the cursor to the specified row and column. Note that this does de-select the current selection.
|
* Moves the cursor to the specified row and column. Note that this does de-select the current selection.
|
||||||
* @param {Number} row The new row number
|
* @param {Number} row The new row number
|
||||||
* @param {Number} column The new column number
|
* @param {Number} column The new column number
|
||||||
|
|
@ -1796,8 +1806,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.
|
* Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.
|
||||||
* @param {Number} times The number of times to change navigation
|
* @param {Number} times The number of times to change navigation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.navigateUp = function(times) {
|
this.navigateUp = function(times) {
|
||||||
if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
|
if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
|
||||||
|
|
@ -1812,8 +1822,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.
|
* Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.
|
||||||
* @param {Number} times The number of times to change navigation
|
* @param {Number} times The number of times to change navigation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.navigateDown = function(times) {
|
this.navigateDown = function(times) {
|
||||||
if (this.selection.isMultiLine() && this.selection.isBackwards()) {
|
if (this.selection.isMultiLine() && this.selection.isBackwards()) {
|
||||||
|
|
@ -1828,8 +1838,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.
|
* Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.
|
||||||
* @param {Number} times The number of times to change navigation
|
* @param {Number} times The number of times to change navigation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.navigateLeft = function(times) {
|
this.navigateLeft = function(times) {
|
||||||
if (!this.selection.isEmpty()) {
|
if (!this.selection.isEmpty()) {
|
||||||
|
|
@ -1848,8 +1858,8 @@ var Editor = function(renderer, session) {
|
||||||
/**
|
/**
|
||||||
* Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.
|
* Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.
|
||||||
* @param {Number} times The number of times to change navigation
|
* @param {Number} times The number of times to change navigation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.navigateRight = function(times) {
|
this.navigateRight = function(times) {
|
||||||
if (!this.selection.isEmpty()) {
|
if (!this.selection.isEmpty()) {
|
||||||
|
|
@ -1866,7 +1876,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the start of the current line. Note that this does de-select the current selection.
|
* Moves the cursor to the start of the current line. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateLineStart = function() {
|
this.navigateLineStart = function() {
|
||||||
|
|
@ -1875,7 +1885,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the end of the current line. Note that this does de-select the current selection.
|
* Moves the cursor to the end of the current line. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateLineEnd = function() {
|
this.navigateLineEnd = function() {
|
||||||
|
|
@ -1884,7 +1894,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the end of the current file. Note that this does de-select the current selection.
|
* Moves the cursor to the end of the current file. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateFileEnd = function() {
|
this.navigateFileEnd = function() {
|
||||||
|
|
@ -1895,7 +1905,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the start of the current file. Note that this does de-select the current selection.
|
* Moves the cursor to the start of the current file. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateFileStart = function() {
|
this.navigateFileStart = function() {
|
||||||
|
|
@ -1906,7 +1916,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.
|
* Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateWordRight = function() {
|
this.navigateWordRight = function() {
|
||||||
|
|
@ -1915,7 +1925,7 @@ var Editor = function(renderer, session) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.
|
* Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.
|
||||||
**/
|
**/
|
||||||
this.navigateWordLeft = function() {
|
this.navigateWordLeft = function() {
|
||||||
|
|
@ -1996,7 +2006,7 @@ var Editor = function(renderer, session) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
|
* {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
|
||||||
* @related Search.getOptions
|
* @related Search.getOptions
|
||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
|
|
@ -2005,7 +2015,7 @@ var Editor = function(renderer, session) {
|
||||||
return this.$search.getOptions();
|
return this.$search.getOptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
|
* Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
|
||||||
* @param {String} needle The text to search for (optional)
|
* @param {String} needle The text to search for (optional)
|
||||||
* @param {Object} options An object defining various search properties
|
* @param {Object} options An object defining various search properties
|
||||||
|
|
@ -2053,7 +2063,7 @@ var Editor = function(renderer, session) {
|
||||||
this.selection.setRange(range);
|
this.selection.setRange(range);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
|
* Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
|
||||||
* @param {Object} options search options
|
* @param {Object} options search options
|
||||||
* @param {Boolean} animate If `true` animate scrolling
|
* @param {Boolean} animate If `true` animate scrolling
|
||||||
|
|
@ -2065,7 +2075,7 @@ var Editor = function(renderer, session) {
|
||||||
this.find({skipCurrent: true, backwards: false}, options, animate);
|
this.find({skipCurrent: true, backwards: false}, options, animate);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
|
* Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
|
||||||
* @param {Object} options search options
|
* @param {Object} options search options
|
||||||
* @param {Boolean} animate If `true` animate scrolling
|
* @param {Boolean} animate If `true` animate scrolling
|
||||||
|
|
@ -2089,7 +2099,7 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.animateScrolling(scrollTop);
|
this.renderer.animateScrolling(scrollTop);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:UndoManager.undo}
|
* {:UndoManager.undo}
|
||||||
* @related UndoManager.undo
|
* @related UndoManager.undo
|
||||||
**/
|
**/
|
||||||
|
|
@ -2100,7 +2110,7 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.scrollCursorIntoView(null, 0.5);
|
this.renderer.scrollCursorIntoView(null, 0.5);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {:UndoManager.redo}
|
* {:UndoManager.redo}
|
||||||
* @related UndoManager.redo
|
* @related UndoManager.redo
|
||||||
**/
|
**/
|
||||||
|
|
@ -2111,16 +2121,16 @@ var Editor = function(renderer, session) {
|
||||||
this.renderer.scrollCursorIntoView(null, 0.5);
|
this.renderer.scrollCursorIntoView(null, 0.5);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Cleans up the entire editor.
|
* Cleans up the entire editor.
|
||||||
**/
|
**/
|
||||||
this.destroy = function() {
|
this.destroy = function() {
|
||||||
this.renderer.destroy();
|
this.renderer.destroy();
|
||||||
this._emit("destroy", this);
|
this._emit("destroy", this);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
|
* Enables automatic scrolling of the cursor into view when editor itself is inside scrollable element
|
||||||
* @param {Boolean} enable default true
|
* @param {Boolean} enable default true
|
||||||
**/
|
**/
|
||||||
|
|
@ -2228,4 +2238,4 @@ config.defineOptions(Editor.prototype, "editor", {
|
||||||
});
|
});
|
||||||
|
|
||||||
exports.Editor = Editor;
|
exports.Editor = Editor;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ module.exports = {
|
||||||
assert.range(editor.getSelectionRange(), 0, 3, 1, 0);
|
assert.range(editor.getSelectionRange(), 0, 3, 1, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: move lines down should select moved lines" : function() {
|
"test: move lines down should keep selection on moved lines" : function() {
|
||||||
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
||||||
var editor = new Editor(new MockRenderer(), session);
|
var editor = new Editor(new MockRenderer(), session);
|
||||||
|
|
||||||
|
|
@ -257,25 +257,25 @@ module.exports = {
|
||||||
|
|
||||||
editor.moveLinesDown();
|
editor.moveLinesDown();
|
||||||
assert.equal(["33", "11", "22", "44"].join("\n"), session.toString());
|
assert.equal(["33", "11", "22", "44"].join("\n"), session.toString());
|
||||||
assert.position(editor.getCursorPosition(), 1, 0);
|
assert.position(editor.getCursorPosition(), 2, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
|
assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 1, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 2, 1);
|
||||||
|
|
||||||
editor.moveLinesDown();
|
editor.moveLinesDown();
|
||||||
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
|
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
|
||||||
assert.position(editor.getCursorPosition(), 2, 0);
|
assert.position(editor.getCursorPosition(), 3, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
|
assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 2, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 3, 1);
|
||||||
|
|
||||||
// moving again should have no effect
|
// moving again should have no effect
|
||||||
editor.moveLinesDown();
|
editor.moveLinesDown();
|
||||||
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
|
assert.equal(["33", "44", "11", "22"].join("\n"), session.toString());
|
||||||
assert.position(editor.getCursorPosition(), 2, 0);
|
assert.position(editor.getCursorPosition(), 3, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 3, 2);
|
assert.position(editor.getSelection().getSelectionAnchor(), 2, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 2, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 3, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: move lines up should select moved lines" : function() {
|
"test: move lines up should keep selection on moved lines" : function() {
|
||||||
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
||||||
var editor = new Editor(new MockRenderer(), session);
|
var editor = new Editor(new MockRenderer(), session);
|
||||||
|
|
||||||
|
|
@ -284,19 +284,18 @@ module.exports = {
|
||||||
|
|
||||||
editor.moveLinesUp();
|
editor.moveLinesUp();
|
||||||
assert.equal(session.toString(), ["11", "33", "44", "22"].join("\n"));
|
assert.equal(session.toString(), ["11", "33", "44", "22"].join("\n"));
|
||||||
assert.position(editor.getCursorPosition(), 1, 0);
|
assert.position(editor.getCursorPosition(), 2, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
|
assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 1, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 2, 1);
|
||||||
|
|
||||||
editor.moveLinesUp();
|
editor.moveLinesUp();
|
||||||
assert.equal(session.toString(), ["33", "44", "11", "22"].join("\n"));
|
assert.equal(session.toString(), ["33", "44", "11", "22"].join("\n"));
|
||||||
assert.position(editor.getCursorPosition(), 0, 0);
|
assert.position(editor.getCursorPosition(), 1, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 2, 0);
|
assert.position(editor.getSelection().getSelectionAnchor(), 0, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 0, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 1, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: move line without active selection should not move cursor relative to the moved line" : function()
|
"test: move line without active selection should not move cursor relative to the moved line" : function() {
|
||||||
{
|
|
||||||
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
||||||
var editor = new Editor(new MockRenderer(), session);
|
var editor = new Editor(new MockRenderer(), session);
|
||||||
|
|
||||||
|
|
@ -314,7 +313,7 @@ module.exports = {
|
||||||
assert.position(editor.getCursorPosition(), 1, 1);
|
assert.position(editor.getCursorPosition(), 1, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: copy lines down should select lines and place cursor at the selection start" : function() {
|
"test: copy lines down should keep selection" : function() {
|
||||||
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
||||||
var editor = new Editor(new MockRenderer(), session);
|
var editor = new Editor(new MockRenderer(), session);
|
||||||
|
|
||||||
|
|
@ -324,12 +323,12 @@ module.exports = {
|
||||||
editor.copyLinesDown();
|
editor.copyLinesDown();
|
||||||
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
|
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
|
||||||
|
|
||||||
assert.position(editor.getCursorPosition(), 3, 0);
|
assert.position(editor.getCursorPosition(), 4, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 5, 0);
|
assert.position(editor.getSelection().getSelectionAnchor(), 3, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 3, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 4, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: copy lines up should select lines and place cursor at the selection start" : function() {
|
"test: copy lines up should keep selection" : function() {
|
||||||
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
var session = new EditSession(["11", "22", "33", "44"].join("\n"));
|
||||||
var editor = new Editor(new MockRenderer(), session);
|
var editor = new Editor(new MockRenderer(), session);
|
||||||
|
|
||||||
|
|
@ -339,9 +338,9 @@ module.exports = {
|
||||||
editor.copyLinesUp();
|
editor.copyLinesUp();
|
||||||
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
|
assert.equal(["11", "22", "33", "22", "33", "44"].join("\n"), session.toString());
|
||||||
|
|
||||||
assert.position(editor.getCursorPosition(), 1, 0);
|
assert.position(editor.getCursorPosition(), 2, 1);
|
||||||
assert.position(editor.getSelection().getSelectionAnchor(), 3, 0);
|
assert.position(editor.getSelection().getSelectionAnchor(), 1, 1);
|
||||||
assert.position(editor.getSelection().getSelectionLead(), 1, 0);
|
assert.position(editor.getSelection().getSelectionLead(), 2, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
"test: input a tab with soft tab should convert it to spaces" : function() {
|
"test: input a tab with soft tab should convert it to spaces" : function() {
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,8 @@ oop.inherits(FoldMode, BaseFoldMode);
|
||||||
var row = stream.getCurrentTokenRow();
|
var row = stream.getCurrentTokenRow();
|
||||||
if (dir === -1)
|
if (dir === -1)
|
||||||
return new Range(row, session.getLine(row).length, startRow, startColumn);
|
return new Range(row, session.getLine(row).length, startRow, startColumn);
|
||||||
else
|
stream.stepBackward();
|
||||||
return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());
|
return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());
|
||||||
};
|
};
|
||||||
|
|
||||||
this.latexSection = function(session, row, column) {
|
this.latexSection = function(session, row, column) {
|
||||||
|
|
|
||||||
|
|
@ -84,14 +84,14 @@ function DefaultHandlers(mouseHandler) {
|
||||||
// selection
|
// selection
|
||||||
if (inSelection && !editor.isFocused()) {
|
if (inSelection && !editor.isFocused()) {
|
||||||
editor.focus();
|
editor.focus();
|
||||||
if (this.$focusTimout && !this.$clickSelection) {
|
if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
|
||||||
this.setState("focusWait");
|
this.setState("focusWait");
|
||||||
this.captureMouse(ev);
|
this.captureMouse(ev);
|
||||||
return ev.preventDefault();
|
return ev.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inSelection || this.$clickSelection || ev.getShiftKey()) {
|
if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
|
||||||
// Directly pick STATE_SELECT, since the user is not clicking inside
|
// Directly pick STATE_SELECT, since the user is not clicking inside
|
||||||
// a selection.
|
// a selection.
|
||||||
this.startSelect(pos);
|
this.startSelect(pos);
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,6 @@ function FoldHandler(editor) {
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.on("guttermousedown", function(e) {
|
editor.on("guttermousedown", function(e) {
|
||||||
if (!editor.isFocused())
|
|
||||||
return;
|
|
||||||
var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
|
var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
|
||||||
|
|
||||||
if (gutterRegion == "foldWidgets") {
|
if (gutterRegion == "foldWidgets") {
|
||||||
|
|
@ -59,6 +57,8 @@ function FoldHandler(editor) {
|
||||||
var session = editor.session;
|
var session = editor.session;
|
||||||
if (session.foldWidgets && session.foldWidgets[row])
|
if (session.foldWidgets && session.foldWidgets[row])
|
||||||
editor.session.onFoldWidgetClick(row, e);
|
editor.session.onFoldWidgetClick(row, e);
|
||||||
|
if (!editor.isFocused())
|
||||||
|
editor.focus();
|
||||||
e.stop();
|
e.stop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -69,27 +69,8 @@ function FoldHandler(editor) {
|
||||||
if (gutterRegion == "foldWidgets") {
|
if (gutterRegion == "foldWidgets") {
|
||||||
var row = e.getDocumentPosition().row;
|
var row = e.getDocumentPosition().row;
|
||||||
var session = editor.session;
|
var session = editor.session;
|
||||||
var fw = session.foldWidgets;
|
var data = session.getParentFoldRangeData(row, true);
|
||||||
if (!fw || fw[row])
|
var range = data.range || data.firstRange;
|
||||||
return;
|
|
||||||
|
|
||||||
var i = row - 1, firstRange;
|
|
||||||
while (i >= 0) {
|
|
||||||
var c = fw[i];
|
|
||||||
if (c == null)
|
|
||||||
c = fw[i] = session.getFoldWidget(i);
|
|
||||||
|
|
||||||
if (c == "start") {
|
|
||||||
var range = session.getFoldWidgetRange(i);
|
|
||||||
if (!firstRange)
|
|
||||||
firstRange = range;
|
|
||||||
if (range && range.end.row >= row)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
if (i == -1)
|
|
||||||
range = firstRange;
|
|
||||||
|
|
||||||
if (range) {
|
if (range) {
|
||||||
var row = range.start.row;
|
var row = range.start.row;
|
||||||
|
|
|
||||||
|
|
@ -78,9 +78,13 @@ var EditSession = require("./edit_session").EditSession;
|
||||||
|
|
||||||
if (!this.inMultiSelectMode && this.rangeCount == 0) {
|
if (!this.inMultiSelectMode && this.rangeCount == 0) {
|
||||||
var oldRange = this.toOrientedRange();
|
var oldRange = this.toOrientedRange();
|
||||||
if (range.intersects(oldRange))
|
this.rangeList.add(oldRange);
|
||||||
|
this.rangeList.add(range);
|
||||||
|
if (this.rangeList.ranges.length != 2) {
|
||||||
|
this.rangeList.removeAll();
|
||||||
return $blockChangeEvents || this.fromOrientedRange(range);
|
return $blockChangeEvents || this.fromOrientedRange(range);
|
||||||
|
}
|
||||||
|
this.rangeList.removeAll();
|
||||||
this.rangeList.add(oldRange);
|
this.rangeList.add(oldRange);
|
||||||
this.$onAddRange(oldRange);
|
this.$onAddRange(oldRange);
|
||||||
}
|
}
|
||||||
|
|
@ -446,6 +450,8 @@ var Editor = require("./editor").Editor;
|
||||||
editor.multiSelect.mergeOverlappingRanges();
|
editor.multiSelect.mergeOverlappingRanges();
|
||||||
} else if (command.multiSelectAction == "forEach") {
|
} else if (command.multiSelectAction == "forEach") {
|
||||||
editor.forEachSelection(command, e.args);
|
editor.forEachSelection(command, e.args);
|
||||||
|
} else if (command.multiSelectAction == "forEachLine") {
|
||||||
|
editor.forEachSelection(command, e.args, true);
|
||||||
} else if (command.multiSelectAction == "single") {
|
} else if (command.multiSelectAction == "single") {
|
||||||
editor.exitMultiSelectMode();
|
editor.exitMultiSelectMode();
|
||||||
command.exec(editor, e.args || {});
|
command.exec(editor, e.args || {});
|
||||||
|
|
@ -461,7 +467,7 @@ var Editor = require("./editor").Editor;
|
||||||
* @param {String} args Any arguments for the command
|
* @param {String} args Any arguments for the command
|
||||||
* @method Editor.forEachSelection
|
* @method Editor.forEachSelection
|
||||||
**/
|
**/
|
||||||
this.forEachSelection = function(cmd, args) {
|
this.forEachSelection = function(cmd, args, $byLines) {
|
||||||
if (this.inVirtualSelectionMode)
|
if (this.inVirtualSelectionMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -475,6 +481,10 @@ var Editor = require("./editor").Editor;
|
||||||
var tmpSel = new Selection(session);
|
var tmpSel = new Selection(session);
|
||||||
this.inVirtualSelectionMode = true;
|
this.inVirtualSelectionMode = true;
|
||||||
for (var i = rangeList.ranges.length; i--;) {
|
for (var i = rangeList.ranges.length; i--;) {
|
||||||
|
if ($byLines) {
|
||||||
|
while (i > 0 && rangeList.ranges[i].start.row == rangeList.ranges[i - 1].end.row)
|
||||||
|
i--;
|
||||||
|
}
|
||||||
tmpSel.fromOrientedRange(rangeList.ranges[i]);
|
tmpSel.fromOrientedRange(rangeList.ranges[i]);
|
||||||
this.selection = session.selection = tmpSel;
|
this.selection = session.selection = tmpSel;
|
||||||
cmd.exec(this, args || {});
|
cmd.exec(this, args || {});
|
||||||
|
|
|
||||||
172
lib/ace/range.js
172
lib/ace/range.js
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Ajax.org B.V.
|
* Copyright (c) 2010, Ajax.org B.V.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* * Neither the name of Ajax.org B.V. nor the
|
* * Neither the name of Ajax.org B.V. nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
|
@ -30,10 +30,10 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
var comparePoints = function(p1, p2) {
|
||||||
|
return p1.row - p2.row || p1.column - p2.column;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
|
||||||
* This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
|
* This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
|
||||||
* @class Range
|
* @class Range
|
||||||
**/
|
**/
|
||||||
|
|
@ -45,7 +45,6 @@ define(function(require, exports, module) {
|
||||||
* @param {Number} endRow The ending row
|
* @param {Number} endRow The ending row
|
||||||
* @param {Number} endColumn The ending column
|
* @param {Number} endColumn The ending column
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @constructor
|
* @constructor
|
||||||
**/
|
**/
|
||||||
var Range = function(startRow, startColumn, endRow, endColumn) {
|
var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
|
|
@ -65,30 +64,29 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* Returns `true` if and only if the starting row and column, and ending row and column, are equivalent to those given by `range`.
|
* Returns `true` if and only if the starting row and column, and ending row and column, are equivalent to those given by `range`.
|
||||||
* @param {Range} range A range to check against
|
* @param {Range} range A range to check against
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isEqual = function(range) {
|
this.isEqual = function(range) {
|
||||||
return this.start.row == range.start.row &&
|
return this.start.row === range.start.row &&
|
||||||
this.end.row == range.end.row &&
|
this.end.row === range.end.row &&
|
||||||
this.start.column == range.start.column &&
|
this.start.column === range.start.column &&
|
||||||
this.end.column == range.end.column
|
this.end.column === range.end.column;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns a string containing the range's row and column information, given like this:
|
* Returns a string containing the range's row and column information, given like this:
|
||||||
* ```
|
* ```
|
||||||
* [start.row/start.column] -> [end.row/end.column]
|
* [start.row/start.column] -> [end.row/end.column]
|
||||||
* ```
|
* ```
|
||||||
* @return {String}
|
* @return {String}
|
||||||
**/
|
**/
|
||||||
this.toString = function() {
|
this.toString = function() {
|
||||||
return ("Range: [" + this.start.row + "/" + this.start.column +
|
return ("Range: [" + this.start.row + "/" + this.start.column +
|
||||||
"] -> [" + this.end.row + "/" + this.end.column + "]");
|
"] -> [" + this.end.row + "/" + this.end.column + "]");
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
|
* Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
|
||||||
* ```javascript
|
* ```javascript
|
||||||
|
|
@ -99,17 +97,16 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* @param {Number} column A column to check for
|
* @param {Number} column A column to check for
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
**/
|
**/
|
||||||
|
|
||||||
this.contains = function(row, column) {
|
this.contains = function(row, column) {
|
||||||
return this.compare(row, column) == 0;
|
return this.compare(row, column) == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares `this` range (A) with another range (B).
|
* Compares `this` range (A) with another range (B).
|
||||||
* @param {Range} range A range to compare with
|
* @param {Range} range A range to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* <br/>
|
* <br/>
|
||||||
|
|
@ -119,7 +116,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* * `+1`: (B) begins inside of (A) but ends outside of (A)<br/>
|
* * `+1`: (B) begins inside of (A) but ends outside of (A)<br/>
|
||||||
* * `+2`: (B) is after (A) and doesn't intersect with (A)<br/>
|
* * `+2`: (B) is after (A) and doesn't intersect with (A)<br/>
|
||||||
* * `42`: FTW state: (B) ends in (A) but starts outside of (A)
|
* * `42`: FTW state: (B) ends in (A) but starts outside of (A)
|
||||||
**/
|
**/
|
||||||
this.compareRange = function(range) {
|
this.compareRange = function(range) {
|
||||||
var cmp,
|
var cmp,
|
||||||
end = range.end,
|
end = range.end,
|
||||||
|
|
@ -149,12 +146,11 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Checks the row and column points of `p` with the row and column points of the calling range.
|
* Checks the row and column points of `p` with the row and column points of the calling range.
|
||||||
*
|
*
|
||||||
* @param {Range} p A point to compare with
|
* @param {Range} p A point to compare with
|
||||||
*
|
*
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* * `0` if the two points are exactly equal<br/>
|
* * `0` if the two points are exactly equal<br/>
|
||||||
|
|
@ -168,19 +164,18 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* If the ending row of the calling range is equal to `p.row`, and:<br/>
|
* If the ending row of the calling range is equal to `p.row`, and:<br/>
|
||||||
* * `p.column` is less than or equal to the calling range's ending column, this returns `0`<br/>
|
* * `p.column` is less than or equal to the calling range's ending column, this returns `0`<br/>
|
||||||
* * Otherwise, it returns 1<br/>
|
* * Otherwise, it returns 1<br/>
|
||||||
**/
|
**/
|
||||||
this.comparePoint = function(p) {
|
this.comparePoint = function(p) {
|
||||||
return this.compare(p.row, p.column);
|
return this.compare(p.row, p.column);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
|
* Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
|
||||||
* @param {Range} range A range to compare with
|
* @param {Range} range A range to compare with
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related Range.comparePoint
|
* @related Range.comparePoint
|
||||||
*
|
**/
|
||||||
**/
|
|
||||||
this.containsRange = function(range) {
|
this.containsRange = function(range) {
|
||||||
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
|
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
|
||||||
};
|
};
|
||||||
|
|
@ -189,7 +184,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* Returns `true` if passed in `range` intersects with the one calling this method.
|
* Returns `true` if passed in `range` intersects with the one calling this method.
|
||||||
* @param {Range} range A range to compare with
|
* @param {Range} range A range to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.intersects = function(range) {
|
this.intersects = function(range) {
|
||||||
|
|
@ -202,7 +196,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isEnd = function(row, column) {
|
this.isEnd = function(row, column) {
|
||||||
|
|
@ -214,9 +207,8 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
this.isStart = function(row, column) {
|
this.isStart = function(row, column) {
|
||||||
return this.start.row == row && this.start.column == column;
|
return this.start.row == row && this.start.column == column;
|
||||||
};
|
};
|
||||||
|
|
@ -226,9 +218,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* @param {Number} row A row point to set
|
* @param {Number} row A row point to set
|
||||||
* @param {Number} column A column point to set
|
* @param {Number} column A column point to set
|
||||||
*
|
*
|
||||||
*
|
**/
|
||||||
*
|
|
||||||
**/
|
|
||||||
this.setStart = function(row, column) {
|
this.setStart = function(row, column) {
|
||||||
if (typeof row == "object") {
|
if (typeof row == "object") {
|
||||||
this.start.column = row.column;
|
this.start.column = row.column;
|
||||||
|
|
@ -244,9 +234,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* @param {Number} row A row point to set
|
* @param {Number} row A row point to set
|
||||||
* @param {Number} column A column point to set
|
* @param {Number} column A column point to set
|
||||||
*
|
*
|
||||||
*
|
**/
|
||||||
*
|
|
||||||
**/
|
|
||||||
this.setEnd = function(row, column) {
|
this.setEnd = function(row, column) {
|
||||||
if (typeof row == "object") {
|
if (typeof row == "object") {
|
||||||
this.end.column = row.column;
|
this.end.column = row.column;
|
||||||
|
|
@ -257,15 +245,15 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the `row` and `column` are within the given range.
|
* Returns `true` if the `row` and `column` are within the given range.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
**/
|
**/
|
||||||
this.inside = function(row, column) {
|
this.inside = function(row, column) {
|
||||||
if (this.compare(row, column) == 0) {
|
if (this.compare(row, column) == 0) {
|
||||||
if (this.isEnd(row, column) || this.isStart(row, column)) {
|
if (this.isEnd(row, column) || this.isStart(row, column)) {
|
||||||
|
|
@ -277,15 +265,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the `row` and `column` are within the given range's starting points.
|
* Returns `true` if the `row` and `column` are within the given range's starting points.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
**/
|
**/
|
||||||
this.insideStart = function(row, column) {
|
this.insideStart = function(row, column) {
|
||||||
if (this.compare(row, column) == 0) {
|
if (this.compare(row, column) == 0) {
|
||||||
if (this.isEnd(row, column)) {
|
if (this.isEnd(row, column)) {
|
||||||
|
|
@ -297,16 +284,15 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns `true` if the `row` and `column` are within the given range's ending points.
|
* Returns `true` if the `row` and `column` are within the given range's ending points.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
* @related Range.compare
|
* @related Range.compare
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
this.insideEnd = function(row, column) {
|
this.insideEnd = function(row, column) {
|
||||||
if (this.compare(row, column) == 0) {
|
if (this.compare(row, column) == 0) {
|
||||||
if (this.isStart(row, column)) {
|
if (this.isStart(row, column)) {
|
||||||
|
|
@ -318,11 +304,11 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the row and column points with the row and column points of the calling range.
|
* Checks the row and column points with the row and column points of the calling range.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* `0` if the two points are exactly equal <br/>
|
* `0` if the two points are exactly equal <br/>
|
||||||
|
|
@ -363,8 +349,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* Checks the row and column points with the row and column points of the calling range.
|
* Checks the row and column points with the row and column points of the calling range.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* <br/>
|
* <br/>
|
||||||
|
|
@ -393,7 +377,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
* Checks the row and column points with the row and column points of the calling range.
|
* Checks the row and column points with the row and column points of the calling range.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* `0` if the two points are exactly equal<br/>
|
* `0` if the two points are exactly equal<br/>
|
||||||
|
|
@ -416,11 +400,11 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the row and column points with the row and column points of the calling range.
|
* Checks the row and column points with the row and column points of the calling range.
|
||||||
* @param {Number} row A row point to compare with
|
* @param {Number} row A row point to compare with
|
||||||
* @param {Number} column A column point to compare with
|
* @param {Number} column A column point to compare with
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Number} This method returns one of the following numbers:<br/>
|
* @returns {Number} This method returns one of the following numbers:<br/>
|
||||||
* * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`<br/>
|
* * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`<br/>
|
||||||
|
|
@ -439,51 +423,34 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
|
* Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
|
||||||
* @param {Number} firstRow The starting row
|
* @param {Number} firstRow The starting row
|
||||||
* @param {Number} lastRow The ending row
|
* @param {Number} lastRow The ending row
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
**/
|
**/
|
||||||
this.clipRows = function(firstRow, lastRow) {
|
this.clipRows = function(firstRow, lastRow) {
|
||||||
if (this.end.row > lastRow) {
|
if (this.end.row > lastRow)
|
||||||
var end = {
|
var end = {row: lastRow + 1, column: 0};
|
||||||
row: lastRow+1,
|
else if (this.end.row < firstRow)
|
||||||
column: 0
|
var end = {row: firstRow, column: 0};
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.start.row > lastRow) {
|
if (this.start.row > lastRow)
|
||||||
var start = {
|
var start = {row: lastRow + 1, column: 0};
|
||||||
row: lastRow+1,
|
else if (this.start.row < firstRow)
|
||||||
column: 0
|
var start = {row: firstRow, column: 0};
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.start.row < firstRow) {
|
|
||||||
var start = {
|
|
||||||
row: firstRow,
|
|
||||||
column: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.end.row < firstRow) {
|
|
||||||
var end = {
|
|
||||||
row: firstRow,
|
|
||||||
column: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return Range.fromPoints(start || this.start, end || this.end);
|
return Range.fromPoints(start || this.start, end || this.end);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the row and column points for the calling range for both the starting and ending points.
|
* Changes the row and column points for the calling range for both the starting and ending points.
|
||||||
* @param {Number} row A new row to extend to
|
* @param {Number} row A new row to extend to
|
||||||
* @param {Number} column A new column to extend to
|
* @param {Number} column A new column to extend to
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Range} The original range with the new row
|
* @returns {Range} The original range with the new row
|
||||||
**/
|
**/
|
||||||
this.extend = function(row, column) {
|
this.extend = function(row, column) {
|
||||||
|
|
@ -500,11 +467,11 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.isEmpty = function() {
|
this.isEmpty = function() {
|
||||||
return (this.start.row == this.end.row && this.start.column == this.end.column);
|
return (this.start.row === this.end.row && this.start.column === this.end.column);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns `true` if the range spans across multiple lines.
|
* Returns `true` if the range spans across multiple lines.
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
**/
|
**/
|
||||||
|
|
@ -512,8 +479,8 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return (this.start.row !== this.end.row);
|
return (this.start.row !== this.end.row);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns a duplicate of the calling range.
|
* Returns a duplicate of the calling range.
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
**/
|
**/
|
||||||
|
|
@ -521,7 +488,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return Range.fromPoints(this.start, this.end);
|
return Range.fromPoints(this.start, this.end);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
|
* Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
|
|
@ -533,38 +500,45 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
|
||||||
return new Range(this.start.row, 0, this.end.row, 0)
|
return new Range(this.start.row, 0, this.end.row, 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
|
* Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
|
||||||
* @param {EditSession} session The `EditSession` to retrieve coordinates from
|
* @param {EditSession} session The `EditSession` to retrieve coordinates from
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
**/
|
**/
|
||||||
this.toScreenRange = function(session) {
|
this.toScreenRange = function(session) {
|
||||||
var screenPosStart =
|
var screenPosStart = session.documentToScreenPosition(this.start);
|
||||||
session.documentToScreenPosition(this.start);
|
var screenPosEnd = session.documentToScreenPosition(this.end);
|
||||||
var screenPosEnd =
|
|
||||||
session.documentToScreenPosition(this.end);
|
|
||||||
|
|
||||||
return new Range(
|
return new Range(
|
||||||
screenPosStart.row, screenPosStart.column,
|
screenPosStart.row, screenPosStart.column,
|
||||||
screenPosEnd.row, screenPosEnd.column
|
screenPosEnd.row, screenPosEnd.column
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* experimental */
|
||||||
|
this.moveBy = function(row, column) {
|
||||||
|
this.start.row += row;
|
||||||
|
this.start.column += column;
|
||||||
|
this.end.row += row;
|
||||||
|
this.end.column += column;
|
||||||
|
};
|
||||||
|
|
||||||
}).call(Range.prototype);
|
}).call(Range.prototype);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns a new `Range` based on the row and column of the given parameters.
|
* Creates and returns a new `Range` based on the row and column of the given parameters.
|
||||||
* @param {Range} start A starting point to use
|
* @param {Range} start A starting point to use
|
||||||
* @param {Range} end An ending point to use
|
* @param {Range} end An ending point to use
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @returns {Range}
|
* @returns {Range}
|
||||||
**/
|
**/
|
||||||
Range.fromPoints = function(start, end) {
|
Range.fromPoints = function(start, end) {
|
||||||
return new Range(start.row, start.column, end.row, end.column);
|
return new Range(start.row, start.column, end.row, end.column);
|
||||||
};
|
};
|
||||||
|
Range.comparePoints = comparePoints;
|
||||||
|
|
||||||
exports.Range = Range;
|
exports.Range = Range;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,30 +30,28 @@
|
||||||
|
|
||||||
define(function(require, exports, module) {
|
define(function(require, exports, module) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
var Range = require("./range").Range;
|
||||||
|
var comparePoints = Range.comparePoints;
|
||||||
|
|
||||||
var RangeList = function() {
|
var RangeList = function() {
|
||||||
this.ranges = [];
|
this.ranges = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
this.comparePoints = function(p1, p2) {
|
this.comparePoints = comparePoints;
|
||||||
return p1.row - p2.row || p1.column - p2.column;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.pointIndex = function(pos, startIndex) {
|
this.pointIndex = function(pos, excludeEdges, startIndex) {
|
||||||
var list = this.ranges;
|
var list = this.ranges;
|
||||||
|
|
||||||
for (var i = startIndex || 0; i < list.length; i++) {
|
for (var i = startIndex || 0; i < list.length; i++) {
|
||||||
var range = list[i];
|
var range = list[i];
|
||||||
var cmp = this.comparePoints(pos, range.end);
|
var cmpEnd = comparePoints(pos, range.end);
|
||||||
|
if (cmpEnd > 0)
|
||||||
if (cmp > 0)
|
|
||||||
continue;
|
continue;
|
||||||
if (cmp == 0)
|
var cmpStart = comparePoints(pos, range.start);
|
||||||
return i;
|
if (cmpEnd === 0)
|
||||||
cmp = this.comparePoints(pos, range.start);
|
return excludeEdges && cmpStart !== 0 ? -i-2 : i;
|
||||||
if (cmp >= 0)
|
if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return -i-1;
|
return -i-1;
|
||||||
|
|
@ -62,17 +60,17 @@ var RangeList = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.add = function(range) {
|
this.add = function(range) {
|
||||||
var startIndex = this.pointIndex(range.start);
|
var excludeEdges = !range.isEmpty();
|
||||||
|
var startIndex = this.pointIndex(range.start, excludeEdges);
|
||||||
if (startIndex < 0)
|
if (startIndex < 0)
|
||||||
startIndex = -startIndex - 1;
|
startIndex = -startIndex - 1;
|
||||||
|
|
||||||
var endIndex = this.pointIndex(range.end, startIndex);
|
var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
|
||||||
|
|
||||||
if (endIndex < 0)
|
if (endIndex < 0)
|
||||||
endIndex = -endIndex - 1;
|
endIndex = -endIndex - 1;
|
||||||
else
|
else
|
||||||
endIndex++;
|
endIndex++;
|
||||||
|
|
||||||
return this.ranges.splice(startIndex, endIndex - startIndex, range);
|
return this.ranges.splice(startIndex, endIndex - startIndex, range);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -95,18 +93,23 @@ var RangeList = function() {
|
||||||
this.merge = function() {
|
this.merge = function() {
|
||||||
var removed = [];
|
var removed = [];
|
||||||
var list = this.ranges;
|
var list = this.ranges;
|
||||||
|
|
||||||
|
list = list.sort(function(a, b) {
|
||||||
|
return comparePoints(a.start, b.start);
|
||||||
|
});
|
||||||
|
|
||||||
var next = list[0], range;
|
var next = list[0], range;
|
||||||
for (var i = 1; i < list.length; i++) {
|
for (var i = 1; i < list.length; i++) {
|
||||||
range = next;
|
range = next;
|
||||||
next = list[i];
|
next = list[i];
|
||||||
var cmp = this.comparePoints(range.end, next.start);
|
var cmp = comparePoints(range.end, next.start);
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (cmp == 0 && !(range.isEmpty() || next.isEmpty()))
|
if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (this.comparePoints(range.end, next.end) < 0) {
|
if (comparePoints(range.end, next.end) < 0) {
|
||||||
range.end.row = next.end.row;
|
range.end.row = next.end.row;
|
||||||
range.end.column = next.end.column;
|
range.end.column = next.end.column;
|
||||||
}
|
}
|
||||||
|
|
@ -116,6 +119,8 @@ var RangeList = function() {
|
||||||
next = range;
|
next = range;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.ranges = list;
|
||||||
|
|
||||||
return removed;
|
return removed;
|
||||||
};
|
};
|
||||||
|
|
@ -199,10 +204,16 @@ var RangeList = function() {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (r.start.row == startRow && r.start.column >= start.column ) {
|
if (r.start.row == startRow && r.start.column >= start.column ) {
|
||||||
|
|
||||||
r.start.column += colDiff;
|
r.start.column += colDiff;
|
||||||
r.start.row += lineDif;
|
r.start.row += lineDif;
|
||||||
}
|
}
|
||||||
if (r.end.row == startRow && r.end.column >= start.column) {
|
if (r.end.row == startRow && r.end.column >= start.column) {
|
||||||
|
// special handling for the case when two ranges share an edge
|
||||||
|
if (r.end.column == start.column && colDiff > 0 && i < n - 1) {
|
||||||
|
if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
|
||||||
|
r.end.column -= colDiff;
|
||||||
|
}
|
||||||
r.end.column += colDiff;
|
r.end.column += colDiff;
|
||||||
r.end.row += lineDif;
|
r.end.row += lineDif;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,26 @@ module.exports = {
|
||||||
assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2);
|
assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2);
|
||||||
assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4);
|
assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"test: rangeList pointIndex excludeEdges": function() {
|
||||||
|
var rangeList = new RangeList();
|
||||||
|
rangeList.ranges = [
|
||||||
|
new Range(1,2,3,4),
|
||||||
|
new Range(4,2,5,4),
|
||||||
|
new Range(8,8,9,9),
|
||||||
|
new Range(10,10,10,10)
|
||||||
|
];
|
||||||
|
|
||||||
|
assert.equal(rangeList.pointIndex({row: 0, column: 1}, true), -1);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 1, column: 2}, true), -1);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 1, column: 3}, true), 0);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 3, column: 4}, true), -2);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 4, column: 1}, true), -2);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 5, column: 1}, true), 1);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 8, column: 9}, true), 2);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 10, column: 10}, true), 3);
|
||||||
|
assert.equal(rangeList.pointIndex({row: 18, column: 9}, true), -5);
|
||||||
|
},
|
||||||
|
|
||||||
"test: rangeList add": function() {
|
"test: rangeList add": function() {
|
||||||
var rangeList = new RangeList();
|
var rangeList = new RangeList();
|
||||||
|
|
@ -153,7 +173,6 @@ module.exports = {
|
||||||
rangeList.substractPoint({row: 6, column: 7});
|
rangeList.substractPoint({row: 6, column: 7});
|
||||||
assert.equal(rangeList.ranges.length, 2);
|
assert.equal(rangeList.ranges.length, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -85,11 +85,12 @@ var TokenIterator = function(session, initialRow, initialColumn) {
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
**/
|
**/
|
||||||
this.stepForward = function() {
|
this.stepForward = function() {
|
||||||
var rowCount = this.$session.getLength();
|
|
||||||
this.$tokenIndex += 1;
|
this.$tokenIndex += 1;
|
||||||
|
var rowCount;
|
||||||
while (this.$tokenIndex >= this.$rowTokens.length) {
|
while (this.$tokenIndex >= this.$rowTokens.length) {
|
||||||
this.$row += 1;
|
this.$row += 1;
|
||||||
|
if (!rowCount)
|
||||||
|
rowCount = this.$session.getLength();
|
||||||
if (this.$row >= rowCount) {
|
if (this.$row >= rowCount) {
|
||||||
this.$row = rowCount - 1;
|
this.$row = rowCount - 1;
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue