diff --git a/demo/demo.js b/demo/demo.js index 0437c78c..5b4b883f 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -257,6 +257,10 @@ exports.launch = function(env) { env.editor.renderer.setShowPrintMargin(checked); }); + bindCheckbox("highlight_selected_word", function(checked) { + env.editor.setHighlightSelectedWord(checked); + }); + function bindCheckbox(id, callback) { var el = document.getElementById(id); var onCheck = function() { diff --git a/index.html b/index.html index d4557f3b..9fa06ea9 100644 --- a/index.html +++ b/index.html @@ -108,6 +108,10 @@ + + + + diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index c2f3abff..82401624 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -143,3 +143,8 @@ position: absolute; z-index: 2; } + +.ace_marker-layer .ace_selected_word { + position: absolute; + z-index: 6; +} diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 60a14c1b..b101c173 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -334,6 +334,9 @@ var Editor =function(renderer, session) { } this.onCursorChange(e); + + if (this.$highlightSelectedWord) + this.mode.highlightSelection(this); }; this.onChangeFrontMarker = function() { @@ -528,6 +531,22 @@ var Editor =function(renderer, session) { return this.$highlightActiveLine; }; + this.$highlightSelectedWord = true; + this.setHighlightSelectedWord = function(shouldHighlight) { + if (this.$highlightSelectedWord == shouldHighlight) + return; + + this.$highlightSelectedWord = shouldHighlight; + if (shouldHighlight) + this.mode.highlightSelection(this); + else + this.mode.clearSelectionHighlight(this); + }; + + this.getHighlightSelectedWord = function() { + return this.$highlightSelectedWord; + }; + this.setShowInvisibles = function(showInvisibles) { if (this.getShowInvisibles() == showInvisibles) return; diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index fe1c9f17..6fc68588 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -1,4 +1,5 @@ -/* ***** BEGIN LICENSE BLOCK ***** +/* vim:ts=4:sts=4:sw=4: + * ***** 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 @@ -20,6 +21,7 @@ * * Contributor(s): * Fabian Jakobs + * Mihai Sucan * * 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 @@ -77,6 +79,65 @@ var Mode = function() { return null; }; + this.highlightSelection = function(editor) { + var session = editor.session; + if (!session.$selectionOccurrences) + session.$selectionOccurrences = []; + + if (session.$selectionOccurrences.length) + this.clearSelectionHighlight(editor); + + var selection = editor.getSelectionRange(); + if (selection.isEmpty() || selection.isMultiLine()) + return; + + var startOuter = selection.start.column - 1; + var endOuter = selection.end.column + 1; + var line = session.getLine(selection.start.row); + var lineCols = line.length - 1; + var needle = line.substring(Math.max(startOuter, 0), + Math.min(endOuter, lineCols)); + + // Make sure the outer characters are not part of the word. + if ((startOuter >= 0 && !/[^\w\d]/.test(needle.charAt(0))) || + (endOuter <= lineCols && !/[^\w\d]/.test(needle.charAt(needle.length - 1)))) + return; + + needle = line.substring(selection.start.column, selection.end.column); + if (!/^[\w\d]+$/.test(needle)) + return; + + var newOptions = { + wrap: true, + wholeWord: true, + needle: needle + }; + + var currentOptions = editor.$search.getOptions(); + editor.$search.set(newOptions); + + var ranges = editor.$search.findAll(session); + session.$selectionOccurrences = []; + ranges.forEach(function(range) { + if (!range.contains(selection.start.row, selection.start.column)) { + var marker = editor.renderer.addMarker(range, + "ace_selected_word"); + session.$selectionOccurrences.push(marker); + } + }); + + editor.$search.set(currentOptions); + }; + + this.clearSelectionHighlight = function(editor) { + if (!editor.session.$selectionOccurrences) + return; + + editor.session.$selectionOccurrences.forEach(function(marker) { + editor.renderer.removeMarker(marker); + }); + }; + }).call(Mode.prototype); exports.Mode = Mode; diff --git a/lib/ace/mouse_handler.js b/lib/ace/mouse_handler.js index 5e836383..b3a16833 100644 --- a/lib/ace/mouse_handler.js +++ b/lib/ace/mouse_handler.js @@ -165,4 +165,4 @@ var MouseHandler = function(editor) { }).call(MouseHandler.prototype); exports.MouseHandler = MouseHandler; -}); \ No newline at end of file +}); diff --git a/lib/ace/theme/tm.css b/lib/ace/theme/tm.css index 0993335c..987901d1 100644 --- a/lib/ace/theme/tm.css +++ b/lib/ace/theme/tm.css @@ -131,6 +131,11 @@ background: rgb(232, 242, 254); } +.ace-tm .ace_marker-layer .ace_selected_word { + background: rgb(250, 250, 255); + border: 1px solid rgb(200, 200, 250); +} + .ace-tm .ace_string.ace_regex { color: rgb(255, 0, 0) -} \ No newline at end of file +}