diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 000000000..c472967b7
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,35 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(npm run build:mac:*)",
+ "Bash(npm install:*)",
+ "Bash(npm run rebuild-native:*)",
+ "Bash(CXXFLAGS=\"-std=c++17\" npm run rebuild-native:*)",
+ "Bash(npm run build:*)",
+ "Bash(npx electron-builder:*)",
+ "Read(//Users/michaeljosephwork/git/marktext_messed_up/**)",
+ "Bash(gh pr list:*)",
+ "Bash(gh pr view:*)",
+ "Bash(git remote add:*)",
+ "Bash(git fetch:*)",
+ "Bash(git cherry-pick:*)",
+ "Bash(git checkout:*)",
+ "Bash(git reset:*)",
+ "Bash(git stash:*)",
+ "Bash(git log:*)",
+ "Bash(git merge:*)",
+ "Bash(git push:*)",
+ "WebFetch(domain:github.com)",
+ "Bash(gh pr create:*)",
+ "Bash(cat:*)",
+ "Bash(npx patch-package)",
+ "Bash(ls:*)",
+ "Bash(awk:*)",
+ "Bash(npx patch-package:*)",
+ "Bash(git add:*)",
+ "Bash(git commit:*)"
+ ],
+ "deny": [],
+ "ask": []
+ }
+}
diff --git a/src/main/preferences/schema.json b/src/main/preferences/schema.json
index 7e3df710d..50275cffa 100644
--- a/src/main/preferences/schema.json
+++ b/src/main/preferences/schema.json
@@ -417,5 +417,10 @@
"description": "Watcher--Whether to use polling. Polling may leads to high CPU utilization but is necessary to watch files over a network.",
"type": "boolean",
"default": false
+ },
+ "autoReloadUnmodifiedFiles": {
+ "description": "Experimental--Automatically reload unmodified documents when changed on disk.",
+ "type": "boolean",
+ "default": true
}
}
diff --git a/src/renderer/src/assets/icons/pref_experimental.svg b/src/renderer/src/assets/icons/pref_experimental.svg
new file mode 100644
index 000000000..cd079ed8a
--- /dev/null
+++ b/src/renderer/src/assets/icons/pref_experimental.svg
@@ -0,0 +1 @@
+
diff --git a/src/renderer/src/components/editorWithTabs/notifications.vue b/src/renderer/src/components/editorWithTabs/notifications.vue
index d69e00e1c..08d6c7cab 100644
--- a/src/renderer/src/components/editorWithTabs/notifications.vue
+++ b/src/renderer/src/components/editorWithTabs/notifications.vue
@@ -7,6 +7,9 @@
>
@@ -28,7 +31,7 @@
diff --git a/src/renderer/src/prefComponents/sideBar/config.js b/src/renderer/src/prefComponents/sideBar/config.js
index 91c5d4678..1b02eb139 100644
--- a/src/renderer/src/prefComponents/sideBar/config.js
+++ b/src/renderer/src/prefComponents/sideBar/config.js
@@ -5,6 +5,7 @@ import ThemeIcon from '@/assets/icons/pref_theme.svg'
import ImageIcon from '@/assets/icons/pref_image.svg'
import SpellIcon from '@/assets/icons/pref_spellcheck.svg'
import KeyBindingIcon from '@/assets/icons/pref_key_binding.svg'
+import ExperimentalIcon from '@/assets/icons/pref_experimental.svg'
import preferences from '../../../../main/preferences/schema.json'
import { t } from '../../i18n'
@@ -51,6 +52,12 @@ export const getCategory = () => [
label: 'keybindings',
icon: KeyBindingIcon,
path: '/preference/keybindings'
+ },
+ {
+ name: t('preferences.categories.experimental'),
+ label: 'experimental',
+ icon: ExperimentalIcon,
+ path: '/preference/experimental'
}
]
@@ -93,7 +100,7 @@ export const getTranslatedSearchContent = () => {
// 计算用于路由跳转的分类(仅允许已存在的路由,否则回退到 general)
let routeCategory = mappedCategory
- const validRoutes = ['general', 'editor', 'markdown', 'spelling', 'theme', 'image', 'keybindings']
+ const validRoutes = ['general', 'editor', 'markdown', 'spelling', 'theme', 'image', 'keybindings', 'experimental']
if (!validRoutes.includes(routeCategory)) routeCategory = 'general'
// 尝试翻译分类和项目
diff --git a/src/renderer/src/router/index.js b/src/renderer/src/router/index.js
index dfac35119..ff52918e6 100644
--- a/src/renderer/src/router/index.js
+++ b/src/renderer/src/router/index.js
@@ -7,6 +7,7 @@ import SpellChecker from '@/prefComponents/spellchecker'
import Theme from '@/prefComponents/theme'
import Image from '@/prefComponents/image'
import Keybindings from '@/prefComponents/keybindings'
+import Experimental from '@/prefComponents/experimental'
const parseSettingsPage = (type) => {
let pageUrl = '/preference'
@@ -67,6 +68,11 @@ const routes = (type) => [
path: 'keybindings',
component: Keybindings,
name: 'keybindings'
+ },
+ {
+ path: 'experimental',
+ component: Experimental,
+ name: 'experimental'
}
]
}
diff --git a/src/renderer/src/store/editor.js b/src/renderer/src/store/editor.js
index e9f94de14..d1e43772d 100644
--- a/src/renderer/src/store/editor.js
+++ b/src/renderer/src/store/editor.js
@@ -71,6 +71,9 @@ export const useEditorStore = defineStore('editor', {
const style = data.style || 'info'
// Whether only one notification should exist.
const exclusiveType = data.exclusiveType || ''
+ const autoHide = data.autoHide || false
+ const autoHideDuration = data.autoHideDuration || 3000
+ const showCountdown = data.showCountdown || false
const tab = this.tabs.find((t) => t.id === tabId)
if (!tab) {
@@ -95,7 +98,10 @@ export const useEditorStore = defineStore('editor', {
showConfirm,
style,
exclusiveType,
- action
+ action,
+ autoHide,
+ autoHideDuration,
+ showCountdown
})
},
@@ -1231,7 +1237,24 @@ export const useEditorStore = defineStore('editor', {
}
case 'add':
case 'change': {
- const { autoSave } = preferencesStore
+ const { autoSave, autoReloadUnmodifiedFiles } = preferencesStore
+
+ // Check if auto-reload unmodified files is enabled
+ if (autoReloadUnmodifiedFiles && isSaved) {
+ this.loadChange(change)
+ this.pushTabNotification({
+ tabId: id,
+ msg: i18n.global.t('store.editor.documentAutoReloaded'),
+ style: 'success',
+ showConfirm: false,
+ exclusiveType: 'file_changed',
+ autoHide: true,
+ autoHideDuration: 5000,
+ showCountdown: true
+ })
+ return
+ }
+
if (autoSave) {
if (autoSaveTimers.has(id)) {
const timer = autoSaveTimers.get(id)
diff --git a/src/renderer/src/store/preferences.js b/src/renderer/src/store/preferences.js
index fbc7ad124..9485f173c 100644
--- a/src/renderer/src/store/preferences.js
+++ b/src/renderer/src/store/preferences.js
@@ -77,6 +77,8 @@ export const usePreferencesStore = defineStore('preferences', {
watcherUsePolling: false,
+ autoReloadUnmodifiedFiles: true,
+
// --------------------------------------------------------------------------
// Edit modes of the current window (not part of persistent settings)
diff --git a/static/locales/en.json b/static/locales/en.json
index 43bcaae3b..19e75d5d0 100644
--- a/static/locales/en.json
+++ b/static/locales/en.json
@@ -448,7 +448,8 @@
"spelling": "Spelling",
"theme": "Theme",
"image": "Image",
- "keybindings": "Keybindings"
+ "keybindings": "Keybindings",
+ "experimental": "Experimental"
},
"general": {
"title": "General",
@@ -854,6 +855,13 @@
"unbind": "Unbind"
}
},
+ "experimental": {
+ "title": "Experimental",
+ "fileHandling": {
+ "title": "File Handling",
+ "autoReloadUnmodified": "Automatically reload unmodified documents when changed on disk"
+ }
+ },
"selectFont": "Select Font",
"spellchecker": {
"autoDetectDescription": "Automatically detect document language",
@@ -1102,7 +1110,8 @@
"exportSuccessTitle": "Exported successfully",
"exportSuccessMessage": "Exported \"{name}\" successfully!",
"fileRemovedOnDisk": "\"{name}\" has been removed on disk.",
- "fileChangedOnDisk": "\"{name}\" has been changed on disk. Do you want to reload it?"
+ "fileChangedOnDisk": "\"{name}\" has been changed on disk. Do you want to reload it?",
+ "documentAutoReloaded": "Document automatically reloaded from disk"
},
"help": {
"lineEndingAssertionError": "Line ending assertion error"
diff --git a/static/preference.json b/static/preference.json
index 304d42d8f..62c1bb728 100644
--- a/static/preference.json
+++ b/static/preference.json
@@ -69,5 +69,7 @@
"searchNoIgnore": false,
"searchFollowSymlinks": true,
- "watcherUsePolling": false
+ "watcherUsePolling": false,
+
+ "autoReloadUnmodifiedFiles": true
}