diff --git a/plugins/editorconfig/resources/messages/EditorConfigBundle.properties b/plugins/editorconfig/resources/messages/EditorConfigBundle.properties index f931698010fa..5633cfc075ee 100644 --- a/plugins/editorconfig/resources/messages/EditorConfigBundle.properties +++ b/plugins/editorconfig/resources/messages/EditorConfigBundle.properties @@ -254,4 +254,5 @@ suppress.inspection.option=Suppress for option suppress.inspection.section=Suppress for section invalid.config.value="{0}" is not a valid value for {1} for file {2} -read.failure=Failed to read .editorconfig file \ No newline at end of file +read.failure=Failed to read .editorconfig file +encoding.change.reloading.files=Reloading files \ No newline at end of file diff --git a/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigStatusListener.java b/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigStatusListener.java index 6a557aad35ad..d2e2df7d0ade 100644 --- a/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigStatusListener.java +++ b/plugins/editorconfig/src/org/editorconfig/configmanagement/editor/EditorConfigStatusListener.java @@ -3,10 +3,18 @@ package org.editorconfig.configmanagement.editor; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileVisitor; +import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.codeStyle.CodeStyleSettingsChangeEvent; import com.intellij.psi.codeStyle.CodeStyleSettingsListener; @@ -14,17 +22,26 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.ui.EditorNotifications; import com.intellij.util.ObjectUtils; import org.editorconfig.Utils; +import org.editorconfig.language.messages.EditorConfigBundle; import org.jetbrains.annotations.NotNull; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + public class EditorConfigStatusListener implements CodeStyleSettingsListener, Disposable { private boolean myEnabledStatus; private final VirtualFile myVirtualFile; private final Project myProject; + private Charset myEncoding; + + private MyReloadTask myReloadTask; public EditorConfigStatusListener(@NotNull Project project, @NotNull VirtualFile virtualFile) { myProject = project; myEnabledStatus = Utils.isEnabled(project); myVirtualFile = virtualFile; + myEncoding = EncodingProjectManager.getInstance(project).getEncoding(virtualFile, true); CodeStyleSettingsManager.getInstance(project).addListener(this); } @@ -35,6 +52,11 @@ public class EditorConfigStatusListener implements CodeStyleSettingsListener, Di myEnabledStatus = newEnabledStatus; onEditorConfigEnabled(newEnabledStatus); } + Charset newEncoding = EncodingProjectManager.getInstance(myProject).getEncoding(myVirtualFile, true); + if (!myEncoding.equals(newEncoding)) { + onEncodingChanged(); + myEncoding = newEncoding; + } } private void onEditorConfigEnabled(boolean isEnabled) { @@ -53,4 +75,48 @@ public class EditorConfigStatusListener implements CodeStyleSettingsListener, Di public void dispose() { CodeStyleSettingsManager.removeListener(myProject, this); } + + private void onEncodingChanged() { + if (myReloadTask != null) { + myReloadTask.interrupt(); + } + MyReloadTask reloadTask = new MyReloadTask(); + ProgressManager.getInstance().run(reloadTask); + myReloadTask = reloadTask; + } + + private class MyReloadTask extends Task.Backgroundable { + private volatile boolean myInterrupted; + + private MyReloadTask() { + super(EditorConfigStatusListener.this.myProject, EditorConfigBundle.message("encoding.change.reloading.files"), false); + } + + @Override + public void run(@NotNull ProgressIndicator indicator) { + List filesToReload = new ArrayList<>(); + VirtualFile parentDir = myVirtualFile.getParent(); + final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); + VfsUtilCore.visitChildrenRecursively( + parentDir, + new VirtualFileVisitor<>() { + @Override + public boolean visitFile(@NotNull VirtualFile file) { + if (myInterrupted) throw new ProcessCanceledException(); + if (!file.isDirectory() && fileDocumentManager.getCachedDocument(file) != null) { + filesToReload.add(file); + } + return true; + } + } + ); + ApplicationManager.getApplication().invokeLater( + () -> fileDocumentManager.reloadFiles(filesToReload.toArray(VirtualFile.EMPTY_ARRAY))); + } + + + void interrupt() { + myInterrupted = true; + } + } }