From 63feeb9f369fc6176e85c1c2d8fcc863caad1946 Mon Sep 17 00:00:00 2001 From: Robert Günzler Date: Tue, 10 Feb 2026 12:32:48 +0100 Subject: start new MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Robert Günzler --- .config/waybar/modules/todo.go | 229 ----------------------------------------- 1 file changed, 229 deletions(-) delete mode 100755 .config/waybar/modules/todo.go (limited to '.config/waybar/modules/todo.go') diff --git a/.config/waybar/modules/todo.go b/.config/waybar/modules/todo.go deleted file mode 100755 index 2692ec9..0000000 --- a/.config/waybar/modules/todo.go +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env yaegi - -// # Documentation -// we try to read a file pointed to by WAYBAR_TODO_FILE. -// While no particular format is assumed, we recommend -// Markdown. -// We extract the todos from the top-level list items -// (listings start with a `*` character). -// -// # Usage: -// go build -o waybar-todo todo.go -package main - -import ( - "bufio" - "encoding/json" - "log" - "os" - "os/signal" - "regexp" - "runtime" - "strings" - "time" - - "github.com/fsnotify/fsnotify" - "golang.org/x/sys/unix" -) - -const ( - TODO_INACTIVE_STRING string = "" - TODO_LABEL_REGEX string = `\[\[!(.*)\]\]` -) - -var ( - active = true - todofile = os.Getenv("WAYBAR_TODO_FILE") - cookiefile = os.ExpandEnv("${XDG_RUNTIME_DIR}/waybar-todo.cookie") - labelFilter = os.Getenv("WAYBAR_TODO_FILTER") -) - -func printJson(text, tooltip string, class []string, alt string, percentage int) error { - return json.NewEncoder(os.Stdout).Encode(map[string]interface{}{ - "text": text, - "tooltip": tooltip, - "class": class, - "alt": alt, - "percentage": percentage, - }) -} - -type todoItem struct { - text string - label string -} - -func readTodofile2(path string) ([]todoItem, error) { - f, err := os.Open(path) - if err != nil { - return nil, err - } - var todos []todoItem - for lr := bufio.NewScanner(f); lr.Scan(); { - skip := 0 - switch { - case strings.HasPrefix(lr.Text(), "*"): - skip = 2 - case strings.HasPrefix(lr.Text(), "- [ ]"): - skip = 6 - case strings.HasPrefix(lr.Text(), "- [x]"): - fallthrough - default: - continue - } - ti := todoItem{text: lr.Text()[skip:]} - matches := labelre.FindAllStringSubmatch(ti.text, -1) - if matches != nil && len(matches) > 0 { - ti.label = matches[0][1] - ti.text = strings.TrimSpace( - strings.Replace(ti.text, matches[0][0], "", 1)) - } - todos = append(todos, ti) - } - return todos, nil -} - -func setCookie(active bool) error { - if !active { - _, err := os.Create(cookiefile) - return err - } - return os.Remove(cookiefile) -} - -func update() error { - if _, err := os.Stat(cookiefile); err == nil { - log.Printf("cookie set, we're inactive") - active = false - } - if !active { - return printJson(TODO_INACTIVE_STRING, "* inactive *", []string{"off"}, "off", 0) - } - todos, err := readTodofile2(todofile) - if err != nil { - return err - } - var ( - text string - tooltip []string - extraClass string - ) - for _, item := range todos { - if labelFilter != "" && strings.Contains(labelFilter, item.label) { - continue - } - if text == "" { - text = item.text - extraClass = item.label - continue - } - // render out the rest of the todos into the tooltip - tooltip = append(tooltip, item.text) - } - return printJson(text, strings.Join(tooltip, "\n"), []string{"on", extraClass}, "on", 1) -} - -var labelre *regexp.Regexp - -func init() { - labelre = regexp.MustCompile(TODO_LABEL_REGEX) -} - -func main() { - runtime.GOMAXPROCS(1) - - var ( - updateC = make(chan os.Signal, 1) - cancelC = make(chan os.Signal, 1) - ) - signal.Notify(updateC, unix.SIGUSR1, unix.SIGUSR2, unix.SIGHUP) - signal.Notify(cancelC, unix.SIGTERM, unix.SIGINT) - - var err error - // we will receive a SIGTERM if our parent dies - err = unix.Prctl(unix.PR_SET_PDEATHSIG, uintptr(unix.SIGTERM), 0, 0, 0) - if err != nil { - log.Fatalf("error: setting prctl: %v", err) - } - - if todofile == "" { - panic("missing TODO file") - // // get from nb(1) - // nb := exec.Command("sh", "-c", "nb show --no-color --path todo") - // nb_output, err := nb.Output() - // if err != nil { - // e := err.(*exec.ExitError) - // log.Fatalf("error: finding todofile via nb: %s", e.Stderr) - // } - // todofile = strings.TrimSpace(string(nb_output)) - } - - log.Printf("watching %q", todofile) - - w, err := fsnotify.NewWatcher() - if err != nil { - log.Fatalf("error: creating watcher: %v", err) - } - defer w.Close() - - if err := w.Add(todofile); err != nil { - log.Fatalf("error: adding watch: %v", err) - } - - if err := update(); err != nil { - // fail here because it's the first time we - // try to read the todofile. - log.Fatalf("error: %v", err) - } - for { - select { - case evt, ok := <-w.Events: - if !ok { - return - } - // see https://github.com/fsnotify/fsnotify/issues/94 - // https://github.com/gohugoio/hugo/pull/4720 - if evt.Op&fsnotify.Remove == fsnotify.Remove { - counter := 0 - for w.Add(todofile) != nil { - counter++ - if counter >= 1000 { - log.Panic("error: unable to add file watcher") - } - time.Sleep(100 * time.Millisecond) - } - } - goto force_update - case err, ok := <-w.Errors: - if !ok { - return - } - log.Printf("error: from watcher: %v", err) - - case sig := <-updateC: - switch sig { - case unix.SIGUSR1: // on - active = !active - if err := setCookie(active); err != nil { - log.Printf("err: %v", err) - } - goto force_update - case unix.SIGUSR2: // - if strings.Contains(labelFilter, "work") { - labelFilter = strings.Trim(strings.ReplaceAll(labelFilter, "work", ""), ",") - } else { - labelFilter = strings.Join([]string{labelFilter, "work"}, ",") - } - continue - case unix.SIGHUP: // force update - log.Println("force update") - goto force_update - } - case <-cancelC: - log.Printf("%s exiting", os.Args[0]) - os.Exit(0) - } - force_update: - _ = update() - } -} -- cgit 1.4.1