diff --git a/demo/demo.js b/demo/demo.js
index 542b6087..0437c78c 100644
--- a/demo/demo.js
+++ b/demo/demo.js
@@ -84,6 +84,7 @@ exports.launch = function(env) {
}
docs.plain = new EditSession(loreIpsum);
docs.plain.setUseWrapMode(true);
+ docs.plain.setWrapLimitRange(80, 80)
docs.plain.setMode(new TextMode());
docs.plain.setUndoManager(new UndoManager());
@@ -189,7 +190,7 @@ exports.launch = function(env) {
if (!doc.getUseWrapMode()) {
wrapModeEl.value = "off";
} else {
- wrapModeEl.value = doc.getWrapLimit();
+ wrapModeEl.value = doc.getWrapLimitRange().min || "free";
}
env.editor.focus();
});
@@ -220,12 +221,17 @@ exports.launch = function(env) {
break;
case "40":
session.setUseWrapMode(true);
- session.setWrapLimit(40);
+ session.setWrapLimitRange(40, 40);
renderer.setPrintMarginColumn(40);
break;
case "80":
session.setUseWrapMode(true);
- session.setWrapLimit(80);
+ session.setWrapLimitRange(80, 80);
+ renderer.setPrintMarginColumn(80);
+ break;
+ case "free":
+ session.setUseWrapMode(true);
+ session.setWrapLimitRange(null, null);
renderer.setPrintMarginColumn(80);
break;
}
diff --git a/editor.html b/editor.html
index c8d0ebec..d4557f3b 100644
--- a/editor.html
+++ b/editor.html
@@ -97,6 +97,7 @@
+
diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js
index d06147ae..98f382bc 100644
--- a/lib/ace/edit_session.js
+++ b/lib/ace/edit_session.js
@@ -642,6 +642,10 @@ var EditSession = function(text, mode) {
// WRAPMODE
this.$wrapLimit = 80;
this.$useWrapMode = false;
+ this.$wrapLimitRange = {
+ min : null,
+ max : null
+ };
this.setUseWrapMode = function(useWrapMode) {
if (useWrapMode != this.$useWrapMode) {
@@ -666,21 +670,61 @@ var EditSession = function(text, mode) {
return this.$useWrapMode;
};
- this.setWrapLimit = function(wrapLimit) {
- if (wrapLimit != this.$wrapLimit) {
- this.$wrapLimit = wrapLimit;
+ // Allow the wrap limit to move freely between min and max. Either
+ // parameter can be null to allow the wrap limit to be unconstrained
+ // in that direction. Or set both parameters to the same number to pin
+ // the limit to that value.
+ this.setWrapLimitRange = function(min, max) {
+ if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
+ this.$wrapLimitRange.min = min;
+ this.$wrapLimitRange.max = max;
this.$modified = true;
- if (this.$useWrapMode) {
- this.$updateWrapData(0, this.getLength() - 1);
- }
+ // This will force a recalculation of the wrap limit
this._dispatchEvent("changeWrapMode");
}
};
+ // This should generally only be called by the renderer when a resize
+ // is detected.
+ this.adjustWrapLimit = function(desiredLimit) {
+ var wrapLimit = this.$constrainWrapLimit(desiredLimit);
+ if (wrapLimit != this.$wrapLimit && wrapLimit > 0) {
+ this.$wrapLimit = wrapLimit;
+ this.$modified = true;
+ if (this.$useWrapMode) {
+ this.$updateWrapData(0, this.getLength() - 1);
+ this._dispatchEvent("changeWrapLimit");
+ }
+ return true;
+ }
+ return false;
+ };
+
+ this.$constrainWrapLimit = function(wrapLimit) {
+ var min = this.$wrapLimitRange.min;
+ if (min)
+ wrapLimit = Math.max(min, wrapLimit);
+
+ var max = this.$wrapLimitRange.max;
+ if (max)
+ wrapLimit = Math.min(max, wrapLimit);
+
+ // What would a limit of 0 even mean?
+ return Math.max(1, wrapLimit);
+ };
+
this.getWrapLimit = function() {
return this.$wrapLimit;
};
+ this.getWrapLimitRange = function() {
+ // Avoid unexpected mutation by returning a copy
+ return {
+ min : this.$wrapLimitRange.min,
+ max : this.$wrapLimitRange.max
+ };
+ };
+
this.$updateWrapDataOnChange = function(e) {
if (!this.$useWrapMode) {
return;
diff --git a/lib/ace/editor.js b/lib/ace/editor.js
index a0669372..685ee10a 100644
--- a/lib/ace/editor.js
+++ b/lib/ace/editor.js
@@ -126,6 +126,7 @@ var Editor =function(renderer, session) {
this.session.removeEventListener("change", this.$onDocumentChange);
this.session.removeEventListener("changeMode", this.$onDocumentModeChange);
this.session.removeEventListener("changeTabSize", this.$onDocumentChangeTabSize);
+ this.session.removeEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
this.session.removeEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
this.session.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
this.session.removeEventListener("changeAnnotation", this.$onDocumentChangeAnnotation);
@@ -149,6 +150,9 @@ var Editor =function(renderer, session) {
this.$onDocumentChangeTabSize = this.renderer.updateText.bind(this.renderer);
session.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
+ this.$onDocumentChangeWrapLimit = this.onDocumentChangeWrapLimit.bind(this);
+ session.addEventListener("changeWrapLimit", this.$onDocumentChangeWrapLimit);
+
this.$onDocumentChangeWrapMode = this.onDocumentChangeWrapMode.bind(this);
session.addEventListener("changeWrapMode", this.$onDocumentChangeWrapMode);
@@ -348,11 +352,15 @@ var Editor =function(renderer, session) {
this.renderer.setTokenizer(this.bgTokenizer);
};
- this.onDocumentChangeWrapMode = function() {
+ this.onDocumentChangeWrapLimit = function() {
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
this.renderer.updateFull();
};
+ this.onDocumentChangeWrapMode = function() {
+ this.renderer.onResize(true);
+ };
+
this.getCopyText = function() {
if (!this.selection.isEmpty()) {
return this.session.getTextRange(this.getSelectionRange());
diff --git a/lib/ace/keyboard/state_handler.js b/lib/ace/keyboard/state_handler.js
index b887cd4d..5861ad23 100644
--- a/lib/ace/keyboard/state_handler.js
+++ b/lib/ace/keyboard/state_handler.js
@@ -197,7 +197,7 @@ StateHandler.prototype = {
// If we pressed any command key but no other key, then ignore the input.
// Otherwise "shift-" is added to the buffer, and later on "shift-g"
// which results in "shift-shift-g" which doesn't make senese.
- if (hashId != 0 && (key == "" || key == String.fromCharCode(0))) {
+ if (hashId != 0 && (key == "" || String.fromCharCode(0))) {
return null;
}
diff --git a/lib/ace/test/edit_session_test.js b/lib/ace/test/edit_session_test.js
index de6d8f39..3ab24e94 100644
--- a/lib/ace/test/edit_session_test.js
+++ b/lib/ace/test/edit_session_test.js
@@ -169,14 +169,14 @@ var Test = {
var wrapLimit = 12;
var session = new EditSession(["foo bar foo bar"]);
session.setUseWrapMode(true);
- session.setWrapLimit(12);
+ session.setWrapLimitRange(12, 12);
assert.position(session.documentToScreenPosition(0, 11), 0, 11);
assert.position(session.documentToScreenPosition(0, 12), 1, 0);
session = new EditSession(["ぁぁa"]);
session.setUseWrapMode(true);
- session.setWrapLimit(2);
+ session.setWrapLimitRange(2, 2);
assert.position(session.documentToScreenPosition(0, 1), 1, 0);
assert.position(session.documentToScreenPosition(0, 2), 2, 0);
assert.position(session.documentToScreenPosition(0, 4), 2, 1);
@@ -202,7 +202,7 @@ var Test = {
var wrapLimit = 12;
var session = new EditSession(["foo bar foo bar"]);
session.setUseWrapMode(true);
- session.setWrapLimit(12);
+ session.setWrapLimitRange(12, 12);
assert.position(session.screenToDocumentPosition(1, 0), 0, 12);
assert.position(session.screenToDocumentPosition(0, 11), 0, 11);
@@ -378,7 +378,7 @@ var Test = {
var document = session.getDocument();
session.setUseWrapMode(true);
- session.setWrapLimit(3);
+ session.setWrapLimitRange(3, 3);
// Test if wrapData is there and was computed.
assert.equal(session.$wrapData.length, 2);
diff --git a/lib/ace/theme/twilight.js b/lib/ace/theme/twilight.js
index 600ba519..2fe50e40 100644
--- a/lib/ace/theme/twilight.js
+++ b/lib/ace/theme/twilight.js
@@ -89,6 +89,9 @@ define(function(require, exports, module) {
.ace-twilight.normal-mode .ace_cursor.ace_overwrite {\
border: 1px solid #FFE300;\
background: #766B13;\
+}\
+.ace-twilight.normal-mode .ace_cursor-layer {\
+ z-index: 0;\
}\
\
.ace-twilight .ace_marker-layer .ace_selection {\
diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js
index a432bd3f..c7fa8d63 100644
--- a/lib/ace/virtual_renderer.js
+++ b/lib/ace/virtual_renderer.js
@@ -210,6 +210,13 @@ var VirtualRenderer = function(container, theme) {
var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0;
this.scroller.style.left = gutterWidth + "px";
this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px";
+
+ if (this.session.getUseWrapMode()) {
+ var limit = Math.floor(this.scroller.clientWidth / this.characterWidth);
+ if (this.session.adjustWrapLimit(limit) || force) {
+ changes = changes | this.CHANGE_FULL;
+ }
+ }
}
this.$size.scrollerWidth = this.scroller.clientWidth;
|