Compare commits

..

No commits in common. "main" and "refactor" have entirely different histories.

3 changed files with 62 additions and 91 deletions

17
README
View file

@ -19,24 +19,15 @@ Designed to help you overcome being overwhelmed
= Roadmap / Issues = = Roadmap / Issues =
- Implement state machine to manage state (See design docs) - Implement state machine to manage state (See design docs)
- Timer spinner - Implement timer
- Timer counts down - It should have big full screen countdown MM:SS
- Task marked as `start`ed once timer begins - Ideally the individual digits are ascii art made from the digit itself
- Ask if task completed on end of timer
- Set break timer
- Loop continues once break is completed
- TaskList Active tasks should _always_ display, and then let the cursor indexing kick in - TaskList Active tasks should _always_ display, and then let the cursor indexing kick in
- Full screen application
- Dynamic column spacing based on WindowResizeMsg - Dynamic column spacing based on WindowResizeMsg
- When going from TaskList to nvim, don't overwrite! Ask! - When going from TaskList to nvim, don't overwrite! Ask!
- Show hints about actions / shortcuts on screen (help information) - Show hints about actions / shortcuts on screen
- Refactor extra functions out of `main.go` and into `task.go` - Refactor extra functions out of `main.go` and into `task.go`
- Make sure task loading happens through `tea.Cmd` - Make sure task loading happens through `tea.Cmd`
- Set up debugging environment?
= Associated Tooling =
When developing this I also realized I need associated tooling to help manage my backlog more generally.
Similar to how I have a task selection section here, for which tasks will be active, I think I also want a backlogger and de-backlogger, for putting things into and out of my backlog easily. I was thinking that things that get backlogged in this way should also get a `recently backlogged` tag or something so that I can sort them easily, but then I thought there should also be a script which removes the recently tag after some time, and then I wondered if I'm just over engineering this for no fucking reason, I don't need cascading backlogs???
= Design Docs = = Design Docs =
- [Excalidraw drawings](https://excalidraw.com/#json=Tucrdp__TOwmtOEvNnbVv,ep_J-9-vB3BRVjnd0Y2H0w) - [Excalidraw drawings](https://excalidraw.com/#json=Tucrdp__TOwmtOEvNnbVv,ep_J-9-vB3BRVjnd0Y2H0w)

73
main.go
View file

@ -4,13 +4,14 @@ import (
"fmt" "fmt"
table "git.sealight.xyz/aynish/poms/table" table "git.sealight.xyz/aynish/poms/table"
task "git.sealight.xyz/aynish/poms/task" task "git.sealight.xyz/aynish/poms/task"
// timer "git.sealight.xyz/aynish/poms/timer" timer "git.sealight.xyz/aynish/poms/timer"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/looplab/fsm"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
"log" "log"
"os" "os"
"os/exec" "os/exec"
"strconv"
"strings"
"time" "time"
) )
@ -30,18 +31,22 @@ var (
) )
type model struct { type model struct {
FSM *fsm.FSM
state string state string
taskList table.Model taskList table.Model
} }
type LoadedTasksMsg struct { func TasksToRows(tasks []task.Task) []table.Row {
TaskList table.Model rows := make([]table.Row, len(tasks))
for i := 0; i < len(tasks); i++ {
t := tasks[i]
rows[i] = []string{strconv.Itoa(t.Id), t.Project, strings.Join(t.Tags[:], " "), t.Description} // fmt.Sprintf("%f", t.Urgency)
}
return rows
} }
func loadTasks() tea.Msg { func CreateTable() table.Model {
var t table.Model var t table.Model
rows := task.TasksToRows(tasks) rows := TasksToRows(tasks)
t = table.New( t = table.New(
table.WithColumns(columns), table.WithColumns(columns),
table.WithRows(rows), table.WithRows(rows),
@ -63,11 +68,50 @@ func loadTasks() tea.Msg {
Foreground(lipgloss.Color("0")). Foreground(lipgloss.Color("0")).
Background(lipgloss.Color("120")) Background(lipgloss.Color("120"))
t.SetStyles(s) t.SetStyles(s)
return LoadedTasksMsg{t} return t
} }
type editorFinishedMsg struct{ err error } type editorFinishedMsg struct{ err error }
func (m model) rowsToFile() []string {
var rows []string
for index, row := range m.taskList.Rows() {
if index < m.taskList.ActiveIndex() {
// get uuid
id := row[0]
uuid_byte, err := exec.Command("task", "_get", id+".uuid").Output()
if err != nil {
log.Fatal(err)
}
uuid := string(uuid_byte[:len(uuid_byte)-1])
// create task-note if it doesn't exist
note_path := "/home/anish/kitaab/vimwiki/task-notes/" + uuid + ".wiki"
if _, err := os.Stat(note_path); os.IsNotExist(err) {
f, err := os.Create(note_path)
if err != nil {
log.Fatal(err)
}
path := time.Now().Format(time.DateOnly)
tags := strings.Replace(row[2], " ", ":", -1)
tags = ":" + row[1] + ":" + tags + ":"
fmt.Fprintln(f, "%title "+row[3])
fmt.Fprintln(f, tags)
fmt.Fprintln(f, "%date "+path)
fmt.Fprintln(f, "")
f.Close()
}
// link to task-note from pom-note
rowClone := make(table.Row, len(row))
_ = copy(rowClone, row)
rowClone[3] = "[[../task-notes/" + uuid + ".wiki|" + row[3] + "]]"
rows = append(rows, strings.Join(row[1:], " - "))
}
}
return rows
}
func (m model) writeFile() string { func (m model) writeFile() string {
t := time.Now() t := time.Now()
var path, full_path string var path, full_path string
@ -82,10 +126,10 @@ func (m model) writeFile() string {
defer f.Close() defer f.Close()
fmt.Fprintln(f, "%title ") fmt.Fprintln(f, "%title ")
fmt.Fprintln(f, ":pom:priv:plan:") fmt.Fprintln(f, ":pom:priv:plan:")
fmt.Fprintln(f, "%date "+t.Format("2006-01-02 15:06")) fmt.Fprintln(f, "%date "+path)
fmt.Fprintln(f, "") fmt.Fprintln(f, "")
rows := task.RowsToFile(m.taskList.Rows(), m.taskList.ActiveIndex()) rows := m.rowsToFile()
for _, value := range rows { for _, value := range rows {
fmt.Fprintln(f, value) // print values to f, one per line fmt.Fprintln(f, value) // print values to f, one per line
} }
@ -104,9 +148,9 @@ func (m model) openEditor() tea.Cmd {
}) })
} }
func (m model) Init() tea.Cmd { // TODO
return loadTasks // This is where the data should be loaded...
} func (m model) Init() tea.Cmd { return nil }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd var cmd tea.Cmd
@ -122,8 +166,6 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
//top, right, bottom, left := baseStyle.GetMargin() //top, right, bottom, left := baseStyle.GetMargin()
m.taskList.SetWidth(msg.Width - 5) m.taskList.SetWidth(msg.Width - 5)
m.taskList.SetHeight(msg.Height - 5) m.taskList.SetHeight(msg.Height - 5)
case LoadedTasksMsg:
m.taskList = msg.TaskList
} }
m.taskList, cmd = m.taskList.Update(msg) m.taskList, cmd = m.taskList.Update(msg)
return m, cmd return m, cmd
@ -135,6 +177,7 @@ func (m model) View() string {
func main() { func main() {
var m model var m model
m.taskList = CreateTable()
if _, err := tea.NewProgram(m).Run(); err != nil { if _, err := tea.NewProgram(m).Run(); err != nil {
fmt.Println("Error running program:", err) fmt.Println("Error running program:", err)
os.Exit(1) os.Exit(1)

View file

@ -3,14 +3,8 @@ package task
import ( import (
"encoding/json" "encoding/json"
"sort" "sort"
"time"
"fmt"
"strconv"
"strings"
"log" "log"
"os"
"os/exec" "os/exec"
table "git.sealight.xyz/aynish/poms/table"
) )
// Task representation. // Task representation.
@ -44,60 +38,3 @@ func GetTasks() []Task {
}) })
return tasks return tasks
} }
func TasksToRows(tasks []Task) []table.Row {
rows := make([]table.Row, len(tasks))
for i := 0; i < len(tasks); i++ {
t := tasks[i]
rows[i] = []string{strconv.Itoa(t.Id), t.Project, strings.Join(t.Tags[:], " "), t.Description} // fmt.Sprintf("%f", t.Urgency)
}
return rows
}
func RowsToFile(taskList []table.Row, activeIndex int) []string {
var rows []string
for index, row := range taskList {
if index < activeIndex {
// get uuid
id := row[0]
uuid_byte, err := exec.Command("task", "_get", id+".uuid").Output()
if err != nil {
log.Fatal(err)
}
uuid := string(uuid_byte[:len(uuid_byte)-1])
// create task-note if it doesn't exist
note_path := "/home/anish/kitaab/vimwiki/task-notes/" + uuid + ".wiki"
if _, err := os.Stat(note_path); os.IsNotExist(err) {
CreateTaskNote(note_path, row)
}
// link to task-note from pom-note
rowClone := make(table.Row, len(row))
_ = copy(rowClone, row)
// TODO add links to indexs of EACH tag
rowClone[2] = ""
for _, tag := range strings.Split(row[2], " ") {
rowClone[2] += "[[../indexs/" + tag + ".wiki|" + tag + "]]"
}
rowClone[3] = "[[../task-notes/" + uuid + ".wiki|" + row[3] + "]]"
rows = append(rows, strings.Join(rowClone[1:], " - "))
}
}
return rows
}
func CreateTaskNote(note_path string, row table.Row) {
t := time.Now()
f, err := os.Create(note_path)
if err != nil {
log.Fatal(err)
}
tags := strings.Replace(row[2], " ", ":", -1)
tags = ":" + row[1] + ":" + tags + ":"
fmt.Fprintln(f, "%title "+row[3])
fmt.Fprintln(f, tags)
fmt.Fprintln(f, "%date "+t.Format("2006-01-02 15:06"))
fmt.Fprintln(f, "")
defer f.Close()
}