;ELC ;;; Compiled ;;; in Emacs version 28.0.50 ;;; with all optimizations. (byte-code "\300\301!\210\300\302!\210\300\303!\210\300\304!\210\300\305!\210\300\306!\207" [require dash transient org json url url-http] 2) (defvar todoist-token (getenv "TODOIST_TOKEN")) (defconst todoist-url "https://api.todoist.com/rest/v1") (defconst todoist-buffer-name "*todoist*") (byte-code "\300\301\302\303\304\305\304\306\307\310& \210\311\312\313\314\315DD\316\304\301\317\320&\210\311\321\313\314\322DD\323\304\301\317\324&\210\311\325\313\314\326DD\327\304\301\317\330&\207" [custom-declare-group todoist nil "Interface for todoist.com, a task tracking tool." :group extensions tools :link (url-link :tag "Repository" "https://github.com/abrochard/emacs-todoist") custom-declare-variable todoist-timeout funcall function #[0 "\300\207" [nil] 1] "Timeout in second to reach todoist API." :type number todoist-backing-buffer #[0 "\300\207" [nil] 1] "File location of the todoist backing buffer." string todoist-show-all #[0 "\300\207" [nil] 1] "If not nil, show all tasks un-collapsed." bool] 10) (defvar todoist--cached-projects nil) #@172 Main function to interact with Todoist api. METHOD is http method string. ENDPOINT is the endpoint string. DATA is the request body. (fn METHOD ENDPOINT &optional DATA) (defalias 'todoist--query #[770 "P\306\307\310 PBC\205\311\"\205\312\313!\314\"\315r\316\315\211 $q\210\317 \320\315\321\322#)\266\203\204F\323\324\325\326\"\"\210\210b\210`d{\327\230?\205\\\330\331`d\314\321$!\262\332p!\210,\207" [todoist-url todoist-token url-request-data url-request-extra-headers url-request-method todoist-timeout append "Authorization" "Bearer " (("Content-Type" . "application/json")) encode-coding-string json-encode utf-8 nil url-retrieve-synchronously todoist--parse-status-code "2.." t string-match throw bad-response format "Bad status code returned: %s" "\n" json-read-from-string decode-coding-region kill-buffer inhibit-changing-match-data url-http-end-of-headers] 16 (#$ . 1140)]) #@41 Parse the todoist response status code. (defalias 'todoist--parse-status-code #[0 "\212eb\210\300\301!\210\302\303!)\207" [re-search-forward "HTTP/1.1 \\([0-9]\\{3\\}\\)" match-string-no-properties 1] 2 (#$ . 2060)]) #@55 Get the task id. TASK is the task object. (fn TASK) (defalias 'todoist--task-id #[257 "\300\301\"\207" [assoc-default id] 4 (#$ . 2283)]) #@60 Get the task due date. TASK is the task object (fn TASK) (defalias 'todoist--task-date #[257 "\300\301\300\302\"\"\207" [assoc-default date due] 6 (#$ . 2430)]) #@60 Get the task content. TASK is the task object. (fn TASK) (defalias 'todoist--task-content #[257 "\300\301\"\207" [assoc-default content] 4 (#$ . 2600)]) #@62 Get the task project id. TASK is the task object (fn TASK) (defalias 'todoist--task-project-id #[257 "\300\301\"\207" [assoc-default project_id] 4 (#$ . 2762)]) #@67 Get the project id. PROJECT is the project object. (fn PROJECT) (defalias 'todoist--project-id #[257 "\300\301\"\207" [assoc-default id] 4 (#$ . 2932)]) #@69 Get the project name. PROJECT is the project object. (fn PROJECT) (defalias 'todoist--project-name #[257 "\300\301\"\207" [assoc-default name] 4 (#$ . 3094)]) #@105 Get subset of tasks under a project. PROJECT the project. TASKS the list of tasks. (fn PROJECT TASKS) (defalias 'todoist--filter-tasks #[514 "\300\301\302\"\"\207" [-filter make-closure #[257 "\301!\302\300!\232\207" [V0 todoist--task-project-id todoist--project-id] 4 "\n\n(fn TASK)"]] 6 (#$ . 3263)]) #@166 Insert a org heading at a certain depth. LEVEL is the level. STR is the heading title. TODO is optional to make this a todo heading. (fn LEVEL STR &optional TODO) (defalias 'todoist--insert-heading #[770 "db\210\211\203\300\301\302\303\"#c\207\300\304\302\303\"#c\207" [format "\n%s TODO %s" make-string 42 "\n%s %s"] 8 (#$ . 3578)]) #@146 Insert the task as 'org-mode' bullet. TASK is the task. LEVEL is the ord heading level. TODO is boolean to show TODO tag. (fn TASK LEVEL TODO) (defalias 'todoist--insert-task #[771 "\300\301!#\210\302!\203\303\304\302!\"\210\305\306\307\310\311!\"\"\210\305\312\307\310\313!\"\"\207" [todoist--insert-heading todoist--task-content todoist--task-date org-deadline nil org-set-property "TODOIST_ID" format "%s" todoist--task-id "TODOIST_PROJECT_ID" todoist--task-project-id] 9 (#$ . 3927)]) #@145 Insert the current project and matching tasks as org buttet list. PROJECT the project object. TASKS the list of all tasks. (fn PROJECT TASKS) (defalias 'todoist--insert-project #[514 "\300\301\302!\"\210\303\304\305\"\"\207" [todoist--insert-heading 2 todoist--project-name mapcar #[257 "\300\301\302#\207" [todoist--insert-task 3 nil] 5 "\n\n(fn TASK)"] todoist--filter-tasks] 7 (#$ . 4436)]) #@85 Get the project id of the inbox. PROJECTS the list of all projects. (fn PROJECTS) (defalias 'todoist--inbox-id #[257 "\300\301\302\"!\207" [todoist--project-id -first #[257 "\300!\301\232\207" [todoist--project-name "Inbox"] 3 "\n\n(fn PROJECT)"]] 5 (#$ . 4842)]) #@94 Return non-nil if the tasks is scheduled for today or overdue. TASK is the task. (fn TASK) (defalias 'todoist--is-today #[257 "\300!\205\301\302\300!\303P!\304 \"\207" [todoist--task-date time-less-p date-to-time " 00:00:00" current-time] 5 (#$ . 5116)]) #@64 Insert today's tasks. TASKS is the list of tasks. (fn TASKS) (defalias 'todoist--insert-today #[257 "\300\301\302\303\"\"\207" [mapcar #[257 "\300\301\302#\207" [todoist--insert-task 2 t] 5 "\n\n(fn TASK)"] -filter todoist--is-today] 6 (#$ . 5383)]) #@107 Get the list of all projects. CACHE to read from cache rather than query upstream. (fn &optional CACHE) (defalias 'todoist--get-projects #[256 "\211\203\207\301\302\303\304\"\305\"\211\207" [todoist--cached-projects append todoist--query "GET" "/projects" nil] 5 (#$ . 5644)]) #@28 Get the list of all tasks. (defalias 'todoist--get-tasks #[0 "\300\301\302\303\"\304\"\207" [append todoist--query "GET" "/tasks" nil] 4 (#$ . 5933)]) #@24 Fold the project list. (defalias 'todoist--fold-projects #[0 "\212eb\210\300\301!\210\302 )\207" [re-search-forward "^\\* Projects$" org-cycle] 2 (#$ . 6090)]) #@41 Fold the today list to hide properties. (defalias 'todoist--fold-today #[0 "\212eb\210\300\301!\210\302 \210\302 )\207" [re-search-forward "^\\* Today$" org-cycle] 2 (#$ . 6256)]) #@22 Only fold top level. (defalias 'todoist--show-all #[0 "\300\301!\207" [org-global-cycle 3] 2 (#$ . 6442)]) #@55 Get the todoist task id of the task under the cursor. (defalias 'todoist--under-cursor-task-id #[0 "\212\300 \210\301\302\303 \")\207" [org-back-to-heading org-element-property :TODOIST_ID org-element-at-point] 3 (#$ . 6555)]) #@96 Parse an org timestring into a simple YYYY-MM-DD string. STR is an org time string. (fn STR) (defalias 'todoist--parse-org-time-string #[257 "\211\300=?\205\301\302\"\210\303\304\"\207" [nil string-match "<\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}+\\) .*>" match-string 1] 4 (#$ . 6788)]) #@132 Take user input to select a project object from a list. CACHE is optional param to get projects from cache. (fn &optional CACHE) (defalias 'todoist--select-project #[256 "\300!\301\302\303\304\"\"\305\306\307\"\"\207" [todoist--get-projects completing-read "Select project: " mapcar todoist--project-name -find make-closure #[257 "\301!\300\232\207" [V0 todoist--project-name] 3 "\n\n(fn X)"]] 7 (#$ . 7090)]) #@68 Create a new project. NAME is the name of the project. (fn NAME) (defalias 'todoist-new-project #[257 "\300\301\302\303BC#\207" [todoist--query "POST" "/projects" "name"] 6 (#$ . 7513) "sProject name: "]) #@31 Change the name of a project. (defalias 'todoist-update-project #[0 "\300\301\302\303\304\305 !\"\306\307\310!BC#\207" [todoist--query "POST" format "/projects/%s" todoist--project-id todoist--select-project "name" read-string "New project name: "] 6 (#$ . 7727) nil]) #@19 Delete a project. (defalias 'todoist-delete-project #[0 "\300\301\302\303\304\305 !\"\"\207" [todoist--query "DELETE" format "/projects/%s" todoist--project-id todoist--select-project] 6 (#$ . 8002) nil]) #@171 Create a new task. CONTENT is the content string. DUE is the human friendly due string and can be empty. P is a prefix argument to select a project. (fn CONTENT DUE P) (defalias 'todoist-new-task #[771 "\300\301\302\303\304B\305BD\205\306\307\310 !BC\"#\210\311 \207" [todoist--query "POST" "/tasks" append "content" "due_string" "project_id" todoist--project-id todoist--select-project todoist] 11 (#$ . 8214) "sTask content: \nsDue: \nP"]) #@59 Update the content and due date of the task under cursor. (defalias 'todoist-update-task #[0 "\300 \301\302\303\304\305\"\"\301\306\307\303\304\310\"!\"\311\312\313\314\"\315B\316BD#\210\317 \207" [todoist--under-cursor-task-id read-string "Task content: " org-entry-get nil "ITEM" "Task due: " todoist--parse-org-time-string "DEADLINE" todoist--query "POST" format "/tasks/%s" "content" "due_string" todoist] 9 (#$ . 8671) nil]) #@35 Delete the task under the cusror. (defalias 'todoist-delete-task #[0 "\300\301\302\303\304 \"\"\210\305 \207" [todoist--query "DELETE" format "/tasks/%s" todoist--under-cursor-task-id todoist] 5 (#$ . 9111) nil]) #@69 Close the task under the cursor, marking it as done or checking it. (defalias 'todoist-close-task #[0 "\300\301\302\303\304 \"\"\210\305 \207" [todoist--query "POST" format "/tasks/%s/close" todoist--under-cursor-task-id todoist] 5 (#$ . 9330) nil]) #@60 Write todoist buffer to file if backing-buffer is defined. (defalias 'todoist--write-to-file-if-needed #[0 "\205\301!\211\203\302!\210\210\303!\207" [todoist-backing-buffer get-file-buffer kill-buffer write-file] 3 (#$ . 9586)]) (defalias 'todoist-task-menu #[0 "\300\301!\207" [transient-setup todoist-task-menu] 2 nil nil]) (byte-code "\300\301\302\303#\210\300\301\304\305#\210\300\301\306\307\310\301\"#\210\300\301\311\312#\207" [put todoist-task-menu interactive-only t function-documentation "Manage Todoist tasks." transient--prefix transient-prefix :command transient--layout ([1 transient-column (:description "Actions") ((1 transient-suffix (:key "c" :description "Close task" :command todoist-close-task)) (1 transient-suffix (:key "n" :description "New task" :command todoist-new-task)) (1 transient-suffix (:key "u" :description "Update task" :command todoist-update-task)) (1 transient-suffix (:key "d" :description "Delete task" :command todoist-delete-task)))])] 6) (defalias 'todoist-project-menu #[0 "\300\301!\207" [transient-setup todoist-project-menu] 2 nil nil]) (byte-code "\300\301\302\303#\210\300\301\304\305#\210\300\301\306\307\310\301\"#\210\300\301\311\312#\207" [put todoist-project-menu interactive-only t function-documentation "Manage Todoist projects." transient--prefix transient-prefix :command transient--layout ([1 transient-column (:description "Actions") ((1 transient-suffix (:key "n" :description "New project" :command todoist-new-project)) (1 transient-suffix (:key "u" :description "Update project" :command todoist-update-project)) (1 transient-suffix (:key "d" :description "Delete project" :command todoist-delete-project)))])] 6) #@28 Keymap for `todoist-mode'. (defvar todoist-mode-map (byte-code "\300 \301\302\303#\210\301\304\305#\210\207" [make-sparse-keymap define-key "t" todoist-task-menu "p" todoist-project-menu] 5) (#$ . 11281)) (defvar todoist-mode-hook nil) (byte-code "\300\301N\204\f\302\300\301\303#\210\304\305!\204\302\305\306\307#\210\300\207" [todoist-mode-hook variable-documentation put "Hook run after entering Todoist mode.\nNo problems result if this variable is not bound.\n`add-hook' automatically binds it. (This is true for all hook variables.)" boundp todoist-mode-map definition-name todoist-mode] 4) (defvar todoist-mode-map (make-sparse-keymap)) (byte-code "\301\302N\204\303\301\302\304\305!#\210\306\307!\204\303\307\310\311#\210\312\313 !\210\307\302N\204-\303\307\302\304\314!#\210\306\300!\204B\303\300\310\311#\210\315\316\300\317\"\210!\210\300\302N\204P\303\300\302\304\320!#\210\303\311\321\322#\207" [todoist-mode-abbrev-table todoist-mode-map variable-documentation put purecopy "Keymap for `todoist-mode'." boundp todoist-mode-syntax-table definition-name todoist-mode (lambda (def-tmp-var) (defvar todoist-mode-syntax-table def-tmp-var)) make-syntax-table "Syntax table for `todoist-mode'." (lambda (def-tmp-var) (defvar todoist-mode-abbrev-table def-tmp-var)) define-abbrev-table nil "Abbrev table for `todoist-mode'." derived-mode-parent org-mode] 5) #@226 Special mode for todoist buffers. In addition to any hooks its parent mode `org-mode' might have run, this mode runs the hook `todoist-mode-hook', as the final or penultimate step during initialization. \{todoist-mode-map} (defalias 'todoist-mode #[0 "\306\300!\210\307\310 \210\311\312\310\313N\203\314\311\313\310\313N#\210\315 !\204'\316 \317 \"\210\320\f!\211\2035\211\321 =\203;\322\f\323 \"\210\210\324 \325\"\204R =\204R\326 \325C#\210\327 !\210\330\f!\210 )\331\332!\207" [delay-mode-hooks major-mode mode-name todoist-mode-map todoist-mode-syntax-table todoist-mode-abbrev-table make-local-variable t org-mode todoist-mode "Todoist" mode-class put keymap-parent set-keymap-parent current-local-map char-table-parent standard-syntax-table set-char-table-parent syntax-table abbrev-table-get :parents abbrev-table-put use-local-map set-syntax-table run-mode-hooks todoist-mode-hook local-abbrev-table] 5 (#$ . 12668) nil]) #@62 Main function to summon the todoist dashboard as 'org-mode'. (defalias 'todoist #[0 "\302 \303 \304\305\306\"r\211q\210\307\310\"\216\210\311!\210ed|\210\312 \210\313c\210\314\315\316\"\210\317!\210\314\315\320\"\210\211\203B\211@\321\"\210A\266\202\2020\210 \203M\322 \210\202S\323 \210\324 \210\325 *\207" [todoist-buffer-name todoist-show-all todoist--get-projects todoist--get-tasks generate-new-buffer " *temp*" t make-closure #[0 "\301\300!\205 \302\300!\207" [V0 buffer-name kill-buffer] 2] pop-to-buffer todoist-mode "#+title: Todoist\n" todoist--insert-heading 1 "Today" todoist--insert-today "Projects" todoist--insert-project todoist--show-all todoist--fold-projects todoist--fold-today todoist--write-to-file-if-needed] 8 (#$ . 13622) nil]) (provide 'todoist)