Add recent files menu functionality

Implemented comprehensive recent files tracking system:
- Created RecentFilesManager singleton with UserDefaults persistence
- Added Recent Files submenu to File menu with up to 10 recent files
- Automatic file validation that removes deleted files from list
- Smart file tracking that adds files when opened and moves to top
- Clear Recent Files option for user control
- User-friendly display showing filename and relative path
- Error handling for missing files with user notification

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
0x8664b2
2025-06-20 10:48:11 -07:00
parent 732f633086
commit a3e8b09a8f
4 changed files with 149 additions and 26 deletions

View File

@@ -0,0 +1,71 @@
import Foundation
class RecentFilesManager: ObservableObject {
static let shared = RecentFilesManager()
@Published var recentFiles: [URL] = []
private let maxRecentFiles = 10
private let userDefaultsKey = "RecentMarkdownFiles"
private init() {
loadRecentFiles()
}
func addRecentFile(_ url: URL) {
// Remove if already exists to move it to top
recentFiles.removeAll { $0 == url }
// Add to beginning
recentFiles.insert(url, at: 0)
// Limit to max count
if recentFiles.count > maxRecentFiles {
recentFiles = Array(recentFiles.prefix(maxRecentFiles))
}
saveRecentFiles()
}
func removeRecentFile(_ url: URL) {
recentFiles.removeAll { $0 == url }
saveRecentFiles()
}
func clearRecentFiles() {
recentFiles.removeAll()
saveRecentFiles()
}
private func loadRecentFiles() {
if let data = UserDefaults.standard.data(forKey: userDefaultsKey),
let urls = try? JSONDecoder().decode([URL].self, from: data) {
// Filter out files that no longer exist
recentFiles = urls.filter { FileManager.default.fileExists(atPath: $0.path) }
// Save filtered list back if any files were removed
if recentFiles.count != urls.count {
saveRecentFiles()
}
}
}
private func saveRecentFiles() {
if let data = try? JSONEncoder().encode(recentFiles) {
UserDefaults.standard.set(data, forKey: userDefaultsKey)
}
}
func getDisplayName(for url: URL) -> String {
return url.lastPathComponent
}
func getRelativePath(for url: URL) -> String {
let homeURL = FileManager.default.homeDirectoryForCurrentUser
if url.path.hasPrefix(homeURL.path) {
let relativePath = String(url.path.dropFirst(homeURL.path.count))
return "~" + relativePath
}
return url.path
}
}