Skip to content

Commit

Permalink
fix: Rename file doesn't send didClose / didOpen LSP notification
Browse files Browse the repository at this point in the history
Fixes #1097

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Sep 11, 2023
1 parent 4b61a21 commit 8bcecff
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,7 @@ private TextDocumentContentChangeEvent createChangeEvent(DocumentEvent event) {
return null;
}

public void documentSaved(DocumentEvent event) {
long timestamp = event.getOldTimeStamp();
Document document = event.getDocument();
this.modificationStamp = timestamp;
public void documentSaved() {
ServerCapabilities serverCapabilities = languageServerWrapper.getServerCapabilities();
if (serverCapabilities != null) {
Either<TextDocumentSyncKind, TextDocumentSyncOptions> textDocumentSync = serverCapabilities.getTextDocumentSync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,18 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.intellij.AppTopics;
import com.intellij.lang.Language;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileEditor.FileDocumentManagerListener;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.util.messages.MessageBusConnection;
import com.redhat.devtools.intellij.lsp4ij.client.LanguageClientImpl;
import com.redhat.devtools.intellij.lsp4ij.internal.SupportedFeatures;
Expand Down Expand Up @@ -65,30 +61,15 @@ public class LanguageServerWrapper implements Disposable {
private static final String CLIENT_NAME = "IntelliJ";
private static final int MAX_NUMBER_OF_RESTART_ATTEMPTS = 20; // TODO move this max value in settings

class Listener implements DocumentListener, FileDocumentManagerListener, FileEditorManagerListener {

@Override
public void documentChanged(@NotNull DocumentEvent event) {
URI uri = LSPIJUtils.toUri(event.getDocument());
if (uri != null) {
DocumentContentSynchronizer documentListener = connectedDocuments.get(uri);
if (documentListener != null && documentListener.getModificationStamp() < event.getOldTimeStamp()) {
documentListener.documentSaved(event);
}
}
}

@Override
public void beforeDocumentSaving(@NotNull Document document) {
/*VirtualFile file = LSPIJUtils.getFile(document);
URI uri = LSPIJUtils.toUri(file);
if (uri != null) {
disconnect(uri);
}*/
}
class Listener implements FileEditorManagerListener, VirtualFileListener {

@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
if (initialProject != null && !Objects.equals(source.getProject(), initialProject)) {
// The file has been closed from another project,don't send textDocument/didClose
return;
}
// Manage textDocument/didClose
URI uri = LSPIJUtils.toUri(file);
if (uri != null) {
try {
Expand All @@ -101,6 +82,32 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f
}
}
}

@Override
public void contentsChanged(@NotNull VirtualFileEvent event) {
// Manage textDocument/didSave
URI uri = LSPIJUtils.toUri(event.getFile());
if (uri != null) {
DocumentContentSynchronizer documentListener = connectedDocuments.get(uri);
if (documentListener != null) {
documentListener.documentSaved();
}
}
}

@Override
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
if (event.getPropertyName().equals(VirtualFile.PROP_NAME) && event.getOldValue() instanceof String) {
// A file (Test1.java) has been renamed (to Test2.java) by using Refactor / Rename from IJ
// Send a didClose for the renamed file (Test1.java)
File parent = VfsUtilCore.virtualToIoFile(event.getFile().getParent());
URI uri = LSPIJUtils.toUri(new File(parent, (String) event.getOldValue()));
DocumentContentSynchronizer documentListener = connectedDocuments.get(uri);
if (documentListener != null) {
disconnect(uri);
}
}
}
}

private Listener fileBufferListener = new Listener();
Expand Down Expand Up @@ -347,10 +354,11 @@ public synchronized void start() throws LanguageServerException {
}
}
});
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(fileBufferListener);

messageBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
messageBusConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, fileBufferListener);
messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, fileBufferListener);
messageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkVirtualFileListenerAdapter(fileBufferListener));

udateStatus(ServerStatus.started);
getLanguageServerLifecycleManager().onStatusChanged(this);
}).exceptionally(e -> {
Expand Down Expand Up @@ -552,7 +560,6 @@ public synchronized void stop(boolean alreadyStopping) {
this.languageServer = null;
this.languageClient = null;

EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(fileBufferListener);
if (messageBusConnection != null) {
messageBusConnection.disconnect();
}
Expand Down Expand Up @@ -719,13 +726,8 @@ private void disconnect(URI path) {
private void disconnect(URI path, boolean stopping) {
DocumentContentSynchronizer documentListener = this.connectedDocuments.remove(path);
if (documentListener != null) {
// Remove teh listener from the old document stored in synchronizer
// Remove the listener from the old document stored in synchronizer
documentListener.getDocument().removeDocumentListener(documentListener);
Document document = getDocument(path, documentListener);
if (document != documentListener.getDocument()) {
// It should never occur, but to be sure we remove the document listener from the document of the VirtualFile
document.removeDocumentListener(documentListener);
}
documentListener.documentClosed();
}
if (!stopping && this.connectedDocuments.isEmpty()) {
Expand Down

0 comments on commit 8bcecff

Please sign in to comment.