From 7f8892f9a5b8b9079c24e9396395b95b276c2472 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 10 Jun 2012 22:10:35 +0400 Subject: [PATCH 01/11] folds with wrong range shouldn't break renderer --- lib/ace/layer/text.js | 54 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index 92683967..e96dff28 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -131,7 +131,7 @@ var Text = function(parentEl) { container.appendChild(measureNode); } } - + // Size and width can be null if the editor is not visible or // detached from the document if (!this.element.offsetWidth) @@ -153,7 +153,7 @@ var Text = function(parentEl) { return null; return size; - } + } : function() { if (!this.$measureNode) { var measureNode = this.$measureNode = dom.createElement("div"); @@ -178,7 +178,7 @@ var Text = function(parentEl) { container.appendChild(measureNode); } - + var rect = this.$measureNode.getBoundingClientRect(); var size = { @@ -382,7 +382,7 @@ var Text = function(parentEl) { "lparen": true }; - this.$renderToken = function(stringBuilder, screenColumn, token, value) { + this.$renderToken = function(stringBuilder, screenColumn, token, value) { var self = this; var replaceReg = /\t|&|<|( +)|([\u0000-\u0019\u00a0\u1680\u180E\u2000-\u200b\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g; var replaceFunc = function(c, a, b, tabIdx, idx4) { @@ -447,7 +447,7 @@ var Text = function(parentEl) { "'>" ); } - + for (var i = 0; i < tokens.length; i++) { var token = tokens[i]; var value = token.value; @@ -461,12 +461,12 @@ var Text = function(parentEl) { else { while (chars + value.length >= splitChars) { screenColumn = self.$renderToken( - stringBuilder, screenColumn, + stringBuilder, screenColumn, token, value.substring(0, splitChars - chars) ); value = value.substring(splitChars - chars); chars = splitChars; - + if (!onlyContents) { stringBuilder.push("", "
Date: Mon, 11 Jun 2012 11:08:24 +0400 Subject: [PATCH 02/11] size multiline markers with "right" instead of "width" --- lib/ace/layer/marker.js | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index f5999338..127cf7f3 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -73,7 +73,7 @@ var Marker = function(parentEl) { var html = []; - for ( var key in this.markers) { + for (var key in this.markers) { var marker = this.markers[key]; if (!marker.range) { @@ -140,29 +140,25 @@ var Marker = function(parentEl) { } }; - // Draws a multi line marker, where lines span the full width - this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig, type) { + // Draws a multi line marker, where lines span the full width + this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, type) { var padding = type === "background" ? 0 : this.$padding; - var layerWidth = layerConfig.width + 2 * this.$padding - padding; // from selection start to the end of the line - var height = layerConfig.lineHeight; - var width = Math.round(layerWidth - (range.start.column * layerConfig.characterWidth)); - var top = this.$getTop(range.start.row, layerConfig); - var left = Math.round( - padding + range.start.column * layerConfig.characterWidth - ); + var height = config.lineHeight; + var top = this.$getTop(range.start.row, config); + var left = Math.round(padding + range.start.column * config.characterWidth); stringBuilder.push( "
" ); // from start of the last line to the selection end - top = this.$getTop(range.end.row, layerConfig); - width = Math.round(range.end.column * layerConfig.characterWidth); + top = this.$getTop(range.end.row, config); + var width = Math.round(range.end.column * config.characterWidth); stringBuilder.push( "
" ); From 3e99b7f4faeaa2781d1c3dca9ee091e00b2d4d86 Mon Sep 17 00:00:00 2001 From: nightwing Date: Mon, 11 Jun 2012 11:12:50 +0400 Subject: [PATCH 03/11] fix folding for c9search (for lines matching /\w:$/) --- lib/ace/edit_session/bracket_match.js | 8 +---- lib/ace/mode/c9search.js | 12 ------- lib/ace/mode/folding/c9search.js | 50 ++++++++++----------------- lib/ace/mode/folding/fold_mode.js | 4 +-- 4 files changed, 21 insertions(+), 53 deletions(-) diff --git a/lib/ace/edit_session/bracket_match.js b/lib/ace/edit_session/bracket_match.js index 83c8f572..4b95c1cd 100644 --- a/lib/ace/edit_session/bracket_match.js +++ b/lib/ace/edit_session/bracket_match.js @@ -194,7 +194,7 @@ function BracketMatch() { return null; }; - this.$findClosingBracket = function(bracket, position, typeRe, allowBlankLine) { + this.$findClosingBracket = function(bracket, position, typeRe) { var closingBracket = this.$brackets[bracket]; var depth = 1; @@ -239,12 +239,6 @@ function BracketMatch() { // whose type matches typeRe do { token = iterator.stepForward(); - if (allowBlankLine) { - // if you've reached the doc end, or, you match a new content line - if (token === null || token.type == "string") { - return {row: iterator.getCurrentTokenRow() + (token === null ? 1 : -1), column: 0}; - } - } } while (token && !typeRe.test(token.type)); if (token == null) diff --git a/lib/ace/mode/c9search.js b/lib/ace/mode/c9search.js index cff2b22a..37a89aab 100644 --- a/lib/ace/mode/c9search.js +++ b/lib/ace/mode/c9search.js @@ -56,18 +56,6 @@ oop.inherits(Mode, TextMode); this.getNextLineIndent = function(state, line, tab) { var indent = this.$getIndent(line); - - // ignore braces in comments - var tokens = this.$tokenizer.getLineTokens(line, state).tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { - return indent; - } - - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; - } - return indent; }; diff --git a/lib/ace/mode/folding/c9search.js b/lib/ace/mode/folding/c9search.js index 406222b6..056f731d 100644 --- a/lib/ace/mode/folding/c9search.js +++ b/lib/ace/mode/folding/c9search.js @@ -48,46 +48,32 @@ oop.inherits(FoldMode, BaseFoldMode); (function() { - this.foldingStartMarker = /[a-zA-Z](:)\s*$/; - this.foldingStopMarker = /^(\s*)$/; + this.foldingStartMarker = /^(\w.*\:|Searching for.*)$/; + this.foldingStopMarker = /^(\s+|Found.*)$/; this.getFoldWidgetRange = function(session, foldStyle, row) { var line = session.getLine(row); - var match = line.match(this.foldingStartMarker); - if (match) { - var i = match.index; + var level1 = /^(Found.*|Searching for.*)$/; + var level2 = /^(\w.*\:|\s+)$/; + var re = level1.test(line) ? level1 : level2; - if (match[1]) - return this.openingBracketBlock(session, match[1], row, i, false, true); - - var range = session.getCommentFoldRange(row, i + match[0].length); - range.end.column -= 2; - return range; - } - - if (foldStyle !== "markbeginend") - return; - - var match = line.match(this.foldingStopMarker); - if (match) { - var i = match.index + match[0].length; - - if (match[2]) { - var range = session.getCommentFoldRange(row, i); - range.end.column -= 2; - return range; + if (this.foldingStartMarker.test(line)) { + for (var i = row + 1, l = session.getLength(); i < l; i++) { + if (re.test(session.getLine(i))) + break; } - var end = {row: row, column: i}; - var start = session.$findOpeningBracket(match[1], end); - - if (!start) - return; + return new Range(row, line.length, i, 0); + } - start.column++; - end.column--; + if (this.foldingStopMarker.test(line)) { + for (var i = row - 1; i >= 0; i--) { + line = session.getLine(i); + if (re.test(line)) + break; + } - return Range.fromPoints(start, end); + return new Range(i, line.length, row, 0); } }; diff --git a/lib/ace/mode/folding/fold_mode.js b/lib/ace/mode/folding/fold_mode.js index 849526c7..0e7aaa52 100644 --- a/lib/ace/mode/folding/fold_mode.js +++ b/lib/ace/mode/folding/fold_mode.js @@ -91,9 +91,9 @@ var FoldMode = exports.FoldMode = function() {}; } }; - this.openingBracketBlock = function(session, bracket, row, column, typeRe, allowBlankLine) { + this.openingBracketBlock = function(session, bracket, row, column, typeRe) { var start = {row: row, column: column + 1}; - var end = session.$findClosingBracket(bracket, start, typeRe, allowBlankLine); + var end = session.$findClosingBracket(bracket, start, typeRe); if (!end) return; From 3d93ad43c3293a2b9af597b0d62abf29778c2854 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 20 Jun 2012 13:33:47 +0400 Subject: [PATCH 04/11] fix coffeescript folding for "[#{}" --- lib/ace/mode/folding/c9search.js | 2 +- lib/ace/mode/folding/fold_mode.js | 2 +- lib/ace/mode/folding/pythonic.js | 2 +- lib/ace/mode/folding/pythonic_test.js | 7 +++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/ace/mode/folding/c9search.js b/lib/ace/mode/folding/c9search.js index 056f731d..2c9828de 100644 --- a/lib/ace/mode/folding/c9search.js +++ b/lib/ace/mode/folding/c9search.js @@ -54,7 +54,7 @@ oop.inherits(FoldMode, BaseFoldMode); this.getFoldWidgetRange = function(session, foldStyle, row) { var line = session.getLine(row); var level1 = /^(Found.*|Searching for.*)$/; - var level2 = /^(\w.*\:|\s+)$/; + var level2 = /^(\w.*\:|\s*)$/; var re = level1.test(line) ? level1 : level2; if (this.foldingStartMarker.test(line)) { diff --git a/lib/ace/mode/folding/fold_mode.js b/lib/ace/mode/folding/fold_mode.js index 0e7aaa52..9dcbda13 100644 --- a/lib/ace/mode/folding/fold_mode.js +++ b/lib/ace/mode/folding/fold_mode.js @@ -101,7 +101,7 @@ var FoldMode = exports.FoldMode = function() {}; if (fw == null) fw = this.getFoldWidget(session, end.row); - if (fw == "start") { + if (fw == "start" && end.row > start.row) { end.row --; end.column = session.getLine(end.row).length; } diff --git a/lib/ace/mode/folding/pythonic.js b/lib/ace/mode/folding/pythonic.js index 90ab2aad..529cc797 100644 --- a/lib/ace/mode/folding/pythonic.js +++ b/lib/ace/mode/folding/pythonic.js @@ -42,7 +42,7 @@ var oop = require("../../lib/oop"); var BaseFoldMode = require("./fold_mode").FoldMode; var FoldMode = exports.FoldMode = function(markers) { - this.foldingStartMarker = new RegExp("(?:([\\[{])|(" + markers + "))(?:\\s*)(?:#.*)?$"); + this.foldingStartMarker = new RegExp("([\\[{])(?:\\s*)$|(" + markers + ")(?:\\s*)(?:#.*)?$"); }; oop.inherits(FoldMode, BaseFoldMode); diff --git a/lib/ace/mode/folding/pythonic_test.js b/lib/ace/mode/folding/pythonic_test.js index 6cfb1f77..ca853715 100644 --- a/lib/ace/mode/folding/pythonic_test.js +++ b/lib/ace/mode/folding/pythonic_test.js @@ -49,11 +49,12 @@ module.exports = { "test: bracket folding": function() { var session = new EditSession([ - '[ #-', + '[ ', 'stuff', ']', '[ ', - '{ ' + '{ ', + '[ #-', ]); var mode = new PythonMode(); @@ -65,9 +66,11 @@ module.exports = { assert.equal(session.getFoldWidget(2), ""); assert.equal(session.getFoldWidget(3), "start"); assert.equal(session.getFoldWidget(4), "start"); + assert.equal(session.getFoldWidget(5), ""); assert.range(session.getFoldWidgetRange(0), 0, 1, 2, 0); assert.equal(session.getFoldWidgetRange(3), null); + assert.equal(session.getFoldWidgetRange(5), null); }, "test: indentation folding": function() { From 927cc4755b8a31b2d2caa3db3a5252cfaaaa7070 Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 15 Jun 2012 14:23:04 +0400 Subject: [PATCH 05/11] fix #809 coffeeScript operator highlighting --- lib/ace/mode/coffee_highlight_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/coffee_highlight_rules.js b/lib/ace/mode/coffee_highlight_rules.js index 2772edf3..d3fe7884 100644 --- a/lib/ace/mode/coffee_highlight_rules.js +++ b/lib/ace/mode/coffee_highlight_rules.js @@ -153,7 +153,7 @@ define(function(require, exports, module) { regex : "\\?|\\:|\\,|\\." }, { token : "keyword.operator", - regex : "(?:[\\-=]>|[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|\\!)" + regex : "(?:[\\-=]>|[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])" }, { token : "paren.lparen", regex : "[({[]" From 38eb07df67459c0a9b2e42612159c5820e8ba938 Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 16 Jun 2012 13:51:18 +0400 Subject: [PATCH 06/11] better folding for coffeescript --- lib/ace/mode/coffee.js | 2 +- lib/ace/mode/folding/coffee.js | 127 ++++++++++++++++++++++++++ lib/ace/mode/folding/coffee_test.js | 108 ++++++++++++++++++++++ lib/ace/mode/folding/fold_mode.js | 24 ++--- lib/ace/mode/folding/pythonic_test.js | 2 +- lib/ace/test/all_browser.js | 1 + 6 files changed, 251 insertions(+), 13 deletions(-) create mode 100644 lib/ace/mode/folding/coffee.js create mode 100644 lib/ace/mode/folding/coffee_test.js diff --git a/lib/ace/mode/coffee.js b/lib/ace/mode/coffee.js index 4afc2896..9d265b67 100644 --- a/lib/ace/mode/coffee.js +++ b/lib/ace/mode/coffee.js @@ -41,7 +41,7 @@ define(function(require, exports, module) { var Tokenizer = require("../tokenizer").Tokenizer; var Rules = require("./coffee_highlight_rules").CoffeeHighlightRules; var Outdent = require("./matching_brace_outdent").MatchingBraceOutdent; -var PythonFoldMode = require("./folding/pythonic").FoldMode; +var PythonFoldMode = require("./folding/coffee").FoldMode; var Range = require("../range").Range; var TextMode = require("./text").Mode; var WorkerClient = require("../worker/worker_client").WorkerClient; diff --git a/lib/ace/mode/folding/coffee.js b/lib/ace/mode/folding/coffee.js new file mode 100644 index 00000000..b502afc4 --- /dev/null +++ b/lib/ace/mode/folding/coffee.js @@ -0,0 +1,127 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var BaseFoldMode = require("./fold_mode").FoldMode; +var Range = require("../../range").Range; + +var FoldMode = exports.FoldMode = function() {}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.getFoldWidgetRange = function(session, foldStyle, row) { + var range = this.indentationBlock(session, row); + if (range) + return range; + + var re = /\S/; + var line = session.getLine(row); + var startLevel = line.search(re); + if (startLevel == -1 || line[startLevel] != "#") + return; + + var startColumn = line.length; + var maxRow = session.getLength(); + var startRow = row; + var endRow = row; + + while (++row < maxRow) { + line = session.getLine(row); + var level = line.search(re); + + if (level == -1) + continue; + + if (line[level] != "#") + break; + + endRow = row; + } + + if (endRow > startRow) { + var endColumn = session.getLine(endRow).length; + return new Range(startRow, startColumn, endRow, endColumn); + } + }; + + // must return "" if there's no fold, to enable caching + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + var indent = line.search(/\S/); + var next = session.getLine(row + 1); + var prev = session.getLine(row - 1); + var prevIndent = prev.search(/\S/); + var nextIndent = next.search(/\S/); + + if (indent == -1) { + session.foldWidgets[row - 1] = prevIndent!= -1 && prevIndent < nextIndent ? "start" : ""; + return ""; + } + + // documentation comments + if (prevIndent == -1) { + if (indent == nextIndent && line[indent] == "#" && next[indent] == "#") { + session.foldWidgets[row - 1] = ""; + session.foldWidgets[row + 1] = ""; + return "start"; + } + } else if (prevIndent == indent && line[indent] == "#" && prev[indent] == "#") { + if (session.getLine(row - 2).search(/\S/) == -1) { + session.foldWidgets[row - 1] = "start"; + session.foldWidgets[row + 1] = ""; + return "" + } + } + + if (prevIndent!= -1 && prevIndent < indent) + session.foldWidgets[row - 1] = "start"; + else + session.foldWidgets[row - 1] = ""; + + if (indent < nextIndent) + return "start"; + else + return ""; + }; + +}).call(FoldMode.prototype); + +}); diff --git a/lib/ace/mode/folding/coffee_test.js b/lib/ace/mode/folding/coffee_test.js new file mode 100644 index 00000000..41c440a2 --- /dev/null +++ b/lib/ace/mode/folding/coffee_test.js @@ -0,0 +1,108 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") + require("amd-loader"); + +define(function(require, exports, module) { +"use strict"; + +var CoffeeMode = require("../coffee").Mode; +var EditSession = require("../../edit_session").EditSession; +var assert = require("../../test/assertions"); +function testFoldWidgets(array) { + var session = array.filter(function(_, i){return i % 2 == 1}); + session = new EditSession(session); + var mode = new CoffeeMode(); + session.setFoldStyle("markbeginend"); + session.setMode(mode); + + var widgets = array.filter(function(_, i){return i % 2 == 0}); + widgets.forEach(function(w, i){ + session.foldWidgets[i] = session.getFoldWidget(i); + }) + widgets.forEach(function(w, i){ + w = w.split(","); + var type = w[0] == ">" ? "start" : w[0] == "<" ? "end" : ""; + assert.equal(session.foldWidgets[i], type); + if (!type) + return; + var range = session.getFoldWidgetRange(i); + if (!w[1]) { + assert.equal(range, null); + return; + } + assert.equal(range.start.row, i); + assert.equal(range.end.row - range.start.row, parseInt(w[1])); + testColumn(w[2], range.start); + testColumn(w[3], range.end); + }); + + function testColumn(w, pos) { + if (!w) + return; + if (w == "l") + w = session.getLine(pos.row).length; + else + w = parseInt(w); + assert.equal(pos.column, w); + } +} +module.exports = { + "test: coffee script indentation based folding": function() { + testFoldWidgets([ + '>,1,l,l', ' ## indented comment', + '', ' # ', + '', '', + '>,1,l,l', ' # plain comment', + '', ' # ', + '>,2', ' function (x)=>', + '', ' ', + '', ' x++', + '', ' ', + '', ' ', + '>,2', ' bar = ', + '', ' foo: 1', + '', ' baz: lighter' + ]); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) + require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/fold_mode.js b/lib/ace/mode/folding/fold_mode.js index 9dcbda13..25407569 100644 --- a/lib/ace/mode/folding/fold_mode.js +++ b/lib/ace/mode/folding/fold_mode.js @@ -58,25 +58,27 @@ var FoldMode = exports.FoldMode = function() {}; return "end"; return ""; }; - + this.getFoldWidgetRange = function(session, foldStyle, row) { return null; }; this.indentationBlock = function(session, row, column) { - var re = /^\s*/; + var re = /\S/; + var line = session.getLine(row); + var startLevel = line.search(re); + if (startLevel == -1) + return; + + var startColumn = column || line.length; + var maxRow = session.getLength(); var startRow = row; var endRow = row; - var line = session.getLine(row); - var startColumn = column || line.length; - var startLevel = line.match(re)[0].length; - var maxRow = session.getLength() - - while (++row < maxRow) { - line = session.getLine(row); - var level = line.match(re)[0].length; - if (level == line.length) + while (++row < maxRow) { + var level = session.getLine(row).search(re); + + if (level == -1) continue; if (level <= startLevel) diff --git a/lib/ace/mode/folding/pythonic_test.js b/lib/ace/mode/folding/pythonic_test.js index ca853715..f0f93799 100644 --- a/lib/ace/mode/folding/pythonic_test.js +++ b/lib/ace/mode/folding/pythonic_test.js @@ -61,7 +61,7 @@ module.exports = { session.setFoldStyle("markbeginend"); session.setMode(mode); - assert.equal(session.getFoldWidget(0), "start"); + assert.equal(session.getFoldWidget(0), ""); assert.equal(session.getFoldWidget(1), ""); assert.equal(session.getFoldWidget(2), ""); assert.equal(session.getFoldWidget(3), "start"); diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index 934149e4..f1f68c81 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -42,6 +42,7 @@ var testNames = [ "ace/mode/folding/html_test", "ace/mode/folding/pythonic_test", "ace/mode/folding/xml_test", + "ace/mode/folding/coffee_test", "ace/multi_select_test", "ace/range_test", "ace/range_list_test", From 241776dd4c011fcbaec45eae0316f1420bdb12bf Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 16 Jun 2012 17:07:55 +0400 Subject: [PATCH 07/11] tweak selectByWords --- lib/ace/edit_session/bracket_match.js | 5 +---- lib/ace/mouse/default_gutter_handler.js | 9 +++------ lib/ace/mouse/default_handlers.js | 17 ++++++++--------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/lib/ace/edit_session/bracket_match.js b/lib/ace/edit_session/bracket_match.js index 4b95c1cd..9b977b8c 100644 --- a/lib/ace/edit_session/bracket_match.js +++ b/lib/ace/edit_session/bracket_match.js @@ -94,7 +94,7 @@ function BracketMatch() { var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); if (!match) { chr = line.charAt(pos.column); - pos.column++; + pos = {row: pos.row, column: pos.column + 1}; match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); before = false; } @@ -123,9 +123,6 @@ function BracketMatch() { range.cursor = range.start; } - if (!before) - pos.column--; - return range; }; diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index fc9b012b..21c792a1 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -58,13 +58,10 @@ function GutterHandler(mouseHandler) { var row = e.getDocumentPosition().row; var selection = editor.session.selection; - if (e.getShiftKey()) { + if (e.getShiftKey()) selection.selectTo(row, 0); - } else { - selection.moveCursorTo(row, 0); - selection.selectLine(); - mouseHandler.$clickSelection = selection.getRange(); - } + else + mouseHandler.$clickSelection = editor.selection.getLineRange(row); mouseHandler.captureMouse(e, "selectByLines"); return e.preventDefault(); diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js index 1b916801..7fabf75d 100644 --- a/lib/ace/mouse/default_handlers.js +++ b/lib/ace/mouse/default_handlers.js @@ -65,7 +65,7 @@ function DefaultHandlers(mouseHandler) { mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange"); mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange"); - + mouseHandler.$focusWaitTimout = 250; } @@ -163,10 +163,12 @@ function DefaultHandlers(mouseHandler) { if (cmpStart == -1 && cmpEnd <= 0) { anchor = this.$clickSelection.end; - cursor = range.start; + if (range.end.row != cursor.row || range.end.column != cursor.column) + cursor = range.start; } else if (cmpEnd == 1 && cmpStart >= 0) { anchor = this.$clickSelection.start; - cursor = range.end; + if (range.start.row != cursor.row || range.start.column != cursor.column) + cursor = range.end; } else if (cmpStart == -1 && cmpEnd == 1) { cursor = range.end; anchor = range.start; @@ -286,7 +288,7 @@ function DefaultHandlers(mouseHandler) { this.setState("select"); return; } - + this.$clickSelection = editor.selection.getWordRange(pos.row, pos.column); this.setState("selectByWords"); }; @@ -296,10 +298,7 @@ function DefaultHandlers(mouseHandler) { var editor = this.editor; this.setState("selectByLines"); - - editor.moveCursorToPosition(pos); - editor.selection.selectLine(); - this.$clickSelection = editor.getSelectionRange(); + this.$clickSelection = editor.selection.getLineRange(pos.row); }; this.onQuadClick = function(ev) { @@ -345,7 +344,7 @@ function calcRangeOrientation(range, cursor) { var cmp = 2 * cursor.column - range.start.column - range.end.column; else var cmp = 2 * cursor.row - range.start.row - range.end.row; - + if (cmp < 0) return {cursor: range.start, anchor: range.end}; else From 71231db0af356a3914ee36cd1c82251a78bca264 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 20 Jun 2012 13:38:31 +0400 Subject: [PATCH 08/11] editor content shouldn't overlay scrollbar --- lib/ace/css/editor.css | 1 - lib/ace/virtual_renderer.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index d53a135b..0a668fff 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -8,7 +8,6 @@ .ace_scroller { position: absolute; overflow: hidden; - width : 100%; } .ace_content { diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index c41d976a..eb6a17c7 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -321,7 +321,7 @@ var VirtualRenderer = function(container, theme) { var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0; this.scroller.style.left = gutterWidth + "px"; size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()); - //this.scroller.style.width = size.scrollerWidth + "px"; + this.scroller.style.right = this.scrollBar.getWidth() + "px"; if (this.session.getUseWrapMode() && this.adjustWrapLimit() || force) changes = changes | this.CHANGE_FULL; From 5eca7dd8203bf80321278fbe3454035390282323 Mon Sep 17 00:00:00 2001 From: nightwing Date: Wed, 20 Jun 2012 14:25:01 +0400 Subject: [PATCH 09/11] fix test --- lib/ace/mode/folding/pythonic_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ace/mode/folding/pythonic_test.js b/lib/ace/mode/folding/pythonic_test.js index f0f93799..ca853715 100644 --- a/lib/ace/mode/folding/pythonic_test.js +++ b/lib/ace/mode/folding/pythonic_test.js @@ -61,7 +61,7 @@ module.exports = { session.setFoldStyle("markbeginend"); session.setMode(mode); - assert.equal(session.getFoldWidget(0), ""); + assert.equal(session.getFoldWidget(0), "start"); assert.equal(session.getFoldWidget(1), ""); assert.equal(session.getFoldWidget(2), ""); assert.equal(session.getFoldWidget(3), "start"); From 3cc878f4c1550857986a27858577b2ca579a8397 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 21 Jun 2012 20:38:00 +0400 Subject: [PATCH 10/11] compatibility with dojo.require --- lib/ace/requirejs/text.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ace/requirejs/text.js b/lib/ace/requirejs/text.js index cf7ef666..6d6f59ce 100644 --- a/lib/ace/requirejs/text.js +++ b/lib/ace/requirejs/text.js @@ -41,17 +41,17 @@ (function() { -var globalRequire = require; +var globalRequire = typeof require != "undefined" && require; define(function (require, exports, module) { "use strict"; exports.load = function (name, req, onLoad, config) { - if (req.isBrowser) - require("ace/lib/net").get(req.toUrl(name), onLoad); + //Using special require.nodeRequire, something added by r.js. + if (globalRequire && globalRequire.nodeRequire) + onLoad(('fs').readFileSync(req.toUrl(name), 'utf8')); else - //Using special require.nodeRequire, something added by r.js. - onLoad(globalRequire.nodeRequire('fs').readFileSync(req.toUrl(name), 'utf8')); + require("ace/lib/net").get(req.toUrl(name), onLoad); }; }); From 8fbe921ad992c118f10556a80750510fddc0e806 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 21 Jun 2012 20:55:55 +0400 Subject: [PATCH 11/11] do not include trailing slash in scriptOptions.base --- lib/ace/config.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/ace/config.js b/lib/ace/config.js index 73a83d51..0bdaf786 100644 --- a/lib/ace/config.js +++ b/lib/ace/config.js @@ -97,10 +97,9 @@ exports.init = function() { } } - var m = src.match(/^(?:(.*\/)ace\.js)(?:\?|$)/); - if (m) { - scriptUrl = m[1] || m[2]; - } + var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/); + if (m) + scriptUrl = m[1]; } if (scriptUrl) {