diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 5a375412..7a2f2e76 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -286,7 +286,7 @@ env.editor.commands.addCommands([{ name: "gotoline", bindKey: {win: "Ctrl-L", mac: "Command-L"}, exec: function(editor, line) { - if (typeof needle == "object") { + if (typeof line == "object") { var arg = this.name + " " + editor.getCursorPosition().row; editor.cmdLine.setValue(arg, 1) editor.cmdLine.focus() @@ -328,7 +328,7 @@ cmdLine.commands.bindKeys({ }, }) -cmdLine.commands.removeCommands(["find", "goToLine", "findAll", "replace", "replaceAll"]) +cmdLine.commands.removeCommands(["find", "gotoline", "findall", "replace", "replaceall"]) /** * This demonstrates how you can define commands and bind shortcuts to them. @@ -557,6 +557,10 @@ bindCheckbox("show_hidden", function(checked) { env.editor.setShowInvisibles(checked); }); +bindCheckbox("display_indent_guides", function(checked) { + env.editor.setDisplayIndentGuides(checked); +}); + bindCheckbox("show_gutter", function(checked) { env.editor.renderer.setShowGutter(checked); }); diff --git a/kitchen-sink.html b/kitchen-sink.html index 6712e59d..825a6194 100644 --- a/kitchen-sink.html +++ b/kitchen-sink.html @@ -59,32 +59,36 @@ @@ -139,8 +143,8 @@ - - +
+ + + +
@@ -162,6 +166,13 @@
+ + + +
@@ -218,7 +229,7 @@ - +
diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 4cf4ef80..b5256e1a 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -165,7 +165,7 @@ var Editor = function(renderer, session) { this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this); session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate); - this.$onChangeTabSize = this.renderer.updateText.bind(this.renderer); + this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer); session.addEventListener("changeTabSize", this.$onChangeTabSize); this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); @@ -991,9 +991,6 @@ var Editor = function(renderer, session) { * If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor. **/ this.setShowInvisibles = function(showInvisibles) { - if (this.getShowInvisibles() == showInvisibles) - return; - this.renderer.setShowInvisibles(showInvisibles); }; @@ -1006,6 +1003,14 @@ var Editor = function(renderer, session) { return this.renderer.getShowInvisibles(); }; + this.setDisplayIndentGuides = function(display) { + this.renderer.setDisplayIndentGuides(display); + }; + + this.getDisplayIndentGuides = function() { + return this.renderer.getDisplayIndentGuides(); + }; + /** * Editor.setShowPrintMargin(showPrintMargin) * - showPrintMargin (Boolean): Specifies whether or not to show the print margin diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js index aca3fd9e..08cc4004 100644 --- a/lib/ace/ext/static_highlight.js +++ b/lib/ace/ext/static_highlight.js @@ -72,11 +72,10 @@ exports.render = function(input, mode, theme, lineStart, disableGutter) { var length = session.getLength(); for(var ix = 0; ix < length; ix++) { - var lineTokens = session.getTokens(ix); stringBuilder.push("
"); if (!disableGutter) stringBuilder.push("" + (ix + lineStart) + ""); - textLayer.$renderLine(stringBuilder, 0, lineTokens, true); + textLayer.$renderLine(stringBuilder, 0, true, false); stringBuilder.push("
"); } diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index e96dff28..3ca19683 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -196,6 +196,7 @@ var Text = function(parentEl) { this.setSession = function(session) { this.session = session; + this.$computeTabString(); }; this.showInvisibles = false; @@ -204,28 +205,52 @@ var Text = function(parentEl) { return false; this.showInvisibles = showInvisibles; + this.$computeTabString(); + return true; + }; + + this.displayIndentGuides = true; + this.setDisplayIndentGuides = function(display) { + if (this.displayIndentGuides == display) + return false; + + this.displayIndentGuides = display; + this.$computeTabString(); return true; }; this.$tabStrings = []; + this.onChangeTabSize = this.$computeTabString = function() { var tabSize = this.session.getTabSize(); + this.tabSize = tabSize; var tabStr = this.$tabStrings = [0]; for (var i = 1; i < tabSize + 1; i++) { if (this.showInvisibles) { tabStr.push("" + this.TAB_CHAR - + new Array(i).join(" ") + + Array(i).join(" ") + ""); } else { tabStr.push(new Array(i+1).join(" ")); } } + if (this.displayIndentGuides) { + this.$indentGuideRe = /\s\S| \t|\t |\s$/; + var className = "ace_indent-guide"; + var content = Array(this.tabSize + 1).join(" "); + var tabContent = content; + if (this.showInvisibles) { + className += " ace_invisible"; + tabContent = this.TAB_CHAR + content.substr(6); + } + this.$tabStrings[" "] = "" + content + ""; + this.$tabStrings["\t"] = "" + tabContent + ""; + } }; this.updateLines = function(config, firstRow, lastRow) { - this.$computeTabString(); // Due to wrap line changes there can be new lines if e.g. // the line to updated wrapped in the meantime. if (this.config.lastRow != config.lastRow || @@ -253,22 +278,32 @@ var Text = function(parentEl) { lineElementsIdx ++; } - for (var i=first; i<=last; i++) { + var row = first; + var foldLine = this.session.getNextFoldLine(row); + var foldStart = foldLine ? foldLine.start.row : Infinity; + + while (true) { + if (row > foldStart) { + row = foldLine.end.row+1; + foldLine = this.session.getNextFoldLine(row, foldLine); + foldStart = foldLine ? foldLine.start.row :Infinity; + } + if (row > last) + break; + var lineElement = lineElements[lineElementsIdx++]; - if (!lineElement) - continue; - - var html = []; - var tokens = this.session.getTokens(i); - this.$renderLine(html, i, tokens, !this.$useLineGroups()); - lineElement = dom.setInnerHtml(lineElement, html.join("")); - - i = this.session.getRowFoldEnd(i); + if (lineElement) { + var html = []; + this.$renderLine( + html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false + ); + dom.setInnerHtml(lineElement, html.join("")); + } + row++; } }; this.scrollLines = function(config) { - this.$computeTabString(); var oldConfig = this.config; this.config = config; @@ -321,8 +356,7 @@ var Text = function(parentEl) { var html = []; // Get the tokens per line as there might be some lines in between // beeing folded. - var tokens = this.session.getTokens(row); - this.$renderLine(html, row, tokens, false); + this.$renderLine(html, row, false, row == foldStart ? foldLine : false); // don't use setInnerHtml since we are working with an empty DIV container.innerHTML = html.join(""); @@ -341,7 +375,6 @@ var Text = function(parentEl) { }; this.update = function(config) { - this.$computeTabString(); this.config = config; var html = []; @@ -363,10 +396,7 @@ var Text = function(parentEl) { if (this.$useLineGroups()) html.push("
") - // Get the tokens per line as there might be some lines in between - // beeing folded. - var tokens = this.session.getTokens(row); - this.$renderLine(html, row, tokens, false); + this.$renderLine(html, row, false, row == foldStart ? foldLine : false); if (this.$useLineGroups()) html.push("
"); // end the line group @@ -429,38 +459,44 @@ var Text = function(parentEl) { return screenColumn + value.length; }; - this.$renderLineCore = function(stringBuilder, lastRow, tokens, splits, onlyContents) { + this.renderIndentGuide = function(stringBuilder, value) { + var cols = value.search(this.$indentGuideRe); + if (cols <= 0) + return value; + if (value[0] == " ") { + cols -= cols % this.tabSize; + stringBuilder.push(Array(cols/this.tabSize + 1).join(this.$tabStrings[" "])); + return value.substr(cols); + } else if (value[0] == "\t") { + stringBuilder.push(Array(cols + 1).join(this.$tabStrings["\t"])); + return value.substr(cols); + } + return value; + }; + + this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) { var chars = 0; var split = 0; - var splitChars; + var splitChars = splits[0]; var screenColumn = 0; - var self = this; - - if (!splits || splits.length == 0) - splitChars = Number.MAX_VALUE; - else - splitChars = splits[0]; - - if (!onlyContents) { - stringBuilder.push("
" - ); - } for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; var value = token.value; + if (i == 0 && this.displayIndentGuides) { + chars = value.length; + value = this.renderIndentGuide(stringBuilder, value); + if (!value) + continue; + chars -= value.length; + } if (chars + value.length < splitChars) { - screenColumn = self.$renderToken( - stringBuilder, screenColumn, token, value - ); + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); chars += value.length; - } - else { + } else { while (chars + value.length >= splitChars) { - screenColumn = self.$renderToken( + screenColumn = this.$renderToken( stringBuilder, screenColumn, token, value.substring(0, splitChars - chars) ); @@ -470,8 +506,7 @@ var Text = function(parentEl) { if (!onlyContents) { stringBuilder.push("
", "
" + this.config.lineHeight, "px'>" ); } @@ -481,37 +516,70 @@ var Text = function(parentEl) { } if (value.length != 0) { chars += value.length; - screenColumn = self.$renderToken( + screenColumn = this.$renderToken( stringBuilder, screenColumn, token, value ); } } } + }; + + this.$renderSimpleLine = function(stringBuilder, tokens) { + var screenColumn = 0; + var token = tokens[0]; + var value = token.value; + if (this.displayIndentGuides) + value = this.renderIndentGuide(stringBuilder, value); + if (value) + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); + for (var i = 1; i < tokens.length; i++) { + token = tokens[i]; + value = token.value; + screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value); + } + }; + + // row is either first row of foldline or not in fold + this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) { + if (!foldLine && foldLine != false) + foldLine = this.session.getFoldLine(row); + + if (foldLine) + var tokens = this.$getFoldLineTokens(row, foldLine); + else + var tokens = this.session.getTokens(row); + + + if (!onlyContents) { + stringBuilder.push( + "
" + ); + } + + if (tokens.length) { + var splits = this.session.getRowSplitData(row); + if (splits && splits.length) + this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents); + else + this.$renderSimpleLine(stringBuilder, tokens); + } if (this.showInvisibles) { - if (lastRow !== this.session.getLength() - 1) - stringBuilder.push("" + this.EOL_CHAR + ""); - else - stringBuilder.push("" + this.EOF_CHAR + ""); + if (foldLine) + row = foldLine.end.row + + stringBuilder.push( + "", + row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR, + "" + ); } if (!onlyContents) stringBuilder.push("
"); }; - this.$renderLine = function(stringBuilder, row, tokens, onlyContents) { - // Check if the line to render is folded or not. If not, things are - // simple, otherwise, we need to fake some things... - if (!this.session.isRowFolded(row)) { - var splits = this.session.getRowSplitData(row); - this.$renderLineCore(stringBuilder, row, tokens, splits, onlyContents); - } else { - this.$renderFoldLine(stringBuilder, row, tokens, onlyContents); - } - }; - - this.$renderFoldLine = function(stringBuilder, row, tokens, onlyContents) { + this.$getFoldLineTokens = function(row, foldLine) { var session = this.session; - var foldLine = session.getFoldLine(row); var renderTokens = []; function addTokens(tokens, from, to) { @@ -552,6 +620,7 @@ var Text = function(parentEl) { } } + var tokens = session.getTokens(row); foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { if (placeholder) { renderTokens.push({ @@ -567,9 +636,7 @@ var Text = function(parentEl) { } }, foldLine.end.row, this.session.getLine(foldLine.end.row).length); - // splits for foldline are stored at its' first row - var splits = this.session.$useWrapMode ? this.session.$wrapData[row] : null; - this.$renderLineCore(stringBuilder, row, renderTokens, splits, onlyContents); + return renderTokens; }; this.$useLineGroups = function() { diff --git a/lib/ace/layer/text_test.js b/lib/ace/layer/text_test.js index bd4f9cbf..38708e9c 100644 --- a/lib/ace/layer/text_test.js +++ b/lib/ace/layer/text_test.js @@ -67,35 +67,61 @@ module.exports = { this.textLayer.$computeTabString(); // row with hard tabs - var row = 0; - var tokens = this.session.getTokens(row); var stringBuilder = []; - this.textLayer.$renderLine(stringBuilder, row, tokens); + this.textLayer.$renderLine(stringBuilder, 0); // row with soft tabs - row = 1; - tokens = this.session.getTokens(row); var stringBuilder2 = []; - this.textLayer.$renderLine(stringBuilder2, row, tokens); + this.textLayer.$renderLine(stringBuilder2, 1); assert.equal(stringBuilder.join(""), stringBuilder2.join("")); }, "test rendering width of ideographic space (U+3000)" : function() { this.session.setValue("\u3000"); - var tokens = this.session.getTokens(0); var stringBuilder = []; - this.textLayer.$renderLine(stringBuilder, 0, tokens, true); + this.textLayer.$renderLine(stringBuilder, 0, true); assert.equal(stringBuilder.join(""), ""); this.textLayer.setShowInvisibles(true); var stringBuilder = []; - this.textLayer.$renderLine(stringBuilder, 0, tokens, true); + this.textLayer.$renderLine(stringBuilder, 0, true); assert.equal( stringBuilder.join(""), "" + this.textLayer.SPACE_CHAR + "" + "\xB6" ); + }, + + "test rendering of indent guides" : function() { + var textLayer = this.textLayer + var EOL = "" + textLayer.EOL_CHAR + ""; + var SPACE = function(i) {return Array(i+1).join(" ")} + var TAB = function(i) {return textLayer.TAB_CHAR + SPACE(i-1)} + function testRender(results) { + for (var i = results.length; i--; ) { + var stringBuilder = []; + textLayer.$renderLine(stringBuilder, i, true); + assert.equal(stringBuilder.join(""), results[i]); + } + } + + this.session.setValue(" \n\t\tf\n "); + testRender([ + "" + SPACE(4) + "" + SPACE(2), + "" + SPACE(4) + "" + SPACE(4) + "f", + SPACE(3) + ]); + this.textLayer.setShowInvisibles(true); + testRender([ + "" + SPACE(4) + "" + SPACE(2) + EOL, + "" + TAB(4) + "" + TAB(4) + "f" + EOL, + ]); + this.textLayer.setDisplayIndentGuides(false); + testRender([ + SPACE(6) + EOL, + "" + TAB(4) + "" + TAB(4) + "f" + EOL + ]); } }; diff --git a/lib/ace/test/mockrenderer.js b/lib/ace/test/mockrenderer.js index 91b1c1ad..a0f031a9 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -154,6 +154,9 @@ MockRenderer.prototype.getScrollTopRow = function() { MockRenderer.prototype.draw = function() { }; +MockRenderer.prototype.onChangeTabSize = function(startRow, endRow) { +}; + MockRenderer.prototype.updateLines = function(startRow, endRow) { }; diff --git a/lib/ace/theme/chrome.css b/lib/ace/theme/chrome.css index 425071dc..26863569 100644 --- a/lib/ace/theme/chrome.css +++ b/lib/ace/theme/chrome.css @@ -156,4 +156,8 @@ color:#FD971F; .ace-chrome .ace_entity.ace_other.ace_attribute-name{ color: #994409; -} \ No newline at end of file +} + +.ace-chrome .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} diff --git a/lib/ace/theme/clouds.css b/lib/ace/theme/clouds.css index 1622cec2..80364f41 100644 --- a/lib/ace/theme/clouds.css +++ b/lib/ace/theme/clouds.css @@ -115,4 +115,8 @@ .ace-clouds .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-clouds .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/clouds_midnight.css b/lib/ace/theme/clouds_midnight.css index b42113d7..22b52c99 100644 --- a/lib/ace/theme/clouds_midnight.css +++ b/lib/ace/theme/clouds_midnight.css @@ -116,4 +116,8 @@ background-color:#E92E2E; .ace-clouds-midnight .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-clouds-midnight .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQlJT8z1BeXv4fAA2KA6+h9Z+2AAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/cobalt.css b/lib/ace/theme/cobalt.css index 2a4aaed0..60fda700 100644 --- a/lib/ace/theme/cobalt.css +++ b/lib/ace/theme/cobalt.css @@ -142,4 +142,8 @@ background-color:#001221; .ace-cobalt .ace_markup.ace_list { background-color:#130D26; +} + +.ace-cobalt .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgUHL4zzBz5sz/AA80BCzv+WXhAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/crimson_editor.css b/lib/ace/theme/crimson_editor.css index 1ed6783a..433ed071 100644 --- a/lib/ace/theme/crimson_editor.css +++ b/lib/ace/theme/crimson_editor.css @@ -148,4 +148,8 @@ .ace-crimson-editor .ace_string.ace_regex { color: rgb(192, 0, 192); +} + +.ace-crimson-editor .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/dawn.css b/lib/ace/theme/dawn.css index 94cbd1c3..d26edebf 100644 --- a/lib/ace/theme/dawn.css +++ b/lib/ace/theme/dawn.css @@ -146,4 +146,8 @@ color:#5A525F; .ace-dawn .ace_markup.ace_list { color:#693A17; +} + +.ace-dawn .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4+fPnf4ZVq1b9BwAkVQboFQv98gAAAABJRU5ErkJggg==) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/dreamweaver.css b/lib/ace/theme/dreamweaver.css index 46ac475c..b01025a1 100644 --- a/lib/ace/theme/dreamweaver.css +++ b/lib/ace/theme/dreamweaver.css @@ -179,4 +179,8 @@ .ace-dreamweaver .ace_string.ace_regex { color: rgb(255, 0, 0) +} + +.ace-dreamweaver .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/eclipse.css b/lib/ace/theme/eclipse.css index f02283b2..55c34f89 100644 --- a/lib/ace/theme/eclipse.css +++ b/lib/ace/theme/eclipse.css @@ -99,4 +99,8 @@ .ace-eclipse .ace_marker-layer .ace_active_line { background: rgb(232, 242, 254); +} + +.ace-eclipse .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/github.css b/lib/ace/theme/github.css index 935990fa..ac4f29ac 100644 --- a/lib/ace/theme/github.css +++ b/lib/ace/theme/github.css @@ -130,4 +130,8 @@ .ace-github .ace_print_margin { width: 1px; background: #e8e8e8; +} + +.ace-github .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/idle_fingers.css b/lib/ace/theme/idle_fingers.css index ba753f20..00e8a81e 100644 --- a/lib/ace/theme/idle_fingers.css +++ b/lib/ace/theme/idle_fingers.css @@ -133,5 +133,9 @@ color:#BC9458; .ace-idle-fingers .ace_collab.ace_user1 { color:#323232; -background-color:#FFF980; + background-color:#FFF980; +} + +.ace-idle-fingers .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjL6zzBz5sz/ABEUBGCqhK6UAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/kr_theme.css b/lib/ace/theme/kr_theme.css index 3e5f7332..ede07375 100644 --- a/lib/ace/theme/kr_theme.css +++ b/lib/ace/theme/kr_theme.css @@ -137,4 +137,8 @@ color:#706D5B; .ace-kr-theme .ace_markup.ace_list { background-color:#0F0040; +} + +.ace-kr-theme .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPg5uL8zzBz5sz/AA1WA+hUYIqjAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/merbivore.css b/lib/ace/theme/merbivore.css index 1048600a..4ee7fa73 100644 --- a/lib/ace/theme/merbivore.css +++ b/lib/ace/theme/merbivore.css @@ -137,4 +137,8 @@ color:#AD2EA4; .ace-merbivore .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-merbivore .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQExP7zzBz5sz/AA50BAyDznYhAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/merbivore_soft.css b/lib/ace/theme/merbivore_soft.css index 8e1d24a5..55e401b1 100644 --- a/lib/ace/theme/merbivore_soft.css +++ b/lib/ace/theme/merbivore_soft.css @@ -143,4 +143,8 @@ color:#AC4BB8; .ace-merbivore-soft .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-merbivore-soft .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQkZH5zzBz5sz/AA8EBB6crd1rAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/mono_industrial.css b/lib/ace/theme/mono_industrial.css index a8af1bcd..8f9056bb 100644 --- a/lib/ace/theme/mono_industrial.css +++ b/lib/ace/theme/mono_industrial.css @@ -145,4 +145,8 @@ background-color:#151C19; .ace-mono-industrial .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-mono-industrial .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ0tH4zzBz5sz/ABAOBECKH+evAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/monokai.css b/lib/ace/theme/monokai.css index cae92734..7c3728ea 100644 --- a/lib/ace/theme/monokai.css +++ b/lib/ace/theme/monokai.css @@ -142,4 +142,8 @@ color:#FD971F; .ace-monokai .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-monokai .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ11D6z7Bq1ar/ABCKBG6g04U2AAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/pastel_on_dark.css b/lib/ace/theme/pastel_on_dark.css index e220569c..104d5168 100644 --- a/lib/ace/theme/pastel_on_dark.css +++ b/lib/ace/theme/pastel_on_dark.css @@ -147,4 +147,8 @@ color:#D2A8A1; .ace-pastel-on-dark .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-pastel-on-dark .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0dD4z9DR0fEfAA+vBBPqhbn1AAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/solarized_dark.css b/lib/ace/theme/solarized_dark.css index df259e8b..f55a1b1e 100644 --- a/lib/ace/theme/solarized_dark.css +++ b/lib/ace/theme/solarized_dark.css @@ -128,4 +128,8 @@ color:#657B83; .ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-solarized-dark .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db7zzBz5sz/AA82BCv7wOIDAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/solarized_light.css b/lib/ace/theme/solarized_light.css index 1bd26c83..d269ecc8 100644 --- a/lib/ace/theme/solarized_light.css +++ b/lib/ace/theme/solarized_light.css @@ -127,4 +127,8 @@ .ace-solarized-light .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-solarized-light .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4++3xf4ZVq1b9BwAjxwbT1g3hiwAAAABJRU5ErkJggg==) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/textmate.css b/lib/ace/theme/textmate.css index 748f5d1d..7f9f5538 100644 --- a/lib/ace/theme/textmate.css +++ b/lib/ace/theme/textmate.css @@ -163,3 +163,7 @@ .ace-tm .ace_string.ace_regex { color: rgb(255, 0, 0) } + +.ace-tm .ace_indent-guide { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y; +} diff --git a/lib/ace/theme/tomorrow.css b/lib/ace/theme/tomorrow.css index e65d3a5a..a9c04182 100644 --- a/lib/ace/theme/tomorrow.css +++ b/lib/ace/theme/tomorrow.css @@ -161,4 +161,8 @@ background-color:#8959A8; .ace-tomorrow .ace_markup.ace_heading { color:#718C00; +} + +.ace-tomorrow .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night.css b/lib/ace/theme/tomorrow_night.css index 3ac694f5..137e35d8 100644 --- a/lib/ace/theme/tomorrow_night.css +++ b/lib/ace/theme/tomorrow_night.css @@ -161,4 +161,8 @@ background-color:#B798BF; .ace-tomorrow-night .ace_markup.ace_heading { color:#B5BD68; +} + +.ace-tomorrow-night .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQlVf8z7Bq1ar/AA/hBFp7egmpAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_blue.css b/lib/ace/theme/tomorrow_night_blue.css index 1bcc86c3..7a8354bb 100644 --- a/lib/ace/theme/tomorrow_night_blue.css +++ b/lib/ace/theme/tomorrow_night_blue.css @@ -161,4 +161,8 @@ background-color:#EBBBFF; .ace-tomorrow-night-blue .ace_markup.ace_heading { color:#D1F1A9; +} + +.ace-tomorrow-night-blue .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgUAn8z7Bq1ar/ABBUBHJ4/r3JAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_bright.css b/lib/ace/theme/tomorrow_night_bright.css index 7cee6607..44d944a5 100644 --- a/lib/ace/theme/tomorrow_night_bright.css +++ b/lib/ace/theme/tomorrow_night_bright.css @@ -161,4 +161,8 @@ background-color:#B798BF; .ace-tomorrow-night-bright .ace_markup.ace_heading { color:#B9CA4A; +} + +.ace-tomorrow-night-bright .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGD4z7Bq1ar/AAz9A/2naJQKAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/tomorrow_night_eighties.css b/lib/ace/theme/tomorrow_night_eighties.css index ce5ef317..1dfd9ead 100644 --- a/lib/ace/theme/tomorrow_night_eighties.css +++ b/lib/ace/theme/tomorrow_night_eighties.css @@ -157,4 +157,8 @@ background-color:#CC99CC; .ace-tomorrow-night-eighties .ace_markup.ace_heading { color:#99CC99; +} + +.ace-tomorrow-night-eighties .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ1dX9z7Bq1ar/ABE1BITwhhuFAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/twilight.css b/lib/ace/theme/twilight.css index 28d1ffa6..6b7df599 100644 --- a/lib/ace/theme/twilight.css +++ b/lib/ace/theme/twilight.css @@ -159,4 +159,8 @@ color:#5F5A60; .ace-twilight .ace_markup.ace_list { color:#F9EE98; +} + +.ace-twilight .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERH5zzBz5sz/AA5EBAYqeZXWAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/theme/vibrant_ink.css b/lib/ace/theme/vibrant_ink.css index 3677a28e..7aebc35c 100644 --- a/lib/ace/theme/vibrant_ink.css +++ b/lib/ace/theme/vibrant_ink.css @@ -138,4 +138,8 @@ color:#99CC99; .ace-vibrant-ink .ace_markup.ace_underline { text-decoration:underline; +} + +.ace-vibrant-ink .ace_indent-guide { + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPg5+f/z7Bq1ar/AA5lBCqoLxsgAAAAAElFTkSuQmCC) right repeat-y; } \ No newline at end of file diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 2b65355f..03555bee 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -105,7 +105,6 @@ var VirtualRenderer = function(container, theme) { this.setHighlightGutterLine(true); this.$gutterLayer = new GutterLayer(this.$gutter); this.$gutterLayer.on("changeGutterWidth", this.onResize.bind(this, true)); - this.setFadeFoldWidgets(true); this.$markerBack = new MarkerLayer(this.content); @@ -250,6 +249,11 @@ var VirtualRenderer = function(container, theme) { this.$loop.schedule(this.CHANGE_LINES); }; + this.onChangeTabSize = function() { + this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER); + this.$textLayer.onChangeTabSize(); + }; + /** * VirtualRenderer.updateText() -> Void * @@ -389,6 +393,15 @@ var VirtualRenderer = function(container, theme) { return this.$textLayer.showInvisibles; }; + this.getDisplayIndentGuides = function() { + return this.$textLayer.displayIndentGuides; + }; + + this.setDisplayIndentGuides = function(display) { + if (this.$textLayer.setDisplayIndentGuides(display)) + this.$loop.schedule(this.CHANGE_TEXT); + }; + this.$showPrintMargin = true; /**