67b0033591fcf30fb7e3c8e3c594064ea4075d9cb0fdedeb9d3e8b4d4937cb9653a3476273d2cc315f2783c26ba48d10fd7f67c1568c735929cc9754b5aaa7 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. import { isLowerAsciiLetter, isUpperAsciiLetter } from '../../../../base/common/strings.js';
  6. import { Range } from '../../../common/core/range.js';
  7. export class WordSelectionRangeProvider {
  8. provideSelectionRanges(model, positions) {
  9. const result = [];
  10. for (const position of positions) {
  11. const bucket = [];
  12. result.push(bucket);
  13. this._addInWordRanges(bucket, model, position);
  14. this._addWordRanges(bucket, model, position);
  15. this._addWhitespaceLine(bucket, model, position);
  16. bucket.push({ range: model.getFullModelRange() });
  17. }
  18. return result;
  19. }
  20. _addInWordRanges(bucket, model, pos) {
  21. const obj = model.getWordAtPosition(pos);
  22. if (!obj) {
  23. return;
  24. }
  25. const { word, startColumn } = obj;
  26. const offset = pos.column - startColumn;
  27. let start = offset;
  28. let end = offset;
  29. let lastCh = 0;
  30. // LEFT anchor (start)
  31. for (; start >= 0; start--) {
  32. const ch = word.charCodeAt(start);
  33. if ((start !== offset) && (ch === 95 /* CharCode.Underline */ || ch === 45 /* CharCode.Dash */)) {
  34. // foo-bar OR foo_bar
  35. break;
  36. }
  37. else if (isLowerAsciiLetter(ch) && isUpperAsciiLetter(lastCh)) {
  38. // fooBar
  39. break;
  40. }
  41. lastCh = ch;
  42. }
  43. start += 1;
  44. // RIGHT anchor (end)
  45. for (; end < word.length; end++) {
  46. const ch = word.charCodeAt(end);
  47. if (isUpperAsciiLetter(ch) && isLowerAsciiLetter(lastCh)) {
  48. // fooBar
  49. break;
  50. }
  51. else if (ch === 95 /* CharCode.Underline */ || ch === 45 /* CharCode.Dash */) {
  52. // foo-bar OR foo_bar
  53. break;
  54. }
  55. lastCh = ch;
  56. }
  57. if (start < end) {
  58. bucket.push({ range: new Range(pos.lineNumber, startColumn + start, pos.lineNumber, startColumn + end) });
  59. }
  60. }
  61. _addWordRanges(bucket, model, pos) {
  62. const word = model.getWordAtPosition(pos);
  63. if (word) {
  64. bucket.push({ range: new Range(pos.lineNumber, word.startColumn, pos.lineNumber, word.endColumn) });
  65. }
  66. }
  67. _addWhitespaceLine(bucket, model, pos) {
  68. if (model.getLineLength(pos.lineNumber) > 0
  69. && model.getLineFirstNonWhitespaceColumn(pos.lineNumber) === 0
  70. && model.getLineLastNonWhitespaceColumn(pos.lineNumber) === 0) {
  71. bucket.push({ range: new Range(pos.lineNumber, 1, pos.lineNumber, model.getLineMaxColumn(pos.lineNumber)) });
  72. }
  73. }
  74. }