diff --git a/README.md b/README.md index 67a0729..be7b827 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ - [x] Set Task due date with quick input buttons (today, +1 day, -1 day) - [x] Update Task Title - [x] Tasklist items should indicate status (done, pending, overdue) using colors +- [x] Export Tasks (Copy title, dueDate and description to clipboard as Markdown) - [ ] Pin Tasks - [x] Shortcut for Adding new Project and Task - [x] Global shortcuts for jumping to Projects or Tasks panel anytime @@ -101,6 +102,7 @@ In case writing in a text input (e,g, new project/task, due date), you have to ` | Task Detail | `e` | Activate note editor for modification | | Task Detail | `v` | Edit task details in external editor (default `vim`) | | Task Detail | `r` | Rename Task Title | +| Task Detail | `x` | Export Task to clipboard | | Active Note Editor | `Esc` | Deactivate note editor and save content | **Tips about using shortcuts efficiently:** diff --git a/app/task_detail.go b/app/task_detail.go index e025dad..2387f9e 100644 --- a/app/task_detail.go +++ b/app/task_detail.go @@ -1,12 +1,14 @@ package main import ( + "bytes" "fmt" "io/ioutil" "os" "os/exec" "time" + "github.com/atotto/clipboard" "github.com/gdamore/tcell/v2" "github.com/pgavlin/femto" "github.com/pgavlin/femto/runtime" @@ -49,7 +51,7 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane { toggleHint := tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText(" to toggle") pane.taskStatusToggle.SetSelectedFunc(pane.toggleTaskStatus) - pane.editorHint = tview.NewTextView().SetText(" e to edit, ↓↑ to scroll").SetTextColor(tcell.ColorDimGray) + pane.editorHint = tview.NewTextView().SetText(" e = edit, v = external, ↓↑ = scroll").SetTextColor(tcell.ColorDimGray) // Prepare static (no external interaction) elements editorLabel := tview.NewFlex(). @@ -58,7 +60,7 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane { editorHelp := tview.NewFlex(). AddItem(pane.editorHint, 0, 1, false). AddItem(tview.NewTextView().SetTextAlign(tview.AlignRight). - SetText("syntax:markdown theme:monakai"). + SetText("syntax:markdown (monakai)"). SetTextColor(tcell.ColorDimGray), 0, 1, false) pane. @@ -78,11 +80,25 @@ func NewTaskDetailPane(taskRepo repository.TaskRepository) *TaskDetailPane { return &pane } +func (td *TaskDetailPane) Export() { + var content bytes.Buffer + + content.WriteString("# " + td.task.Title + " \n") + if td.taskDate.GetText() != "" { + content.WriteString("\n> Due Date: " + td.taskDate.GetText() + " \n") + } + content.WriteString("\n" + td.task.Details + " \n") + + clipboard.WriteAll(content.String()) + app.SetFocus(td) + statusBar.showForSeconds("Task copyed. Try Pasting anywhere.", 5) +} + func (td *TaskDetailPane) makeDateRow() *tview.Flex { td.taskDate = makeLightTextInput("yyyy-mm-dd"). SetLabel("Set:"). - SetLabelColor(tcell.ColorGray). + SetLabelColor(tcell.ColorWhiteSmoke). SetFieldWidth(12). SetDoneFunc(func(key tcell.Key) { switch key { @@ -220,7 +236,7 @@ func (td *TaskDetailPane) activateEditor() { func (td *TaskDetailPane) deactivateEditor() { td.taskDetailView.Readonly = true td.taskDetailView.SetBorderColor(tcell.ColorLightSlateGray) - td.editorHint.SetText(" e to edit, ↓↑ to scroll") + td.editorHint.SetText(" e = edit, v = external, ↓↑ = scroll") app.SetFocus(td) } @@ -259,7 +275,6 @@ func (td *TaskDetailPane) editInExternalEditor() { td.SetTask(td.task) } - // @TODO: Mouse events not being captured after returning from Suspend - fix it app.EnableMouse(true) _ = os.Remove(tmpFileName) @@ -310,6 +325,9 @@ func (td *TaskDetailPane) handleShortcuts(event *tcell.EventKey) *tcell.EventKey case ' ': td.toggleTaskStatus() return nil + case 'x': + td.Export() + return nil } } diff --git a/app/task_title.go b/app/task_title.go index ab4f351..99fa729 100644 --- a/app/task_title.go +++ b/app/task_title.go @@ -37,7 +37,9 @@ func NewTaskDetailHeader(taskRepo repository.TaskRepository) *TaskDetailHeader { buttons := tview.NewFlex(). AddItem(tview.NewTextView().SetTextColor(tcell.ColorDimGray).SetText("r = Rename"), 0, 1, false). AddItem(blankCell, 0, 1, false). - AddItem(makeButton("rename", func() { header.ShowRename() }), 8, 0, false) + AddItem(makeButton("[::ub]r[::-]ename", func() { header.ShowRename() }), 8, 0, false). + AddItem(blankCell, 1, 0, false). + AddItem(makeButton("e[::ub]x[::-]port", func() { taskDetailPane.Export() }), 8, 0, false) header. AddItem(header.pages, 1, 1, true). diff --git a/go.mod b/go.mod index 30a682b..32638f8 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/DataDog/zstd v1.4.5 // indirect github.com/Sereal/Sereal v0.0.0-20200820125258-a016b7cda3f3 // indirect github.com/asdine/storm/v3 v3.2.1 + github.com/atotto/clipboard v0.1.4 // indirect github.com/gdamore/tcell/v2 v2.1.0 github.com/golang/protobuf v1.4.3 // indirect github.com/golang/snappy v0.0.2 // indirect diff --git a/go.sum b/go.sum index d714dd2..44543bf 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/asdine/storm/v3 v3.2.1 h1:I5AqhkPK6nBZ/qJXySdI7ot5BlXSZ7qvDY1zAn5ZJac github.com/asdine/storm/v3 v3.2.1/go.mod h1:LEpXwGt4pIqrE/XcTvCnZHT5MgZCV6Ub9q7yQzOFWr0= github.com/atotto/clipboard v0.1.2 h1:YZCtFu5Ie8qX2VmVTBnrqLSiU9XOWwqNRmdT3gIQzbY= github.com/atotto/clipboard v0.1.2/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=