Java 类com.intellij.openapi.editor.TextChange 实例源码

项目:intellij-ce-playground    文件:TextChangesStorage.java   
/**
 * Store given change merging it with previously stored ones if necessary.
 * <p/>
 * <b>Note:</b> it's assumed that given change offsets are related to the current state of the text (<code>'client text'</code>),
 * i.e. with all stored changes applied to it. Example:
 * <ol>
 *   <li>Say, we have initial text <code>'12345'</code>;</li>
 *   <li>
 *     Suppose the change <code>'replace text at [2; 3) range with 'ABC''</code> is applied to it (stored at the current object).
 *     End-users see the text <code>'12ABC45'</code> now;
 *   </li>
 *   <li>
 *     This method is called with change like <code>'replace text at [1; 6) range with 'XY''</code>. Change range is assumed to
 *     be related to the text visible to end-user, not initial one (<code>'12ABC45'</code>, not <code>'12345'</code>).
 *     I.e. the user will see text <code>'1XY5'</code> now;
 *   </li>
 * </ol>
 *
 * @param change    change to store
 */
public void store(@NotNull TextChange change) {
  if (myChanges.isEmpty()) {
    myChanges.add(new ChangeEntry(new TextChangeImpl(change.getText(), change.getStart(), change.getEnd()), change.getStart()));
    return;
  }

  // There is a big chance that the document is processed sequentially from start to end, hence, it makes sense
  // to check if given change lays beyond other registered changes and register it quickly in case of success.
  ChangeEntry last = myChanges.get(myChanges.size() - 1);
  if (last.clientStartOffset + last.change.getText().length() < change.getStart()) {
    int clientShift = last.clientStartOffset - last.change.getStart() + last.change.getDiff();
    myChanges.add(new ChangeEntry(
      new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
      change.getStart()
    ));
    return;
  }

  int insertionIndex = doStore(change);
  if (insertionIndex < 0) {
    return;
  }
  mergeIfNecessary(insertionIndex);
}
项目:tools-idea    文件:TextChangesStorage.java   
/**
 * Store given change merging it with previously stored ones if necessary.
 * <p/>
 * <b>Note:</b> it's assumed that given change offsets are related to the current state of the text (<code>'client text'</code>),
 * i.e. with all stored changes applied to it. Example:
 * <ol>
 *   <li>Say, we have initial text <code>'12345'</code>;</li>
 *   <li>
 *     Suppose the change <code>'replace text at [2; 3) range with 'ABC''</code> is applied to it (stored at the current object).
 *     End-users see the text <code>'12ABC45'</code> now;
 *   </li>
 *   <li>
 *     This method is called with change like <code>'replace text at [1; 6) range with 'XY''</code>. Change range is assumed to
 *     be related to the text visible to end-user, not initial one (<code>'12ABC45'</code>, not <code>'12345'</code>).
 *     I.e. the user will see text <code>'1XY5'</code> now;
 *   </li>
 * </ol>
 *
 * @param change    change to store
 */
public void store(@NotNull TextChange change) {
  if (myChanges.isEmpty()) {
    myChanges.add(new ChangeEntry(new TextChangeImpl(change.getText(), change.getStart(), change.getEnd()), change.getStart()));
    return;
  }

  // There is a big chance that the document is processed sequentially from start to end, hence, it makes sense
  // to check if given change lays beyond other registered changes and register it quickly in case of success.
  ChangeEntry last = myChanges.get(myChanges.size() - 1);
  if (last.clientStartOffset + last.change.getText().length() < change.getStart()) {
    int clientShift = last.clientStartOffset - last.change.getStart() + last.change.getDiff();
    myChanges.add(new ChangeEntry(
      new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
      change.getStart()
    ));
    return;
  }

  int insertionIndex = doStore(change);
  if (insertionIndex < 0) {
    return;
  }
  mergeIfNecessary(insertionIndex);
}
项目:consulo    文件:TextChangesStorage.java   
/**
 * Store given change merging it with previously stored ones if necessary.
 * <p/>
 * <b>Note:</b> it's assumed that given change offsets are related to the current state of the text (<code>'client text'</code>),
 * i.e. with all stored changes applied to it. Example:
 * <ol>
 *   <li>Say, we have initial text <code>'12345'</code>;</li>
 *   <li>
 *     Suppose the change <code>'replace text at [2; 3) range with 'ABC''</code> is applied to it (stored at the current object).
 *     End-users see the text <code>'12ABC45'</code> now;
 *   </li>
 *   <li>
 *     This method is called with change like <code>'replace text at [1; 6) range with 'XY''</code>. Change range is assumed to
 *     be related to the text visible to end-user, not initial one (<code>'12ABC45'</code>, not <code>'12345'</code>).
 *     I.e. the user will see text <code>'1XY5'</code> now;
 *   </li>
 * </ol>
 *
 * @param change    change to store
 */
