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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 "Down": "goLineDown", | 81 "Down": "goLineDown", |
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 "Esc": "dismissMultipleSelections" |
92 }; | 93 }; |
93 | 94 |
94 CodeMirror.keyMap["devtools-pc"] = { | 95 CodeMirror.keyMap["devtools-pc"] = { |
95 "Ctrl-A": "selectAll", | 96 "Ctrl-A": "selectAll", |
96 "Ctrl-Z": "undoAndReveal", | 97 "Ctrl-Z": "undoAndReveal", |
97 "Shift-Ctrl-Z": "redoAndReveal", | 98 "Shift-Ctrl-Z": "redoAndReveal", |
98 "Ctrl-Y": "redo", | 99 "Ctrl-Y": "redo", |
99 "Ctrl-Home": "goDocStart", | 100 "Ctrl-Home": "goDocStart", |
100 "Ctrl-Up": "goDocStart", | 101 "Ctrl-Up": "goDocStart", |
101 "Ctrl-End": "goDocEnd", | 102 "Ctrl-End": "goDocEnd", |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 this._codeMirror.setOption("crudeMeasuringFrom", 1000); | 141 this._codeMirror.setOption("crudeMeasuringFrom", 1000); |
141 | 142 |
142 this._shouldClearHistory = true; | 143 this._shouldClearHistory = true; |
143 this._lineSeparator = "\n"; | 144 this._lineSeparator = "\n"; |
144 | 145 |
145 this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighligh
ter(this._codeMirror); | 146 this._tokenHighlighter = new WebInspector.CodeMirrorTextEditor.TokenHighligh
ter(this._codeMirror); |
146 this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockInd
entController(this._codeMirror); | 147 this._blockIndentController = new WebInspector.CodeMirrorTextEditor.BlockInd
entController(this._codeMirror); |
147 this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovemen
t(this._codeMirror); | 148 this._fixWordMovement = new WebInspector.CodeMirrorTextEditor.FixWordMovemen
t(this._codeMirror); |
148 this._autocompleteController = new WebInspector.CodeMirrorTextEditor.Autocom
pleteController(this, this._codeMirror); | 149 this._autocompleteController = new WebInspector.CodeMirrorTextEditor.Autocom
pleteController(this, this._codeMirror); |
149 | 150 |
150 this._codeMirror.on("change", this._change.bind(this)); | 151 this._codeMirror.on("changes", this._changes.bind(this)); |
151 this._codeMirror.on("beforeChange", this._beforeChange.bind(this)); | 152 this._codeMirror.on("beforeChange", this._beforeChange.bind(this)); |
152 this._codeMirror.on("gutterClick", this._gutterClick.bind(this)); | 153 this._codeMirror.on("gutterClick", this._gutterClick.bind(this)); |
153 this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this)); | 154 this._codeMirror.on("cursorActivity", this._cursorActivity.bind(this)); |
154 this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bin
d(this)); | 155 this._codeMirror.on("beforeSelectionChange", this._beforeSelectionChange.bin
d(this)); |
155 this._codeMirror.on("scroll", this._scroll.bind(this)); | 156 this._codeMirror.on("scroll", this._scroll.bind(this)); |
156 this._codeMirror.on("focus", this._focus.bind(this)); | 157 this._codeMirror.on("focus", this._focus.bind(this)); |
157 this._codeMirror.on("blur", this._blur.bind(this)); | 158 this._codeMirror.on("blur", this._blur.bind(this)); |
158 this.element.addEventListener("contextmenu", this._contextMenu.bind(this), f
alse); | 159 this.element.addEventListener("contextmenu", this._contextMenu.bind(this), f
alse); |
159 /** | 160 /** |
160 * @this {WebInspector.CodeMirrorTextEditor} | 161 * @this {WebInspector.CodeMirrorTextEditor} |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 | 232 |
232 CodeMirror.commands.redoAndReveal = function(codemirror) | 233 CodeMirror.commands.redoAndReveal = function(codemirror) |
233 { | 234 { |
234 var scrollInfo = codemirror.getScrollInfo(); | 235 var scrollInfo = codemirror.getScrollInfo(); |
235 codemirror.execCommand("redo"); | 236 codemirror.execCommand("redo"); |
236 var cursor = codemirror.getCursor("start"); | 237 var cursor = codemirror.getCursor("start"); |
237 codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo); | 238 codemirror._codeMirrorTextEditor._innerRevealLine(cursor.line, scrollInfo); |
238 codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete(
); | 239 codemirror._codeMirrorTextEditor._autocompleteController.finishAutocomplete(
); |
239 } | 240 } |
240 | 241 |
| 242 CodeMirror.commands.dismissMultipleSelections = function(codemirror) |
| 243 { |
| 244 if (codemirror.getSelections().length <= 1) |
| 245 return CodeMirror.Pass; |
| 246 var range = codemirror.listSelections()[0]; |
| 247 codemirror.setSelection(range.anchor, range.head, {scroll: false}); |
| 248 codemirror._codeMirrorTextEditor._revealLine(range.anchor.line); |
| 249 } |
| 250 |
241 WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000; | 251 WebInspector.CodeMirrorTextEditor.LongLineModeLineLengthThreshold = 2000; |
242 WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16; | 252 WebInspector.CodeMirrorTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16; |
243 WebInspector.CodeMirrorTextEditor.MaxEditableTextSize = 1024 * 1024 * 10; | 253 WebInspector.CodeMirrorTextEditor.MaxEditableTextSize = 1024 * 1024 * 10; |
244 | 254 |
245 WebInspector.CodeMirrorTextEditor.prototype = { | 255 WebInspector.CodeMirrorTextEditor.prototype = { |
246 _enableBracketMatchingIfNeeded: function() | 256 _enableBracketMatchingIfNeeded: function() |
247 { | 257 { |
248 this._codeMirror.setOption("autoCloseBrackets", WebInspector.settings.te
xtEditorBracketMatching.get() ? { explode: false } : false); | 258 this._codeMirror.setOption("autoCloseBrackets", WebInspector.settings.te
xtEditorBracketMatching.get() ? { explode: false } : false); |
249 }, | 259 }, |
250 | 260 |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
930 { | 940 { |
931 if (!this._dictionary) | 941 if (!this._dictionary) |
932 return; | 942 return; |
933 this._updatedLines = this._updatedLines || {}; | 943 this._updatedLines = this._updatedLines || {}; |
934 for (var i = changeObject.from.line; i <= changeObject.to.line; ++i) | 944 for (var i = changeObject.from.line; i <= changeObject.to.line; ++i) |
935 this._updatedLines[i] = this.line(i); | 945 this._updatedLines[i] = this.line(i); |
936 }, | 946 }, |
937 | 947 |
938 /** | 948 /** |
939 * @param {!CodeMirror} codeMirror | 949 * @param {!CodeMirror} codeMirror |
940 * @param {!WebInspector.CodeMirrorTextEditor.ChangeObject} changeObject | 950 * @param {!Array.<!WebInspector.CodeMirrorTextEditor.ChangeObject>} changes |
941 */ | 951 */ |
942 _change: function(codeMirror, changeObject) | 952 _changes: function(codeMirror, changes) |
943 { | 953 { |
| 954 if (!changes.length) |
| 955 return; |
944 // We do not show "scroll beyond end of file" span for one line document
s, so we need to check if "document has one line" changed. | 956 // We do not show "scroll beyond end of file" span for one line document
s, so we need to check if "document has one line" changed. |
945 var hasOneLine = this._codeMirror.lineCount() === 1; | 957 var hasOneLine = this._codeMirror.lineCount() === 1; |
946 if (hasOneLine !== this._hasOneLine) | 958 if (hasOneLine !== this._hasOneLine) |
947 this._resizeEditor(); | 959 this._resizeEditor(); |
948 this._hasOneLine = hasOneLine; | 960 this._hasOneLine = hasOneLine; |
949 var widgets = this._elementToWidget.values(); | 961 var widgets = this._elementToWidget.values(); |
950 for (var i = 0; i < widgets.length; ++i) | 962 for (var i = 0; i < widgets.length; ++i) |
951 this._codeMirror.removeLineWidget(widgets[i]); | 963 this._codeMirror.removeLineWidget(widgets[i]); |
952 this._elementToWidget.clear(); | 964 this._elementToWidget.clear(); |
953 | 965 |
954 if (this._updatedLines) { | 966 if (this._updatedLines) { |
955 for (var lineNumber in this._updatedLines) | 967 for (var lineNumber in this._updatedLines) |
956 this._removeTextFromCompletionDictionary(this._updatedLines[line
Number]); | 968 this._removeTextFromCompletionDictionary(this._updatedLines[line
Number]); |
957 delete this._updatedLines; | 969 delete this._updatedLines; |
958 } | 970 } |
959 | 971 |
960 var linesToUpdate = {}; | 972 var linesToUpdate = {}; |
961 var singleCharInput = false; | 973 var singleCharInput = false; |
962 do { | 974 for (var changeIndex = 0; changeIndex < changes.length; ++changeIndex) { |
| 975 var changeObject = changes[changeIndex]; |
963 var oldRange = this._toRange(changeObject.from, changeObject.to); | 976 var oldRange = this._toRange(changeObject.from, changeObject.to); |
964 var newRange = oldRange.clone(); | 977 var newRange = oldRange.clone(); |
965 var linesAdded = changeObject.text.length; | 978 var linesAdded = changeObject.text.length; |
966 singleCharInput = (changeObject.origin === "+input" && changeObject.
text.length === 1 && changeObject.text[0].length === 1) || | 979 singleCharInput = (changeObject.origin === "+input" && changeObject.
text.length === 1 && changeObject.text[0].length === 1) || |
967 (changeObject.origin === "+delete" && changeObject.removed.lengt
h === 1 && changeObject.removed[0].length === 1); | 980 (changeObject.origin === "+delete" && changeObject.removed.lengt
h === 1 && changeObject.removed[0].length === 1); |
968 if (linesAdded === 0) { | 981 if (linesAdded === 0) { |
969 newRange.endLine = newRange.startLine; | 982 newRange.endLine = newRange.startLine; |
970 newRange.endColumn = newRange.startColumn; | 983 newRange.endColumn = newRange.startColumn; |
971 } else if (linesAdded === 1) { | 984 } else if (linesAdded === 1) { |
972 newRange.endLine = newRange.startLine; | 985 newRange.endLine = newRange.startLine; |
973 newRange.endColumn = newRange.startColumn + changeObject.text[0]
.length; | 986 newRange.endColumn = newRange.startColumn + changeObject.text[0]
.length; |
974 } else { | 987 } else { |
975 newRange.endLine = newRange.startLine + linesAdded - 1; | 988 newRange.endLine = newRange.startLine + linesAdded - 1; |
976 newRange.endColumn = changeObject.text[linesAdded - 1].length; | 989 newRange.endColumn = changeObject.text[linesAdded - 1].length; |
977 } | 990 } |
978 | 991 |
979 if (!this._muteTextChangedEvent) | 992 if (!this._muteTextChangedEvent) |
980 this._delegate.onTextChanged(oldRange, newRange); | 993 this._delegate.onTextChanged(oldRange, newRange); |
981 | 994 |
982 if (this._dictionary) { | 995 if (this._dictionary) { |
983 for (var i = newRange.startLine; i <= newRange.endLine; ++i) | 996 for (var i = newRange.startLine; i <= newRange.endLine; ++i) |
984 linesToUpdate[i] = this.line(i); | 997 linesToUpdate[i] = this.line(i); |
985 } | 998 } |
986 } while (changeObject = changeObject.next); | 999 } |
987 if (this._dictionary) { | 1000 if (this._dictionary) { |
988 for (var lineNumber in linesToUpdate) | 1001 for (var lineNumber in linesToUpdate) |
989 this._addTextToCompletionDictionary(linesToUpdate[lineNumber]); | 1002 this._addTextToCompletionDictionary(linesToUpdate[lineNumber]); |
990 } | 1003 } |
991 if (singleCharInput) | 1004 if (singleCharInput) |
992 this._autocompleteController.autocomplete(); | 1005 this._autocompleteController.autocomplete(); |
993 }, | 1006 }, |
994 | 1007 |
995 _cursorActivity: function() | 1008 _cursorActivity: function() |
996 { | 1009 { |
997 var start = this._codeMirror.getCursor("anchor"); | 1010 var start = this._codeMirror.getCursor("anchor"); |
998 var end = this._codeMirror.getCursor("head"); | 1011 var end = this._codeMirror.getCursor("head"); |
999 this._delegate.selectionChanged(this._toRange(start, end)); | 1012 this._delegate.selectionChanged(this._toRange(start, end)); |
1000 if (!this._tokenHighlighter.highlightedRegex()) | 1013 if (!this._tokenHighlighter.highlightedRegex()) |
1001 this._codeMirror.operation(this._tokenHighlighter.highlightSelectedT
okens.bind(this._tokenHighlighter)); | 1014 this._codeMirror.operation(this._tokenHighlighter.highlightSelectedT
okens.bind(this._tokenHighlighter)); |
1002 }, | 1015 }, |
1003 | 1016 |
1004 /** | 1017 /** |
1005 * @param {!CodeMirror} codeMirror | 1018 * @param {!CodeMirror} codeMirror |
1006 * @param {!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}} selection | 1019 * @param {{ranges: !Array.<{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}
>}} selection |
1007 */ | 1020 */ |
1008 _beforeSelectionChange: function(codeMirror, selection) | 1021 _beforeSelectionChange: function(codeMirror, selection) |
1009 { | 1022 { |
1010 if (!this._isHandlingMouseDownEvent) | 1023 if (!this._isHandlingMouseDownEvent) |
1011 return; | 1024 return; |
1012 this._reportJump(this.selection(), this._toRange(selection.anchor, selec
tion.head)); | 1025 if (!selection.ranges.length) |
| 1026 return; |
| 1027 var primarySelection = selection.ranges[0]; |
| 1028 this._reportJump(this.selection(), this._toRange(primarySelection.anchor
, primarySelection.head)); |
1013 }, | 1029 }, |
1014 | 1030 |
1015 /** | 1031 /** |
1016 * @param {?WebInspector.TextRange} from | 1032 * @param {?WebInspector.TextRange} from |
1017 * @param {?WebInspector.TextRange} to | 1033 * @param {?WebInspector.TextRange} to |
1018 */ | 1034 */ |
1019 _reportJump: function(from, to) | 1035 _reportJump: function(from, to) |
1020 { | 1036 { |
1021 if (from && to && from.equal(to)) | 1037 if (from && to && from.equal(to)) |
1022 return; | 1038 return; |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 if (this._highlightDescriptor && this._highlightDescriptor.selectionStar
t) | 1343 if (this._highlightDescriptor && this._highlightDescriptor.selectionStar
t) |
1328 this._codeMirror.removeLineClass(this._highlightDescriptor.selection
Start.line, "wrap", "cm-line-with-selection"); | 1344 this._codeMirror.removeLineClass(this._highlightDescriptor.selection
Start.line, "wrap", "cm-line-with-selection"); |
1329 this._removeHighlight(); | 1345 this._removeHighlight(); |
1330 var selectionStart = this._codeMirror.getCursor("start"); | 1346 var selectionStart = this._codeMirror.getCursor("start"); |
1331 var selectionEnd = this._codeMirror.getCursor("end"); | 1347 var selectionEnd = this._codeMirror.getCursor("end"); |
1332 if (selectionStart.line !== selectionEnd.line) | 1348 if (selectionStart.line !== selectionEnd.line) |
1333 return; | 1349 return; |
1334 if (selectionStart.ch === selectionEnd.ch) | 1350 if (selectionStart.ch === selectionEnd.ch) |
1335 return; | 1351 return; |
1336 | 1352 |
1337 var selectedText = this._codeMirror.getSelection(); | 1353 var selections = this._codeMirror.getSelections(); |
| 1354 if (selections.length !== 1) |
| 1355 return; |
| 1356 var selectedText = selections[0]; |
1338 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s
electionEnd.ch)) { | 1357 if (this._isWord(selectedText, selectionStart.line, selectionStart.ch, s
electionEnd.ch)) { |
1339 if (selectionStart) | 1358 if (selectionStart) |
1340 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l
ine-with-selection") | 1359 this._codeMirror.addLineClass(selectionStart.line, "wrap", "cm-l
ine-with-selection") |
1341 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText,
selectionStart), selectionStart); | 1360 this._setHighlighter(this._tokenHighlighter.bind(this, selectedText,
selectionStart), selectionStart); |
1342 } | 1361 } |
1343 }, | 1362 }, |
1344 | 1363 |
1345 /** | 1364 /** |
1346 * @param {string} selectedText | 1365 * @param {string} selectedText |
1347 * @param {number} lineNumber | 1366 * @param {number} lineNumber |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 } | 1511 } |
1493 | 1512 |
1494 /** | 1513 /** |
1495 * @constructor | 1514 * @constructor |
1496 * @param {!CodeMirror} codeMirror | 1515 * @param {!CodeMirror} codeMirror |
1497 */ | 1516 */ |
1498 WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror) | 1517 WebInspector.CodeMirrorTextEditor.FixWordMovement = function(codeMirror) |
1499 { | 1518 { |
1500 function moveLeft(shift, codeMirror) | 1519 function moveLeft(shift, codeMirror) |
1501 { | 1520 { |
| 1521 codeMirror.setExtending(shift); |
1502 var cursor = codeMirror.getCursor("head"); | 1522 var cursor = codeMirror.getCursor("head"); |
1503 if (cursor.ch !== 0 || cursor.line === 0) | 1523 codeMirror.execCommand("goGroupLeft"); |
1504 return CodeMirror.Pass; | 1524 var newCursor = codeMirror.getCursor("head"); |
1505 codeMirror.setExtending(shift); | 1525 if (newCursor.ch === 0 && newCursor.line !== 0) { |
1506 codeMirror.execCommand("goLineUp"); | 1526 codeMirror.setExtending(false); |
1507 codeMirror.execCommand("goLineEnd") | 1527 return; |
| 1528 } |
| 1529 |
| 1530 var skippedText = codeMirror.getRange(newCursor, cursor, "#"); |
| 1531 if (/^\s+$/.test(skippedText)) |
| 1532 codeMirror.execCommand("goGroupLeft"); |
1508 codeMirror.setExtending(false); | 1533 codeMirror.setExtending(false); |
1509 } | 1534 } |
| 1535 |
1510 function moveRight(shift, codeMirror) | 1536 function moveRight(shift, codeMirror) |
1511 { | 1537 { |
| 1538 codeMirror.setExtending(shift); |
1512 var cursor = codeMirror.getCursor("head"); | 1539 var cursor = codeMirror.getCursor("head"); |
1513 var line = codeMirror.getLine(cursor.line); | 1540 codeMirror.execCommand("goGroupRight"); |
1514 if (cursor.ch !== line.length || cursor.line + 1 === codeMirror.lineCoun
t()) | 1541 var newCursor = codeMirror.getCursor("head"); |
1515 return CodeMirror.Pass; | 1542 if (newCursor.ch === 0 && newCursor.line !== 0) { |
1516 codeMirror.setExtending(shift); | 1543 codeMirror.setExtending(false); |
1517 codeMirror.execCommand("goLineDown"); | 1544 return; |
1518 codeMirror.execCommand("goLineStart"); | 1545 } |
| 1546 |
| 1547 var skippedText = codeMirror.getRange(cursor, newCursor, "#"); |
| 1548 if (/^\s+$/.test(skippedText)) |
| 1549 codeMirror.execCommand("goGroupRight"); |
1519 codeMirror.setExtending(false); | 1550 codeMirror.setExtending(false); |
1520 } | 1551 } |
1521 function delWordBack(codeMirror) | |
1522 { | |
1523 if (codeMirror.somethingSelected()) | |
1524 return CodeMirror.Pass; | |
1525 var cursor = codeMirror.getCursor("head"); | |
1526 if (cursor.ch === 0) | |
1527 codeMirror.execCommand("delCharBefore"); | |
1528 else | |
1529 return CodeMirror.Pass; | |
1530 } | |
1531 | 1552 |
1532 var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl"; | 1553 var modifierKey = WebInspector.isMac() ? "Alt" : "Ctrl"; |
1533 var leftKey = modifierKey + "-Left"; | 1554 var leftKey = modifierKey + "-Left"; |
1534 var rightKey = modifierKey + "-Right"; | 1555 var rightKey = modifierKey + "-Right"; |
1535 var keyMap = {}; | 1556 var keyMap = {}; |
1536 keyMap[leftKey] = moveLeft.bind(null, false); | 1557 keyMap[leftKey] = moveLeft.bind(null, false); |
1537 keyMap[rightKey] = moveRight.bind(null, false); | 1558 keyMap[rightKey] = moveRight.bind(null, false); |
1538 keyMap["Shift-" + leftKey] = moveLeft.bind(null, true); | 1559 keyMap["Shift-" + leftKey] = moveLeft.bind(null, true); |
1539 keyMap["Shift-" + rightKey] = moveRight.bind(null, true); | 1560 keyMap["Shift-" + rightKey] = moveRight.bind(null, true); |
1540 keyMap[modifierKey + "-Backspace"] = delWordBack; | |
1541 codeMirror.addKeyMap(keyMap); | 1561 codeMirror.addKeyMap(keyMap); |
1542 } | 1562 } |
1543 | 1563 |
1544 /** | 1564 /** |
1545 * @constructor | 1565 * @constructor |
1546 * @implements {WebInspector.SuggestBoxDelegate} | 1566 * @implements {WebInspector.SuggestBoxDelegate} |
1547 * @param {!WebInspector.CodeMirrorTextEditor} textEditor | 1567 * @param {!WebInspector.CodeMirrorTextEditor} textEditor |
1548 * @param {!CodeMirror} codeMirror | 1568 * @param {!CodeMirror} codeMirror |
1549 */ | 1569 */ |
1550 WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor,
codeMirror) | 1570 WebInspector.CodeMirrorTextEditor.AutocompleteController = function(textEditor,
codeMirror) |
1551 { | 1571 { |
1552 this._textEditor = textEditor; | 1572 this._textEditor = textEditor; |
1553 this._codeMirror = codeMirror; | 1573 this._codeMirror = codeMirror; |
1554 this._codeMirror.on("scroll", this._onScroll.bind(this)); | 1574 this._codeMirror.on("scroll", this._onScroll.bind(this)); |
1555 this._codeMirror.on("cursorActivity", this._onCursorActivity.bind(this)); | 1575 this._codeMirror.on("cursorActivity", this._onCursorActivity.bind(this)); |
1556 } | 1576 } |
1557 | 1577 |
1558 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { | 1578 WebInspector.CodeMirrorTextEditor.AutocompleteController.prototype = { |
| 1579 /** |
| 1580 * @param {!WebInspector.TextRange} mainSelection |
| 1581 * @param {!Array.<!{head: !CodeMirror.Pos, anchor: !CodeMirror.Pos}>} selec
tions |
| 1582 * @return {boolean} |
| 1583 */ |
| 1584 _validateSelectionsContexts: function(mainSelection, selections) |
| 1585 { |
| 1586 var mainSelectionContext = this._textEditor.copyRange(mainSelection); |
| 1587 for (var i = 0; i < selections.length; ++i) { |
| 1588 var wordRange = this._textEditor._wordRangeForCursorPosition(selecti
ons[i].head.line, selections[i].head.ch, false); |
| 1589 if (!wordRange) |
| 1590 return false; |
| 1591 var context = this._textEditor.copyRange(wordRange); |
| 1592 if (context !== mainSelectionContext) |
| 1593 return false; |
| 1594 } |
| 1595 return true; |
| 1596 }, |
| 1597 |
1559 autocomplete: function() | 1598 autocomplete: function() |
1560 { | 1599 { |
1561 var dictionary = this._textEditor._dictionary; | 1600 var dictionary = this._textEditor._dictionary; |
1562 if (!dictionary || this._codeMirror.somethingSelected()) { | 1601 if (!dictionary || this._codeMirror.somethingSelected()) { |
1563 this.finishAutocomplete(); | 1602 this.finishAutocomplete(); |
1564 return; | 1603 return; |
1565 } | 1604 } |
1566 | 1605 |
1567 var cursor = this._codeMirror.getCursor(); | 1606 var selections = this._codeMirror.listSelections().slice(); |
| 1607 var topSelection = selections.shift(); |
| 1608 var cursor = topSelection.head; |
1568 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso
r.line, cursor.ch, false); | 1609 var substituteRange = this._textEditor._wordRangeForCursorPosition(curso
r.line, cursor.ch, false); |
1569 if (!substituteRange || substituteRange.startColumn === cursor.ch) { | 1610 if (!substituteRange || substituteRange.startColumn === cursor.ch || !th
is._validateSelectionsContexts(substituteRange, selections)) { |
1570 this.finishAutocomplete(); | 1611 this.finishAutocomplete(); |
1571 return; | 1612 return; |
1572 } | 1613 } |
| 1614 |
1573 var prefixRange = substituteRange.clone(); | 1615 var prefixRange = substituteRange.clone(); |
1574 prefixRange.endColumn = cursor.ch; | 1616 prefixRange.endColumn = cursor.ch; |
1575 | 1617 |
1576 var substituteWord = this._textEditor.copyRange(substituteRange); | 1618 var substituteWord = this._textEditor.copyRange(substituteRange); |
1577 var hasPrefixInDictionary = dictionary.hasWord(substituteWord); | 1619 var hasPrefixInDictionary = dictionary.hasWord(substituteWord); |
1578 if (hasPrefixInDictionary) | 1620 if (hasPrefixInDictionary) |
1579 dictionary.removeWord(substituteWord); | 1621 dictionary.removeWord(substituteWord); |
1580 var wordsWithPrefix = dictionary.wordsWithPrefix(this._textEditor.copyRa
nge(prefixRange)); | 1622 var wordsWithPrefix = dictionary.wordsWithPrefix(this._textEditor.copyRa
nge(prefixRange)); |
1581 if (hasPrefixInDictionary) | 1623 if (hasPrefixInDictionary) |
1582 dictionary.addWord(substituteWord); | 1624 dictionary.addWord(substituteWord); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 * @param {string} suggestion | 1674 * @param {string} suggestion |
1633 * @param {boolean=} isIntermediateSuggestion | 1675 * @param {boolean=} isIntermediateSuggestion |
1634 */ | 1676 */ |
1635 applySuggestion: function(suggestion, isIntermediateSuggestion) | 1677 applySuggestion: function(suggestion, isIntermediateSuggestion) |
1636 { | 1678 { |
1637 this._currentSuggestion = suggestion; | 1679 this._currentSuggestion = suggestion; |
1638 }, | 1680 }, |
1639 | 1681 |
1640 acceptSuggestion: function() | 1682 acceptSuggestion: function() |
1641 { | 1683 { |
1642 if (this._prefixRange.endColumn - this._prefixRange.startColumn !== this
._currentSuggestion.length) { | 1684 if (this._prefixRange.endColumn - this._prefixRange.startColumn === this
._currentSuggestion.length) |
1643 var pos = this._textEditor._toPos(this._prefixRange); | 1685 return; |
1644 this._codeMirror.replaceRange(this._currentSuggestion, pos.start, po
s.end, "+autocomplete"); | 1686 |
| 1687 var selections = this._codeMirror.listSelections().slice(); |
| 1688 var prefixLength = this._prefixRange.endColumn - this._prefixRange.start
Column; |
| 1689 for (var i = selections.length - 1; i >= 0; --i) { |
| 1690 var start = selections[i].head; |
| 1691 var end = new CodeMirror.Pos(start.line, start.ch - prefixLength); |
| 1692 this._codeMirror.replaceRange(this._currentSuggestion, start, end, "
+autocomplete"); |
1645 } | 1693 } |
1646 }, | 1694 }, |
1647 | 1695 |
1648 _onScroll: function() | 1696 _onScroll: function() |
1649 { | 1697 { |
1650 if (!this._suggestBox) | 1698 if (!this._suggestBox) |
1651 return; | 1699 return; |
1652 var cursor = this._codeMirror.getCursor(); | 1700 var cursor = this._codeMirror.getCursor(); |
1653 var scrollInfo = this._codeMirror.getScrollInfo(); | 1701 var scrollInfo = this._codeMirror.getScrollInfo(); |
1654 var topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, "l
ocal"); | 1702 var topmostLineNumber = this._codeMirror.lineAtHeight(scrollInfo.top, "l
ocal"); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1723 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte
d { background-color: " + backgroundColor + ";}" : ""; | 1771 var backgroundColorRule = backgroundColor ? ".CodeMirror .CodeMirror-selecte
d { background-color: " + backgroundColor + ";}" : ""; |
1724 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); | 1772 var foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); |
1725 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte
dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import
ant;}" : ""; | 1773 var foregroundColorRule = foregroundColor ? ".CodeMirror .CodeMirror-selecte
dtext:not(.CodeMirror-persist-highlight) { color: " + foregroundColor + "!import
ant;}" : ""; |
1726 if (!foregroundColorRule && !backgroundColorRule) | 1774 if (!foregroundColorRule && !backgroundColorRule) |
1727 return; | 1775 return; |
1728 | 1776 |
1729 var style = document.createElement("style"); | 1777 var style = document.createElement("style"); |
1730 style.textContent = backgroundColorRule + foregroundColorRule; | 1778 style.textContent = backgroundColorRule + foregroundColorRule; |
1731 document.head.appendChild(style); | 1779 document.head.appendChild(style); |
1732 })(); | 1780 })(); |
OLD | NEW |