diff --git a/demo/demo.js b/demo/demo.js index 7b0646db..7854cce9 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,15 +533,25 @@ 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); - 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); 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/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++; } 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); };