Documentation ¶
Index ¶
- Constants
- Variables
- func Create(path string) error
- func Editor(path string) error
- func Exec(command string) error
- func Exists(path string) bool
- func Input(prompt string) string
- func InputConfirm(prompt string) bool
- func InsertLine(path, newLine string) error
- func InsertLineAtIndex(path, newLine string, index int) error
- func List(dir string) []string
- func Mkdir(path string) error
- func Open(path string) error
- func Read(filePath string) (string, error)
- func ReadLines(filePath string) ([]string, error)
- func Remove(path string) error
- func RemoveAll(path string) error
- func StopWatchFormat(dur time.Duration) string
- func Write(path string, text string) error
- func WriteAppend(path string, text string) error
- type Conf
- func (c Conf) Data() []byte
- func (c Conf) Del(key string) error
- func (c Conf) DirPath() string
- func (c Conf) Edit() error
- func (c Conf) Init() error
- func (c Conf) OverWrite(newconf any) error
- func (c Conf) Path() string
- func (c Conf) Print() error
- func (c Conf) Query(q string) string
- func (c Conf) QueryPrint(q string)
- func (c Conf) Set(key string, val any) error
- type Session
- type SessionType
Constants ¶
View Source
const ( Duration = "25m" Break = "5m" LongBreak = "15m" Warn = "1m" Prefix = "🍅" PrefixBreak = "🧘" PrefixWarn = "💢" // Goals WorkGoal = 8*time.Hour + 20*time.Minute RestGoal = 1*time.Hour + 40*time.Minute )
View Source
const (
DefaultPerms = 0600
)
View Source
const SESSION_FILENAME = "session.log"
Variables ¶
View Source
var App = &cli.App{ Name: "pomo", Usage: "A pomodoro command line interface 🍅", EnableBashCompletion: true, Action: func(cCtx *cli.Context) error { var arg string if cCtx.Args().Present() { arg = cCtx.Args().First() _, err := time.ParseDuration(arg) if err != nil { return fmt.Errorf("error: the input must be like 1m, 1h, 1s, 1h30m, etc") } } var duration string if arg != "" { duration = arg } else { duration = conf.Query("duration") } if duration == "" { duration = Duration } dur, err := time.ParseDuration(duration) if err != nil { return err } now := time.Now() endtime := now.Add(dur).Format(time.RFC3339) session := Session{} if err := session.Current(); err != nil { return err } if session.isRunning() { if session.Type == WorkSession { ok := InputConfirm("[WARNING]: A session is already running, do you want to reset it?") if ok { if err := session.Remove(); err != nil { return err } } else { return nil } } else { if err := session.Stop(); err != nil { return err } } } if err := startSession(now, endtime, WorkSession); err != nil { return err } if err := conf.Set("prefix", Prefix); err != nil { return err } return nil }, Commands: []*cli.Command{ { Name: "break", Usage: "initialize a break session", Action: func(cCtx *cli.Context) error { var arg string if cCtx.Args().Present() { arg = cCtx.Args().First() _, err := time.ParseDuration(arg) if err != nil { return fmt.Errorf("error: the input must be like 1m, 1h, 1s, 1h30m, etc") } } var duration string if arg != "" { duration = arg } else { duration = conf.Query("break") } if duration == "" { duration = Break } dur, err := time.ParseDuration(duration) if err != nil { return err } now := time.Now() endtime := now.Add(dur).Format(time.RFC3339) session := Session{} if err := session.Current(); err != nil { return err } if session.isRunning() { if session.Type == BreakSession { ok := InputConfirm("[WARNING]: A session is already running, do you want to reset it?") if ok { if err := session.Remove(); err != nil { return err } } else { return nil } } else { if err := session.Stop(); err != nil { return err } } } if err := startSession(now, endtime, BreakSession); err != nil { return err } if err := conf.Set("prefix", PrefixBreak); err != nil { return err } return nil }, }, { Name: "stop", Usage: "stop the pomodoro countdown", Action: func(_ *cli.Context) error { session := Session{} if err := session.Current(); err != nil { return err } if !session.isRunning() { return fmt.Errorf("no session is running") } if err := session.Stop(); err != nil { return err } if err := conf.Del("endtime"); err != nil { return err } return nil }, }, { Name: "print", Usage: "print current to standard output", Action: func(_ *cli.Context) error { endtime := conf.Query("endtime") if endtime == "" { fmt.Print("No session...") return nil } endt, err := time.Parse(time.RFC3339, endtime) if err != nil { return err } var subt time.Duration subc := conf.Query("interval") if subc != "" { subt, err = time.ParseDuration(subc) if err != nil { return err } } prefix := conf.Query("prefix") prefixWarn := conf.Query("prefix_warn") warn := conf.Query("warn") warnt, err := time.ParseDuration(warn) if err != nil { return err } sec := time.Second left := time.Until(endt).Round(sec) var sub float64 if subc != "" { sub = math.Abs(math.Mod(left.Seconds(), subt.Seconds())) } if left < warnt && left%(sec*2) == 0 { prefix = prefixWarn } if subc != "" { fmt.Printf("%v %v(%02v)", prefix, StopWatchFormat(left), sub) } else { fmt.Printf("%v %v", prefix, StopWatchFormat(left)) } return nil }, }, { Name: "init", Action: func(_ *cli.Context) error { err := conf.Init() if err != nil { log.Fatal(err) } conf.Set("duration", Duration) conf.Set("break", Break) conf.Set("long_break", LongBreak) conf.Set("warn", Warn) conf.Set("prefix", Prefix) conf.Set("prefix_warn", PrefixWarn) return nil }, }, { Name: "config", Action: func(_ *cli.Context) error { if err := conf.Print(); err != nil { return err } return nil }, Subcommands: []*cli.Command{ { Name: "edit", Usage: "Opens the editor on the current config", Action: func(_ *cli.Context) error { return conf.Edit() }, }, }, }, { Name: "status", Usage: "Displays an summary of all the sessions that was acomplished today", Action: func(_ *cli.Context) error { sessions, err := ListSessions() if err != nil { return err } todaySessions, err := filterTodaySessions(sessions) if err != nil { return err } typeDurations, _ := summarizeSessions(todaySessions) workDuration := typeDurations[WorkSession] breakDuration := typeDurations[BreakSession] green := color.New(color.FgGreen).SprintFunc() blue := color.New(color.FgBlue).SprintFunc() yellow := color.New(color.FgYellow).SprintFunc() workGoalPercent := float64(workDuration) / float64(WorkGoal) * 100 fmt.Print("\n=== Sessions Today ===\n\n") fmt.Printf("Work -> %s\n", green(formatDurationHm(workDuration))) fmt.Printf("Break -> %s\n", blue(formatDurationHm(breakDuration))) fmt.Print("\n=== Goals ===\n\n") fmt.Printf("Work: %s => %s%%\n", yellow(formatDurationHm(WorkGoal)), yellow(fmt.Sprintf("%.2f", workGoalPercent))) fmt.Printf("Break: %s\n\n", yellow(formatDurationHm(RestGoal))) return nil }, }, { Name: "sessions", Subcommands: []*cli.Command{ { Name: "edit", Usage: "Opens the editor on the current sessions file", Action: func(_ *cli.Context) error { path, err := sessionPath() if err != nil { return err } return Editor(path) }, }, }, }, }, }
Functions ¶
func InputConfirm ¶
func InsertLine ¶
func InsertLineAtIndex ¶
func StopWatchFormat ¶
func Write ¶
Write writes content to a file. It will overwrite to the file if it already exists and create the file if it does not.
func WriteAppend ¶
WriteAppend writes content to a file. It will append to the file if it already exists and create the file if it does not.
Types ¶
type Conf ¶
type Conf struct { Id string // usually application name Dir string // usually os.UserConfigDir File string // usually config.yaml }
type Session ¶
type Session struct { StartTime string EndTime string Type SessionType Filepath string }
func ListSessions ¶
type SessionType ¶
type SessionType string
create a enum for the session type
const ( WorkSession SessionType = "work" BreakSession SessionType = "break" LongBreakSession SessionType = "longbreak" )
Click to show internal directories.
Click to hide internal directories.