Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Side by Side Diff: Source/devtools/front_end/CodeMirrorTextEditor.js

Issue 219583002: DevTools: [CodeMirror] Implement "select next occurrence" functionality (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: add testcase Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 "End": "goLineEnd", 82 "End": "goLineEnd",
83 "Home": "goLineStartSmart", 83 "Home": "goLineStartSmart",
84 "PageUp": "goPageUp", 84 "PageUp": "goPageUp",
85 "PageDown": "goPageDown", 85 "PageDown": "goPageDown",
86 "Delete": "delCharAfter", 86 "Delete": "delCharAfter",
87 "Backspace": "delCharBefore", 87 "Backspace": "delCharBefore",
88 "Tab": "defaultTab", 88 "Tab": "defaultTab",
89 "Shift-Tab": "indentLess", 89 "Shift-Tab": "indentLess",
90 "Enter": "smartNewlineAndIndent", 90 "Enter": "smartNewlineAndIndent",
91 "Ctrl-Space": "autocomplete", 91 "Ctrl-Space": "autocomplete",
92 "Ctrl-D": "selectNextOccurence",
apavlov 2014/04/01 08:24:58 ditto for this file
92 "Esc": "dismissMultipleSelections" 93 "Esc": "dismissMultipleSelections"
93 }; 94 };
94 95
95 CodeMirror.keyMap["devtools-pc"] = { 96 CodeMirror.keyMap["devtools-pc"] = {
96 "Ctrl-A": "selectAll", 97 "Ctrl-A": "selectAll",
97 "Ctrl-Z": "undoAndReveal", 98 "Ctrl-Z": "undoAndReveal",
98 "Shift-Ctrl-Z": "redoAndReveal", 99 "Shift-Ctrl-Z": "redoAndReveal",
99 "Ctrl-Y": "redo", 100 "Ctrl-Y": "redo",
100 "Ctrl-Home": "goDocStart", 101 "Ctrl-Home": "goDocStart",
101 "Ctrl-Up": "goDocStart", 102 "Ctrl-Up": "goDocStart",
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 this._codeMirror.setOption("keyMap", WebInspector.isMac() ? "devtools-mac" : "devtools-pc"); 137 this._codeMirror.setOption("keyMap", WebInspector.isMac() ? "devtools-mac" : "devtools-pc");
137 this._codeMirror.setOption("flattenSpans", false); 138 this._codeMirror.setOption("flattenSpans", false);
138 139
139 this._codeMirror.setOption("maxHighlightLength", WebInspector.CodeMirrorText Editor.maxHighlightLength); 140 this._codeMirror.setOption("maxHighlightLength", WebInspector.CodeMirrorText Editor.maxHighlightLength);
140 this._codeMirror.setOption("mode", null); 141 this._codeMirror.setOption("mode", null);
141 this._codeMirror.setOption("crudeMeasuringFrom", 1000); 142 this._codeMirror.setOption("crudeMeasuringFrom", 1000);
142 143
143 this._shouldClearHistory = true; 144 this._shouldClearHistory = true;
144 this._lineSeparator = "\n"; 145 this._lineSeparator = "\n";
145 146
146 this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighligh ter(this._codeMirror); 147 this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighligh ter(this, this._codeMirror);
147 this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockInd entController(this._codeMirror); 148 this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockInd entController(this._codeMirror);
148 this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovemen t(this._codeMirror); 149 this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovemen t(this._codeMirror);
149 this._autocompleteController = new WebInspector.CodeMirrorTextEditor.Autocom pleteController(this, this._codeMirror); 150 this._autocompleteController = new WebInspector.CodeMirrorTextEditor.Autocom pleteController(this, this._codeMirror);
151 this._selectNextOccurenceController = new WebInspector.CodeMirrorTextEditor. SelectNextOccurenceController(this, this._codeMirror);
150 152
151 this._codeMirror.on("changes", this._changes.bind(this)); 153 this._codeMirror.on("changes", this._changes.bind(this));
152 this._codeMirror.on("beforeChange", this._beforeChange.bind(this)); 154 this._codeMirror.on("beforeChange", this._beforeChange.bind(this));
153 this._codeMirror.on("gutterClick", this._gutterClick.bind(this)); 155 this._codeMirror.on("gutterClick", this._gutterClick.bind(this));
154 this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this)); 156 this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this));
155 this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bin d(this)); 157 this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bin d(this));
156 this._codeMirror.on("scroll", this._scroll.bind(this)); 158 this._codeMirror.on("scroll", this._scroll.bind(this));
157 this._codeMirror.on("focus", this._focus.bind(this)); 159 this._codeMirror.on("focus", this._focus.bind(this));
158 this._codeMirror.on("blur", this._blur.bind(this)); 160 this._codeMirror.on("blur", this._blur.bind(this));
159 this.element.addEventListener("contextmenu", this._contextMenu.bind(this), f alse); 161 this.element.addEventListener("contextmenu", this._contextMenu.bind(this), f alse);
(...skipping 22 matching lines...) Expand all
182 } 184 }
183 185
184 /** @typedef {{canceled: boolean, from: CodeMirror.Pos, to: CodeMirror.Pos, text : string, origin: string, cancel: function()}} */ 186 /** @typedef {{canceled: boolean, from: CodeMirror.Pos, to: CodeMirror.Pos, text : string, origin: string, cancel: function()}} */
185 WebInspector.CodeMirrorTextEditor.BeforeChangeObject; 187 WebInspector.CodeMirrorTextEditor.BeforeChangeObject;
186 188
187 /** @typedef {{from: CodeMirror.Pos, to: CodeMirror.Pos, origin: string, text: ! Array.<string>, removed: !Array.<string>}} */ 189 /** @typedef {{from: CodeMirror.Pos, to: CodeMirror.Pos, origin: string, text: ! Array.<string>, removed: !Array.<string>}} */
188 WebInspector.CodeMirrorTextEditor.ChangeObject; 190 WebInspector.CodeMirrorTextEditor.ChangeObject;
189 191
190 WebInspector.CodeMirrorTextEditor.maxHighlightLength = 1000; 192 WebInspector.CodeMirrorTextEditor.maxHighlightLength = 1000;
191 193
194 /**
195 * @param {!CodeMirror} codeMirror
196 */
192 WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror) 197 WebInspector.CodeMirrorTextEditor.autocompleteCommand = function(codeMirror)
193 { 198 {
194 codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete(); 199 codeMirror._codeMirrorTextEditor._autocompleteController.autocomplete();
195 } 200 }
196 CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocomplet eCommand; 201 CodeMirror.commands.autocomplete = WebInspector.CodeMirrorTextEditor.autocomplet eCommand;
197 202
203 /**
204 * @param {!CodeMirror} codeMirror
205 */
206 WebInspector.CodeMirrorTextEditor.selectNextOccurenceCommand = function(codeMirr or)
207 {
208 codeMirror._codeMirrorTextEditor._selectNextOccurenceController.selectNextOc curence();
209 }
210 CodeMirror.commands.selectNextOccurence = WebInspector.CodeMirrorTextEditor.sele ctNextOccurenceCommand;
211
212 /**
213 * @param {!CodeMirror} codeMirror
214 */
198 CodeMirror.commands.smartNewlineAndIndent = function(codeMirror) 215 CodeMirror.commands.smartNewlineAndIndent = function(codeMirror)
199 { 216 {
200 codeMirror.operation(innerSmartNewlineAndIndent.bind(null, codeMirror)); 217 codeMirror.operation(innerSmartNewlineAndIndent.bind(null, codeMirror));
201 218
202 function countIndent(line) 219 function countIndent(line)
203 { 220 {
204 for (var i = 0; i < line.length; ++i) { 221 for (var i = 0; i < line.length; ++i) {
205 if (!WebInspector.TextUtils.isSpaceChar(line[i])) 222 if (!WebInspector.TextUtils.isSpaceChar(line[i]))
206 return i; 223 return i;
207 } 224 }
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(th is._codeMirror.indexFromPos(pos.start) + text.length)); 923 var newRange = this._toRange(pos.start, this._codeMirror.posFromIndex(th is._codeMirror.indexFromPos(pos.start) + text.length));
907 this._delegate.onTextChanged(range, newRange); 924 this._delegate.onTextChanged(range, newRange);
908 if (WebInspector.settings.textEditorAutoDetectIndent.get()) 925 if (WebInspector.settings.textEditorAutoDetectIndent.get())
909 this._updateEditorIndentation(); 926 this._updateEditorIndentation();
910 return newRange; 927 return newRange;
911 }, 928 },
912 929
913 /** 930 /**
914 * @param {number} lineNumber 931 * @param {number} lineNumber
915 * @param {number} column 932 * @param {number} column
916 * @param {boolean=} prefixOnly
917 * @return {?WebInspector.TextRange} 933 * @return {?WebInspector.TextRange}
918 */ 934 */
919 _wordRangeForCursorPosition: function(lineNumber, column, prefixOnly) 935 _wordRangeForCursorPosition: function(lineNumber, column)
920 { 936 {
921 var line = this.line(lineNumber); 937 var line = this.line(lineNumber);
922 if (column === 0 || !WebInspector.TextUtils.isWordChar(line.charAt(colum n - 1))) 938 var wordStart = column;
923 return null; 939 if (column !== 0 && WebInspector.TextUtils.isWordChar(line.charAt(column - 1))) {
924 var wordStart = column - 1; 940 wordStart = column - 1;
925 while (wordStart > 0 && WebInspector.TextUtils.isWordChar(line.charAt(wo rdStart - 1))) 941 while (wordStart > 0 && WebInspector.TextUtils.isWordChar(line.charA t(wordStart - 1)))
926 --wordStart; 942 --wordStart;
927 if (prefixOnly) 943 }
928 return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, column);
929 var wordEnd = column; 944 var wordEnd = column;
930 while (wordEnd < line.length && WebInspector.TextUtils.isWordChar(line.c harAt(wordEnd))) 945 while (wordEnd < line.length && WebInspector.TextUtils.isWordChar(line.c harAt(wordEnd)))
931 ++wordEnd; 946 ++wordEnd;
932 return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wor dEnd); 947 return new WebInspector.TextRange(lineNumber, wordStart, lineNumber, wor dEnd);
933 }, 948 },
934 949
935 /** 950 /**
936 * @param {!CodeMirror} codeMirror 951 * @param {!CodeMirror} codeMirror
937 * @param {!WebInspector.CodeMirrorTextEditor.BeforeChangeObject} changeObje ct 952 * @param {!WebInspector.CodeMirrorTextEditor.BeforeChangeObject} changeObje ct
938 */ 953 */
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 if (!this._tokenHighlighter.highlightedRegex()) 1028 if (!this._tokenHighlighter.highlightedRegex())
1014 this._codeMirror.operation(this._tokenHighlighter.highlightSelectedT okens.bind(this._tokenHighlighter)); 1029 this._codeMirror.operation(this._tokenHighlighter.highlightSelectedT okens.bind(this._tokenHighlighter));
1015 }, 1030 },
1016 1031
1017 /** 1032 /**
1018 * @param {!CodeMirror} codeMirror 1033 * @param {!CodeMirror} codeMirror
1019 * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos} >}} selection 1034 * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos} >}} selection
1020 */ 1035 */
1021 _beforeSelectionChange: function(codeMirror, selection) 1036 _beforeSelectionChange: function(codeMirror, selection)
1022 { 1037 {
1038 this._selectNextOccurenceController.selectionWillChange();
1023 if (!this._isHandlingMouseDownEvent) 1039 if (!this._isHandlingMouseDownEvent)
1024 return; 1040 return;
1025 if (!selection.ranges.length) 1041 if (!selection.ranges.length)
1026 return; 1042 return;
1027 var primarySelection = selection.ranges[0]; 1043 var primarySelection = selection.ranges[0];
1028 this._reportJump(this.selection(), this._toRange(primarySelection.anchor , primarySelection.head)); 1044 this._reportJump(this.selection(), this._toRange(primarySelection.anchor , primarySelection.head));
1029 }, 1045 },
1030 1046
1031 /** 1047 /**
1032 * @param {?WebInspector.TextRange} from 1048 * @param {?WebInspector.TextRange} from
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 */ 1105 */
1090 selection: function() 1106 selection: function()
1091 { 1107 {
1092 var start = this._codeMirror.getCursor("anchor"); 1108 var start = this._codeMirror.getCursor("anchor");
1093 var end = this._codeMirror.getCursor("head"); 1109 var end = this._codeMirror.getCursor("head");
1094 1110
1095 return this._toRange(start, end); 1111 return this._toRange(start, end);
1096 }, 1112 },
1097 1113
1098 /** 1114 /**
1115 * @return {!Array.<!WebInspector.TextRange>}
1116 */
1117 selections: function()
1118 {
1119 var selectionList = this._codeMirror.listSelections();
1120 var result = [];
1121 for (var i = 0; i < selectionList.length; ++i) {
1122 var selection = selectionList[i];
1123 result.push(this._toRange(selection.anchor, selection.head));
1124 }
1125 return result;
1126 },
1127
1128 /**
1099 * @return {?WebInspector.TextRange} 1129 * @return {?WebInspector.TextRange}
1100 */ 1130 */
1101 lastSelection: function() 1131 lastSelection: function()
1102 { 1132 {
1103 return this._lastSelection; 1133 return this._lastSelection;
1104 }, 1134 },
1105 1135
1106 /** 1136 /**
1107 * @param {!WebInspector.TextRange} textRange 1137 * @param {!WebInspector.TextRange} textRange
1108 */ 1138 */
1109 setSelection: function(textRange) 1139 setSelection: function(textRange)
1110 { 1140 {
1111 this._lastSelection = textRange; 1141 this._lastSelection = textRange;
1112 var pos = this._toPos(textRange); 1142 var pos = this._toPos(textRange);
1113 this._codeMirror.setSelection(pos.start, pos.end); 1143 this._codeMirror.setSelection(pos.start, pos.end);
1114 }, 1144 },
1115 1145
1116 /** 1146 /**
1147 * @param {!Array.<!WebInspector.TextRange>} ranges
1148 */
1149 setSelections: function(ranges)
1150 {
1151 var selections = [];
1152 for (var i = 0; i < ranges.length; ++i) {
1153 var selection = this._toPos(ranges[i]);
1154 selections.push({
1155 anchor: selection.start,
1156 head: selection.end
1157 });
1158 }
1159 this._codeMirror.setSelections(selections);
1160 },
1161
1162 /**
1117 * @param {string} text 1163 * @param {string} text
1118 */ 1164 */
1119 _detectLineSeparator: function(text) 1165 _detectLineSeparator: function(text)
1120 { 1166 {
1121 this._lineSeparator = text.indexOf("\r\n") >= 0 ? "\r\n" : "\n"; 1167 this._lineSeparator = text.indexOf("\r\n") >= 0 ? "\r\n" : "\n";
1122 }, 1168 },
1123 1169
1124 /** 1170 /**
1125 * @param {string} text 1171 * @param {string} text
1126 */ 1172 */
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 * @return {boolean} 1326 * @return {boolean}
1281 */ 1327 */
1282 equal: function(positionHandle) 1328 equal: function(positionHandle)
1283 { 1329 {
1284 return positionHandle._lineHandle === this._lineHandle && positionHandle ._columnNumber == this._columnNumber && positionHandle._codeMirror === this._cod eMirror; 1330 return positionHandle._lineHandle === this._lineHandle && positionHandle ._columnNumber == this._columnNumber && positionHandle._codeMirror === this._cod eMirror;
1285 } 1331 }
1286 } 1332 }
1287 1333
1288 /** 1334 /**
1289 * @constructor 1335 * @constructor
1336 * @param {!WebInspector.CodeMirrorTextEditor} textEditor
1290 * @param {!CodeMirror} codeMirror 1337 * @param {!CodeMirror} codeMirror
1291 */ 1338 */
1292 WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(codeMirror) 1339 WebInspector.CodeMirrorTextEditor.TokenHighlighter = function(textEditor, codeMi rror)
1293 { 1340 {
1341 this._textEditor = textEditor;
1294 this._codeMirror = codeMirror; 1342 this._codeMirror = codeMirror;
1295 } 1343 }
1296 1344
1297 WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = { 1345 WebInspector.CodeMirrorTextEditor.TokenHighlighter.prototype = {
1298 /** 1346 /**
1299 * @param {!RegExp} regex 1347 * @param {!RegExp} regex
1300 * @param {?WebInspector.TextRange} range 1348 * @param {?WebInspector.TextRange} range
1301 */ 1349 */
1302 highlightSearchResults: function(regex, range) 1350 highlightSearchResults: function(regex, range)
1303 { 1351 {
(...skipping 24 matching lines...) Expand all
1328 }, 1376 },
1329 1377
1330 /** 1378 /**
1331 * @return {!RegExp|undefined} 1379 * @return {!RegExp|undefined}
1332 */ 1380 */
1333 highlightedRegex: function() 1381 highlightedRegex: function()
1334 { 1382 {
1335 return this._highlightRegex; 1383 return this._highlightRegex;
1336 }, 1384 },
1337 1385
1386 /**
1387 * @param {!Array.<string>} selections
1388 */
1389 _validateSelections: function(selections)
1390 {
1391 var mainText = selections[0];
1392 for (var i = 1; i < selections.length; ++i) {
1393 if (selections[i] !== mainText)
1394 return false;
1395 }
1396 return true;
1397 },
1398
1338 highlightSelectedTokens: function() 1399 highlightSelectedTokens: function()
1339 { 1400 {
1340 delete this._highlightRegex; 1401 delete this._highlightRegex;
1341 delete this._highlightRange; 1402 delete this._highlightRange;
1342 1403
1343 if (this._highlightDescriptor && this._highlightDescriptor.selectionStar t) 1404 if (this._highlightDescriptor && this._highlightDescriptor.selectionStar t)
1344 this._codeMirror.removeLineClass(this._highlightDescriptor.selection Start.line, "wrap", "cm-line-with-selection"); 1405 this._codeMirror.removeLineClass(this._highlightDescriptor.selection Start.line, "wrap", "cm-line-with-selection");
1345 this._removeHighlight(); 1406 this._removeHighlight();
1346 var selectionStart = this._codeMirror.getCursor("start"); 1407 var selectionStart = this._codeMirror.getCursor("start");
1347 var selectionEnd = this._codeMirror.getCursor("end"); 1408 var selectionEnd = this._codeMirror.getCursor("end");
1348 if (selectionStart.line !== selectionEnd.line) 1409 if (selectionStart.line !== selectionEnd.line)
1349 return; 1410 return;
1350 if (selectionStart.ch === selectionEnd.ch) 1411 if (selectionStart.ch === selectionEnd.ch)
1351 return; 1412 return;
1352 1413
1353 var selections = this._codeMirror.getSelections(); 1414 var selections = this._codeMirror.getSelections();
1354 if (selections.length !== 1) 1415 if (!this._validateSelections(selections))
1355 return; 1416 return;
1356 var selectedText = selections[0]; 1417 var selectedText = selections[0];
1357 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s electionEnd.ch)) { 1418 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s electionEnd.ch)) {
1358 if (selectionStart) 1419 if (selectionStart)
1359 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l ine-with-selection") 1420 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l ine-with-selection")
1360 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart); 1421 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText, selectionStart), selectionStart);
1361 } 1422 }
1362 }, 1423 },
1363 1424
1364 /** 1425 /**
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { 1639 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = {
1579 /** 1640 /**
1580 * @param {!WebInspector.TextRange} mainSelection 1641 * @param {!WebInspector.TextRange} mainSelection
1581 * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selec tions 1642 * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selec tions
1582 * @return {boolean} 1643 * @return {boolean}
1583 */ 1644 */
1584 _validateSelectionsContexts: function(mainSelection, selections) 1645 _validateSelectionsContexts: function(mainSelection, selections)
1585 { 1646 {
1586 var mainSelectionContext = this._textEditor.copyRange(mainSelection); 1647 var mainSelectionContext = this._textEditor.copyRange(mainSelection);
1587 for (var i = 0; i < selections.length; ++i) { 1648 for (var i = 0; i < selections.length; ++i) {
1588 var wordRange = this._textEditor._wordRangeForCursorPosition(selecti ons[i].head.line, selections[i].head.ch, false); 1649 var wordRange = this._textEditor._wordRangeForCursorPosition(selecti ons[i].head.line, selections[i].head.ch);
1589 if (!wordRange) 1650 if (!wordRange)
1590 return false; 1651 return false;
1591 var context = this._textEditor.copyRange(wordRange); 1652 var context = this._textEditor.copyRange(wordRange);
1592 if (context !== mainSelectionContext) 1653 if (context !== mainSelectionContext)
1593 return false; 1654 return false;
1594 } 1655 }
1595 return true; 1656 return true;
1596 }, 1657 },
1597 1658
1598 autocomplete: function() 1659 autocomplete: function()
1599 { 1660 {
1600 var dictionary = this._textEditor._dictionary; 1661 var dictionary = this._textEditor._dictionary;
1601 if (!dictionary || this._codeMirror.somethingSelected()) { 1662 if (!dictionary || this._codeMirror.somethingSelected()) {
1602 this.finishAutocomplete(); 1663 this.finishAutocomplete();
1603 return; 1664 return;
1604 } 1665 }
1605 1666
1606 var selections = this._codeMirror.listSelections().slice(); 1667 var selections = this._codeMirror.listSelections().slice();
1607 var topSelection = selections.shift(); 1668 var topSelection = selections.shift();
1608 var cursor = topSelection.head; 1669 var cursor = topSelection.head;
1609 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso r.line, cursor.ch, false); 1670 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso r.line, cursor.ch);
1610 if (!substituteRange || substituteRange.startColumn === cursor.ch || !th is._validateSelectionsContexts(substituteRange, selections)) { 1671 if (!substituteRange || substituteRange.startColumn === cursor.ch || !th is._validateSelectionsContexts(substituteRange, selections)) {
1611 this.finishAutocomplete(); 1672 this.finishAutocomplete();
1612 return; 1673 return;
1613 } 1674 }
1614 1675
1615 var prefixRange = substituteRange.clone(); 1676 var prefixRange = substituteRange.clone();
1616 prefixRange.endColumn = cursor.ch; 1677 prefixRange.endColumn = cursor.ch;
1617 1678
1618 var substituteWord = this._textEditor.copyRange(substituteRange); 1679 var substituteWord = this._textEditor.copyRange(substituteRange);
1619 var hasPrefixInDictionary = dictionary.hasWord(substituteWord); 1680 var hasPrefixInDictionary = dictionary.hasWord(substituteWord);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 * @return {?AnchorBox} 1785 * @return {?AnchorBox}
1725 */ 1786 */
1726 _anchorBoxForPosition: function(line, column) 1787 _anchorBoxForPosition: function(line, column)
1727 { 1788 {
1728 var metrics = this._textEditor.cursorPositionToCoordinates(line, column) ; 1789 var metrics = this._textEditor.cursorPositionToCoordinates(line, column) ;
1729 return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null; 1790 return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height) : null;
1730 }, 1791 },
1731 } 1792 }
1732 1793
1733 /** 1794 /**
1795 * @constructor
1796 * @param {!WebInspector.CodeMirrorTextEditor} textEditor
1797 * @param {!CodeMirror} codeMirror
1798 */
1799 WebInspector.CodeMirrorTextEditor.SelectNextOccurenceController = function(textE ditor, codeMirror)
1800 {
1801 this._textEditor = textEditor;
1802 this._codeMirror = codeMirror;
1803 }
1804
1805 WebInspector.CodeMirrorTextEditor.SelectNextOccurenceController.prototype = {
1806 selectionWillChange: function()
1807 {
1808 if (!this._muteSelectionListener)
1809 delete this._fullWordSelection;
1810 },
1811
1812 /**
1813 * @param {!Array.<!WebInspector.TextRange>} selections
1814 * @param {!WebInspector.TextRange} range
1815 * @return {boolean}
1816 */
1817 _findRange: function(selections, range)
1818 {
1819 for (var i = 0; i < selections.length; ++i) {
1820 if (range.equal(selections[i]))
1821 return true;
1822 }
1823 return false;
1824 },
1825
1826 selectNextOccurence: function()
1827 {
1828 var selections = this._textEditor.selections();
1829 var anyEmptySelection = false;
1830 for (var i = 0; i < selections.length; ++i) {
1831 var selection = selections[i];
1832 anyEmptySelection = anyEmptySelection || selection.isEmpty();
1833 if (selection.startLine !== selection.endLine)
1834 return;
1835 }
1836 if (anyEmptySelection) {
1837 this._expandSelectionsToWords(selections);
1838 return;
1839 }
1840
1841 var last = selections[selections.length - 1];
1842 var next = last;
1843 do {
1844 next = this._findNextOccurence(next, !!this._fullWordSelection);
1845 } while (next && this._findRange(selections, next) && !next.equal(last)) ;
1846
1847 if (!next)
1848 return;
1849 selections.push(next);
1850
1851 this._muteSelectionListener = true;
1852 this._textEditor.setSelections(selections);
1853 delete this._muteSelectionListener;
1854
1855 this._textEditor._revealLine(next.startLine);
1856 },
1857
1858 /**
1859 * @param {!Array.<!WebInspector.TextRange>} selections
1860 */
1861 _expandSelectionsToWords: function(selections)
1862 {
1863 var newSelections = [];
1864 for (var i = 0; i < selections.length; ++i) {
1865 var selection = selections[i];
1866 var startRangeWord = this._textEditor._wordRangeForCursorPosition(se lection.startLine, selection.startColumn)
1867 || WebInspector.TextRange.createFromLocation(selection.startLine , selection.startColumn);
1868 var endRangeWord = this._textEditor._wordRangeForCursorPosition(sele ction.endLine, selection.endColumn)
1869 || WebInspector.TextRange.createFromLocation(selection.endLine, selection.endColumn);
1870 var newSelection = new WebInspector.TextRange(startRangeWord.startLi ne, startRangeWord.startColumn, endRangeWord.endLine, endRangeWord.endColumn);
1871 newSelections.push(newSelection);
1872 }
1873 this._textEditor.setSelections(newSelections);
1874 this._fullWordSelection = true;
1875 },
1876
1877 /**
1878 * @param {!WebInspector.TextRange} range
1879 * @param {boolean} fullWord
1880 * @return {?WebInspector.TextRange}
1881 */
1882 _findNextOccurence: function(range, fullWord)
1883 {
1884 range = range.normalize();
1885 var matchedLineNumber;
1886 var matchedColumnNumber;
1887 var textToFind = this._textEditor.copyRange(range);
1888 function findWordInLine(wordRegex, lineNumber, lineText, from, to)
1889 {
1890 if (typeof matchedLineNumber === "number")
1891 return true;
1892 wordRegex.lastIndex = from;
1893 var result = wordRegex.exec(lineText);
1894 if (!result || result.index + textToFind.length > to)
1895 return false;
1896 matchedLineNumber = lineNumber;
1897 matchedColumnNumber = result.index;
1898 return true;
1899 }
1900
1901 var iteratedLineNumber;
1902 function lineIterator(regex, lineHandle)
1903 {
1904 if (findWordInLine(regex, iteratedLineNumber++, lineHandle.text, 0, lineHandle.text.length))
1905 return true;
1906 }
1907
1908 var regexSource = textToFind.escapeForRegExp();
1909 if (fullWord)
1910 regexSource = "\\b" + regexSource + "\\b";
1911 var wordRegex = new RegExp(regexSource, "gi");
1912 var currentLineText = this._codeMirror.getLine(range.startLine);
1913
1914 findWordInLine(wordRegex, range.startLine, currentLineText, range.endCol umn, currentLineText.length);
1915 iteratedLineNumber = range.startLine + 1;
1916 this._codeMirror.eachLine(range.startLine + 1, this._codeMirror.lineCoun t(), lineIterator.bind(null, wordRegex));
1917 iteratedLineNumber = 0;
1918 this._codeMirror.eachLine(0, range.startLine, lineIterator.bind(null, wo rdRegex));
1919 findWordInLine(wordRegex, range.startLine, currentLineText, 0, range.sta rtColumn);
1920
1921 if (typeof matchedLineNumber !== "number")
1922 return null;
1923 return new WebInspector.TextRange(matchedLineNumber, matchedColumnNumber , matchedLineNumber, matchedColumnNumber + textToFind.length);
1924 }
1925 }
1926
1927 /**
1734 * @param {string} modeName 1928 * @param {string} modeName
1735 * @param {string} tokenPrefix 1929 * @param {string} tokenPrefix
1736 */ 1930 */
1737 WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(mod eName, tokenPrefix) 1931 WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(mod eName, tokenPrefix)
1738 { 1932 {
1739 var oldModeName = modeName + "-old"; 1933 var oldModeName = modeName + "-old";
1740 if (CodeMirror.modes[oldModeName]) 1934 if (CodeMirror.modes[oldModeName])
1741 return; 1935 return;
1742 1936
1743 CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]); 1937 CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]);
(...skipping 27 matching lines...) Expand all
1771 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte d { background-color: " + backgroundColor + ";}" : ""; 1965 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte d { background-color: " + backgroundColor + ";}" : "";
1772 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); 1966 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor();
1773 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import ant;}" : ""; 1967 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import ant;}" : "";
1774 if (!foregroundColorRule && !backgroundColorRule) 1968 if (!foregroundColorRule && !backgroundColorRule)
1775 return; 1969 return;
1776 1970
1777 var style = document.createElement("style"); 1971 var style = document.createElement("style");
1778 style.textContent = backgroundColorRule + foregroundColorRule; 1972 style.textContent = backgroundColorRule + foregroundColorRule;
1779 document.head.appendChild(style); 1973 document.head.appendChild(style);
1780 })(); 1974 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698