084fb78ef2160c0bd494ec1e7ed4a68b5aabcd626ccca82ff9406fd6f4ce9f00307fca5ecb2ef68c31d29d8444d848d22a194b51993dd23cf9b7ed6f2c63be 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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 { EditOperation } from '../../../common/core/editOperation.js';
  6. import { Range } from '../../../common/core/range.js';
  7. export class SortLinesCommand {
  8. constructor(selection, descending) {
  9. this.selection = selection;
  10. this.descending = descending;
  11. this.selectionId = null;
  12. }
  13. static getCollator() {
  14. if (!SortLinesCommand._COLLATOR) {
  15. SortLinesCommand._COLLATOR = new Intl.Collator();
  16. }
  17. return SortLinesCommand._COLLATOR;
  18. }
  19. getEditOperations(model, builder) {
  20. const op = sortLines(model, this.selection, this.descending);
  21. if (op) {
  22. builder.addEditOperation(op.range, op.text);
  23. }
  24. this.selectionId = builder.trackSelection(this.selection);
  25. }
  26. computeCursorState(model, helper) {
  27. return helper.getTrackedSelection(this.selectionId);
  28. }
  29. static canRun(model, selection, descending) {
  30. if (model === null) {
  31. return false;
  32. }
  33. const data = getSortData(model, selection, descending);
  34. if (!data) {
  35. return false;
  36. }
  37. for (let i = 0, len = data.before.length; i < len; i++) {
  38. if (data.before[i] !== data.after[i]) {
  39. return true;
  40. }
  41. }
  42. return false;
  43. }
  44. }
  45. SortLinesCommand._COLLATOR = null;
  46. function getSortData(model, selection, descending) {
  47. const startLineNumber = selection.startLineNumber;
  48. let endLineNumber = selection.endLineNumber;
  49. if (selection.endColumn === 1) {
  50. endLineNumber--;
  51. }
  52. // Nothing to sort if user didn't select anything.
  53. if (startLineNumber >= endLineNumber) {
  54. return null;
  55. }
  56. const linesToSort = [];
  57. // Get the contents of the selection to be sorted.
  58. for (let lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++) {
  59. linesToSort.push(model.getLineContent(lineNumber));
  60. }
  61. let sorted = linesToSort.slice(0);
  62. sorted.sort(SortLinesCommand.getCollator().compare);
  63. // If descending, reverse the order.
  64. if (descending === true) {
  65. sorted = sorted.reverse();
  66. }
  67. return {
  68. startLineNumber: startLineNumber,
  69. endLineNumber: endLineNumber,
  70. before: linesToSort,
  71. after: sorted
  72. };
  73. }
  74. /**
  75. * Generate commands for sorting lines on a model.
  76. */
  77. function sortLines(model, selection, descending) {
  78. const data = getSortData(model, selection, descending);
  79. if (!data) {
  80. return null;
  81. }
  82. return EditOperation.replace(new Range(data.startLineNumber, 1, data.endLineNumber, model.getLineMaxColumn(data.endLineNumber)), data.after.join('\n'));
  83. }