Skip to content

Commit c535e86

Browse files
authored
Do hot reload on auto-save (#5774)
1 parent acad411 commit c535e86

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

src/io/flutter/run/FlutterReloadManager.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package io.flutter.run;
77

8+
import com.intellij.AppTopics;
89
import com.intellij.codeInsight.hint.HintManager;
910
import com.intellij.codeInsight.hint.HintManagerImpl;
1011
import com.intellij.codeInsight.hint.HintUtil;
@@ -22,11 +23,16 @@
2223
import com.intellij.openapi.actionSystem.DataContext;
2324
import com.intellij.openapi.actionSystem.ex.AnActionListener;
2425
import com.intellij.openapi.application.ApplicationManager;
26+
import com.intellij.openapi.application.ModalityState;
2527
import com.intellij.openapi.components.ServiceManager;
2628
import com.intellij.openapi.diagnostic.Logger;
2729
import com.intellij.openapi.editor.Document;
2830
import com.intellij.openapi.editor.Editor;
31+
import com.intellij.openapi.editor.EditorFactory;
2932
import com.intellij.openapi.fileEditor.FileDocumentManager;
33+
import com.intellij.openapi.fileEditor.FileDocumentManagerListener;
34+
import com.intellij.openapi.fileEditor.FileEditor;
35+
import com.intellij.openapi.fileEditor.FileEditorManager;
3036
import com.intellij.openapi.project.Project;
3137
import com.intellij.openapi.ui.popup.Balloon;
3238
import com.intellij.openapi.util.Computable;
@@ -54,6 +60,7 @@
5460
import io.flutter.run.common.RunMode;
5561
import io.flutter.run.daemon.FlutterApp;
5662
import io.flutter.settings.FlutterSettings;
63+
import io.flutter.utils.FlutterModuleUtils;
5764
import io.flutter.utils.MostlySilentColoredProcessHandler;
5865
import org.jetbrains.annotations.NotNull;
5966
import org.jetbrains.annotations.Nullable;
@@ -85,7 +92,6 @@ private static NotificationGroup getNotificationGroup(String toolWindowId) {
8592
}
8693

8794
private final @NotNull Project myProject;
88-
private final FlutterSettings mySettings;
8995

9096
private Notification lastNotification;
9197

@@ -103,7 +109,6 @@ public static FlutterReloadManager getInstance(@NotNull Project project) {
103109

104110
private FlutterReloadManager(@NotNull Project project) {
105111
this.myProject = project;
106-
this.mySettings = FlutterSettings.getInstance();
107112

108113
final MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(project);
109114
connection.subscribe(AnActionListener.TOPIC, new AnActionListener() {
@@ -146,10 +151,48 @@ public void afterActionPerformed(@NotNull AnAction action, @NotNull DataContext
146151
}
147152
}
148153
});
154+
connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerListener() {
155+
@Override
156+
public void beforeAllDocumentsSaving() {
157+
if (!FlutterSettings.getInstance().isReloadOnSave()) return;
158+
if (myProject.isDisposed()) return;
159+
if (!FlutterModuleUtils.hasFlutterModule(myProject)) return;
160+
// The "Save files if the IDE is idle ..." option runs whether there are any changes or not.
161+
boolean isModified = false;
162+
for (FileEditor fileEditor : FileEditorManager.getInstance(myProject).getAllEditors()) {
163+
if (fileEditor.isModified()) {
164+
isModified = true;
165+
break;
166+
}
167+
}
168+
if (!isModified) return;
169+
170+
ApplicationManager.getApplication().invokeLater(() -> {
171+
// Find a Dart editor to trigger the reload.
172+
final Editor anEditor = ApplicationManager.getApplication().runReadAction((Computable<Editor>)() -> {
173+
Editor someEditor = null;
174+
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
175+
if (editor.isDisposed()) continue;
176+
if (editor.getProject() != myProject) continue;
177+
final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
178+
if (psiFile instanceof DartFile && someEditor == null) {
179+
someEditor = editor;
180+
}
181+
if (null != PsiTreeUtil.findChildOfType(psiFile, PsiErrorElement.class, false)) {
182+
// If there are analysis errors we want to silently exit, without showing a notification.
183+
return null;
184+
}
185+
}
186+
return someEditor;
187+
});
188+
handleSaveAllNotification(anEditor);
189+
}, ModalityState.any());
190+
}
191+
});
149192
}
150193

151194
private void handleSaveAllNotification(@Nullable Editor editor) {
152-
if (!mySettings.isReloadOnSave() || editor == null) {
195+
if (!FlutterSettings.getInstance().isReloadOnSave() || editor == null) {
153196
return;
154197
}
155198

0 commit comments

Comments
 (0)