diff --git a/.config/kak/autoload/notes.kak b/.config/kak/autoload/notes.kak new file mode 100644 index 00000000..42c5d2c8 --- /dev/null +++ b/.config/kak/autoload/notes.kak @@ -0,0 +1,287 @@ +provide-module notes %~ +# Global directory for notes. +declare-option str notes_root_dir "%sh{ echo $HOME/notes/kak }" + +# Active directory. +# +# Global directory (`notes_root_dir`) or a local override. +declare-option str notes_active_dir "%opt{notes_root_dir}" + +declare-option str notes_sym_todo 'TODO' +declare-option str notes_sym_wip 'WIP' +declare-option str notes_sym_done 'DONE' +declare-option str notes_sym_wontdo 'WONTDO' +declare-option str notes_sym_idea 'IDEA' +declare-option str notes_sym_question 'QUESTION' +declare-option str notes_sym_hold 'HOLD' +declare-option str notes_sym_review 'REVIEW' +declare-option str notes_find 'fd -t file .md' +declare-option -hidden str notes_tasks_list_current_line +declare-option -hidden str notes_journal_now + +# Main notes mode. +declare-user-mode notes + +# Mode to edit tasks. +declare-user-mode notes-tasks + +# Mode to list tasks. +declare-user-mode notes-tasks-list + +# Mode to navigate journal. +declare-user-mode notes-journal-nav + +# Mode to navigate journal (last journals). +declare-user-mode notes-journal-nav-last + +set-face global notes_todo green +set-face global notes_wip blue +set-face global notes_done black +set-face global notes_wontdo black +set-face global notes_idea green +set-face global notes_question cyan +set-face global notes_hold red +set-face global notes_review yellow + +set-face global notes_issue cyan+u +set-face global notes_subtask_uncheck green +set-face global notes_subtask_check black +set-face global notes_tag blue+i + +# Open the daily journal. +define-command notes-journal-open -docstring 'open daily journal' %{ + nop %sh{ + mkdir -p "$kak_opt_notes_active_dir/journal/$(date +%Y/%b)" + } + + evaluate-commands %{ + edit "%opt{notes_active_dir}/journal/%sh{ date '+%Y/%b/%a %d' }.md" + set-option buffer notes_journal_now %sh{ date } + } +} + +# Open a journal relative to today. +define-command -hidden notes-journal-open-rel -params -1 %{ + nop %sh{ + mkdir -p "$kak_opt_notes_active_dir/journal/$(date -d ""$kak_opt_notes_journal_now $1"" +%Y/%b)" + } + + evaluate-commands %{ + edit -existing "%opt{notes_active_dir}/journal/%sh{ date -d ""$kak_opt_notes_journal_now $1"" ""+%Y/%b/%a %d"" }.md" + set-option buffer notes_journal_now %sh{ date -d """$kak_opt_notes_journal_now $1""" } + } +} + +# Open a note by prompting the user with a menu. +define-command notes-open -docstring 'open note' %{ + prompt -menu -shell-script-candidates "$kak_opt_notes_find $kak_opt_notes_active_dir/notes" 'open note:' %{ + edit %sh{ + echo "${kak_text%.md}.md" + } + } +} + +# Create a new note by prompting the user for its text. +define-command notes-new-note -docstring 'new note' %{ + prompt note: %{ + edit %sh{ + echo "$kak_opt_notes_active_dir/notes/${kak_text%.md}.md" + } + } +} + +# Archive a note by prompting the user for which note to operate on. +define-command notes-archive-note -docstring 'archive note' %{ + prompt -menu -shell-script-candidates "$kak_opt_notes_find $kak_opt_notes_active_dir/notes" archive: %{ + nop %sh{ + mkdir -p "$kak_opt_notes_active_dir/archives" + mv "$kak_text" "$kak_opt_notes_active_dir/archives/" + } + } +} + +# Prompt the user to pick and open an archived note. +define-command notes-archive-open -docstring 'open archive' %{ + prompt -menu -shell-script-candidates "$kak_opt_notes_find $kak_opt_notes_active_dir/archives" 'open archive:' %{ + edit %sh{ + echo "${kak_text%.md}.md" + } + } +} + +# Capture a new note. +define-command notes-capture -docstring 'capture' %{ + prompt capture: %{ + nop %sh{ + echo -e "> $(date '+%a %b %d %Y, %H:%M:%S')\n$kak_text\n" >> "$kak_opt_notes_active_dir/capture.md" + } + } +} + +# Open the capture file. +define-command notes-open-capture -docstring 'open capture' %{ + edit "%opt{notes_active_dir}/capture.md" +} + +# Switch the status of a note to the input parameter. +define-command notes-task-switch-status -params 1 -docstring 'switch task' %{ + execute-keys -draft "gife_c%arg{1}" +} + +# Open a GitHub issue. This requires a specific formatting of the file. +define-command notes-task-gh-open-issue -docstring 'open GitHub issue' %{ + evaluate-commands -save-regs 'il' %{ + try %{ + execute-keys -draft 'w"iy' + execute-keys -draft '%sgithub_project: ;_"ly' + nop %sh{ + open "https://github.com/$kak_reg_l/issues/$kak_reg_i" + } + } + } +} + +define-command -hidden notes-tasks-list-by-regex -params 1 -docstring 'list tasks by status' %{ + edit -scratch *notes-tasks-list* + unset-option buffer notes_tasks_list_current_line + execute-keys "%%d|rg -n --column -e '%arg{1}' '%opt{notes_active_dir}/notes' '%opt{notes_active_dir}/journal' '%opt{notes_active_dir}/capture.md'|sortgg" +} + +# List all tasks. +define-command notes-tasks-list-all -docstring 'list all tasks' %{ + notes-tasks-list-by-regex "%opt{notes_sym_todo}\|%opt{notes_sym_wip}\|%opt{notes_sym_done}\|%opt{notes_sym_wontdo}\|%opt{notes_sym_idea}\|%opt{notes_sym_question}\|opt{notes_sym_hold}" +} + +# Command executed when pressing in a *notes-tasks-list* buffer. +define-command -hidden notes-tasks-list-open %{ + set-option buffer notes_tasks_list_current_line %val{cursor_line} + execute-keys -with-hooks -save-regs 'flc' 'giT:"fyllT:"lyllT:"cy:edit "%reg{f}" %reg{l} %reg{c}' +} + +# Run a grepper with the provided arguments as search query. +define-command -hidden notes-grepcmd -params 2 %{ + # Initial implementation based on rg . + execute-keys ":grep %arg{2} %arg{1}" +} + +# Prompt the user for terms to search in notes, journals, archives and the +# capture file. +define-command notes-search -docstring 'search notes' %{ + prompt 'search notes:' %{ + notes-grepcmd "%opt{notes_active_dir}" "%val{text}" + } +} + +# Synchronize notes remotely. +define-command notes-sync -docstring 'synchronize notes' %{ + # First, we always check-in new modifications; then, we check whether we have anything else to send + info -title 'notes' 'starting synchronizing…' + + nop %sh{ + cd $kak_opt_notes_active_dir + git fetch --prune origin + git rebase --autostash origin/master + git add -A . + git commit -m "$(date +'Sync update %a %b %d %Y')" + git push origin + } + + info -title 'notes' 'finished synchronizing' +} + +# Toggle overriding the active directory with pwd and vice versa. +define-command notes-override-active-dir -docstring 'override the active directory with PWD' %{ + set-option global notes_active_dir %sh{ + dir=$(pwd) + if [ "$kak_opt_notes_active_dir" == "$dir" ]; then + echo "$kak_opt_notes_root_dir" + else + echo "$dir" + fi + } + + info -title notes "active dir: %opt{notes_active_dir}" +} + +add-highlighter shared/notes-tasks group +add-highlighter shared/notes-tasks/todo regex "(%opt{notes_sym_todo})" 1:notes_todo +add-highlighter shared/notes-tasks/wip regex "(%opt{notes_sym_wip})" 1:notes_wip +add-highlighter shared/notes-tasks/done regex "(%opt{notes_sym_done})" 1:notes_done +add-highlighter shared/notes-tasks/wontdo regex "(%opt{notes_sym_wontdo})" 1:notes_wontdo +add-highlighter shared/notes-tasks/idea regex "(%opt{notes_sym_idea})" 1:notes_idea +add-highlighter shared/notes-tasks/question regex "(%opt{notes_sym_question})" 1:notes_question +add-highlighter shared/notes-tasks/hold regex "(%opt{notes_sym_hold})" 1:notes_hold +add-highlighter shared/notes-tasks/review regex "(%opt{notes_sym_review})" 1:notes_review +add-highlighter shared/notes-tasks/issue regex " (#[0-9]+)" 1:notes_issue +add-highlighter shared/notes-tasks/subtask-uncheck regex "-\s* (\[ \])[^\n]*" 1:notes_subtask_uncheck +add-highlighter shared/notes-tasks/subtask-check regex "-\s* (\[x\])\s*([^\n]*)"\ + 1:notes_subtask_check + +add-highlighter shared/notes-tasks-list group +add-highlighter shared/notes-tasks-list/path regex "^((?:\w:)?[^:\n]+):(\d+):(\d+)?" 1:green 2:blue 3:blue +add-highlighter shared/notes-tasks-list/current-line line %{%opt{notes_tasks_list_current_line}} default+b + +map global user o ':enter-user-mode notes' -docstring 'notes' + +map global notes A ':notes-archive-note' -docstring 'archive note' +map global notes a ':notes-archive-open' -docstring 'open archived note' +map global notes C ':notes-capture' -docstring 'capture' +map global notes c ':notes-open-capture' -docstring 'open capture' +map global notes j ':notes-journal-open' -docstring 'open journal' +map global notes J ':enter-user-mode notes-journal-nav' -docstring 'navigate journals' +map global notes l ':enter-user-mode notes-tasks-list' -docstring 'tasks list' +map global notes N ':notes-new-note' -docstring 'new note' +map global notes n ':notes-open' -docstring 'open note' +map global notes / ':notes-search' -docstring 'search in notes' +map global notes S ':notes-sync' -docstring 'synchronize notes' +map global notes t ':enter-user-mode notes-tasks' -docstring 'tasks' +map global notes z ':notes-override-active-dir' -docstring 'switch notes dir with PWD' + +map global notes-journal-nav l ':enter-user-mode notes-journal-nav-last' -docstring 'last…' +map global notes-journal-nav d ':notes-journal-open-rel "-1 day"' -docstring 'day before' +map global notes-journal-nav D ':notes-journal-open-rel "+1 day"' -docstring 'day after' +map global notes-journal-nav w ':notes-journal-open-rel "-1 week"' -docstring 'week before' +map global notes-journal-nav W ':notes-journal-open-rel "+1 week"' -docstring 'week after' +map global notes-journal-nav m ':notes-journal-open-rel "-1 month"' -docstring 'month before' +map global notes-journal-nav M ':notes-journal-open-rel "+1 month"' -docstring 'month after' + +map global notes-journal-nav-last m ':notes-journal-open-rel "last monday"' -docstring 'monday' +map global notes-journal-nav-last t ':notes-journal-open-rel "last tuesday"' -docstring 'tuesday' +map global notes-journal-nav-last w ':notes-journal-open-rel "last wednesday"' -docstring 'wednesday' +map global notes-journal-nav-last h ':notes-journal-open-rel "last thursday"' -docstring 'thursday' +map global notes-journal-nav-last f ':notes-journal-open-rel "last friday"' -docstring 'friday' +map global notes-journal-nav-last T ':notes-journal-open-rel "last saturday"' -docstring 'saturday' +map global notes-journal-nav-last S ':notes-journal-open-rel "last sunday"' -docstring 'sunday' + +map global notes-tasks-list a ":notes-tasks-list-all" -docstring 'list all tasks' +map global notes-tasks-list d ":notes-tasks-list-by-regex %opt{notes_sym_done}" -docstring 'list done tasks' +map global notes-tasks-list h ":notes-tasks-list-by-regex %opt{notes_sym_hold}" -docstring 'list hold tasks' +map global notes-tasks-list i ":notes-tasks-list-by-regex %opt{notes_sym_idea}" -docstring 'list ideas' +map global notes-tasks-list l ":notes-tasks-list-by-regex '\ :[^:]+:'" -docstring 'list tasks by labels' +map global notes-tasks-list n ":notes-tasks-list-by-regex %opt{notes_sym_wontdo}" -docstring 'list wontdo tasks' +map global notes-tasks-list q ":notes-tasks-list-by-regex %opt{notes_sym_question}" -docstring 'list questions' +map global notes-tasks-list r ":notes-tasks-list-by-regex %opt{notes_sym_review}" -docstring 'list reviews' +map global notes-tasks-list t ":notes-tasks-list-by-regex %opt{notes_sym_todo}" -docstring 'list todo tasks' +map global notes-tasks-list w ":notes-tasks-list-by-regex %opt{notes_sym_wip}" -docstring 'list wip tasks' + +hook -group notes-tasks global WinCreate \*notes-tasks-list\* %{ + map buffer normal '' ':notes-tasks-list-open' + add-highlighter window/ ref notes-tasks + add-highlighter window/ ref notes-tasks-list +} + +hook -group notes-tasks global WinCreate .*\.md %{ + add-highlighter window/ ref notes-tasks + + map window notes-tasks d ":notes-task-switch-status %opt{notes_sym_done}" -docstring 'switch task to done' + map window notes-tasks h ":notes-task-switch-status %opt{notes_sym_hold}" -docstring 'switch task to hold' + map window notes-tasks i ":notes-task-switch-status %opt{notes_sym_idea}" -docstring 'switch task to idea' + map window notes-tasks n ":notes-task-switch-status %opt{notes_sym_wontdo}" -docstring 'switch task to wontdo' + map window notes-tasks q ":notes-task-switch-status %opt{notes_sym_question}" -docstring 'switch task to question' + map window notes-tasks ":notes-task-gh-open-issue" -docstring 'open GitHub issue' + map window notes-tasks r ":notes-task-switch-status %opt{notes_sym_review}" -docstring 'switch task to review' + map window notes-tasks t ":notes-task-switch-status %opt{notes_sym_todo}" -docstring 'switch task to todo' + map window notes-tasks w ":notes-task-switch-status %opt{notes_sym_wip}" -docstring 'switch task to wip' +} + +~ diff --git a/.config/kak/kakrc b/.config/kak/kakrc index f45dd876..6f08f435 100644 --- a/.config/kak/kakrc +++ b/.config/kak/kakrc @@ -8,6 +8,7 @@ require-module ficgrep require-module byline require-module spell require-module title-bar +require-module notes set-option global scrolloff 3,3 require-module ui-mode