下面列出了怎么用org.eclipse.lsp4j.TextDocumentContentChangeEvent的API类实例代码及写法,或者点击链接到github查看源代码。
public void didChange(DidChangeTextDocumentParams params) {
URI uri = URI.create(params.getTextDocument().getUri());
String oldText = openFiles.get(uri);
TextDocumentContentChangeEvent change = params.getContentChanges().get(0);
Range range = change.getRange();
if (range == null) {
openFiles.put(uri, change.getText());
} else {
int offset = Positions.getOffset(oldText, change.getRange().getStart());
StringBuilder builder = new StringBuilder();
builder.append(oldText.substring(0, offset));
builder.append(change.getText());
builder.append(oldText.substring(offset + change.getRangeLength()));
openFiles.put(uri, builder.toString());
}
changedFiles.add(uri);
}
public static void main(String[] args) {
InputStream in = TextDocumentUpdatePerformance.class.getResourceAsStream("/xml/nasa.xml");
String text = convertStreamToString(in);
TextDocument document = new TextDocument(text, "nasa.xml");
document.setIncremental(true);
// Continuously parses the large nasa.xml file with the DOM parser.
while (true) {
long start = System.currentTimeMillis();
// Insert a space
List<TextDocumentContentChangeEvent> changes = new ArrayList<>();
TextDocumentContentChangeEvent change = new TextDocumentContentChangeEvent(
new Range(new Position(14, 13), new Position(14, 13)), 0, " ");
changes.add(change);
document.update(changes);
System.err.println("Update 'nasa.xml' text document in " + (System.currentTimeMillis() - start) + " ms.");
}
}
@Test
void testChangeEventUpdatesStoredText() throws Exception {
CamelLanguageServer camelLanguageServer = initializeLanguageServer("<to uri=\"\" xmlns=\"http://camel.apache.org/schema/blueprint\"></to>\n");
DidChangeTextDocumentParams changeEvent = new DidChangeTextDocumentParams();
VersionedTextDocumentIdentifier textDocument = new VersionedTextDocumentIdentifier();
textDocument.setUri(DUMMY_URI+".xml");
changeEvent.setTextDocument(textDocument);
TextDocumentContentChangeEvent contentChange = new TextDocumentContentChangeEvent("<to xmlns=\"http://camel.apache.org/schema/blueprint\" uri=\"\"></to>\n");
changeEvent.setContentChanges(Collections.singletonList(contentChange));
camelLanguageServer.getTextDocumentService().didChange(changeEvent);
//check old position doesn't provide completion
CompletableFuture<Either<List<CompletionItem>, CompletionList>> completionsAtOldPosition = getCompletionFor(camelLanguageServer, new Position(0, 11));
assertThat(completionsAtOldPosition.get().getLeft()).isEmpty();
//check new position provides completion
CompletableFuture<Either<List<CompletionItem>, CompletionList>> completionsAtNewPosition = getCompletionFor(camelLanguageServer, new Position(0, 58));
assertThat(completionsAtNewPosition.get().getLeft()).isNotEmpty();
}
private void closeFile(FileURI fileURI, boolean discardChanges) {
if (!isOpen(fileURI)) {
Assert.fail("trying to close a file that is not open: " + fileURI);
}
boolean dirty = isDirty(fileURI);
if (dirty && !discardChanges) {
Assert.fail("trying to close a file with unsaved changes: " + fileURI);
} else if (!dirty && discardChanges) {
Assert.fail("no unsaved changes to discard in file: " + fileURI);
}
OpenFileInfo info = openFiles.remove(fileURI);
if (dirty) {
// when closing a file with unsaved changes, LSP clients send a 'textDocument/didChange' to bring its
// content back to the content on disk
String contentOnDisk = getContentOfFileOnDisk(fileURI);
DidChangeTextDocumentParams params = new DidChangeTextDocumentParams(
new VersionedTextDocumentIdentifier(fileURI.toString(), info.version + 1),
Collections.singletonList(new TextDocumentContentChangeEvent(contentOnDisk)));
languageServer.didChange(params);
}
languageServer.didClose(new DidCloseTextDocumentParams(new TextDocumentIdentifier(fileURI.toString())));
joinServerRequests();
}
private void changeOpenedFile(FileURI fileURI, Function<String, String> modification,
BiFunction<String, String, List<TextDocumentContentChangeEvent>> changeComputer) {
if (!isOpen(fileURI)) {
Assert.fail("file is not open: " + fileURI);
}
// 1) change in memory (i.e. in map 'openFiles')
OpenFileInfo info = openFiles.get(fileURI);
int oldVersion = info.version;
String oldContent = info.content;
int newVersion = oldVersion + 1;
String newContent = modification.apply(oldContent);
Assert.assertNotNull(newContent);
info.version = newVersion;
info.content = newContent;
// 2) notify LSP server
VersionedTextDocumentIdentifier docId = new VersionedTextDocumentIdentifier(fileURI.toString(), newVersion);
List<TextDocumentContentChangeEvent> changes = changeComputer.apply(oldContent, newContent);
DidChangeTextDocumentParams params = new DidChangeTextDocumentParams(docId, changes);
languageServer.didChange(params);
}
@SafeVarargs
private List<TextDocumentContentChangeEvent> replacementsToChangeEvents(XDocument document,
Pair<String, String>... replacements) {
List<TextDocumentContentChangeEvent> result = new ArrayList<>(replacements.length);
for (Pair<String, String> replacement : replacements) {
int offset = document.getContents().indexOf(replacement.getKey());
if (offset < 0) {
throw new IllegalArgumentException(
"string \"" + replacement.getKey() + "\" not found in content of document");
}
int len = replacement.getKey().length();
Range range = new Range(document.getPosition(offset), document.getPosition(offset + len));
result.add(new TextDocumentContentChangeEvent(range, len, replacement.getValue()));
}
return result;
}
/**
* As opposed to {@link TextEdit}[] the positions in the edits of a {@link DidChangeTextDocumentParams} refer to the
* state after applying the preceding edits. See
* https://microsoft.github.io/language-server-protocol/specification#textedit-1 and
* https://github.com/microsoft/vscode/issues/23173#issuecomment-289378160 for details.
*
* @return a new document with an incremented version and the text document changes applied.
* @since 2.18
*/
@Override
public XDocument applyTextDocumentChanges(Iterable<? extends TextDocumentContentChangeEvent> changes) {
XDocument currentDocument = this;
int newVersion = currentDocument.version + 1;
for (TextDocumentContentChangeEvent change : changes) {
String newContent;
Range range = change.getRange();
if (range == null) {
newContent = change.getText();
} else {
int start = currentDocument.getOffSet(range.getStart());
int end = currentDocument.getOffSet(range.getEnd());
String oldContents = currentDocument.contents;
newContent = oldContents.substring(0, start) + change.getText() + oldContents.substring(end);
}
currentDocument = new XDocument(newVersion, newContent, printSourceOnError, true);
}
return currentDocument;
}
@Override
public void didChange(DidChangeTextDocumentParams params) {
Document doc = openedDocuments.get(params.getTextDocument().getUri());
NbDocument.runAtomic((StyledDocument) doc, () -> {
for (TextDocumentContentChangeEvent change : params.getContentChanges()) {
try {
int start = getOffset(doc, change.getRange().getStart());
int end = getOffset(doc, change.getRange().getEnd());
doc.remove(start, end - start);
doc.insertString(start, change.getText(), null);
} catch (BadLocationException ex) {
throw new IllegalStateException(ex);
}
}
});
runDiagnoticTasks(params.getTextDocument().getUri());
}
protected void changeDocument(ICompilationUnit unit, String content, int version, Range range, int length) {
DidChangeTextDocumentParams changeParms = new DidChangeTextDocumentParams();
VersionedTextDocumentIdentifier textDocument = new VersionedTextDocumentIdentifier();
textDocument.setUri(JDTUtils.toURI(unit));
textDocument.setVersion(version);
changeParms.setTextDocument(textDocument);
TextDocumentContentChangeEvent event = new TextDocumentContentChangeEvent();
if (range != null) {
event.setRange(range);
event.setRangeLength(length);
}
event.setText(content);
List<TextDocumentContentChangeEvent> contentChanges = new ArrayList<>();
contentChanges.add(event);
changeParms.setContentChanges(contentChanges);
lifeCycleHandler.didChange(changeParms);
}
private void changeDocument(ICompilationUnit cu, String content, int version, Range range, int length) throws JavaModelException {
DidChangeTextDocumentParams changeParms = new DidChangeTextDocumentParams();
VersionedTextDocumentIdentifier textDocument = new VersionedTextDocumentIdentifier();
textDocument.setUri(JDTUtils.toURI(cu));
textDocument.setVersion(version);
changeParms.setTextDocument(textDocument);
TextDocumentContentChangeEvent event = new TextDocumentContentChangeEvent();
if (range != null) {
event.setRange(range);
event.setRangeLength(length);
}
event.setText(content);
List<TextDocumentContentChangeEvent> contentChanges = new ArrayList<>();
contentChanges.add(event);
changeParms.setContentChanges(contentChanges);
lifeCycleHandler.didChange(changeParms);
}
public void changeFile(Path path, List<TextDocumentContentChangeEvent> contentChanges)
{
for (TextDocumentContentChangeEvent change : contentChanges)
{
if (change.getRange() == null)
{
sourceByPath.put(path, change.getText());
}
else if(sourceByPath.containsKey(path))
{
String existingText = sourceByPath.get(path);
String newText = patch(existingText, change);
sourceByPath.put(path, newText);
}
else
{
System.err.println("Failed to apply changes to code intelligence from path: " + path);
}
}
}
@Test
public void testUpdate_01() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("hello world");
_builder.newLine();
_builder.append("foo");
_builder.newLine();
_builder.append("bar");
_builder.newLine();
String _normalize = this.normalize(_builder);
Document _document = new Document(Integer.valueOf(1), _normalize);
final Procedure1<Document> _function = (Document it) -> {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("hello world");
_builder_1.newLine();
_builder_1.append("bar");
_builder_1.newLine();
TextDocumentContentChangeEvent _change = this.change(this.position(1, 0), this.position(2, 0), "");
Assert.assertEquals(this.normalize(_builder_1), it.applyTextDocumentChanges(
Collections.<TextDocumentContentChangeEvent>unmodifiableList(CollectionLiterals.<TextDocumentContentChangeEvent>newArrayList(_change))).getContents());
};
ObjectExtensions.<Document>operator_doubleArrow(_document, _function);
}
@Test
public void testUpdate_02() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("hello world");
_builder.newLine();
_builder.append("foo");
_builder.newLine();
_builder.append("bar");
_builder.newLine();
String _normalize = this.normalize(_builder);
Document _document = new Document(Integer.valueOf(1), _normalize);
final Procedure1<Document> _function = (Document it) -> {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("hello world");
_builder_1.newLine();
_builder_1.append("future");
_builder_1.newLine();
_builder_1.append("bar");
_builder_1.newLine();
TextDocumentContentChangeEvent _change = this.change(this.position(1, 1), this.position(1, 3), "uture");
Assert.assertEquals(this.normalize(_builder_1), it.applyTextDocumentChanges(
Collections.<TextDocumentContentChangeEvent>unmodifiableList(CollectionLiterals.<TextDocumentContentChangeEvent>newArrayList(_change))).getContents());
};
ObjectExtensions.<Document>operator_doubleArrow(_document, _function);
}
@Test
public void testUpdate_03() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("hello world");
_builder.newLine();
_builder.append("foo");
_builder.newLine();
_builder.append("bar");
String _normalize = this.normalize(_builder);
Document _document = new Document(Integer.valueOf(1), _normalize);
final Procedure1<Document> _function = (Document it) -> {
TextDocumentContentChangeEvent _change = this.change(this.position(0, 0), this.position(2, 3), "");
Assert.assertEquals("", it.applyTextDocumentChanges(
Collections.<TextDocumentContentChangeEvent>unmodifiableList(CollectionLiterals.<TextDocumentContentChangeEvent>newArrayList(_change))).getContents());
};
ObjectExtensions.<Document>operator_doubleArrow(_document, _function);
}
@Test
public void testApplyTextDocumentChanges_04() {
StringConcatenation _builder = new StringConcatenation();
_builder.append("foo");
_builder.newLine();
_builder.append("bar");
_builder.newLine();
String _normalize = this.normalize(_builder);
TextDocumentContentChangeEvent _change = this.change(this.position(0, 3), this.position(0, 3), "b");
TextDocumentContentChangeEvent _change_1 = this.change(this.position(0, 4), this.position(0, 4), "a");
TextDocumentContentChangeEvent _change_2 = this.change(this.position(0, 5), this.position(0, 5), "r");
Document _applyTextDocumentChanges = new Document(Integer.valueOf(1), _normalize).applyTextDocumentChanges(
Collections.<TextDocumentContentChangeEvent>unmodifiableList(CollectionLiterals.<TextDocumentContentChangeEvent>newArrayList(_change, _change_1, _change_2)));
final Procedure1<Document> _function = (Document it) -> {
StringConcatenation _builder_1 = new StringConcatenation();
_builder_1.append("foobar");
_builder_1.newLine();
_builder_1.append("bar");
_builder_1.newLine();
Assert.assertEquals(this.normalize(_builder_1), it.getContents());
Assert.assertEquals(2, (it.getVersion()).intValue());
};
ObjectExtensions.<Document>operator_doubleArrow(_applyTextDocumentChanges, _function);
}
private TextDocumentContentChangeEvent change(final Position startPos, final Position endPos, final String newText) {
TextDocumentContentChangeEvent _textDocumentContentChangeEvent = new TextDocumentContentChangeEvent();
final Procedure1<TextDocumentContentChangeEvent> _function = (TextDocumentContentChangeEvent it) -> {
if ((startPos != null)) {
Range _range = new Range();
final Procedure1<Range> _function_1 = (Range it_1) -> {
it_1.setStart(startPos);
it_1.setEnd(endPos);
};
Range _doubleArrow = ObjectExtensions.<Range>operator_doubleArrow(_range, _function_1);
it.setRange(_doubleArrow);
}
it.setText(newText);
};
return ObjectExtensions.<TextDocumentContentChangeEvent>operator_doubleArrow(_textDocumentContentChangeEvent, _function);
}
/**
* As opposed to {@link TextEdit}[] the positions in the edits of a {@link DidChangeTextDocumentParams} refer to the
* state after applying the preceding edits. See
* https://microsoft.github.io/language-server-protocol/specification#textedit-1 and
* https://github.com/microsoft/vscode/issues/23173#issuecomment-289378160 for details.
*
* @return a new document with an incremented version and the text document changes applied.
* @since 2.18
*/
public Document applyTextDocumentChanges(Iterable<? extends TextDocumentContentChangeEvent> changes) {
Document currentDocument = this;
Integer newVersion = null;
if (currentDocument.version != null) {
newVersion = Integer.valueOf(currentDocument.version.intValue() + 1);
}
for (TextDocumentContentChangeEvent change : changes) {
final String newContent;
if (change.getRange() == null) {
newContent = change.getText();
} else {
int start = currentDocument.getOffSet(change.getRange().getStart());
int end = currentDocument.getOffSet(change.getRange().getEnd());
newContent = currentDocument.contents.substring(0, start) + change.getText()
+ currentDocument.contents.substring(end);
}
currentDocument = new Document(newVersion, newContent, printSourceOnError);
}
return currentDocument;
}
public EditorEventManager(Editor editor, DocumentListener documentListener, EditorMouseListener mouseListener,
EditorMouseMotionListener mouseMotionListener, LSPCaretListenerImpl caretListener,
RequestManager requestManager, ServerOptions serverOptions, LanguageServerWrapper wrapper) {
this.editor = editor;
this.documentListener = documentListener;
this.mouseListener = mouseListener;
this.mouseMotionListener = mouseMotionListener;
this.requestManager = requestManager;
this.wrapper = wrapper;
this.caretListener = caretListener;
this.identifier = new TextDocumentIdentifier(FileUtils.editorToURIString(editor));
this.changesParams = new DidChangeTextDocumentParams(new VersionedTextDocumentIdentifier(),
Collections.singletonList(new TextDocumentContentChangeEvent()));
this.syncKind = serverOptions.syncKind;
this.completionTriggers = (serverOptions.completionOptions != null
&& serverOptions.completionOptions.getTriggerCharacters() != null) ?
serverOptions.completionOptions.getTriggerCharacters() :
new ArrayList<>();
this.signatureTriggers = (serverOptions.signatureHelpOptions != null
&& serverOptions.signatureHelpOptions.getTriggerCharacters() != null) ?
serverOptions.signatureHelpOptions.getTriggerCharacters() :
new ArrayList<>();
this.project = editor.getProject();
EditorEventManagerBase.uriToManager.put(FileUtils.editorToURIString(editor), this);
EditorEventManagerBase.editorToManager.put(editor, this);
changesParams.getTextDocument().setUri(identifier.getUri());
this.currentHint = null;
}
@Test
void testDidChangeWithoutRange() {
DidOpenTextDocumentParams openParams = new DidOpenTextDocumentParams();
openParams.setTextDocument(new TextDocumentItem("file.txt", "plaintext", 1, "hello world"));
tracker.didOpen(openParams);
DidChangeTextDocumentParams changeParams = new DidChangeTextDocumentParams();
changeParams.setTextDocument(new VersionedTextDocumentIdentifier("file.txt", 2));
TextDocumentContentChangeEvent changeEvent = new TextDocumentContentChangeEvent();
changeEvent.setText("hi there");
changeParams.setContentChanges(Collections.singletonList(changeEvent));
tracker.didChange(changeParams);
Assertions.assertEquals("hi there", tracker.getContents(URI.create("file.txt")));
}
@Test
void testDidChangeWithRange() {
DidOpenTextDocumentParams openParams = new DidOpenTextDocumentParams();
openParams.setTextDocument(new TextDocumentItem("file.txt", "plaintext", 1, "hello world"));
tracker.didOpen(openParams);
DidChangeTextDocumentParams changeParams = new DidChangeTextDocumentParams();
changeParams.setTextDocument(new VersionedTextDocumentIdentifier("file.txt", 2));
TextDocumentContentChangeEvent changeEvent = new TextDocumentContentChangeEvent();
changeEvent.setText(", friend");
changeEvent.setRange(new Range(new Position(0, 5), new Position(0, 11)));
changeEvent.setRangeLength(6);
changeParams.setContentChanges(Collections.singletonList(changeEvent));
tracker.didChange(changeParams);
Assertions.assertEquals("hello, friend", tracker.getContents(URI.create("file.txt")));
}
@Test
void testDidChangeWithRangeMultiline() {
DidOpenTextDocumentParams openParams = new DidOpenTextDocumentParams();
openParams.setTextDocument(new TextDocumentItem("file.txt", "plaintext", 1, "hello\nworld"));
tracker.didOpen(openParams);
DidChangeTextDocumentParams changeParams = new DidChangeTextDocumentParams();
changeParams.setTextDocument(new VersionedTextDocumentIdentifier("file.txt", 2));
TextDocumentContentChangeEvent changeEvent = new TextDocumentContentChangeEvent();
changeEvent.setText("affles");
changeEvent.setRange(new Range(new Position(1, 1), new Position(1, 5)));
changeEvent.setRangeLength(4);
changeParams.setContentChanges(Collections.singletonList(changeEvent));
tracker.didChange(changeParams);
Assertions.assertEquals("hello\nwaffles", tracker.getContents(URI.create("file.txt")));
}
/**
* Convert IntelliJ {@link DocumentEvent} to LS according {@link TextDocumentSyncKind}.
*
* @param event
* IntelliJ {@link DocumentEvent}
* @return true if change event is ready to be sent
*/
private boolean createChangeEvent(DocumentEvent event) {
changeParams = new DidChangeTextDocumentParams(new VersionedTextDocumentIdentifier(), Collections.singletonList(new TextDocumentContentChangeEvent()));
changeParams.getTextDocument().setUri(fileUri.toString());
Document document = event.getDocument();
TextDocumentContentChangeEvent changeEvent = null;
TextDocumentSyncKind syncKind = getTextDocumentSyncKind();
switch (syncKind) {
case None:
return false;
case Full:
changeParams.getContentChanges().get(0).setText(event.getDocument().getText());
break;
case Incremental:
changeEvent = changeParams.getContentChanges().get(0);
CharSequence newText = event.getNewFragment();
int offset = event.getOffset();
int length = event.getOldLength();
try {
// try to convert the Eclipse start/end offset to LS range.
Range range = new Range(LSPIJUtils.toPosition(offset, document),
LSPIJUtils.toPosition(offset + length, document));
changeEvent.setRange(range);
changeEvent.setText(newText.toString());
changeEvent.setRangeLength(length);
} finally {
}
break;
}
return true;
}
@Test
public void testBasicChange() {
String text =
"<>\r\n" + /// <-- inserting 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</a>\r\n";
String expectedText =
"<a>\r\n" + /// <-- inserted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</a>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 1), new Position(0,1));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 0, "a");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testBasicChangeWord() {
String text =
"<>\r\n" + /// <-- inserting 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</aaa>\r\n";
String expectedText =
"<aaa>\r\n" + /// <-- inserted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</aaa>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 1), new Position(0,1));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 0, "aaa");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testChangeReplaceRange() {
String text =
"<zzz>\r\n" + /// <-- inserting 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</aaa>\r\n";
String expectedText =
"<aaa>\r\n" + /// <-- inserted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</aaa>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 1), new Position(0,4));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 3, "aaa");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testBasicChangeMultipleChanges() {
String text =
"<>\r\n" + // <-- inserting 'a' in tag name
" <b>\r\n" +
" </>\r\n" + // <-- inserting 'b' in tag name
"</a>\r\n";
String expectedText =
"<a>\r\n" + // <-- inserted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" + // <-- inserted 'b' in tag name
"</a>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 1), new Position(0,1));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 0, "a");
Range range2 = new Range(new Position(2, 4), new Position(2,4));
TextDocumentContentChangeEvent change2 = new TextDocumentContentChangeEvent(range2, 0, "b");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
// The order they are added in is backwards with the largest offset being first
changes.add(change2);
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testBasicChangeMultipleChangesReplaceRange() {
String text =
"<zzz>\r\n" + // <-- inserting 'a' in tag name
" <b>\r\n" +
" </eee>\r\n" + // <-- inserting 'b' in tag name
"</a>\r\n";
String expectedText =
"<a>\r\n" + // <-- inserted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" + // <-- inserted 'b' in tag name
"</a>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 1), new Position(0,4));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 3, "a");
Range range2 = new Range(new Position(2, 4), new Position(2,7));
TextDocumentContentChangeEvent change2 = new TextDocumentContentChangeEvent(range2, 3, "b");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
// The order they are added in is backwards with the largest offset being first
changes.add(change2);
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testBasicDeletionChange() {
String text =
"<aa>\r\n" + /// <-- deleting 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</a>\r\n";
String expectedText =
"<a>\r\n" + /// <-- deleted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</a>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 2), new Position(0,3));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 1, "");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Test
public void testMultipleDeletionChanges() {
String text =
"<aa>\r\n" + /// <-- deleting 'a' in tag name
" <b>\r\n" +
" </bb>\r\n" +
"</a>\r\n";
String expectedText =
"<a>\r\n" + /// <-- deleted 'a' in tag name
" <b>\r\n" +
" </b>\r\n" +
"</a>\r\n";
TextDocument document = new TextDocument(text, "uri");
document.setIncremental(true);
Range range1 = new Range(new Position(0, 2), new Position(0,3));
TextDocumentContentChangeEvent change1 = new TextDocumentContentChangeEvent(range1, 1, "");
Range range2 = new Range(new Position(2, 5), new Position(2,6));
TextDocumentContentChangeEvent change2 = new TextDocumentContentChangeEvent(range2, 1, "");
ArrayList<TextDocumentContentChangeEvent> changes = new ArrayList<TextDocumentContentChangeEvent>();
changes.add(change2);
changes.add(change1);
document.update(changes);
assertEquals(expectedText, document.getText());
}
@Override
public void didChange(DidChangeTextDocumentParams params) {
LOGGER.info("didChange: {}", params.getTextDocument());
List<TextDocumentContentChangeEvent> contentChanges = params.getContentChanges();
TextDocumentItem textDocumentItem = openedDocuments.get(params.getTextDocument().getUri());
if (!contentChanges.isEmpty()) {
textDocumentItem.setText(contentChanges.get(0).getText());
new DiagnosticRunner(getCamelCatalog(), camelLanguageServer).compute(params);
}
}