OLD | NEW |
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 Loading... |
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": "selectNextOccurrence", |
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 Loading... |
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._selectNextOccurrenceController = new WebInspector.CodeMirrorTextEditor
.SelectNextOccurrenceController(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 Loading... |
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.selectNextOccurrenceCommand = function(codeMir
ror) |
| 207 { |
| 208 codeMirror._codeMirrorTextEditor._selectNextOccurrenceController.selectNextO
ccurrence(); |
| 209 } |
| 210 CodeMirror.commands.selectNextOccurrence = WebInspector.CodeMirrorTextEditor.sel
ectNextOccurrenceCommand; |
| 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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 */ | 365 */ |
349 function innerHighlightRegex() | 366 function innerHighlightRegex() |
350 { | 367 { |
351 if (range) { | 368 if (range) { |
352 this._revealLine(range.startLine); | 369 this._revealLine(range.startLine); |
353 if (range.endColumn > WebInspector.CodeMirrorTextEditor.maxHighl
ightLength) | 370 if (range.endColumn > WebInspector.CodeMirrorTextEditor.maxHighl
ightLength) |
354 this.setSelection(range); | 371 this.setSelection(range); |
355 else | 372 else |
356 this.setSelection(WebInspector.TextRange.createFromLocation(
range.startLine, range.startColumn)); | 373 this.setSelection(WebInspector.TextRange.createFromLocation(
range.startLine, range.startColumn)); |
357 } else { | 374 } else { |
358 // Collapse selection to end on search start so that we jump to
next occurence on the first enter press. | 375 // Collapse selection to end on search start so that we jump to
next occurrence on the first enter press. |
359 this.setSelection(this.selection().collapseToEnd()); | 376 this.setSelection(this.selection().collapseToEnd()); |
360 } | 377 } |
361 this._tokenHighlighter.highlightSearchResults(regex, range); | 378 this._tokenHighlighter.highlightSearchResults(regex, range); |
362 } | 379 } |
363 if (!this._selectionBeforeSearch) | 380 if (!this._selectionBeforeSearch) |
364 this._selectionBeforeSearch = this.selection(); | 381 this._selectionBeforeSearch = this.selection(); |
365 this._codeMirror.operation(innerHighlightRegex.bind(this)); | 382 this._codeMirror.operation(innerHighlightRegex.bind(this)); |
366 }, | 383 }, |
367 | 384 |
368 cancelSearchResultsHighlight: function() | 385 cancelSearchResultsHighlight: function() |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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._selectNextOccurrenceController.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 Loading... |
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, 0, { scroll: false }); |
| 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 Loading... |
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1344 this._codeMirror.removeLineClass(this._highlightDescriptor.selection
Start.line, "wrap", "cm-line-with-selection"); | 1392 this._codeMirror.removeLineClass(this._highlightDescriptor.selection
Start.line, "wrap", "cm-line-with-selection"); |
1345 this._removeHighlight(); | 1393 this._removeHighlight(); |
1346 var selectionStart = this._codeMirror.getCursor("start"); | 1394 var selectionStart = this._codeMirror.getCursor("start"); |
1347 var selectionEnd = this._codeMirror.getCursor("end"); | 1395 var selectionEnd = this._codeMirror.getCursor("end"); |
1348 if (selectionStart.line !== selectionEnd.line) | 1396 if (selectionStart.line !== selectionEnd.line) |
1349 return; | 1397 return; |
1350 if (selectionStart.ch === selectionEnd.ch) | 1398 if (selectionStart.ch === selectionEnd.ch) |
1351 return; | 1399 return; |
1352 | 1400 |
1353 var selections = this._codeMirror.getSelections(); | 1401 var selections = this._codeMirror.getSelections(); |
1354 if (selections.length !== 1) | 1402 if (selections.length > 1) |
1355 return; | 1403 return; |
1356 var selectedText = selections[0]; | 1404 var selectedText = selections[0]; |
1357 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s
electionEnd.ch)) { | 1405 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s
electionEnd.ch)) { |
1358 if (selectionStart) | 1406 if (selectionStart) |
1359 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l
ine-with-selection") | 1407 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l
ine-with-selection") |
1360 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText,
selectionStart), selectionStart); | 1408 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText,
selectionStart), selectionStart); |
1361 } | 1409 } |
1362 }, | 1410 }, |
1363 | 1411 |
1364 /** | 1412 /** |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1578 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { | 1626 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { |
1579 /** | 1627 /** |
1580 * @param {!WebInspector.TextRange} mainSelection | 1628 * @param {!WebInspector.TextRange} mainSelection |
1581 * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selec
tions | 1629 * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selec
tions |
1582 * @return {boolean} | 1630 * @return {boolean} |
1583 */ | 1631 */ |
1584 _validateSelectionsContexts: function(mainSelection, selections) | 1632 _validateSelectionsContexts: function(mainSelection, selections) |
1585 { | 1633 { |
1586 var mainSelectionContext = this._textEditor.copyRange(mainSelection); | 1634 var mainSelectionContext = this._textEditor.copyRange(mainSelection); |
1587 for (var i = 0; i < selections.length; ++i) { | 1635 for (var i = 0; i < selections.length; ++i) { |
1588 var wordRange = this._textEditor._wordRangeForCursorPosition(selecti
ons[i].head.line, selections[i].head.ch, false); | 1636 var wordRange = this._textEditor._wordRangeForCursorPosition(selecti
ons[i].head.line, selections[i].head.ch); |
1589 if (!wordRange) | 1637 if (!wordRange) |
1590 return false; | 1638 return false; |
1591 var context = this._textEditor.copyRange(wordRange); | 1639 var context = this._textEditor.copyRange(wordRange); |
1592 if (context !== mainSelectionContext) | 1640 if (context !== mainSelectionContext) |
1593 return false; | 1641 return false; |
1594 } | 1642 } |
1595 return true; | 1643 return true; |
1596 }, | 1644 }, |
1597 | 1645 |
1598 autocomplete: function() | 1646 autocomplete: function() |
1599 { | 1647 { |
1600 var dictionary = this._textEditor._dictionary; | 1648 var dictionary = this._textEditor._dictionary; |
1601 if (!dictionary || this._codeMirror.somethingSelected()) { | 1649 if (!dictionary || this._codeMirror.somethingSelected()) { |
1602 this.finishAutocomplete(); | 1650 this.finishAutocomplete(); |
1603 return; | 1651 return; |
1604 } | 1652 } |
1605 | 1653 |
1606 var selections = this._codeMirror.listSelections().slice(); | 1654 var selections = this._codeMirror.listSelections().slice(); |
1607 var topSelection = selections.shift(); | 1655 var topSelection = selections.shift(); |
1608 var cursor = topSelection.head; | 1656 var cursor = topSelection.head; |
1609 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso
r.line, cursor.ch, false); | 1657 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso
r.line, cursor.ch); |
1610 if (!substituteRange || substituteRange.startColumn === cursor.ch || !th
is._validateSelectionsContexts(substituteRange, selections)) { | 1658 if (!substituteRange || substituteRange.startColumn === cursor.ch || !th
is._validateSelectionsContexts(substituteRange, selections)) { |
1611 this.finishAutocomplete(); | 1659 this.finishAutocomplete(); |
1612 return; | 1660 return; |
1613 } | 1661 } |
1614 | 1662 |
1615 var prefixRange = substituteRange.clone(); | 1663 var prefixRange = substituteRange.clone(); |
1616 prefixRange.endColumn = cursor.ch; | 1664 prefixRange.endColumn = cursor.ch; |
1617 | 1665 |
1618 var substituteWord = this._textEditor.copyRange(substituteRange); | 1666 var substituteWord = this._textEditor.copyRange(substituteRange); |
1619 var hasPrefixInDictionary = dictionary.hasWord(substituteWord); | 1667 var hasPrefixInDictionary = dictionary.hasWord(substituteWord); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1724 * @return {?AnchorBox} | 1772 * @return {?AnchorBox} |
1725 */ | 1773 */ |
1726 _anchorBoxForPosition: function(line, column) | 1774 _anchorBoxForPosition: function(line, column) |
1727 { | 1775 { |
1728 var metrics = this._textEditor.cursorPositionToCoordinates(line, column)
; | 1776 var metrics = this._textEditor.cursorPositionToCoordinates(line, column)
; |
1729 return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height)
: null; | 1777 return metrics ? new AnchorBox(metrics.x, metrics.y, 0, metrics.height)
: null; |
1730 }, | 1778 }, |
1731 } | 1779 } |
1732 | 1780 |
1733 /** | 1781 /** |
| 1782 * @constructor |
| 1783 * @param {!WebInspector.CodeMirrorTextEditor} textEditor |
| 1784 * @param {!CodeMirror} codeMirror |
| 1785 */ |
| 1786 WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController = function(text
Editor, codeMirror) |
| 1787 { |
| 1788 this._textEditor = textEditor; |
| 1789 this._codeMirror = codeMirror; |
| 1790 } |
| 1791 |
| 1792 WebInspector.CodeMirrorTextEditor.SelectNextOccurrenceController.prototype = { |
| 1793 selectionWillChange: function() |
| 1794 { |
| 1795 if (!this._muteSelectionListener) |
| 1796 delete this._fullWordSelection; |
| 1797 }, |
| 1798 |
| 1799 /** |
| 1800 * @param {!Array.<!WebInspector.TextRange>} selections |
| 1801 * @param {!WebInspector.TextRange} range |
| 1802 * @return {boolean} |
| 1803 */ |
| 1804 _findRange: function(selections, range) |
| 1805 { |
| 1806 for (var i = 0; i < selections.length; ++i) { |
| 1807 if (range.equal(selections[i])) |
| 1808 return true; |
| 1809 } |
| 1810 return false; |
| 1811 }, |
| 1812 |
| 1813 selectNextOccurrence: function() |
| 1814 { |
| 1815 var selections = this._textEditor.selections(); |
| 1816 var anyEmptySelection = false; |
| 1817 for (var i = 0; i < selections.length; ++i) { |
| 1818 var selection = selections[i]; |
| 1819 anyEmptySelection = anyEmptySelection || selection.isEmpty(); |
| 1820 if (selection.startLine !== selection.endLine) |
| 1821 return; |
| 1822 } |
| 1823 if (anyEmptySelection) { |
| 1824 this._expandSelectionsToWords(selections); |
| 1825 return; |
| 1826 } |
| 1827 |
| 1828 var last = selections[selections.length - 1]; |
| 1829 var next = last; |
| 1830 do { |
| 1831 next = this._findNextOccurrence(next, !!this._fullWordSelection); |
| 1832 } while (next && this._findRange(selections, next) && !next.equal(last))
; |
| 1833 |
| 1834 if (!next) |
| 1835 return; |
| 1836 selections.push(next); |
| 1837 |
| 1838 this._muteSelectionListener = true; |
| 1839 this._textEditor.setSelections(selections); |
| 1840 delete this._muteSelectionListener; |
| 1841 |
| 1842 this._textEditor._revealLine(next.startLine); |
| 1843 }, |
| 1844 |
| 1845 /** |
| 1846 * @param {!Array.<!WebInspector.TextRange>} selections |
| 1847 */ |
| 1848 _expandSelectionsToWords: function(selections) |
| 1849 { |
| 1850 var newSelections = []; |
| 1851 for (var i = 0; i < selections.length; ++i) { |
| 1852 var selection = selections[i]; |
| 1853 var startRangeWord = this._textEditor._wordRangeForCursorPosition(se
lection.startLine, selection.startColumn) |
| 1854 || WebInspector.TextRange.createFromLocation(selection.startLine
, selection.startColumn); |
| 1855 var endRangeWord = this._textEditor._wordRangeForCursorPosition(sele
ction.endLine, selection.endColumn) |
| 1856 || WebInspector.TextRange.createFromLocation(selection.endLine,
selection.endColumn); |
| 1857 var newSelection = new WebInspector.TextRange(startRangeWord.startLi
ne, startRangeWord.startColumn, endRangeWord.endLine, endRangeWord.endColumn); |
| 1858 newSelections.push(newSelection); |
| 1859 } |
| 1860 this._textEditor.setSelections(newSelections); |
| 1861 this._fullWordSelection = true; |
| 1862 }, |
| 1863 |
| 1864 /** |
| 1865 * @param {!WebInspector.TextRange} range |
| 1866 * @param {boolean} fullWord |
| 1867 * @return {?WebInspector.TextRange} |
| 1868 */ |
| 1869 _findNextOccurrence: function(range, fullWord) |
| 1870 { |
| 1871 range = range.normalize(); |
| 1872 var matchedLineNumber; |
| 1873 var matchedColumnNumber; |
| 1874 var textToFind = this._textEditor.copyRange(range); |
| 1875 function findWordInLine(wordRegex, lineNumber, lineText, from, to) |
| 1876 { |
| 1877 if (typeof matchedLineNumber === "number") |
| 1878 return true; |
| 1879 wordRegex.lastIndex = from; |
| 1880 var result = wordRegex.exec(lineText); |
| 1881 if (!result || result.index + textToFind.length > to) |
| 1882 return false; |
| 1883 matchedLineNumber = lineNumber; |
| 1884 matchedColumnNumber = result.index; |
| 1885 return true; |
| 1886 } |
| 1887 |
| 1888 var iteratedLineNumber; |
| 1889 function lineIterator(regex, lineHandle) |
| 1890 { |
| 1891 if (findWordInLine(regex, iteratedLineNumber++, lineHandle.text, 0,
lineHandle.text.length)) |
| 1892 return true; |
| 1893 } |
| 1894 |
| 1895 var regexSource = textToFind.escapeForRegExp(); |
| 1896 if (fullWord) |
| 1897 regexSource = "\\b" + regexSource + "\\b"; |
| 1898 var wordRegex = new RegExp(regexSource, "gi"); |
| 1899 var currentLineText = this._codeMirror.getLine(range.startLine); |
| 1900 |
| 1901 findWordInLine(wordRegex, range.startLine, currentLineText, range.endCol
umn, currentLineText.length); |
| 1902 iteratedLineNumber = range.startLine + 1; |
| 1903 this._codeMirror.eachLine(range.startLine + 1, this._codeMirror.lineCoun
t(), lineIterator.bind(null, wordRegex)); |
| 1904 iteratedLineNumber = 0; |
| 1905 this._codeMirror.eachLine(0, range.startLine, lineIterator.bind(null, wo
rdRegex)); |
| 1906 findWordInLine(wordRegex, range.startLine, currentLineText, 0, range.sta
rtColumn); |
| 1907 |
| 1908 if (typeof matchedLineNumber !== "number") |
| 1909 return null; |
| 1910 return new WebInspector.TextRange(matchedLineNumber, matchedColumnNumber
, matchedLineNumber, matchedColumnNumber + textToFind.length); |
| 1911 } |
| 1912 } |
| 1913 |
| 1914 /** |
1734 * @param {string} modeName | 1915 * @param {string} modeName |
1735 * @param {string} tokenPrefix | 1916 * @param {string} tokenPrefix |
1736 */ | 1917 */ |
1737 WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(mod
eName, tokenPrefix) | 1918 WebInspector.CodeMirrorTextEditor._overrideModeWithPrefixedTokens = function(mod
eName, tokenPrefix) |
1738 { | 1919 { |
1739 var oldModeName = modeName + "-old"; | 1920 var oldModeName = modeName + "-old"; |
1740 if (CodeMirror.modes[oldModeName]) | 1921 if (CodeMirror.modes[oldModeName]) |
1741 return; | 1922 return; |
1742 | 1923 |
1743 CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]); | 1924 CodeMirror.defineMode(oldModeName, CodeMirror.modes[modeName]); |
(...skipping 27 matching lines...) Expand all Loading... |
1771 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte
d { background-color: " + backgroundColor + ";}" : ""; | 1952 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte
d { background-color: " + backgroundColor + ";}" : ""; |
1772 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); | 1953 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); |
1773 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte
dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import
ant;}" : ""; | 1954 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte
dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import
ant;}" : ""; |
1774 if (!foregroundColorRule && !backgroundColorRule) | 1955 if (!foregroundColorRule && !backgroundColorRule) |
1775 return; | 1956 return; |
1776 | 1957 |
1777 var style = document.createElement("style"); | 1958 var style = document.createElement("style"); |
1778 style.textContent = backgroundColorRule + foregroundColorRule; | 1959 style.textContent = backgroundColorRule + foregroundColorRule; |
1779 document.head.appendChild(style); | 1960 document.head.appendChild(style); |
1780 })(); | 1961 })(); |
OLD | NEW |