02d8dfbb0f8d5733d679f321e2bbc37e46d626ddd1253eb082ff1797f37ff7d592c018fa920a0cb09b83de22a6206b467ce407a38a856f67a3ab9e9f69deb0 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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 * as strings from '../../../../base/common/strings.js';
  6. import { Range } from '../../../common/core/range.js';
  7. import { CancellationTokenSource } from '../../../../base/common/cancellation.js';
  8. import { DisposableStore } from '../../../../base/common/lifecycle.js';
  9. import { EditorKeybindingCancellationTokenSource } from './keybindingCancellation.js';
  10. export class EditorState {
  11. constructor(editor, flags) {
  12. this.flags = flags;
  13. if ((this.flags & 1 /* CodeEditorStateFlag.Value */) !== 0) {
  14. const model = editor.getModel();
  15. this.modelVersionId = model ? strings.format('{0}#{1}', model.uri.toString(), model.getVersionId()) : null;
  16. }
  17. else {
  18. this.modelVersionId = null;
  19. }
  20. if ((this.flags & 4 /* CodeEditorStateFlag.Position */) !== 0) {
  21. this.position = editor.getPosition();
  22. }
  23. else {
  24. this.position = null;
  25. }
  26. if ((this.flags & 2 /* CodeEditorStateFlag.Selection */) !== 0) {
  27. this.selection = editor.getSelection();
  28. }
  29. else {
  30. this.selection = null;
  31. }
  32. if ((this.flags & 8 /* CodeEditorStateFlag.Scroll */) !== 0) {
  33. this.scrollLeft = editor.getScrollLeft();
  34. this.scrollTop = editor.getScrollTop();
  35. }
  36. else {
  37. this.scrollLeft = -1;
  38. this.scrollTop = -1;
  39. }
  40. }
  41. _equals(other) {
  42. if (!(other instanceof EditorState)) {
  43. return false;
  44. }
  45. const state = other;
  46. if (this.modelVersionId !== state.modelVersionId) {
  47. return false;
  48. }
  49. if (this.scrollLeft !== state.scrollLeft || this.scrollTop !== state.scrollTop) {
  50. return false;
  51. }
  52. if (!this.position && state.position || this.position && !state.position || this.position && state.position && !this.position.equals(state.position)) {
  53. return false;
  54. }
  55. if (!this.selection && state.selection || this.selection && !state.selection || this.selection && state.selection && !this.selection.equalsRange(state.selection)) {
  56. return false;
  57. }
  58. return true;
  59. }
  60. validate(editor) {
  61. return this._equals(new EditorState(editor, this.flags));
  62. }
  63. }
  64. /**
  65. * A cancellation token source that cancels when the editor changes as expressed
  66. * by the provided flags
  67. * @param range If provided, changes in position and selection within this range will not trigger cancellation
  68. */
  69. export class EditorStateCancellationTokenSource extends EditorKeybindingCancellationTokenSource {
  70. constructor(editor, flags, range, parent) {
  71. super(editor, parent);
  72. this._listener = new DisposableStore();
  73. if (flags & 4 /* CodeEditorStateFlag.Position */) {
  74. this._listener.add(editor.onDidChangeCursorPosition(e => {
  75. if (!range || !Range.containsPosition(range, e.position)) {
  76. this.cancel();
  77. }
  78. }));
  79. }
  80. if (flags & 2 /* CodeEditorStateFlag.Selection */) {
  81. this._listener.add(editor.onDidChangeCursorSelection(e => {
  82. if (!range || !Range.containsRange(range, e.selection)) {
  83. this.cancel();
  84. }
  85. }));
  86. }
  87. if (flags & 8 /* CodeEditorStateFlag.Scroll */) {
  88. this._listener.add(editor.onDidScrollChange(_ => this.cancel()));
  89. }
  90. if (flags & 1 /* CodeEditorStateFlag.Value */) {
  91. this._listener.add(editor.onDidChangeModel(_ => this.cancel()));
  92. this._listener.add(editor.onDidChangeModelContent(_ => this.cancel()));
  93. }
  94. }
  95. dispose() {
  96. this._listener.dispose();
  97. super.dispose();
  98. }
  99. }
  100. /**
  101. * A cancellation token source that cancels when the provided model changes
  102. */
  103. export class TextModelCancellationTokenSource extends CancellationTokenSource {
  104. constructor(model, parent) {
  105. super(parent);
  106. this._listener = model.onDidChangeContent(() => this.cancel());
  107. }
  108. dispose() {
  109. this._listener.dispose();
  110. super.dispose();
  111. }
  112. }