@@ -232,6 +232,10 @@ open class EditorHandlerActivity :
232232 loadPluginTabs()
233233 }
234234
235+ /* *
236+ * Persists which tabs are open (preferences only). Does **not** write project file buffers to disk;
237+ * saving is explicit or prompted (e.g. close project).
238+ */
235239 override fun onPause () {
236240 super .onPause()
237241 // Record timestamps for all currently open files before saving the cache
@@ -246,7 +250,6 @@ open class EditorHandlerActivity :
246250 if (! isOpenedFilesSaved.get()) {
247251 saveOpenedFiles()
248252 saveOpenedPluginTabs()
249- saveAllAsync(notify = false )
250253 }
251254 }
252255
@@ -271,26 +274,29 @@ open class EditorHandlerActivity :
271274 invalidateOptionsMenu()
272275 }
273276
277+ /* *
278+ * Reloads disk content into an open editor only when the file changed on disk since the last
279+ * [onPause] snapshot **and** the in-memory buffer is still clean ([CodeEditorView.isModified] is
280+ * false). A clean buffer may still have undo history after [IDEEditor.markUnmodified] / save; we
281+ * reload anyway so external edits are not ignored. Never replaces buffers with unsaved edits.
282+ */
274283 private fun checkForExternalFileChanges () {
275- // Get the list of files currently managed by the ViewModel
276284 val openFiles = editorViewModel.getOpenedFiles()
277285 if (openFiles.isEmpty() || fileTimestamps.isEmpty()) return
278286
279287 lifecycleScope.launch(Dispatchers .IO ) {
280- // Check each open file
281288 openFiles.forEach { file ->
282289 val lastKnownTimestamp = fileTimestamps[file.absolutePath] ? : return @forEach
283290 val currentTimestamp = file.lastModified()
284291
285- // If the file on disk is newer.
286292 if (currentTimestamp > lastKnownTimestamp) {
287293 val newContent = runCatching { file.readText() }.getOrNull() ? : return @forEach
288294 withContext(Dispatchers .Main ) {
289- // If the editor for the new file exists AND has no unsaved changes...
290295 val editorView = getEditorForFile(file) ? : return @withContext
291296 if (editorView.isModified) return @withContext
297+ val ideEditor = editorView.editor ? : return @withContext
292298
293- editorView.editor? .setText(newContent)
299+ ideEditor .setText(newContent)
294300 editorView.markAsSaved()
295301 updateTabs()
296302 }
@@ -341,12 +347,19 @@ open class EditorHandlerActivity :
341347 prefs.getString(PREF_KEY_OPEN_FILES_CACHE , null )
342348 } ? : return @launch
343349
350+ if (editorViewModel.getOpenedFileCount() > 0 ) {
351+ // Returning to an in-memory session (e.g. after onPause/onStop). Replaying the
352+ // snapshot would be redundant and could interfere with dirty buffers and undo.
353+ withContext(Dispatchers .IO ) { prefs.putString(PREF_KEY_OPEN_FILES_CACHE , null ) }
354+ return @launch
355+ }
356+
344357 val cache = withContext(Dispatchers .Default ) {
345358 Gson ().fromJson(jsonCache, OpenedFilesCache ::class .java)
346359 }
347360 onReadOpenedFilesCache(cache)
348361
349- // Clear the preference so it's only loaded once on startup
362+ // Clear the preference so it's only loaded once per cold restore
350363 withContext(Dispatchers .IO ) { prefs.putString(PREF_KEY_OPEN_FILES_CACHE , null ) }
351364 } catch (err: Throwable ) {
352365 log.error(" Failed to reopen recently opened files" , err)
@@ -747,6 +760,11 @@ open class EditorHandlerActivity :
747760 override fun onConfigurationChanged (newConfig : Configuration ) {
748761 super .onConfigurationChanged(newConfig)
749762
763+ val safeContent = contentOrNull ? : return
764+ for (i in 0 until safeContent.editorContainer.childCount) {
765+ (safeContent.editorContainer.getChildAt(i) as ? CodeEditorView )?.reapplyEditorDisplayPreferences()
766+ }
767+
750768 getCurrentEditor()?.editor?.apply {
751769 doOnNextLayout {
752770 cursor?.let { c -> ensurePositionVisible(c.leftLine, c.leftColumn, true ) }
@@ -1069,17 +1087,20 @@ open class EditorHandlerActivity :
10691087 nameBuilder.addPath(it, it.path)
10701088 }
10711089
1072- for (index in 0 until content.tabs.tabCount) {
1073- val file = files.getOrNull(index) ? : continue
1090+ for (tabPos in 0 until content.tabs.tabCount) {
1091+ if (isPluginTab(tabPos)) continue
1092+ val fileIndex = getFileIndexForTabPosition(tabPos)
1093+ if (fileIndex < 0 ) continue
1094+ val file = files.getOrNull(fileIndex) ? : continue
10741095 val count = dupliCount[file.name] ? : 0
10751096
1076- val isModified = getEditorAtIndex(index )?.isModified ? : false
1097+ val isModified = getEditorAtIndex(fileIndex )?.isModified ? : false
10771098 var name = if (count > 1 ) nameBuilder.getShortPath(file) else file.name
10781099 if (isModified) {
10791100 name = " *$name "
10801101 }
10811102
1082- names[index ] = name to FileExtension .Factory .forFile(file, file.isDirectory).icon
1103+ names[tabPos ] = name to FileExtension .Factory .forFile(file, file.isDirectory).icon
10831104 }
10841105
10851106 withContext(Dispatchers .Main ) {
0 commit comments