public void store(@Nonnull TextChange change) {
  if (myChanges.isEmpty()) {
    myChanges.add(new ChangeEntry(new TextChangeImpl(change.getText(), change.getStart(), change.getEnd()), change.getStart()));
    return;
  }

  // There is a big chance that the document is processed sequentially from start to end, hence, it makes sense
  // to check if given change lays beyond other registered changes and register it quickly in case of success.
  ChangeEntry last = myChanges.get(myChanges.size() - 1);
  if (last.clientStartOffset + last.change.getText().length() < change.getStart()) {
    int clientShift = last.clientStartOffset - last.change.getStart() + last.change.getDiff();
    myChanges.add(new ChangeEntry(
      new TextChangeImpl(change.getText(), change.getStart() - clientShift, change.getEnd() - clientShift),
      change.getStart()
    ));
    return;
  }

  int insertionIndex = doStore(change);
  if (insertionIndex < 0) {
    return;
  }
  mergeIfNecessary(insertionIndex);
}
项目:intellij-ce-playground    文件:TextChangeImplTest.java   
@Test
public void propertiesExposing() {
  int start = 1;
  int end = 10;
  String text = "test";
  TextChange textChange = new TextChangeImpl(text, start, end);
  assertTrue(StringUtil.equals(text, textChange.getText()));
  assertArrayEquals(text.toCharArray(), textChange.getChars());
  assertEquals(start, textChange.getStart());
  assertEquals(end, textChange.getEnd());
}
项目:intellij-ce-playground    文件:BulkChangesMerger.java   
/**
 * Given an offset of some location in the document, returns offset of this location after application of given changes. List of changes
 * is supposed to satisfy the same constraints as required by {@link #mergeToCharSequence(char[], int, List)} method.
 */
public int updateOffset(int originalOffset, @NotNull List<? extends TextChange> changes) {
  int offset = originalOffset;
  for (TextChange change : changes) {
    if (originalOffset > change.getStart()) {
      offset += change.getText().length() - (change.getEnd() - change.getStart());
    }
  }
  return offset;
}
项目:intellij-ce-playground    文件:TextChangesStorage.java   
/**
 * Allows to ask the storage for the list of changes that have intersections with the target text range (identified by the given
 * arguments).
 * 
 * @param start   target range start offset (inclusive)
 * @param end     target range end offset (exclusive)
 * @return        list that contains all registered changes that have intersections with the target text range
 */
@NotNull
public List<? extends TextChange> getChanges(int start, int end) {
  assert start <= end;

  int changeStartIndex = getChangeIndex(start);
  if (changeStartIndex < 0) {
    changeStartIndex = -changeStartIndex - 1;
  }
  if (changeStartIndex >= myChanges.size()) {
    return Collections.emptyList();
  }

  int changeEndIndex = getChangeIndex(end);
  boolean endInclusive = true;
  if (changeEndIndex < 0) {
    changeEndIndex = -changeEndIndex - 1;
    endInclusive = false;
  }

  List<TextChange> result = null;
  for (int i = changeStartIndex; i <= changeEndIndex; i++) {
    if (!endInclusive && i == changeEndIndex) {
      break;
    }
    if (result == null) {
      result = new ArrayList<TextChange>();
    }
    result.add(myChanges.get(i).change);
  }
  return result == null ? Collections.<TextChange>emptyList() : result;
}
项目:tools-idea    文件:TextChangeImplTest.java   
@Test
public void propertiesExposing() {
  int start = 1;
  int end = 10;
  String text = "test";
  TextChange textChange = new TextChangeImpl(text, start, end);
  assertTrue(StringUtil.equals(text, textChange.getText()));
  assertArrayEquals(text.toCharArray(), textChange.getChars());
  assertEquals(start, textChange.getStart());
  assertEquals(end, textChange.getEnd());
}
项目:tools-idea    文件:TextChangesStorage.java   
/**
 * Allows to ask the storage for the list of changes that have intersections with the target text range (identified by the given
 * arguments).
 * 
 * @param start   target range start offset (inclusive)
 * @param end     target range end offset (exclusive)
 * @return        list that contains all registered changes that have intersections with the target text range
 */
