krz/orgstar

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

Commit 34cbb80650

34cbb80650216e41303f2a9ddc54190da93cd978

parent: 13ab79873c

Verified · cmc

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

Show brackets in the inactive timestamp prompt preview

Prompt.DateRead carries whether the stamp is inactive.

Layout: unified · split

Sources/OrgCore/Commands/Command.swift +6 −1
@@ -151,7 +151,12 @@ public struct Prompt: Sendable, Equatable {
151 151
152 public struct DateRead: Sendable, Equatable { 152 public struct DateRead: Sendable, Equatable {
153 public let defaultDate: Date? 153 public let defaultDate: Date?
154 public init(defaultDate: Date?) { self.defaultDate = defaultDate } 154 /// Whether the answer becomes an inactive timestamp, shown in brackets.
155 public let inactive: Bool
156 public init(defaultDate: Date?, inactive: Bool = false) {
157 self.defaultDate = defaultDate
158 self.inactive = inactive
159 }
155 } 160 }
156 161
157 public init( 162 public init(
Sources/OrgCore/Commands/TimestampCommands.swift +1 −1
@@ -113,7 +113,7 @@ public struct InsertTimestamp: OrgCommand {
113 let stamp = buffer.atTimestamp().map { buffer.substring($0.match[0]!.lowerBound, $0.match[0]!.upperBound) } 113 let stamp = buffer.atTimestamp().map { buffer.substring($0.match[0]!.lowerBound, $0.match[0]!.upperBound) }
114 let repeated = context.lastCommand == "org.timestamp.active" || context.lastCommand == "org.timestamp.inactive" 114 let repeated = context.lastCommand == "org.timestamp.active" || context.lastCommand == "org.timestamp.inactive"
115 return .prompt(Prompt(key: "date", message: "Date+time:", initial: timeOfDayAtCaret(context), 115 return .prompt(Prompt(key: "date", message: "Date+time:", initial: timeOfDayAtCaret(context),
116 date: .init(defaultDate: repeated ? nil : buffer.dateDefault(stamp)))) 116 date: .init(defaultDate: repeated ? nil : buffer.dateDefault(stamp), inactive: inactive)))
117 } 117 }
118 // Twice in a row on a timestamp: a range to a second one. 118 // Twice in a row on a timestamp: a range to a second one.
119 let repeated = context.lastCommand == "org.timestamp.active" || context.lastCommand == "org.timestamp.inactive" 119 let repeated = context.lastCommand == "org.timestamp.active" || context.lastCommand == "org.timestamp.inactive"
Sources/Orgstar/DatePickerView.swift +4 −3
@@ -22,7 +22,7 @@ struct DatePickerView: View {
22 Button { month = calendar.date(byAdding: .month, value: 1, to: shown) } label: { Image(systemName: "chevron.right") } 22 Button { month = calendar.date(byAdding: .month, value: 1, to: shown) } label: { Image(systemName: "chevron.right") }
23 .accessibilityLabel("Next month") 23 .accessibilityLabel("Next month")
24 Spacer() 24 Spacer()
25 Text("=> " + Self.stamp(result, calendar)).font(.system(.callout, design: .monospaced)) 25 Text("=> " + Self.stamp(result, calendar, inactive: read.inactive)).font(.system(.callout, design: .monospaced))
26 } 26 }
27 .buttonStyle(.plain) 27 .buttonStyle(.plain)
28 Grid(horizontalSpacing: 4, verticalSpacing: 2) { 28 Grid(horizontalSpacing: 4, verticalSpacing: 2) {
@@ -102,11 +102,12 @@ struct DatePickerView: View {
102 return Self.answer(for: day, keeping: result, calendar) 102 return Self.answer(for: day, keeping: result, calendar)
103 } 103 }
104 104
105 static func stamp(_ result: ReadDate.Answer, _ calendar: Calendar) -> String { 105 static func stamp(_ result: ReadDate.Answer, _ calendar: Calendar, inactive: Bool) -> String {
106 let formatter = DateFormatter() 106 let formatter = DateFormatter()
107 formatter.locale = Locale(identifier: "en_US_POSIX") 107 formatter.locale = Locale(identifier: "en_US_POSIX")
108 formatter.dateFormat = result.timeGiven ? "yyyy-MM-dd EEE HH:mm" : "yyyy-MM-dd EEE" 108 formatter.dateFormat = result.timeGiven ? "yyyy-MM-dd EEE HH:mm" : "yyyy-MM-dd EEE"
109 let end = result.timeGiven ? result.endTime.map { "-" + $0 } ?? "" : "" 109 let end = result.timeGiven ? result.endTime.map { "-" + $0 } ?? "" : ""
110 return "<" + formatter.string(from: calendar.date(from: result.components(calendar))!) + end + ">" 110 let stamp = formatter.string(from: calendar.date(from: result.components(calendar))!) + end
111 return inactive ? "[" + stamp + "]" : "<" + stamp + ">"
111 } 112 }
112} 113}
Tests/OrgCoreTests/TimestampCommandTests.swift +11
@@ -28,6 +28,17 @@ struct TimestampCommandTests {
28 #expect(run(ShiftTimestamp(up: true), "<2026-09-10 Thu 10:07>\n", caret: 20).text == "<2026-09-10 Thu 10:10>\n") 28 #expect(run(ShiftTimestamp(up: true), "<2026-09-10 Thu 10:07>\n", caret: 20).text == "<2026-09-10 Thu 10:10>\n")
29 } 29 }
30 30
31 @Test func promptSaysWhetherTheStampIsInactive() {
32 for inactive in [false, true] {
33 let context = EditContext(revision: 0, text: "x\n", tree: OrgParser.parse("x\n"), selection: [1..<1], now: Self.now, calendar: Self.calendar)
34 guard case .prompt(let prompt) = InsertTimestamp(inactive: inactive).run(in: context) else {
35 Issue.record("no prompt")
36 continue
37 }
38 #expect(prompt.date?.inactive == inactive)
39 }
40 }
41
31 static let texts = [ 42 static let texts = [
32 "* a\n", 43 "* a\n",
33 "* a\nbody <2026-09-01 Tue> text\n", 44 "* a\nbody <2026-09-01 Tue> text\n",