Repository: CodeEditApp/CodeEdit
File: CodeEdit/Documents/WorkspaceDocument.swift (Swift)

Code before:
                        self.fileItems.remove(at: index)
                    } else {
                        self.fileItems.append(newFile)
                    }
                }
            }
            .store(in: &cancellables)

        // initialize extensions
        do {
            try ExtensionsManager.shared?.load { extensionID in
                return CodeEditAPI(extensionId: extensionID, workspace: self)
            }
        } catch let error {
            Swift.print(error)
        }
    }

    override func write(to url: URL, ofType typeName: String) throws {}

    // MARK: Close Workspace

    private func saveSelectionState() throws {
        guard let path = fileURL?.path,
              let pathData = path.data(using: .utf8) else { return }
        let hash = String(CryptoKit.SHA256.hash(data: pathData).hashValue)
        let data =  try PropertyListEncoder().encode(selectionState)
        UserDefaults.standard.set(data, forKey: hash)
    }

    override func close() {
        do {
            try saveSelectionState()
        } catch {
            Swift.print("couldn't save selection state from user defaults")
        }

        selectionState.selectedId = nil
        selectionState.openFileItems.forEach { item in
            do {
                try selectionState.openedCodeFiles[item]?.write(to: item.url, ofType: "public.source-code")
                selectionState.openedCodeFiles[item]?.close()
            } catch {}
        }
        selectionState.openedCodeFiles.removeAll()

        if let url = self.fileURL {
            ExtensionsManager.shared?.close(url: url)
        }

        super.close()

Review comment (suggestion):
`.hashValue` will not be equal across executions of the program ([source](https://developer.apple.com/documentation/swift/string/hashvalue)).

Consider implementing it something like that:

```swift
let stringData = "Hello World".data(using: .utf8)!

let hash = SHA256.hash(data: stringData)

let hashString = hash.compactMap { String(format: "%02x", $0) }.joined()
```

Code after:
                    } else {
                        self.fileItems.append(newFile)
                    }
                }
            }
            .store(in: &cancellables)

        // initialize extensions
        do {
            try ExtensionsManager.shared?.load { extensionID in
                return CodeEditAPI(extensionId: extensionID, workspace: self)
            }
        } catch let error {
            Swift.print(error)
        }
    }

    override func write(to url: URL, ofType typeName: String) throws {}

    // MARK: Close Workspace

    /// Saves selection state to UserDefaults using SHA256 hash of project  path as key
    /// - Throws: `EncodingError.invalidValue` error if sellection state is not encodable
    private func saveSelectionState() throws {
        guard let path = fileURL?.path,
              let hash = path.sha256Hash else { return }
        let data = try PropertyListEncoder().encode(selectionState)
        UserDefaults.standard.set(data, forKey: hash)
    }

    override func close() {
        do {
            try saveSelectionState()
        } catch {
            Swift.print("couldn't save selection state from user defaults")
        }

        selectionState.selectedId = nil
        selectionState.openFileItems.forEach { item in
            do {
                try selectionState.openedCodeFiles[item]?.write(to: item.url, ofType: "public.source-code")
                selectionState.openedCodeFiles[item]?.close()
            } catch {}
        }
        selectionState.openedCodeFiles.removeAll()

        if let url = self.fileURL {
            ExtensionsManager.shared?.close(url: url)
        }

        super.close()