2fc0fdb6a812c0c63325740cf861fd6c69ec1bf42bdd02f81defffc0a4d857d02d9751446e3705a1cc3ec53c4c11e048d7526c0b900f25a9426218e3509167 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  6. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  7. return new (P || (P = Promise))(function (resolve, reject) {
  8. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  9. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  10. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  11. step((generator = generator.apply(thisArg, _arguments || [])).next());
  12. });
  13. };
  14. import { LinkedList } from '../../../../base/common/linkedList.js';
  15. import { Position } from '../../../common/core/position.js';
  16. import { Range } from '../../../common/core/range.js';
  17. export class BracketSelectionRangeProvider {
  18. provideSelectionRanges(model, positions) {
  19. return __awaiter(this, void 0, void 0, function* () {
  20. const result = [];
  21. for (const position of positions) {
  22. const bucket = [];
  23. result.push(bucket);
  24. const ranges = new Map();
  25. yield new Promise(resolve => BracketSelectionRangeProvider._bracketsRightYield(resolve, 0, model, position, ranges));
  26. yield new Promise(resolve => BracketSelectionRangeProvider._bracketsLeftYield(resolve, 0, model, position, ranges, bucket));
  27. }
  28. return result;
  29. });
  30. }
  31. static _bracketsRightYield(resolve, round, model, pos, ranges) {
  32. const counts = new Map();
  33. const t1 = Date.now();
  34. while (true) {
  35. if (round >= BracketSelectionRangeProvider._maxRounds) {
  36. resolve();
  37. break;
  38. }
  39. if (!pos) {
  40. resolve();
  41. break;
  42. }
  43. const bracket = model.bracketPairs.findNextBracket(pos);
  44. if (!bracket) {
  45. resolve();
  46. break;
  47. }
  48. const d = Date.now() - t1;
  49. if (d > BracketSelectionRangeProvider._maxDuration) {
  50. setTimeout(() => BracketSelectionRangeProvider._bracketsRightYield(resolve, round + 1, model, pos, ranges));
  51. break;
  52. }
  53. if (bracket.bracketInfo.isOpeningBracket) {
  54. const key = bracket.bracketInfo.bracketText;
  55. // wait for closing
  56. const val = counts.has(key) ? counts.get(key) : 0;
  57. counts.set(key, val + 1);
  58. }
  59. else {
  60. const key = bracket.bracketInfo.getClosedBrackets()[0].bracketText;
  61. // process closing
  62. let val = counts.has(key) ? counts.get(key) : 0;
  63. val -= 1;
  64. counts.set(key, Math.max(0, val));
  65. if (val < 0) {
  66. let list = ranges.get(key);
  67. if (!list) {
  68. list = new LinkedList();
  69. ranges.set(key, list);
  70. }
  71. list.push(bracket.range);
  72. }
  73. }
  74. pos = bracket.range.getEndPosition();
  75. }
  76. }
  77. static _bracketsLeftYield(resolve, round, model, pos, ranges, bucket) {
  78. const counts = new Map();
  79. const t1 = Date.now();
  80. while (true) {
  81. if (round >= BracketSelectionRangeProvider._maxRounds && ranges.size === 0) {
  82. resolve();
  83. break;
  84. }
  85. if (!pos) {
  86. resolve();
  87. break;
  88. }
  89. const bracket = model.bracketPairs.findPrevBracket(pos);
  90. if (!bracket) {
  91. resolve();
  92. break;
  93. }
  94. const d = Date.now() - t1;
  95. if (d > BracketSelectionRangeProvider._maxDuration) {
  96. setTimeout(() => BracketSelectionRangeProvider._bracketsLeftYield(resolve, round + 1, model, pos, ranges, bucket));
  97. break;
  98. }
  99. if (!bracket.bracketInfo.isOpeningBracket) {
  100. const key = bracket.bracketInfo.getClosedBrackets()[0].bracketText;
  101. // wait for opening
  102. const val = counts.has(key) ? counts.get(key) : 0;
  103. counts.set(key, val + 1);
  104. }
  105. else {
  106. const key = bracket.bracketInfo.bracketText;
  107. // opening
  108. let val = counts.has(key) ? counts.get(key) : 0;
  109. val -= 1;
  110. counts.set(key, Math.max(0, val));
  111. if (val < 0) {
  112. const list = ranges.get(key);
  113. if (list) {
  114. const closing = list.shift();
  115. if (list.size === 0) {
  116. ranges.delete(key);
  117. }
  118. const innerBracket = Range.fromPositions(bracket.range.getEndPosition(), closing.getStartPosition());
  119. const outerBracket = Range.fromPositions(bracket.range.getStartPosition(), closing.getEndPosition());
  120. bucket.push({ range: innerBracket });
  121. bucket.push({ range: outerBracket });
  122. BracketSelectionRangeProvider._addBracketLeading(model, outerBracket, bucket);
  123. }
  124. }
  125. }
  126. pos = bracket.range.getStartPosition();
  127. }
  128. }
  129. static _addBracketLeading(model, bracket, bucket) {
  130. if (bracket.startLineNumber === bracket.endLineNumber) {
  131. return;
  132. }
  133. // xxxxxxxx {
  134. //
  135. // }
  136. const startLine = bracket.startLineNumber;
  137. const column = model.getLineFirstNonWhitespaceColumn(startLine);
  138. if (column !== 0 && column !== bracket.startColumn) {
  139. bucket.push({ range: Range.fromPositions(new Position(startLine, column), bracket.getEndPosition()) });
  140. bucket.push({ range: Range.fromPositions(new Position(startLine, 1), bracket.getEndPosition()) });
  141. }
  142. // xxxxxxxx
  143. // {
  144. //
  145. // }
  146. const aboveLine = startLine - 1;
  147. if (aboveLine > 0) {
  148. const column = model.getLineFirstNonWhitespaceColumn(aboveLine);
  149. if (column === bracket.startColumn && column !== model.getLineLastNonWhitespaceColumn(aboveLine)) {
  150. bucket.push({ range: Range.fromPositions(new Position(aboveLine, column), bracket.getEndPosition()) });
  151. bucket.push({ range: Range.fromPositions(new Position(aboveLine, 1), bracket.getEndPosition()) });
  152. }
  153. }
  154. }
  155. }
  156. BracketSelectionRangeProvider._maxDuration = 30;
  157. BracketSelectionRangeProvider._maxRounds = 2;