Skip to content

Commit

Permalink
Fixed Open As Source Code menu item for all type of text files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonardo Larrañaga committed Sep 5, 2024
1 parent 460dfcb commit 9ac49cf
Showing 1 changed file with 29 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,15 @@ final class ProjectNavigatorMenu: NSMenu {
// Use UTType to distinguish between bundle file and user-browsable directory
// The isDirectory property is not accurate on this.
guard let type = item.contentType else { return ([.none()], []) }

if type.conforms(to: .folder) {
return ([.none()], [])
}
var primaryItems = [NSMenuItem]()
if type.conforms(to: .sourceCode) {
primaryItems.append(
menuItem("Source Code", action: #selector(openInSourceCode))
)

if type.conforms(to: .text) || checkFileIsText(for: item) {
primaryItems.append(menuItem("Source Code", action: #selector(openInSourceCode)))
primaryItems.append(.separator())
}
if type.conforms(to: .propertyList) {
primaryItems.append(.propertyList())
Expand Down Expand Up @@ -177,6 +178,30 @@ final class ProjectNavigatorMenu: NSMenu {
return sourceControlMenu
}

/// Checks if the given `CEWorkspaceFile` is a text file.
/// This function verifies if the content of the file can be decoded as text.
/// It is used as a fallback when the type identifier does not conform to the expected text type.
func checkFileIsText(for item: CEWorkspaceFile) -> Bool {
do {
// Read the first 512 bytes of the file.
let fileHandle = try FileHandle(forReadingFrom: item.url)
defer { fileHandle.closeFile() }
guard let fileData = try fileHandle.read(upToCount: 512) else { return false }

// Extreme use case: Returns true for empty files.
// E.g. The user hasn't typed anything on it, yet.
// This used for files like .env, .gitignore or files that lack an extension.
if fileData.isEmpty {
return true
}
// swiftlint:disable:next non_optional_string_data_conversion
return String(data: fileData, encoding: .utf8) != nil
} catch {
print("Error reading file: \(error)")
return false
}
}

/// Updates the menu for the selected item and hides it if no item is provided.
override func update() {
removeAllItems()
Expand Down

0 comments on commit 9ac49cf

Please sign in to comment.