lune

created pr with 124.1 on 2026-04-22T02:46:44Z · by 613b58b7
changed status to closed on 2026-06-21T16:45:31Z · by 66ddd677
Closing as superceded by 126
cmds
checkout latest patchset:
ssh pr.pico.sh print 124 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print 124.[rev] | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 124
set PR to open (enables RSS notifications):
ssh pr.pico.sh pr open 124
set PR to draft (stops RSS notifications):
ssh pr.pico.sh pr draft 124

Patchset 124.1 on 2026-04-22T02:46:44Z · commit 7eef5ba

listing real name of tasks
juan 2026-04-21T03:21:16Z
construction of db for management of decrypted names of tasks
juan 2026-04-21T05:43:09Z
fix UTF8 chracteres
juan 2026-04-21T21:13:24Z
filter by status and coloring types of status
juan 2026-04-21T21:18:53Z
update help
juan 2026-04-21T21:21:36Z
list areas names
juan 2026-04-21T21:44:53Z
adjust table tasks to truncate name and list area
juan 2026-04-21T21:56:40Z
partial implementation of listing tasks by areas
juan 2026-04-21T22:05:20Z
final implementation of listing tasks by areas with UTF-8 chracteres
juan 2026-04-21T22:10:20Z
sort on task list to show first do now
juan 2026-04-21T22:33:29Z
update with 8 char of id and db.go
juan 2026-04-21T23:27:54Z
partial implementation of TUI menu on task update
juan 2026-04-21T23:35:35Z
task name correcion on TUI menu of Update task
juan 2026-04-21T23:38:19Z
TUI menu for update task with others flags
juan 2026-04-21T23:43:02Z
helper for TUI update task
juan 2026-04-21T23:49:56Z
search by first 8 char of note id for editing it
juan 2026-04-22T00:00:17Z
partial implementation on note TUI menu for update
juan 2026-04-22T00:05:46Z
TUI menu notebook just with tags
juan 2026-04-22T00:20:55Z
Note update now let you insert only the first 8 char of notebook id in update
juan 2026-04-22T00:25:53Z
implementation of (lune note notebook-list) for listing all notebooks and its ID
juan 2026-04-22T01:10:51Z
partial implementation of lune note show-content ID
juan 2026-04-22T02:01:11Z
convert \n in new line and \ in space for lune note show-content ID
juan 2026-04-22T02:18:42Z
+62 -19 cmd/task/list.go #
......@@ -47,6 +47,7 @@ are not available through the API. Only metadata is shown.`,
4747 func init() {
4848 ListCmd.Flags().StringP("area", "a", "", "Filter by area key")
4949 ListCmd.Flags().StringP("status", "s", "", "Filter by status")
50+ ListCmd.Flags().StringP("scheduled", "d", "", "Filter by scheduled date (today, tomorrow, or YYYY-MM-DD)")
5051 ListCmd.Flags().Bool("all", false, "Show all tasks including completed")
5152 ListCmd.Flags().Bool("json", false, "Output as JSON")
5253
......@@ -87,8 +88,13 @@ func runList(cmd *cobra.Command, _ []string) error {
8788 return err
8889 }
8990
91+ scheduledFilter, err := resolveScheduledFilter(cmd)
92+ if err != nil {
93+ return err
94+ }
95+
9096 showAll := mustGetBoolFlag(cmd, "all")
91- filtered := applyFiltersEnriched(enriched, areaID, statusFilter, showAll)
97+ filtered := applyFiltersEnriched(enriched, areaID, statusFilter, scheduledFilter, showAll)
9298
9399 if len(filtered) == 0 {
94100 fmt.Fprintln(cmd.OutOrStdout(), "No tasks found")
......@@ -103,8 +109,6 @@ func runList(cmd *cobra.Command, _ []string) error {
103109 return outputTableEnriched(cmd, filtered)
104110 }
105111
106-// mustGetStringFlag returns the string flag value. Panics if flag doesn't exist
107-// (indicates a programming error—flags are defined in init).
108112 func mustGetStringFlag(cmd *cobra.Command, name string) string {
109113 f := cmd.Flags().Lookup(name)
110114 if f == nil {
......@@ -114,7 +118,6 @@ func mustGetStringFlag(cmd *cobra.Command, name string) string {
114118 return f.Value.String()
115119 }
116120
117-// mustGetBoolFlag returns the bool flag value. Panics if flag doesn't exist.
118121 func mustGetBoolFlag(cmd *cobra.Command, name string) bool {
119122 f := cmd.Flags().Lookup(name)
120123 if f == nil {
......@@ -129,19 +132,15 @@ func resolveAreaFilter(cmd *cobra.Command) (string, error) {
129132
130133 cfg, err := config.Load()
131134 if err != nil {
132- // Config not required if no area flag and we just skip default
133135 if errors.Is(err, config.ErrNotFound) {
134136 if areaKey != "" {
135137 return "", err
136138 }
137-
138139 return "", nil
139140 }
140-
141141 return "", err
142142 }
143143
144- // Use default area if no explicit flag
145144 if areaKey == "" {
146145 areaKey = cfg.Defaults.Area
147146 }
......@@ -172,8 +171,30 @@ func resolveStatusFilter(cmd *cobra.Command) (string, error) {
172171 return string(s), nil
173172 }
174173
175-func applyFiltersEnriched(tasks []enrichedTask, areaID, statusFilter string, showAll bool) []enrichedTask {
176- // Extract basic tasks for library filter
174+func resolveScheduledFilter(cmd *cobra.Command) (string, error) {
175+ val := mustGetStringFlag(cmd, "scheduled")
176+ if val == "" {
177+ return "", nil
178+ }
179+
180+ today := time.Now().Format("2006-01-02")
181+ tomorrow := time.Now().AddDate(0, 0, 1).Format("2006-01-02")
182+
183+ switch val {
184+ case "today":
185+ return today, nil
186+ case "tomorrow":
187+ return tomorrow, nil
188+ default:
189+ _, err := time.Parse("2006-01-02", val)
190+ if err != nil {
191+ return "", fmt.Errorf("invalid date format for --scheduled, use YYYY-MM-DD: %w", err)
192+ }
193+ return val, nil
194+ }
195+}
196+
197+func applyFiltersEnriched(tasks []enrichedTask, areaID, statusFilter, scheduledFilter string, showAll bool) []enrichedTask {
177198 baseTasks := make([]lunatask.Task, len(tasks))
178199 for i, t := range tasks {
179200 baseTasks[i] = t.Task
......@@ -193,9 +214,18 @@ func applyFiltersEnriched(tasks []enrichedTask, areaID, statusFilter string, sho
193214
194215 filteredBase := lunatask.FilterTasks(baseTasks, opts)
195216
196- // Map back to enriched
197217 res := make([]enrichedTask, 0, len(filteredBase))
198218 for _, fb := range filteredBase {
219+ if scheduledFilter != "" {
220+ taskDate := ""
221+ if fb.ScheduledOn != nil {
222+ taskDate = fb.ScheduledOn.Time.Format("2006-01-02")
223+ }
224+ if taskDate != scheduledFilter {
225+ continue
226+ }
227+ }
228+
199229 for _, et := range tasks {
200230 if et.ID == fb.ID {
201231 res = append(res, et)
......@@ -209,12 +239,7 @@ func applyFiltersEnriched(tasks []enrichedTask, areaID, statusFilter string, sho
209239 func outputJSONEnriched(cmd *cobra.Command, tasks []enrichedTask) error {
210240 enc := json.NewEncoder(cmd.OutOrStdout())
211241 enc.SetIndent("", " ")
212-
213- if err := enc.Encode(tasks); err != nil {
214- return fmt.Errorf("encoding JSON: %w", err)
215- }
216-
217- return nil
242+ return enc.Encode(tasks)
218243 }
219244
220245 func outputTableEnriched(cmd *cobra.Command, tasks []enrichedTask) error {
......@@ -247,11 +272,29 @@ func outputTableEnriched(cmd *cobra.Command, tasks []enrichedTask) error {
247272 return ui.TableHeaderStyle()
248273 }
249274
275+ if row >= 0 && row < len(tasks) {
276+ t := tasks[row]
277+ if t.Status != nil {
278+ switch *t.Status {
279+ case lunatask.StatusLater:
280+ return ui.StatusLater
281+ case lunatask.StatusNext:
282+ return ui.StatusNext
283+ case lunatask.StatusInProgress:
284+ return ui.StatusInProgress
285+ case lunatask.StatusWaiting:
286+ return ui.StatusWaiting
287+ case lunatask.StatusCompleted:
288+ return ui.StatusCompleted
289+ }
290+ }
291+ }
292+
250293 return lipgloss.NewStyle()
251294 }).
252- Border(ui.TableBorder())
295+ Border(ui.TableBorder()).
296+ BorderRow(true)
253297
254298 fmt.Fprintln(cmd.OutOrStdout(), tbl.Render())
255-
256299 return nil
257300 }
+9 -0 internal/ui/styles.go #
......@@ -61,6 +61,15 @@ var (
6161 Padding(0, 1)}
6262 )
6363
64+// Task status colors.
65+var (
66+ StatusLater = lipgloss.NewStyle().Foreground(lipgloss.Color("8")) // Gray
67+ StatusNext = lipgloss.NewStyle().Foreground(lipgloss.Color("12")) // Light Blue
68+ StatusInProgress = lipgloss.NewStyle().Foreground(lipgloss.Color("4")) // Blue
69+ StatusWaiting = lipgloss.NewStyle().Foreground(lipgloss.Color("5")) // Magenta
70+ StatusCompleted = lipgloss.NewStyle().Foreground(lipgloss.Color("2")) // Green
71+)
72+
6473 // FormatDate formats a time.Time as a date string using the user's locale.
6574 // Locale is auto-detected from LC_TIME, LC_ALL, or LANG environment variables.
6675 func FormatDate(t time.Time) string {
Back to top