krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Commit bbff3cc2a0

bbff3cc2a0281563a2440ea61b5f2826cbb15e97

parent: 674de54223

Verified · cmc

cmc <hello@cleberg.net> · 2026-10-08 03:34 UTC

Use the file's settings for the iOS agenda's Done swipe

The done keyword comes from DocumentSession.settings(for:), which applies
the configured TODO keywords and the file's setup files, as the editor does.

Layout: unified · split

Sources/OrgApp/DocumentSession.swift +8
@@ -82,6 +82,14 @@ public final class DocumentSession {
82 DocumentState(bytes: bytes, defaults: defaults.resolvingSetupFiles(in: SourceText(bytes: bytes).text, path: path, read: readText)) 82 DocumentState(bytes: bytes, defaults: defaults.resolvingSetupFiles(in: SourceText(bytes: bytes).text, path: path, read: readText))
83 } 83 }
84 84
85 /// The settings of the file at `path` as the editor sees them: its open buffer's, or its
86 /// text on disk with the defaults and the setup files it names.
87 public func settings(for path: String) -> OrgSettings? {
88 if let entry = entry(path) { return entry.buffer.document.tree.settings }
89 guard let bytes = (try? fileSystem.read(URL(fileURLWithPath: path))).flatMap({ $0 }) else { return nil }
90 return loaded(bytes, path: path).tree.settings
91 }
92
85 /// A file's text, for setup files. 93 /// A file's text, for setup files.
86 func readText(_ file: String) -> String? { 94 func readText(_ file: String) -> String? {
87 (try? fileSystem.read(URL(fileURLWithPath: file))).flatMap { $0 }.flatMap { String(bytes: $0, encoding: .utf8) } 95 (try? fileSystem.read(URL(fileURLWithPath: file))).flatMap { $0 }.flatMap { String(bytes: $0, encoding: .utf8) }
Sources/OrgstarMobile/AgendaScreen.swift +1 −3
@@ -260,9 +260,7 @@ struct AgendaScreen: View {
260 260
261 /// The first done keyword of the item's TODO sequence. 261 /// The first done keyword of the item's TODO sequence.
262 private func doneKeyword(for item: AgendaItem) -> String? { 262 private func doneKeyword(for item: AgendaItem) -> String? {
263 guard let todo = item.todo, let path = item.path else { return nil } 263 guard let todo = item.todo, let path = item.path, let settings = session.settings(for: path) else { return nil }
264 let text = session.openTexts[path] ?? (try? String(contentsOfFile: path, encoding: .utf8)) ?? ""
265 let settings = OrgParser.parse(text).settings
266 return settings.todoSequences.first { ($0.active + $0.done).contains { $0.name == todo } }?.done.first?.name 264 return settings.todoSequences.first { ($0.active + $0.done).contains { $0.name == todo } }?.done.first?.name
267 } 265 }
268 266
Tests/OrgAppTests/AppTests.swift +14
@@ -226,6 +226,20 @@ struct DocumentSessionTests {
226 #expect(session.document?.tree.settings.todoKeywordNames.contains("NEXT") == true) 226 #expect(session.document?.tree.settings.todoKeywordNames.contains("NEXT") == true)
227 } 227 }
228 228
229 @Test func settingsForAFileUseDefaultsAndSetupFiles() throws {
230 let notes = try Folder()
231 try notes.write("setup.org", "#+TODO: NEXT | FINISHED\n")
232 let viaSetup = try notes.write("a.org", "#+SETUPFILE: setup.org\n* NEXT One\n")
233 let plain = try notes.write("b.org", "* WAIT Two\n")
234 let session = DocumentSession(recovery: FileRecoveryStore(directory: notes.url.appendingPathComponent(".r")))
235 session.defaults = try #require(OrgSettings.default.withTodoKeywords("WAIT | OK"))
236 #expect(session.settings(for: viaSetup.path)?.todoSequences.first?.done.first?.name == "FINISHED")
237 #expect(session.settings(for: plain.path)?.todoSequences.first?.done.first?.name == "OK")
238 session.open(plain.path)
239 #expect(session.settings(for: plain.path)?.todoSequences.first?.done.first?.name == "OK")
240 #expect(session.settings(for: notes.url.appendingPathComponent("missing.org").path) == nil)
241 }
242
229 @Test func keywordCtrlCCtrlCRereadsSetupFiles() throws { 243 @Test func keywordCtrlCCtrlCRereadsSetupFiles() throws {
230 let notes = try Folder() 244 let notes = try Folder()
231 try notes.write("setup.org", "#+TODO: NEXT | DONE\n") 245 try notes.write("setup.org", "#+TODO: NEXT | DONE\n")