diff --git a/CodeApp/Managers/MainApp.swift b/CodeApp/Managers/MainApp.swift index 5cd1f2048..ceca66c32 100644 --- a/CodeApp/Managers/MainApp.swift +++ b/CodeApp/Managers/MainApp.swift @@ -643,6 +643,9 @@ class MainApp: ObservableObject { } private func createExtensionEditorFromURL(url: URL) throws -> EditorInstance { + guard url.lastPathComponent.contains(".") else { + throw AppError.unknownFileFormat + } let fileExtension = url.lastPathComponent.components(separatedBy: ".").last?.lowercased() ?? "" let provider = extensionManager.editorProviderManager.providers.first { diff --git a/CodeApp/Views/FileIcon.swift b/CodeApp/Views/FileIcon.swift index 501cec7fb..372958bf0 100644 --- a/CodeApp/Views/FileIcon.swift +++ b/CodeApp/Views/FileIcon.swift @@ -65,7 +65,8 @@ private let extensionNames = [ "stylelintrc.yml": "stylelint", "stylelintrc.js": "stylelint", "stylelintignore": "stylelint", "direnv": "config", "env": "config", "static": "config", "editorconfig": "config", "slugignore": "config", "tmp": "clock", "htaccess": "config", "key": "lock", "cert": "lock", - "DS_Store": "ignored", "svelte": "svelte", + "DS_Store": "ignored", "svelte": "svelte", "mjs": "javascript", "cjs": "javascript", + "mts": "typescript", "cts": "typescript" ] private let level2ExtensionNames = [ "css.map": "css", "js.map": "javascript", "spec.js": "javascript_yellow", @@ -78,7 +79,11 @@ private let level2ExtensionNames = [ "stylelintrc.json": "stylelint", "stylelintrc.yaml": "stylelint", "stylelintrc.yml": "stylelint", "stylelintrc.js": "stylelint", ] -private let fileNames = ["LICENSE": "license", "README.md": "info"] +private let fileNames = [ + "license": "license", "licence": "license", "license.txt": "license", "licence.txt": "license", + "license.md": "license", "licence.md": "license", "readme.txt": "info", "readme.md": "info", + "readme": "info" +] struct FileIcon: View { let url: String @@ -87,22 +92,18 @@ struct FileIcon: View { @Environment(\.sizeCategory) var sizeCategory var body: some View { - let fileName = url.components(separatedBy: "/").last ?? "" - switch fileName { - case let x where fileNames[x] != nil: - Image(fileNames[x]!).resizable().frame(width: iconSize + 6, height: iconSize + 6) - case let x - where - level2ExtensionNames[ - x.lowercased().components(separatedBy: ".").dropFirst().joined(separator: ".")] - != nil: - Image( - level2ExtensionNames[ - x.lowercased().components(separatedBy: ".").dropFirst().joined( - separator: ".")]! - ).resizable().frame(width: iconSize + 6, height: iconSize + 6) - default: - switch fileName.lowercased().components(separatedBy: ".").last ?? "" { + let fileName = url.components(separatedBy: "/").last?.lowercased() ?? "" + if let image = fileNames[fileName] { + Image(image) + .resizable() + .frame(width: iconSize + 6, height: iconSize + 6) + } else if let image = level2ExtensionNames[ + fileName.components(separatedBy: ".").suffix(2).joined(separator: ".")] { + Image(image) + .resizable() + .frame(width: iconSize + 6, height: iconSize + 6) + } else if fileName.contains(".") { + switch fileName.components(separatedBy: ".").last ?? "" { case "swift": Image(systemName: "swift") .foregroundColor(.orange) @@ -118,17 +119,25 @@ struct FileIcon: View { .foregroundColor(.gray) .font(.system(size: iconSize - 2)) .frame(width: iconSize + 6, height: iconSize + 6) - case let x where extensionNames[x] != nil: - Image(extensionNames[x]!) - .resizable() - .frame(width: iconSize + 6, height: iconSize + 6) case "icloud": - Image(systemName: "icloud.and.arrow.down").foregroundColor(.gray).font( - .system(size: iconSize - 2)) - default: - Image(systemName: "text.alignleft").foregroundColor(.gray).font( - .system(size: iconSize - 2)) + Image(systemName: "icloud.and.arrow.down") + .foregroundColor(.gray) + .font(.system(size: iconSize - 2)) + case let x: + if let image = extensionNames[x] { + Image(image) + .resizable() + .frame(width: iconSize + 6, height: iconSize + 6) + } else { + Image(systemName: "text.alignleft") + .foregroundColor(.gray) + .font(.system(size: iconSize - 2)) + } } + } else { + Image(systemName: "text.alignleft") + .foregroundColor(.gray) + .font(.system(size: iconSize - 2)) } } } diff --git a/CodeApp/Views/NewFileView.swift b/CodeApp/Views/NewFileView.swift index d7da5f86b..4cdb44a11 100644 --- a/CodeApp/Views/NewFileView.swift +++ b/CodeApp/Views/NewFileView.swift @@ -168,7 +168,7 @@ struct NewFileView: View { default: if name.contains(".") { name = returnFileName( - defaultName: name.components(separatedBy: ".").dropLast().joined(), + defaultName: name.components(separatedBy: ".").dropLast().joined(separator: "."), extensionName: name.components(separatedBy: ".").last ?? "") } content = "" diff --git a/Extensions/ImageViewer/ImageViewerExtension.swift b/Extensions/ImageViewer/ImageViewerExtension.swift index 8986bac3d..fdd04851a 100644 --- a/Extensions/ImageViewer/ImageViewerExtension.swift +++ b/Extensions/ImageViewer/ImageViewerExtension.swift @@ -70,7 +70,7 @@ class ImageViewerExtension: CodeAppExtension { override func onInitialize(app: MainApp, contribution: CodeAppExtension.Contribution) { let provider = EditorProvider( registeredFileExtensions: [ - "png", "tiff", "tif", "jpeg", "jpg", "gif", "bmp", "bmp", "BMPf", "ico", "cur", + "png", "tiff", "tif", "jpeg", "jpg", "gif", "bmp", "bmpf", "ico", "cur", "xbm", "heic", "webp", ], onCreateEditor: { [weak self] url in