@NotNull
public List<? extends TextChange> getChanges(int start, int end) {
  assert start <= end;

  int changeStartIndex = getChangeIndex(start);
  if (changeStartIndex < 0) {
    changeStartIndex = -changeStartIndex - 1;
  }
  if (changeStartIndex >= myChanges.size()) {
    return Collections.emptyList();
  }

  int changeEndIndex = getChangeIndex(end);
  boolean endInclusive = true;
  if (changeEndIndex < 0) {
    changeEndIndex = -changeEndIndex - 1;
    endInclusive = false;
  }

  List<TextChange> result = null;
  for (int i = changeStartIndex; i <= changeEndIndex; i++) {
    if (!endInclusive && i == changeEndIndex) {
      break;
    }
    if (result == null) {
      result = new ArrayList<TextChange>();
    }
    result.add(myChanges.get(i).change);
  }
  return result == null ? Collections.<TextChange>emptyList() : result;
}
项目:consulo    文件:TextChangeImplTest.java   
@Test
public void propertiesExposing() {
  int start = 1;
  int end = 10;
  String text = "test";
  TextChange textChange = new TextChangeImpl(text, start, end);
  assertTrue(StringUtil.equals(text, textChange.getText()));
  assertArrayEquals(text.toCharArray(), textChange.getChars());
  assertEquals(start, textChange.getStart());
  assertEquals(end, textChange.getEnd());
}
项目:consulo    文件:BulkChangesMerger.java   
/**
 * Given an offset of some location in the document, returns offset of this location after application of given changes. List of changes
 * is supposed to satisfy the same constraints as required by {@link #mergeToCharSequence(char[], int, List)} method.
 */
public int updateOffset(int originalOffset, @Nonnull List<? extends TextChange> changes) {
  int offset = originalOffset;
  for (TextChange change : changes) {
    if (originalOffset > change.getStart()) {
      offset += change.getText().length() - (change.getEnd() - change.getStart());
    }
  }
  return offset;
}
项目:consulo    文件:TextChangesStorage.java   
/**
 * Allows to ask the storage for the list of changes that have intersections with the target text range (identified by the given
 * arguments).
 * 
 * @param start   target range start offset (inclusive)
 * @param end     target range end offset (exclusive)
 * @return        list that contains all registered changes that have intersections with the target text range
 */
@Nonnull
public List<? extends TextChange> getChanges(int start, int end) {
  assert start <= end;

  int changeStartIndex = getChangeIndex(start);
  if (changeStartIndex < 0) {
    changeStartIndex = -changeStartIndex - 1;
  }
  if (changeStartIndex >= myChanges.size()) {
    return Collections.emptyList();
  }

  int changeEndIndex = getChangeIndex(end);
  boolean endInclusive = true;
  if (changeEndIndex < 0) {
    changeEndIndex = -changeEndIndex - 1;
    endInclusive = false;
  }

  List<TextChange> result = null;
  for (int i = changeStartIndex; i <= changeEndIndex; i++) {
    if (!endInclusive && i == changeEndIndex) {
      break;
    }
    if (result == null) {
      result = new ArrayList<TextChange>();
    }
    result.add(myChanges.get(i).change);
  }
  return result == null ? Collections.<TextChange>emptyList() : result;
}
项目:intellij-ce-playground    文件:DocumentChangesCollectorTest.java   
private void checkResult(TextChange ... expected) {
  List<? extends TextChange> actual = myCollector.getChanges();
  assertEquals(asList(expected), actual);
}
项目:intellij-ce-playground    文件:FormatProcessor.java   
private void update(@NotNull List<? extends TextChange> changes) {
  BulkChangesMerger merger = BulkChangesMerger.INSTANCE;
  for (Map.Entry<Editor, Integer> entry : myCaretOffsets.entrySet()) {
    entry.setValue(merger.updateOffset(entry.getValue(), changes));
  }
}
项目:tools-idea    文件:DocumentChangesCollectorTest.java   
private void checkResult(TextChange ... expected) {
  List<? extends TextChange> actual = myCollector.getChanges();
  assertEquals(asList(expected), actual);
}
项目:consulo    文件:DocumentChangesCollectorTest.java   
private void checkResult(TextChange ... expected) {
  List<? extends TextChange> actual = myCollector.getChanges();
  assertEquals(asList(expected), actual);
}
项目:consulo    文件:CaretOffsetUpdater.java   
public void update(@Nonnull List<? extends TextChange> changes) {
  BulkChangesMerger merger = BulkChangesMerger.INSTANCE;
  for (Map.Entry<Editor, Integer> entry : myCaretOffsets.entrySet()) {
    entry.setValue(merger.updateOffset(entry.getValue(), changes));
  }
}
项目:intellij-ce-playground    文件:BulkChangesMerger.java   
/**
 * Merges given changes within the given text and returns result as a new char sequence.
 *
 * @param text          text to apply given changes for
 * @param textLength    interested number of symbols from the given text to use
 * @param changes       changes to apply to the given text. It's assumed that there are no intersections between them and that they
 *                      are sorted by offsets in ascending order 
 * @return              merge result
 */
public CharSequence mergeToCharSequence(@NotNull char[] text, int textLength, @NotNull List<? extends TextChange> changes) {
  return StringFactory.createShared(mergeToCharArray(text, textLength, changes));
}
项目:intellij-ce-playground    文件:DocumentChangesCollector.java   
/**
 * Returns aggregated and merged document changes sorted by their start offsets in ascending order.
 * <p/>
 * <b>Example</b>
 * <pre>
 * <ol>
 *   <li>Suppose we have a document with text '0123456';</li>
 *   <li>
 *      Document range <code>[1; 3)</code> is removed (text <code>'12'</code> is removed, current text is
 *      <code>'03456'</code>);
 *   </li>
 *   <li>
 *      Document range <code>[1; 4)</code> (<code>'345'</code>) is replaced to <code>'abc'</code>
 *      (current text is <code>'0abc6'</code>);
 *   </li>
 * </ol>
 * </pre>
 * <p/>
 * So, initial document is <code>'0123456'</code>; final one is <code>'0abc6'</code>. We expect single aggregated change
 * to be returned then - <code>[1; 4)</code> with text <code>'12345'</code>, i.e. the range defines offset within the
 * current document and text shows initial document text at that range.
 *
 * @return    aggregated and merged document changes sorted by their start offsets in ascending order
 */
@NotNull
public List<? extends TextChange> getChanges() {
  return myChanges;
}
项目:tools-idea    文件:BulkChangesMerger.java   
/**
 * Merges given changes within the given text and returns result as a new char sequence.
 *
 * @param text          text to apply given changes for
 * @param textLength    interested number of symbols from the given text to use
 * @param changes       changes to apply to the given text. It's assumed that there are no intersections between them and that they
 *                      are sorted by offsets in ascending order 
 * @return              merge result
 */
public CharSequence mergeToCharSequence(@NotNull char[] text, int textLength, @NotNull List<? extends TextChange> changes) {
  return StringFactory.createShared(mergeToCharArray(text, textLength, changes));
}
项目:tools-idea    文件:DocumentChangesCollector.java   
/**
 * Returns aggregated and merged document changes sorted by their start offsets in ascending order.
 * <p/>
 * <b>Example</b>
 * <pre>
 * <ol>
 *   <li>Suppose we have a document with text '0123456';</li>
 *   <li>
 *      Document range <code>[1; 3)</code> is removed (text <code>'12'</code> is removed, current text is
 *      <code>'03456'</code>);
 *   </li>
 *   <li>
 *      Document range <code>[1; 4)</code> (<code>'345'</code>) is replaced to <code>'abc'</code>
 *      (current text is <code>'0abc6'</code>);
 *   </li>
 * </ol>
 * </pre>
 * <p/>
 * So, initial document is <code>'0123456'</code>; final one is <code>'0abc6'</code>. We expect single aggregated change
 * to be returned then - <code>[1; 4)</code> with text <code>'12345'</code>, i.e. the range defines offset within the
 * current document and text shows initial document text at that range.
 *
 * @return    aggregated and merged document changes sorted by their start offsets in ascending order
 */
@NotNull
public List<? extends TextChange> getChanges() {
  return myChanges;
}
项目:consulo    文件:BulkChangesMerger.java   
/**
 * Merges given changes within the given text and returns result as a new char sequence.
 *
 * @param text          text to apply given changes for
 * @param textLength    interested number of symbols from the given text to use
 * @param changes       changes to apply to the given text. It's assumed that there are no intersections between them and that they
 *                      are sorted by offsets in ascending order
 * @return              merge result
 */
public CharSequence mergeToCharSequence(@Nonnull char[] text, int textLength, @Nonnull List<? extends TextChange> changes) {
  return StringFactory.createShared(mergeToCharArray(text, textLength, changes));
}
项目:consulo    文件:DocumentChangesCollector.java   
/**
 * Returns aggregated and merged document changes sorted by their start offsets in ascending order.
 * <p/>
 * <b>Example</b>
 * <pre>
 * <ol>
 *   <li>Suppose we have a document with text '0123456';</li>
 *   <li>
 *      Document range <code>[1; 3)</code> is removed (text <code>'12'</code> is removed, current text is
 *      <code>'03456'</code>);
 *   </li>
 *   <li>
 *      Document range <code>[1; 4)</code> (<code>'345'</code>) is replaced to <code>'abc'</code>
 *      (current text is <code>'0abc6'</code>);
 *   </li>
 * </ol>
 * </pre>
 * <p/>
 * So, initial document is <code>'0123456'</code>; final one is <code>'0abc6'</code>. We expect single aggregated change
 * to be returned then - <code>[1; 4)</code> with text <code>'12345'</code>, i.e. the range defines offset within the
 * current document and text shows initial document text at that range.
 *
 * @return    aggregated and merged document changes sorted by their start offsets in ascending order
 */
@Nonnull
public List<? extends TextChange> getChanges() {
  return myChanges;
}