From fe4465fe236c71800212601bb5397503bda54669 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Fri, 20 May 2011 19:13:11 +0200 Subject: [PATCH 1/4] Select folds as the user clicks on it and expand them on double clicking --- lib/ace/css/editor.css | 10 +++++-- lib/ace/mouse_handler.js | 61 +++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index 075c317e..45ca6d71 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -3,13 +3,13 @@ overflow: hidden; font-family: "Menlo", "Monaco", "Courier New", monospace; - font-size: 12px; + font-size: 12px; } .ace_scroller { position: absolute; overflow-x: scroll; - overflow-y: hidden; + overflow-y: hidden; } .ace_content { @@ -90,7 +90,7 @@ .ace_layer { z-index: 1; position: absolute; - overflow: hidden; + overflow: hidden; white-space: nowrap; height: 100%; width: 100%; @@ -154,6 +154,10 @@ -webkit-box-sizing: border-box; } +.ace_line .ace_fold { + cursor: pointer; +} + .ace_dragging .ace_marker-layer, .ace_dragging .ace_text-layer { cursor: move; } diff --git a/lib/ace/mouse_handler.js b/lib/ace/mouse_handler.js index 8c722431..910a4ec0 100644 --- a/lib/ace/mouse_handler.js +++ b/lib/ace/mouse_handler.js @@ -58,7 +58,7 @@ var MouseHandler = function(editor) { event.addListener(editor.container, "selectstart", function(e) { return event.preventDefault(e); }); - + var mouseTarget = editor.renderer.getMouseEventTarget(); event.addListener(mouseTarget, "mousedown", this.onMouseDown.bind(this)); event.addMultiMouseDownListener(mouseTarget, 0, 2, 500, this.onMouseDoubleClick.bind(this)); @@ -73,7 +73,7 @@ var MouseHandler = function(editor) { this.setScrollSpeed = function(speed) { this.$scrollSpeed = speed; }; - + this.getScrollSpeed = function() { return this.$scrollSpeed; }; @@ -100,7 +100,7 @@ var MouseHandler = function(editor) { var selectionEmpty = selectionRange.isEmpty(); var state = STATE_UNKNOWN; var inSelection = false; - + var button = event.getButton(e); if (button !== 0) { if (selectionEmpty) { @@ -112,6 +112,13 @@ var MouseHandler = function(editor) { } return; } else { + // Select the fold as the user clicks it. + var fold = editor.session.getFoldAt(pos.row, pos.column, 1); + if (fold) { + editor.selection.setSelectionRange(fold.range); + return; + } + inSelection = !editor.getReadOnly() && !selectionEmpty && selectionRange.contains(pos.row, pos.column); @@ -127,19 +134,19 @@ var MouseHandler = function(editor) { var overwrite = editor.getOverwrite(); var mousedownTime = (new Date()).getTime(); var dragCursor, dragRange; - + var onMouseSelection = function(e) { mousePageX = event.getDocumentX(e); mousePageY = event.getDocumentY(e); }; - + var onMouseSelectionEnd = function() { clearInterval(timerId); if (state == STATE_UNKNOWN) onStartSelect(pos); else if (state == STATE_DRAG) onMouseDragSelectionEnd(); - + self.$clickSelection = null; state = STATE_UNKNOWN; }; @@ -172,7 +179,7 @@ var MouseHandler = function(editor) { editor.selection.setSelectionRange(newRange); }; - + var onSelectionInterval = function() { if (mousePageX === undefined || mousePageY === undefined) return; @@ -181,7 +188,7 @@ var MouseHandler = function(editor) { var distance = self.$distance(pageX, pageY, mousePageX, mousePageY); var time = (new Date()).getTime(); - + if (distance > DRAG_OFFSET) { state = STATE_SELECT; var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY); @@ -197,13 +204,13 @@ var MouseHandler = function(editor) { } } - + if (state == STATE_DRAG) onDragSelectionInterval(); else if (state == STATE_SELECT) onUpdateSelectionInterval(); }; - + function onStartSelect(pos) { if (e.shiftKey) editor.selection.selectToPosition(pos) @@ -215,12 +222,12 @@ var MouseHandler = function(editor) { } state = STATE_SELECT; } - + var onUpdateSelectionInterval = function() { var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY); cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1)); - - if (self.$clickSelection) { + + if (self.$clickSelection) { if (self.$clickSelection.contains(cursor.row, cursor.column)) { editor.selection.setSelectionRange(self.$clickSelection); } else { @@ -236,7 +243,7 @@ var MouseHandler = function(editor) { else { editor.selection.selectToPosition(cursor); } - + editor.renderer.scrollCursorIntoView(); }; @@ -250,32 +257,40 @@ var MouseHandler = function(editor) { event.capture(editor.container, onMouseSelection, onMouseSelectionEnd); var timerId = setInterval(onSelectionInterval, 20); - + return event.preventDefault(e); }; - + this.onMouseDoubleClick = function(e) { + var editor = this.editor; var pos = this.$getEventPosition(e); - this.editor.moveCursorToPosition(pos); - this.editor.selection.selectWord(); - this.$clickSelection = this.editor.getSelectionRange(); + + // If the user dclicked on a fold, then expand it. + var fold = editor.session.getFoldAt(pos.row, pos.column, 1); + if (fold) { + editor.session.expandFold(fold); + } else { + editor.moveCursorToPosition(pos); + editor.selection.selectWord(); + this.$clickSelection = editor.getSelectionRange(); + } }; - + this.onMouseTripleClick = function(e) { var pos = this.$getEventPosition(e); this.editor.moveCursorToPosition(pos); this.editor.selection.selectLine(); this.$clickSelection = this.editor.getSelectionRange(); }; - + this.onMouseQuadClick = function(e) { this.editor.selectAll(); this.$clickSelection = this.editor.getSelectionRange(); }; - + this.onMouseWheel = function(e) { var speed = this.$scrollSpeed * 2; - + this.editor.renderer.scrollBy(e.wheelX * speed, e.wheelY * speed); return event.preventDefault(e); }; From 6cc2453f8ba60f5f02050b7174c9e274a658c178 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Fri, 20 May 2011 19:53:34 +0200 Subject: [PATCH 2/4] Demo: Fold comments if the cursor is inside of a comment block --- demo/demo.js | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 7b0646db..6e0fa34e 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -496,14 +496,34 @@ exports.launch = function(env) { } }); + function isCommentRow(row) { + var session = env.editor.session; + var token; + var tokens = session.getTokens(row, row)[0].tokens; + var c = 0; + for (var i = 0; i < tokens.length; i++) { + token = tokens[i]; + if (/^comment/.test(token.type)) { + return c; + } else if (!/^text/.test(token.type)) { + return false; + } + c += token.value.length; + } + return false; + }; + function toggleFold(env, tryToUnfold) { - var session = env.editor.session, - selection = env.editor.selection, - range = selection.getRange(), addFold; + var session = env.editor.session; + var selection = env.editor.selection; + var range = selection.getRange(); + var addFold; if(range.isEmpty()) { var br = session.findMatchingBracket(range.start); - var fold = session.getFoldAt(range.start.row, range.start.column) + var fold = session.getFoldAt(range.start.row, range.start.column); + var column; + if(fold) { session.expandFold(fold); selection.setSelectionRange(fold.range) @@ -513,6 +533,22 @@ exports.launch = function(env) { else range.start = br; addFold = true; + } else if ((column = isCommentRow(range.start.row)) !== false) { + var firstCommentRow = range.start.row; + var lastCommentRow = range.start.row; + var t; + while ((t = isCommentRow(firstCommentRow - 1)) !== false) { + firstCommentRow --; + column = t; + } + while (isCommentRow(lastCommentRow + 1) !== false) { + lastCommentRow ++; + } + range.start.row = firstCommentRow; + range.start.column = column + 2; + range.end.row = lastCommentRow; + range.end.column = session.getLine(lastCommentRow).length - 1; + addFold = true; } } else { var folds = session.getFoldsInRange(range); From 50aac69d56c43b918b858aadaed764a63cca1ceb Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Mon, 23 May 2011 19:41:47 +0200 Subject: [PATCH 3/4] Fold on selection - dont expand in the demo. Otherwise it's hard to test nested folding --- demo/demo.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/demo/demo.js b/demo/demo.js index 6e0fa34e..7854cce9 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -551,13 +551,7 @@ exports.launch = function(env) { addFold = true; } } else { - var folds = session.getFoldsInRange(range); - if(tryToUnfold && folds.length) - session.expandFolds(folds); - else if(folds.length == 1 && folds[0].range.compare(range) == 0) - session.expandFolds(folds); - else - addFold = true; + addFold = true; } if(addFold) { var placeHolder = session.getTextRange(range); From c87f10e6d984907da9afadd8e71f2f08d4028367 Mon Sep 17 00:00:00 2001 From: Julian Viereck Date: Fri, 20 May 2011 20:14:36 +0200 Subject: [PATCH 4/4] Add a vertical line on the gutter to indicate wrapped lines --- lib/ace/layer/gutter.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/ace/layer/gutter.js b/lib/ace/layer/gutter.js index 0d2fe564..190fa6f1 100644 --- a/lib/ace/layer/gutter.js +++ b/lib/ace/layer/gutter.js @@ -108,7 +108,7 @@ var Gutter = function(parentEl) { while (true) { if(i > foldStart) { - i = fold.end.row+1; + i = fold.end.row + 1; fold = this.session.getNextFold(i); foldStart = fold ?fold.start.row :Infinity; } @@ -121,7 +121,14 @@ var Gutter = function(parentEl) { this.$breakpoints[i] ? " ace_breakpoint " : " ", annotation.className, "' title='", annotation.text.join("\n"), - "' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), ""); + "' style='height:", config.lineHeight, "px;'>", (i+1)); + + var wrappedRowLength = this.session.getRowLength(i) - 1; + while (wrappedRowLength--) { + html.push("
¦
"); + } + + html.push(""); i++; }