-
-
Notifications
You must be signed in to change notification settings - Fork 426
Expand file tree
/
Copy pathFilespace.swift
More file actions
88 lines (74 loc) · 2.39 KB
/
Filespace.swift
File metadata and controls
88 lines (74 loc) · 2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import Environment
import Foundation
import SuggestionModel
public protocol FilespacePropertyKey {
associatedtype Value
static func createDefaultValue() -> Value
}
@WorkspaceActor
public final class FilespacePropertyValues {
var storage: [ObjectIdentifier: Any] = [:]
public subscript<K: FilespacePropertyKey>(_ key: K.Type) -> K.Value {
get {
if let value = storage[ObjectIdentifier(key)] as? K.Value {
return value
}
let value = key.createDefaultValue()
storage[ObjectIdentifier(key)] = value
return value
}
set {
storage[ObjectIdentifier(key)] = newValue
}
}
}
@WorkspaceActor
@dynamicMemberLookup
public final class Filespace {
public let fileURL: URL
public private(set) lazy var language: String = languageIdentifierFromFileURL(fileURL).rawValue
public var suggestions: [CodeSuggestion] = [] {
didSet { refreshUpdateTime() }
}
public var suggestionIndex: Int = 0
public var presentingSuggestion: CodeSuggestion? {
guard suggestions.endIndex > suggestionIndex, suggestionIndex >= 0 else { return nil }
return suggestions[suggestionIndex]
}
public var isExpired: Bool {
Environment.now().timeIntervalSince(lastSuggestionUpdateTime) > 60 * 3
}
private(set) var lastSuggestionUpdateTime: Date = Environment.now()
var additionalProperties = FilespacePropertyValues()
let fileSaveWatcher: FileSaveWatcher
let onClose: (URL) -> Void
deinit {
onClose(fileURL)
}
init(
fileURL: URL,
onSave: @escaping (Filespace) -> Void,
onClose: @escaping (URL) -> Void
) {
self.fileURL = fileURL
self.onClose = onClose
fileSaveWatcher = .init(fileURL: fileURL)
fileSaveWatcher.changeHandler = { [weak self] in
guard let self else { return }
onSave(self)
}
}
public subscript<K>(
dynamicMember dynamicMember: WritableKeyPath<FilespacePropertyValues, K>
) -> K {
get { additionalProperties[keyPath: dynamicMember] }
set { additionalProperties[keyPath: dynamicMember] = newValue }
}
public func reset() {
suggestions = []
suggestionIndex = 0
}
public func refreshUpdateTime() {
lastSuggestionUpdateTime = Environment.now()
}
}