From f966a69a85ed9ce615cf1723db89e21dbbe2f663 Mon Sep 17 00:00:00 2001 From: azerr Date: Fri, 8 Sep 2023 19:30:04 +0200 Subject: [PATCH] fix: Rename file doesn't send didClose / didOpen LSP notification Fixes #1097 Signed-off-by: azerr --- .../lsp4ij/DocumentContentSynchronizer.java | 5 +- .../lsp4ij/LanguageServerWrapper.java | 70 +++++++++---------- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/DocumentContentSynchronizer.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/DocumentContentSynchronizer.java index fd59f809c..25c73a27f 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/DocumentContentSynchronizer.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/DocumentContentSynchronizer.java @@ -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 textDocumentSync = serverCapabilities.getTextDocumentSync(); diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java index adb8bd15d..5449a117e 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java @@ -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; @@ -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 { @@ -101,6 +82,28 @@ 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)) { + // A file (Test1.java) has been renamed (to Test2.java) by using Refactor / Rename from IJ + + // LSPFileEventManager.fileRenamed((String) event.getOldValue(), (String) event.getNewValue()); + System.out.println("X"); + } + } } private Listener fileBufferListener = new Listener(); @@ -347,10 +350,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 -> { @@ -552,7 +556,6 @@ public synchronized void stop(boolean alreadyStopping) { this.languageServer = null; this.languageClient = null; - EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(fileBufferListener); if (messageBusConnection != null) { messageBusConnection.disconnect(); } @@ -719,13 +722,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()) {