implement file open from Finder, save preserves format, save-as with format choice
This commit is contained in:
parent
93d00f4282
commit
3d20668edc
|
|
@ -43,6 +43,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func application(_ application: NSApplication, open urls: [URL]) {
|
||||||
|
guard let url = urls.first else { return }
|
||||||
|
appState.loadNoteFromFile(url)
|
||||||
|
}
|
||||||
|
|
||||||
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +174,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
|
|
||||||
@objc private func openNote() {
|
@objc private func openNote() {
|
||||||
let panel = NSOpenPanel()
|
let panel = NSOpenPanel()
|
||||||
panel.allowedContentTypes = [UTType(filenameExtension: "md")!, .plainText]
|
panel.allowedContentTypes = Self.supportedContentTypes
|
||||||
panel.canChooseFiles = true
|
panel.canChooseFiles = true
|
||||||
panel.canChooseDirectories = false
|
panel.canChooseDirectories = false
|
||||||
panel.allowsMultipleSelection = false
|
panel.allowsMultipleSelection = false
|
||||||
|
|
@ -180,13 +185,21 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func saveNote() {
|
@objc private func saveNote() {
|
||||||
appState.saveNote()
|
if appState.currentFileURL != nil {
|
||||||
|
appState.saveNote()
|
||||||
|
} else {
|
||||||
|
saveNoteAs()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func saveNoteAs() {
|
@objc private func saveNoteAs() {
|
||||||
let panel = NSSavePanel()
|
let panel = NSSavePanel()
|
||||||
panel.allowedContentTypes = [UTType(filenameExtension: "md")!]
|
panel.allowedContentTypes = Self.supportedContentTypes
|
||||||
panel.nameFieldStringValue = defaultFilename()
|
panel.nameFieldStringValue = defaultFilename()
|
||||||
|
if let url = appState.currentFileURL {
|
||||||
|
panel.directoryURL = url.deletingLastPathComponent()
|
||||||
|
panel.nameFieldStringValue = url.lastPathComponent
|
||||||
|
}
|
||||||
panel.beginSheetModal(for: window) { [weak self] response in
|
panel.beginSheetModal(for: window) { [weak self] response in
|
||||||
guard response == .OK, let url = panel.url else { return }
|
guard response == .OK, let url = panel.url else { return }
|
||||||
self?.appState.saveNoteToFile(url)
|
self?.appState.saveNoteToFile(url)
|
||||||
|
|
@ -194,6 +207,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func defaultFilename() -> String {
|
private func defaultFilename() -> String {
|
||||||
|
if let url = appState.currentFileURL {
|
||||||
|
return url.lastPathComponent
|
||||||
|
}
|
||||||
let firstLine = appState.documentText
|
let firstLine = appState.documentText
|
||||||
.components(separatedBy: "\n").first?
|
.components(separatedBy: "\n").first?
|
||||||
.trimmingCharacters(in: .whitespaces) ?? ""
|
.trimmingCharacters(in: .whitespaces) ?? ""
|
||||||
|
|
@ -201,11 +217,74 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
of: "^#+\\s*", with: "", options: .regularExpression
|
of: "^#+\\s*", with: "", options: .regularExpression
|
||||||
)
|
)
|
||||||
let trimmed = stripped.trimmingCharacters(in: .whitespaces)
|
let trimmed = stripped.trimmingCharacters(in: .whitespaces)
|
||||||
guard !trimmed.isEmpty, trimmed != "Untitled" else { return "note.md" }
|
let ext = extensionForFormat(appState.currentFileFormat)
|
||||||
|
guard !trimmed.isEmpty, trimmed != "Untitled" else { return "note.\(ext)" }
|
||||||
let sanitized = trimmed.map { "/:\\\\".contains($0) ? "-" : String($0) }.joined()
|
let sanitized = trimmed.map { "/:\\\\".contains($0) ? "-" : String($0) }.joined()
|
||||||
return sanitized.prefix(80) + ".md"
|
return sanitized.prefix(80) + ".\(ext)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func extensionForFormat(_ format: FileFormat) -> String {
|
||||||
|
switch format {
|
||||||
|
case .markdown: return "md"
|
||||||
|
case .csv: return "csv"
|
||||||
|
case .json: return "json"
|
||||||
|
case .toml: return "toml"
|
||||||
|
case .yaml: return "yaml"
|
||||||
|
case .xml: return "xml"
|
||||||
|
case .svg: return "svg"
|
||||||
|
case .rust: return "rs"
|
||||||
|
case .c: return "c"
|
||||||
|
case .cpp: return "cpp"
|
||||||
|
case .objc: return "m"
|
||||||
|
case .javascript: return "js"
|
||||||
|
case .typescript: return "ts"
|
||||||
|
case .jsx: return "jsx"
|
||||||
|
case .tsx: return "tsx"
|
||||||
|
case .html: return "html"
|
||||||
|
case .css: return "css"
|
||||||
|
case .scss: return "scss"
|
||||||
|
case .less: return "less"
|
||||||
|
case .python: return "py"
|
||||||
|
case .go: return "go"
|
||||||
|
case .ruby: return "rb"
|
||||||
|
case .php: return "php"
|
||||||
|
case .lua: return "lua"
|
||||||
|
case .shell: return "sh"
|
||||||
|
case .java: return "java"
|
||||||
|
case .kotlin: return "kt"
|
||||||
|
case .swift: return "swift"
|
||||||
|
case .zig: return "zig"
|
||||||
|
case .sql: return "sql"
|
||||||
|
case .makefile: return "mk"
|
||||||
|
case .dockerfile: return "Dockerfile"
|
||||||
|
case .config: return "conf"
|
||||||
|
case .lock: return "lock"
|
||||||
|
case .plainText, .unknown: return "txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static let supportedContentTypes: [UTType] = {
|
||||||
|
let extensions = [
|
||||||
|
"md", "markdown", "mdown",
|
||||||
|
"csv", "json", "toml", "yaml", "yml", "xml", "svg",
|
||||||
|
"rs", "c", "cpp", "cc", "cxx", "h", "hpp", "hxx",
|
||||||
|
"js", "jsx", "ts", "tsx",
|
||||||
|
"html", "htm", "css", "scss", "less",
|
||||||
|
"py", "go", "rb", "php", "lua",
|
||||||
|
"sh", "bash", "zsh", "fish",
|
||||||
|
"java", "kt", "kts", "swift", "zig", "sql",
|
||||||
|
"mk", "ini", "cfg", "conf", "env",
|
||||||
|
"lock", "txt", "text", "log"
|
||||||
|
]
|
||||||
|
var types: [UTType] = [.plainText]
|
||||||
|
for ext in extensions {
|
||||||
|
if let t = UTType(filenameExtension: ext) {
|
||||||
|
types.append(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array(Set(types))
|
||||||
|
}()
|
||||||
|
|
||||||
@objc private func openSettings() {
|
@objc private func openSettings() {
|
||||||
SettingsWindowController.show()
|
SettingsWindowController.show()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue