From e1697c2dfda2507604ac9674acdd98f71500ec27 Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 12 Oct 2012 15:28:02 +0400 Subject: [PATCH 1/5] allow folds with empty placeholder --- lib/ace/edit_session.js | 5 ++--- lib/ace/edit_session/folding.js | 7 ++----- lib/ace/edit_session_test.js | 2 +- lib/ace/layer/text.js | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index b23a60ecc69..09e72ab42cb 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -1893,10 +1893,9 @@ var EditSession = function(text, mode) { row ++; } else { tokens = []; - foldLine.walk( - function(placeholder, row, column, lastColumn) { + foldLine.walk(function(placeholder, row, column, lastColumn) { var walkTokens; - if (placeholder) { + if (placeholder != null) { walkTokens = this.$getDisplayTokens( placeholder, tokens.length); walkTokens[0] = PLACEHOLDER_START; diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index 7676150cb98..7b0b929edc5 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -274,9 +274,6 @@ function Folding() { var endColumn = fold.end.column; // --- Some checking --- - if (fold.placeholder.length < 2) - throw "Placeholder has to be at least 2 characters"; - if (startRow == endRow && endColumn - startColumn < 2) throw "The range has to be at least 2 characters width"; @@ -489,7 +486,7 @@ function Folding() { } lastColumn = Math.max(startColumn, lastColumn); } - if (placeholder) { + if (placeholder != null) { textLine += placeholder; } else { textLine += doc.getLine(row).substring(lastColumn, column); @@ -722,7 +719,7 @@ function Folding() { } else { if (addSubfolds) this.foldAll(row + 1, this.getLength()); - (e.target || e.srcElement).className += " invalid" + (e.target || e.srcElement).className += " ace_invalid" } }; diff --git a/lib/ace/edit_session_test.js b/lib/ace/edit_session_test.js index d349384e3db..e89ad57f1c9 100644 --- a/lib/ace/edit_session_test.js +++ b/lib/ace/edit_session_test.js @@ -920,7 +920,7 @@ module.exports = { tryAddFold("foo", new Range(0, 13, 0, 18), false); assert.equal(session.$foldData[0].folds.length, 1); - tryAddFold("f", new Range(0, 13, 0, 18), true); + tryAddFold("f", new Range(0, 13, 0, 18), false); tryAddFold("foo", new Range(0, 18, 0, 21), false); assert.equal(session.$foldData[0].folds.length, 2); session.removeFold(fold); diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index c53c7169fe4..812dd066189 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -616,7 +616,7 @@ var Text = function(parentEl) { var tokens = session.getTokens(row); foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) { - if (placeholder) { + if (placeholder != null) { renderTokens.push({ type: "fold", value: placeholder From ccee8e70414bbffca3ae5d5b350e286ae1f3aa80 Mon Sep 17 00:00:00 2001 From: nightwing Date: Fri, 12 Oct 2012 15:43:43 +0400 Subject: [PATCH 2/5] fix several typos --- lib/ace/edit_session/folding.js | 2 +- lib/ace/mode/folding/asciidoc.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index 7b0b929edc5..a1800efda00 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -625,7 +625,7 @@ function Folding() { var range = this.getFoldWidgetRange(row); // sometimes range can be incompatible with existing fold // wouldn't it be better for addFold to return null istead of throwing? - if (range && range.end.row < endRow) try { + if (range && range.end.row <= endRow) try { this.addFold("...", range); } catch(e) {} } diff --git a/lib/ace/mode/folding/asciidoc.js b/lib/ace/mode/folding/asciidoc.js index a15f4a64c3c..d684917e0a9 100644 --- a/lib/ace/mode/folding/asciidoc.js +++ b/lib/ace/mode/folding/asciidoc.js @@ -39,7 +39,7 @@ var FoldMode = exports.FoldMode = function() {}; oop.inherits(FoldMode, BaseFoldMode); (function() { - this.foldingStartMarker = /^(?:\|={10,}|[\.\/=\-~^+]{4,}|={1,5} )/; + this.foldingStartMarker = /^(?:\|={10,}|[\.\/=\-~^+]{4,}\s*$|={1,5} )/; this.singleLineHeadingRe = /^={1,5}(?=\s+\S)/; this.getFoldWidget = function(session, foldStyle, row) { From 3bcb122a72c41b29fd1a32f71e57752200b0515f Mon Sep 17 00:00:00 2001 From: nightwing Date: Sat, 13 Oct 2012 14:37:43 +0400 Subject: [PATCH 3/5] add foldMode.closingBracketBlock --- lib/ace/mode/folding/cstyle.js | 21 ++++++--------------- lib/ace/mode/folding/fold_mode.js | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/lib/ace/mode/folding/cstyle.js b/lib/ace/mode/folding/cstyle.js index 46d1c501f34..bb6d8939dec 100644 --- a/lib/ace/mode/folding/cstyle.js +++ b/lib/ace/mode/folding/cstyle.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 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 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -42,7 +42,7 @@ oop.inherits(FoldMode, BaseFoldMode); this.foldingStartMarker = /(\{|\[)[^\}\]]*$|^\s*(\/\*)/; this.foldingStopMarker = /^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/; - + this.getFoldWidgetRange = function(session, foldStyle, row) { var line = session.getLine(row); var match = line.match(this.foldingStartMarker); @@ -59,7 +59,7 @@ oop.inherits(FoldMode, BaseFoldMode); if (foldStyle !== "markbeginend") return; - + var match = line.match(this.foldingStopMarker); if (match) { var i = match.index + match[0].length; @@ -70,19 +70,10 @@ oop.inherits(FoldMode, BaseFoldMode); return range; } - var end = {row: row, column: i}; - var start = session.$findOpeningBracket(match[1], end); - - if (!start) - return; - - start.column++; - end.column--; - - return Range.fromPoints(start, end); + return this.closingBracketBlock(session, match[1], row, i); } }; - + }).call(FoldMode.prototype); }); diff --git a/lib/ace/mode/folding/fold_mode.js b/lib/ace/mode/folding/fold_mode.js index 05795ef8bce..9272cdcde7b 100644 --- a/lib/ace/mode/folding/fold_mode.js +++ b/lib/ace/mode/folding/fold_mode.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 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 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -103,6 +103,18 @@ var FoldMode = exports.FoldMode = function() {}; return Range.fromPoints(start, end); }; + this.closingBracketBlock = function(session, bracket, row, column, typeRe) { + var end = {row: row, column: column}; + var start = session.$findOpeningBracket(bracket, end); + + if (!start) + return; + + start.column++; + end.column--; + + return Range.fromPoints(start, end); + }; }).call(FoldMode.prototype); }); From ebd4b5bfaaee88b0883b5109430b6708f474cb9d Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 14 Oct 2012 01:45:15 +0400 Subject: [PATCH 4/5] improve comment folding --- lib/ace/edit_session/folding.js | 28 ++++++++++++++++------------ lib/ace/mode/folding/cstyle.js | 13 ++++--------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index a1800efda00..f3029c18651 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -585,30 +585,34 @@ function Folding() { this.addFold(placeholder, range); }; - this.getCommentFoldRange = function(row, column) { + this.getCommentFoldRange = function(row, column, dir) { var iterator = new TokenIterator(this, row, column); var token = iterator.getCurrentToken(); if (token && /^comment|string/.test(token.type)) { var range = new Range(); var re = new RegExp(token.type.replace(/\..*/, "\\.")); - do { - token = iterator.stepBackward(); - } while(token && re.test(token.type)); - - iterator.stepForward(); + if (dir != 1) { + do { + token = iterator.stepBackward(); + } while(token && re.test(token.type)); + iterator.stepForward(); + } + range.start.row = iterator.getCurrentTokenRow(); range.start.column = iterator.getCurrentTokenColumn() + 2; iterator = new TokenIterator(this, row, column); - - do { - token = iterator.stepForward(); - } while(token && re.test(token.type)); - token = iterator.stepBackward(); + if (dir != -1) { + do { + token = iterator.stepForward(); + } while(token && re.test(token.type)); + token = iterator.stepBackward(); + } else + token = iterator.getCurrentToken(); range.end.row = iterator.getCurrentTokenRow(); - range.end.column = iterator.getCurrentTokenColumn() + token.value.length; + range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2; return range; } }; diff --git a/lib/ace/mode/folding/cstyle.js b/lib/ace/mode/folding/cstyle.js index bb6d8939dec..f3ee25eaa59 100644 --- a/lib/ace/mode/folding/cstyle.js +++ b/lib/ace/mode/folding/cstyle.js @@ -52,9 +52,7 @@ oop.inherits(FoldMode, BaseFoldMode); if (match[1]) return this.openingBracketBlock(session, match[1], row, i); - var range = session.getCommentFoldRange(row, i + match[0].length); - range.end.column -= 2; - return range; + return session.getCommentFoldRange(row, i + match[0].length, 1); } if (foldStyle !== "markbeginend") @@ -64,13 +62,10 @@ oop.inherits(FoldMode, BaseFoldMode); 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 (match[1]) + return this.closingBracketBlock(session, match[1], row, i); - return this.closingBracketBlock(session, match[1], row, i); + return session.getCommentFoldRange(row, i, -1); } }; From e220a11f34dd7e2fd69d7aee7c955a3df8a645c3 Mon Sep 17 00:00:00 2001 From: nightwing Date: Thu, 18 Oct 2012 01:12:53 +0400 Subject: [PATCH 5/5] nicer mouse behavior for foldwigets activate on mousedown and on double click --- lib/ace/mouse/default_gutter_handler.js | 4 +- lib/ace/mouse/fold_handler.js | 57 ++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index e76efca4a43..90d9747c313 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 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 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE diff --git a/lib/ace/mouse/fold_handler.js b/lib/ace/mouse/fold_handler.js index b0e0389d558..058107e0a35 100644 --- a/lib/ace/mouse/fold_handler.js +++ b/lib/ace/mouse/fold_handler.js @@ -3,7 +3,7 @@ * * Copyright (c) 2010, Ajax.org B.V. * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright @@ -14,7 +14,7 @@ * * Neither the name of Ajax.org B.V. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 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 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -32,11 +32,11 @@ define(function(require, exports, module) { "use strict"; function FoldHandler(editor) { - + editor.on("click", function(e) { var position = e.getDocumentPosition(); var session = editor.session; - + // If the user clicked on a fold, then expand it. var fold = session.getFoldAt(position.row, position.column, 1); if (fold) { @@ -44,12 +44,12 @@ function FoldHandler(editor) { session.removeFold(fold); else session.expandFold(fold); - + e.stop(); } }); - - editor.on("gutterclick", function(e) { + + editor.on("guttermousedown", function(e) { var gutterRegion = editor.renderer.$gutterLayer.getRegion(e); if (gutterRegion == "foldWidgets") { @@ -60,6 +60,49 @@ function FoldHandler(editor) { e.stop(); } }); + + editor.on("gutterdblclick", function(e) { + var gutterRegion = editor.renderer.$gutterLayer.getRegion(e); + + if (gutterRegion == "foldWidgets") { + var row = e.getDocumentPosition().row; + var session = editor.session; + var fw = session.foldWidgets; + if (!fw || fw[row]) + return; + + var i = row - 1, firstRange; + while (i >= 0) { + var c = fw[i]; + if (c == null) + c = fw[i] = session.getFoldWidget(); + + 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) { + var row = range.start.row; + var fold = session.getFoldAt(row, session.getLine(row).length, 1); + + if (fold) { + session.removeFold(fold); + } else { + session.addFold("...", range); + editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0}); + } + } + e.stop(); + } + }); } exports.FoldHandler = FoldHandler;