diff --git a/init.org b/init.org index 35f266e..ca591b1 100644 --- a/init.org +++ b/init.org @@ -1178,778 +1178,37 @@ behind it. #+BEGIN_SRC emacs-lisp (use-package avy :ensure t - :commans '(avy-goto-char - avy-goto-char-2 - avy-goto-char-2-above - avy-goto-char-2-below - avy-goto-char-in-line - avy-goto-char-timer - avy-goto-line - avy-goto-line-above - avy-goto-line-below - avy-goto-subword-0 - avy-goto-subword-1 - avy-goto-symbol-1 - avy-goto-symbol-1-above - avy-goto-symbol-1-below - avy-goto-word-0 - avy-goto-word-1 - avy-goto-word-1-above - avy-goto-word-1-below - avy-goto-word-or-subword-1)) + :commands (avy-goto-char + avy-goto-char-2 + avy-goto-char-2-above + avy-goto-char-2-below + avy-goto-char-in-line + avy-goto-char-timer + avy-goto-line + avy-goto-line-above + avy-goto-line-below + avy-goto-subword-0 + avy-goto-subword-1 + avy-goto-symbol-1 + avy-goto-symbol-1-above + avy-goto-symbol-1-below + avy-goto-word-0 + avy-goto-word-1 + avy-goto-word-1-above + avy-goto-word-1-below + avy-goto-word-or-subword-1) + :general + (:states 'normal + " j j" #'avy-goto-char-timer + " j w" #'avy-goto-word-0)) #+END_SRC +#+RESULTS: + Avy is supported by evil and setup in the *evil-integration* package. #+RESULTS: -* Writing and Planning - -#+BEGIN_SRC emacs-lisp -(report-time-since-load "Writing and Planning") -#+END_SRC - -** Org Mode - -*** Mixed Pitch Support by Default in Org -#+BEGIN_SRC emacs-lisp - (defun pti-org-mode-config () - "Set options for better writing in org buffers." - (mixed-pitch-mode) - (visual-line-mode) - (turn-on-auto-fill) - ) - - (use-package org-bullets - :ensure t - :if (display-graphic-p) - :hook (org-mode . org-bullets-mode)) - - (use-package mixed-pitch - :ensure t - :if (display-graphic-p) - :hook - (org-mode . mixed-pitch-mode)) -#+END_SRC - -#+RESULTS: -: [nil 26279 36119 854408 nil elpaca-process-queues nil nil 376000 nil] -*** Org Configuration -#+BEGIN_SRC emacs-lisp - (use-package org - :ensure nil - :custom - (org-return-follows-link t) - (org-mouse-1-follows-link t) - (org-link-descriptive t) - (org-agenda-skip-scheduled-if-done t) - (org-agenda-skip-deadline-if-done t) - (org-hide-emphasis-markers t) - - (line-spacing 0.1) - (left-margin-width 2) - (right-margin-width 2) - - (org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w)" "SOMEDAY(s)" "PROJ(p)" - "|" "DONE(d)" "CANCELED(c)"))) - (org-todo-keywords-for-agenda '((sequence "NEXT(n)" "TODO(t)" "WAITING(w)" "SOMEDAY(s)" "PROJ(p)" "|" "DONE(d)" "CANCELED(c)"))) - (org-agenda-files (list "~/Nextcloud/org/" "~/org/snamellit/" "~/org/customer/" "~/org/personal/")) - (org-refile-targets '( - (org-agenda-files . (:level . 1)) - ("~/org/personal/bijen.org" . (:level . 1)) - ("~/org/personal/fitness.org" . (:level . 1)) - )) - :config - ;; set files for agenda views - (setq +org-capture-todo-file "~/Nextcloud/org/inbox.org" - +org-capture-notes-file "~/Nextcloud/org/inbox.org" - +org-capture-journal-file "~/Nextcloud/org/journal.org" - +org-capture-projects-file "~/Nextcloud/org/projects.org") - :hook ( - (org-mode . pti-org-mode-config) - (org-mode . org-indent-mode) - - ) - :bind ( - (" o a" . org-agenda) - (" o s" . org-store-link) - )) -#+END_SRC - -#+RESULTS: -*** Org Appear - -Hide the org markers when point is not on the element being decorated. - -#+BEGIN_SRC emacs-lisp - - (use-package org-appear - :ensure t - :hook (org-mode . org-appear-mode)) - - -#+END_SRC - -#+RESULTS: -: [nil 26432 31427 677147 nil elpaca-process-queues nil nil 738000 nil] - -*** Org Babel Support - -I have a test file which has samples of babel features for easy -testing in my [[file:~/org/snamellit/testfile.org::*User Journey Graph][org babel test file.]] - -**** Support REST calls in Babel Blocks - -#+BEGIN_SRC emacs-lisp - ;; enable verb package to do REST calls - (use-package verb - :ensure t - :defer 3 - :bind - (:map org-mode-map - ("C-c C-r" . verb-command-map))) - - (use-package ob-verb - :after verb - :defer 3) - #+END_SRC -**** Support Mermaid Diagrams in Babel Blocks - -#+BEGIN_SRC emacs-lisp - ;; enable mermaid for org-babel - (use-package ob-mermaid - :ensure t - :defer 3) - #+END_SRC - - Mermaid needs support of the mermaid-cli which is a node package. It - can be installed with - -#+BEGIN_SRC shell :tangle no -npm install -g @mermaid-js/mermaid-cli -#+END_SRC - -#+RESULTS: -| | | | | | | -| changed | 194 | packages | in | 6s | | -| | | | | | | -| 39 | packages | are | looking | for | funding | -| run | `npm | fund` | for | details | | - -**** Support PlantUML Diagrams in Babel Blocks - -Requires nothing special, other than *plantuml.jar* archive installed. - -The following code block depends on [[*Get latest version of a github released project][Get latest version of a github -released project]] utility function. This block will check if there is a -plantuml.jar in the emacs config directory and if not download the -latest version from github. The `pti-download-latest-plantuml` is made -interactive to manually install the latest version if needed. - -#+BEGIN_SRC emacs-lisp :lexical t - (defun pti-download-latest-plantuml () - "Download the latest version of PlantUML. - - This function is interactive to make it easy to upgrade to - the latest, current version with `M-x pti-download-latest-plantuml'." - (interactive) - (let* ((version (pti-latest-github-release "plantuml/plantuml")) - (url (format - "https://github.com/plantuml/plantuml/releases/download/%s/plantuml-%s.jar" - version (substring version 1)))) - (message "Downloading PlantUML version %s from %s" version url) - (url-copy-file - url - (concat user-emacs-directory "plantuml.jar") - t))) - - (let ((plantuml-jar (concat user-emacs-directory "plantuml.jar"))) - (if (not (file-exists-p plantuml-jar)) - (pti-download-latest-plantuml)) - - (setq org-plantuml-jar-path plantuml-jar)) -#+END_SRC - -#+RESULTS: -: /home/pti/.config/emacs/plantuml.jar - -**** Configure Babel Languages -#+BEGIN_SRC emacs-lisp - ;; configure babel languages - (use-package org-babel - :no-require - :after '(ob-verb ob-mermaid) - :config - (org-babel-do-load-languages - 'org-babel-load-languages - '((emacs-lisp . t) - (shell . t) - (python . t) - (latex . t) - (verb . t) - (scheme . t) - (plantuml . t) - (mermaid . t) - (dot . t)))) -#+END_SRC - -**** Temporary Patches for Org Babel - -***** Fix Scheme Babel Bug -#+BEGIN_SRC emacs-lisp - ;; fix a bug in ob-scheme which causes an error to be thrown when evaluating - ;; a cons cell or improper list - ;; see https://list.orgmode.org/87bkk3x1bu.fsf@gajsin.name/T/ - (defun org-babel-scheme--table-or-string (results) - "Convert RESULTS into an appropriate elisp value. - If the results look like a list or tuple, then convert them into an - Emacs-lisp table, otherwise return the results as a string." - (let ((res (org-babel-script-escape results))) - (cond ((proper-list-p res) - (mapcar (lambda (el) - (if (or (null el) (eq el 'null)) - org-babel-scheme-null-to - el)) - res)) - (t res)))) -#+END_SRC - -#+RESULTS: -: org-babel-scheme--table-or-string - -**** TODO Move babel test file to emacs config folder - -Alternatively I might add a sample after each configured block to keep -it in the same context. Hmmm.... sounds even better. - - -*** Org Export -#+BEGIN_SRC emacs-lisp - (use-package ox - :ensure nil) - -#+END_SRC - -**** Org Export to Markdown -#+BEGIN_SRC emacs-lisp - (use-package ox-md - :ensure nil - :after ox - ) -#+END_SRC -**** Org Latex Export -***** Syntax Highlighting requires Multiple Passes -#+BEGIN_SRC emacs-lisp - ;; support for minted in LaTeX for code highlighting - (use-package ox-latex - :ensure nil - :after ox - :config - (setq org-latex-compiler "lualatex") - (setq org-latex-pdf-process - '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f" - "%latex -interaction nonstopmode -output-directory %o %f")) - ) -#+END_SRC -***** Load Customer Latex Classes -#+BEGIN_SRC emacs-lisp - ;; Customer LaTeX classes - (setq mlx-latex-classes - '( - ("mlx-beamer" "\\documentclass{mlx-beamer} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("mlx-book" "\\documentclass{mlx-book} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("mlx-report" "\\documentclass{mlx-report} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("mlx-article" "\\documentclass{mlx-article} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) - ("mlx-project-charter" "\\documentclass{mlx-project-charter} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s} - \\begin{mdframed}" "\\end{mdframed}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) -#+END_SRC -***** Load My Latex Classes -#+BEGIN_SRC emacs-lisp - (setq snm-latex-classes - '( - ("snm-beamer" "\\documentclass{snm-beamer} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("snm-book" "\\documentclass{snm-book} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("snm-report" "\\documentclass{snm-report} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\part{%s}" . "\\part*{%s}") - ("\\chapter{%s}" . "\\chapter*{%s}") - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) - ("snm-invoice" "\\documentclass{snm-invoice} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) - ("snm-article" "\\documentclass{snm-article} - [NO-DEFAULT-PACKAGES] - [NO-PACKAGES]" - ("\\section{%s}" . "\\section*{%s}") - ("\\subsection{%s}" . "\\subsection*{%s}") - ("\\subsubsection{%s}" . "\\subsubsection*{%s}") - ("\\paragraph{%s}" . "\\paragraph*{%s}") - ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) - - (with-eval-after-load 'ox-latex - (dolist - (class (append mlx-latex-classes snm-latex-classes)) - (add-to-list 'org-latex-classes class))) -#+END_SRC -**** Blogging with Zola - -gicrisf has [[https://github.com/gicrisf/ox-zola][created a package]] to export org files to Zola. - -#+BEGIN_SRC emacs-lisp - (use-package ox-hugo - :ensure t - :after ox) - (use-package ox-zola - :ensure (ox-zola :host github :repo "gicrisf/ox-zola" :files (:defaults "*.el" "backend" "stylesheets")) - :after ox-hugo - :config - (require 'ox-hugo) - :general - (" o z" 'ox-zola-export-wim-to-md)) -#+END_SRC - -#+RESULTS: - -It is a wrapper around ~ox-hugo~ to export org files to Zola. It -supports most features of it and directs the user to the [[https://ox-hugo.scripter.co/][the hugo -exporter manual.]] - - -*** Org Capture Customization -#+BEGIN_SRC emacs-lisp - (use-package org-capture - :ensure nil - :config (progn - (setq org-capture-templates '()) - (add-to-list 'org-capture-templates - '("t" "Todo" entry (file+headline +org-capture-todo-file "Tasks") - "* TODO %?\n %i\n %a")) - (add-to-list 'org-capture-templates - '("n" "Note" entry (file+headline +org-capture-todo-file "Notes") - "* %?\n %i\n %a")) - (add-to-list 'org-capture-templates - '("j" "Journal" entry (file+datetree +org-capture-journal-file) - "* %?\nEntered on %U\n %i\n %a")) - (add-to-list 'org-capture-templates - '("b" "Blog Post" entry - (file+headline "~/org/snamellit/blog.org" "Blog Posts") - "** %^{Blog Title:}\n:PROPERTIES:\n:EXPORT_FILE_NAME %^{Export Filename:}\n:EXPORT_DATE: %t\n:END:\n%i%?")) - - ;; configure support for recipes - (add-to-list 'org-capture-templates - '("c" "Cookbook" entry (file "~/org/cookbook.org") - "%(org-chef-get-recipe-from-url)" - :empty-lines 1)) - (add-to-list 'org-capture-templates - '("m" "Manual Cookbook" entry (file "~/org/cookbook.org") - "* %^{Recipe title: }\n :PROPERTIES:\n :source-url:\n :servings:\n :prep-time:\n :cook-time:\n :ready-in:\n :END:\n** Ingredients\n %?\n** Directions\n\n"))) - :bind (("X" . org-capture))) - -#+END_SRC - -#+RESULTS: -: t -*** Evil Support for Org - -Better keybinding for evil mode from [[https://github.com/Somelauw/evil-org-mode][the evil-org github repo]]. -#+BEGIN_SRC emacs-lisp - (use-package evil-org - :ensure t - :after org - :hook - (org-mode . evil-org-mode) - :config - (require 'evil-org-agenda) - (evil-org-agenda-set-keys)) -#+END_SRC - -Here is a snapshot of the keybindings dd <2024-07-30 Tue>. - -**** Quick overview - - |----------------+---------------------------| - | key | explanation | - |----------------+---------------------------| - | gh, gj, gk, gl | navigate between elements | - | vae | select an element | - |----------------+---------------------------| - -**** Headings and items - - |--------------+------------------------| - | key | explanation | - |--------------+------------------------| - | M-ret | insert heading | - | , g TAB | fold / unfold headings | - | M-h or << | promote a heading | - | M-l or >> | demote a heading | - | M-k | move subtree up | - | M-j | move subtree down | - | M-S-h or aR | demote a subtree | - | vaR | select a subtree | - |--------------+------------------------| - -**** Tables - - |-----------+--------------------------------| - | key | explanation | - |-----------+--------------------------------| - | ( | previous table cell | - | ) | next table cell | - | { | beginning of table | - | } | end of table | - | M-h / M-l | move table column left / right | - | M-k / M-j | move table column up / down | - | vae | select table cell | - | vaE | select table row | - | var | select whole table | - |-----------+--------------------------------| - -**** Agenda - - |-------------------------+-------------------------+-----------------------------------------------------------------------------------| - | Evil key | Emacs key | explanation | - |-------------------------+-------------------------+-----------------------------------------------------------------------------------| - | gH | | Move cursor to the top of window | - | gM | | Move cursor to the middle of window | - | gL | | Move cursor to the bottom of window | - | , S- | | go to the corresponding entry at point | - | g TAB | | go to the corresponding entry at point | - | | | go to the Org mode file which contains the item at point | - | M- | L | Display Org file and center around the item | - | | | scroll up | - | or | or | scroll down | - | j, k | n, p | next, previous line | - | gj, gk, C-j, C-k | N, P | next, previous item | - | [, ] | b, f | previous, next week | - | J, K | -, +, S-down, S-up | down, up priority | - | H, L | S-left, S-right | modify date to earlier, later | - | t | t | cycle TODO keywords | - | M-j, M-k | M-down, M-up | drag line forward, backward | - | C-S-h, C-S-l | C-S-left, C-S-right | previous, next keyword | - | u | C-_, C-/ | undo | - | dd | C-k | delete item | - | da | a | ask and archive item | - | dA | $ | archive item | - | ct | : | set tags | - | ce | e | set effort | - | cT | ; | set timer | - | i | i | insert entry in diary | - | a | z | add note | - | A | A | append to agenda | - | C | k | capture | - | m | m | mark | - | * | * | toggle all marks | - | % | % | mark regexp | - | M | U | remove all marks | - | x | B | execute action on marks | - | gr | r | refresh agenda | - | gR | g | refresh all agendas | - | ZQ | x | exit agenda | - | ZZ | Q | quit agenda | - | gD | v | tweak display (deadlines, diary, follow/log-mode, entry text, grid, day/week/year | - | ZD | # | dim blocked tasks | - | sc, sr, se, st, s^ | <, =, _, /, ^ | filter by category, regexp, effort, tag, top headline | - | S | \vert | remove all filters | - | ss | ~ | filter/limit interactively | - | I | I | clock in | - | O | O | clock out | - | cg | J | jump to the currently clocked in task within the agenda | - | cc | X | cancel the current running clock | - | cr | R | toggle clocktable mode in an agenda buffer | - | . | . | go to today's date | - | gc | c | pop up calendar | - | gC | C | pop up date converter | - | p | > | pop up date selector | - | gh | H | pop up holiday calendar | - | gm | M | pop up phases of the moon | - | gs | S | pop up sunrise/sunset times | - | gt | T | pop up tag list | - | +, - | [, ] | manipulate the query by adding a search term with positive or negative selection | - |-------------------------+-------------------------+-----------------------------------------------------------------------------------| - -*** Org GCal Support - -#+BEGIN_SRC emacs-lisp - ;; configure support for google calendar - (use-package org-gcal - ;; :ensure t - :custom - (org-gcal-client-id (auth-source-pass-get 'secret "snamellit/org-gcal-client")) - (org-gcal-client-secret (auth-source-pass-get "id" "snamellit/org-gcal-client")) - (org-gcal-fetch-file-alist '(("pti@snamellit.com" . "~/org/schedule.org"))) - :commands (org-gcal-sync org-gcal-fetch) ) -#+END_SRC - -#+RESULTS: - -*** Org Jira Integration - -#+BEGIN_SRC emacs-lisp - ;; configure org-jira - (use-package org-jira - :ensure (:host github :repo "ptillemans/org-jira" :branch "pti_fix_getUsers") - :commands (org-jira-get-issues org-jira-get-projects) - :config - (setq org-jira-users '(("Peter Tillemans". "557058:bdf83521-663b-4ae6-9b71-487bb98e2add"))) - (setq jiralib-agile-page-size 1000) - (setq org-jira-custom-jqls - '( - (:jql " assignee = currentUser() and (created > '2024-01-01' of updated > '2024-01-01) order by created DESC" - :limit 100 :filename "this-year") - (:jql "project = TTRK and (resolution = Unresolved OR updated>=-15d) ORDER BY priority DESC" - :limit 100 :filename "~/Projects/timetrak/jira") - )) - (make-directory "~/.org-jira" 'parents) - (setq jiralib-url (auth-source-pass-get "url" "customer/jira")) - (setq org-jira-custom-jqls - '((:jql " assignee = currentUser() and project = TTRK order by priority DESC " :limit 100 :filename "~/Projects/timetrak/jira") - (:jql " assignee = currentUser() and createdDate >= '2024-01-01' order by created DESC " :limit 100 :filename "this-years-work"))) - (jiralib-login - (auth-source-pass-get "user" "customer/jira") - (auth-source-pass-get 'secret "customer/jira")) - :bind (("C-c ig" . 'org-jira-get-issues) - ("C-c ip" . 'org-jira-get-projects) - ("C-c ij" . 'org-jira-get-issues-from-custom-jql))) -#+END_SRC - -#+RESULTS: -: [nil 26292 53013 676464 nil elpaca-process-queues nil nil 459000 nil] - -It is very useful to create for each active project a custom JQL to -make a snapshot of issues just for that project in the folder of the -project to keep everything in context. - - - -**** Keybindings - -| Key | Command | -|---------+------------------------------------------| -| C-c pg | org-jira-get-projects | -| C-c bg | org-jira-get-boards | -| C-c iv | org-jira-get-issues-by-board | -| C-c ib | org-jira-browse-issue | -| C-c ig | org-jira-get-issues | -| C-c ij | org-jira-get-issues-from-custom-jql | -| C-c ih | org-jira-get-issues-headonly | -| C-c if | org-jira-get-issues-from-filter-headonly | -| C-c iF | org-jira-get-issues-from-filter | -| C-c iu | org-jira-update-issue | -| C-c iw | org-jira-progress-issue | -| C-c in | org-jira-progress-issue-next | -| C-c ia | org-jira-assign-issue | -| C-c isr | org-jira-set-issue-reporter | -| C-c ir | org-jira-refresh-issue | -| C-c iR | org-jira-refresh-issues-in-buffer | -| C-c ic | org-jira-create-issue | -| C-c ik | org-jira-copy-current-issue-key | -| C-c sc | org-jira-create-subtask | -| C-c sg | org-jira-get-subtasks | -| C-c cc | org-jira-add-comment | -| C-c cu | org-jira-update-comment | -| C-c wu | org-jira-update-worklogs-from-org-clocks | -| C-c tj | org-jira-todo-to-jira | -| C-c if | org-jira-get-issues-by-fixversion | - -**** TODO add focused project support -There should be some things we can do to better integrate this with -projects: -- update issues in background when opening the project. -- run custom JQL defined in the project iso globally. - - -*** Daviwil's Productivity Tools - -@daviwil has a set of productivity tools which are very useful. I have - - -**** Find all tasks with a specific tag (or without) - -#+BEGIN_SRC emacs-lisp :tangle no - (setq org-agenda-custom-commands - '(("p" "Planning" tags-todo "+@planning"))) -#+END_SRC - -#+RESULTS: -| p | Planning | tags-todo | +@planning | - -We can remove tasks with a certain tag by adding `-@work` to the pattern. - -**** Find all tasks with a specific tag (or without) - - -#+BEGIN_SRC emacs-lisp :tangle no - (setq org-agenda-custom-commands - '(("u" "Untagged Tasks" tags-todo "-{.*}"))) -#+END_SRC - -#+RESULTS: -| u | Untagged Tasks | tags-todo | -{.*} | - -**** Combine multiple filters - -We can add a list of queries - -#+BEGIN_SRC emacs-lisp :tangle no - (setq org-agenda-custom-commands - '(("p" "Planning" ((tags-todo "+@planning") - (tags-todo "-{.*}"))))) -#+END_SRC - -#+RESULTS: -| p | Planning | ((tags-todo +@planning) (tags-todo -{.*})) | - -**** We can add settings to each filter - -#+BEGIN_SRC emacs-lisp :tangle no - (setq org-agenda-custom-commands - '(("p" "Planning" ((tags-todo "+@planning" - ((org-agenda-overriding-header "Planning Tasks"))) - (tags-todo "-{.*}" - ((org-agenda-overriding-header "Untagged Tasks"))))))) -#+END_SRC - -#+RESULTS: -| p | Planning | ((tags-todo +@planning ((org-agenda-overriding-header Planning Tasks))) (tags-todo -{.*} ((org-agenda-overriding-header Untagged Tasks)))) | - -**** Add support for an input file - -#+BEGIN_SRC emacs-lisp - (setq org-agenda-custom-commands - '(("i" "Inbox" ((todo ".*" - ((org-agenda-files '("~/Nextcloud/org/inbox.org")) - (org-agenda-overriding-header "Unprocessed Inbox Items"))))))) -#+END_SRC - -#+RESULTS: -| i | Inbox | ((todo .* ((org-agenda-files '(~/Nextcloud/org/inbox.org)) (org-agenda-overriding-header Unprocessed Inbox Items)))) | - - -**** Daily Agenda - -#+BEGIN_SRC emacs-lisp - (setq org-agenda-custom-commands - '(("d" "Daily Agenda" - ((agenda "" ((org-agenda-span 'day) - (org-deadline-warning-days 1) - (org-agenda-overriding-header "Today's Agenda"))) - (tags-todo "+PRIORITY=\"A\"" - ((org-agenda-overriding-header "High-Priority Unfinished Tasks") - )))))) -#+END_SRC - -#+RESULTS: -| d | Daily Agenda | ((agenda ((org-agenda-span 'day) (org-deadline-warning-days 1) (org-agenda-overriding-header Today's Agenda))) (tags-todo +PRIORITY="A" ((org-agenda-overriding-header High-priority unfinished tasks)))) | - - -**** Weekly Review - -#+BEGIN_SRC emacs-lisp - (setq org-log-done 'time) ; log the time when a task is completed - (setq org-agenda-start-with-log-mode t) ; show the log mode when starting the agenda - - (setq org-agenda-custom-commands - '(("w" "Weekly Review" - ((agenda "" ((org-agenda-overriding-header "Completed Tasks") - (org-agenda-skip-function (org-agenda-skip-entry-if 'nottodo 'done)) - (org-agenda-span 'week))) - (agenda "" ((org-agenda-overriding-header "Unfinished Scheduled Tasks") - (org-agenda-skip-function (org-agenda-skip-entry-if 'todo 'done)) - (org-agenda-span 'week))) - )))) -#+END_SRC - -#+RESULTS: -| w | Weekly Review | ((agenda ((org-agenda-overriding-header Completed Tasks) (org-agenda-skip-function (org-agenda-skip-entry-if 'nottodo 'done)) (org-agenda-span 'week))) (agenda ((org-agenda-overriding-header Unfinished Scheduled Tasks) (org-agenda-skip-function (org-agenda-skip-entry-if 'todo 'done)) (org-agenda-span 'week)))) | - - -** Denote - -#+BEGIN_SRC emacs-lisp - ;; configure denote - (use-package denote - :ensure t - :init - (setq denote-directory (file-name-concat (expand-file-name "~") "Nextcloud/denote")) - (setq denote-dired-directories - (list denote-directory - (expand-file-name "~/Documents/denote"))) - :hook (dired-mode . denote-dired-mode-in-directories) - :bind ( - (" n d" . (lambda () (interactive) (dired denote-directory))) - (" n n" . #'denote) - (" n N" . #'denote-type) - (" n c" . #'denote-link-or-create) - (" n t" . #'denote-template) - (" n z" . #'denote-signature) - (" n l" . #'denote-link) - (" n L" . #'denote-find-link) - (" n k" . #'denote-keywords-add) - (" n b" . #'denote-link-backlink) - (" n B" . #'denote-find-backlink) - (" n r" . #'denote-rename-file) - (" n R" . #'denote-rename-file-using-front-matter) - (" n f" . (lambda () (interactive) (consult-find denote-directory))))) -#+END_SRC - -**** TODO explain what denote-dired-mode-in-directories does. - * Programming #+BEGIN_SRC emacs-lisp @@ -2748,6 +2007,753 @@ templates to be generated. By default it uses : [nil 26455 5250 886750 nil elpaca-process-queues nil nil 641000 nil] +* Writing and Planning + +#+BEGIN_SRC emacs-lisp +(report-time-since-load "Writing and Planning") +#+END_SRC + +** Org Mode + +*** Mixed Pitch Support by Default in Org +#+BEGIN_SRC emacs-lisp + (defun pti-org-mode-config () + "Set options for better writing in org buffers." + (mixed-pitch-mode) + (visual-line-mode) + (turn-on-auto-fill) + ) + + (use-package org-bullets + :ensure t + :if (display-graphic-p) + :hook (org-mode . org-bullets-mode)) + + (use-package mixed-pitch + :ensure t + :if (display-graphic-p) + :hook + (org-mode . mixed-pitch-mode)) +#+END_SRC + +#+RESULTS: +: [nil 26279 36119 854408 nil elpaca-process-queues nil nil 376000 nil] +*** Org Configuration +#+BEGIN_SRC emacs-lisp + (use-package org + :ensure nil + :custom + (org-return-follows-link t) + (org-mouse-1-follows-link t) + (org-link-descriptive t) + (org-agenda-skip-scheduled-if-done t) + (org-agenda-skip-deadline-if-done t) + (org-hide-emphasis-markers t) + + (line-spacing 0.1) + (left-margin-width 2) + (right-margin-width 2) + + (org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w)" "SOMEDAY(s)" "PROJ(p)" + "|" "DONE(d)" "CANCELED(c)"))) + (org-todo-keywords-for-agenda '((sequence "NEXT(n)" "TODO(t)" "WAITING(w)" "SOMEDAY(s)" "PROJ(p)" "|" "DONE(d)" "CANCELED(c)"))) + (org-agenda-files (list "~/Nextcloud/org/" "~/org/snamellit/" "~/org/customer/" "~/org/personal/")) + (org-refile-targets '( + (org-agenda-files . (:level . 1)) + ("~/org/personal/bijen.org" . (:level . 1)) + ("~/org/personal/fitness.org" . (:level . 1)) + )) + :config + ;; set files for agenda views + (setq +org-capture-todo-file "~/Nextcloud/org/inbox.org" + +org-capture-notes-file "~/Nextcloud/org/inbox.org" + +org-capture-journal-file "~/Nextcloud/org/journal.org" + +org-capture-projects-file "~/Nextcloud/org/projects.org") + :hook ( + (org-mode . pti-org-mode-config) + (org-mode . org-indent-mode) + + ) + :bind ( + (" o a" . org-agenda) + (" o s" . org-store-link) + )) +#+END_SRC + +#+RESULTS: +*** Org Appear + +Hide the org markers when point is not on the element being decorated. + +#+BEGIN_SRC emacs-lisp + + (use-package org-appear + :ensure t + :hook (org-mode . org-appear-mode)) + + +#+END_SRC + +#+RESULTS: +: [nil 26432 31427 677147 nil elpaca-process-queues nil nil 738000 nil] + +*** Org Babel Support + +I have a test file which has samples of babel features for easy +testing in my [[file:~/org/snamellit/testfile.org::*User Journey Graph][org babel test file.]] + +**** Support REST calls in Babel Blocks + +#+BEGIN_SRC emacs-lisp + ;; enable verb package to do REST calls + (use-package verb + :ensure t + :defer 3 + :bind + (:map org-mode-map + ("C-c C-r" . verb-command-map))) + + (use-package ob-verb + :after verb + :defer 3) + #+END_SRC +**** Support Mermaid Diagrams in Babel Blocks + +#+BEGIN_SRC emacs-lisp + ;; enable mermaid for org-babel + (use-package ob-mermaid + :ensure t + :defer 3) + #+END_SRC + + Mermaid needs support of the mermaid-cli which is a node package. It + can be installed with + +#+BEGIN_SRC shell :tangle no +npm install -g @mermaid-js/mermaid-cli +#+END_SRC + +#+RESULTS: +| | | | | | | +| changed | 194 | packages | in | 6s | | +| | | | | | | +| 39 | packages | are | looking | for | funding | +| run | `npm | fund` | for | details | | + +**** Support PlantUML Diagrams in Babel Blocks + +Requires nothing special, other than *plantuml.jar* archive installed. + +The following code block depends on [[*Get latest version of a github released project][Get latest version of a github +released project]] utility function. This block will check if there is a +plantuml.jar in the emacs config directory and if not download the +latest version from github. The `pti-download-latest-plantuml` is made +interactive to manually install the latest version if needed. + +#+BEGIN_SRC emacs-lisp :lexical t + (defun pti-download-latest-plantuml () + "Download the latest version of PlantUML. + + This function is interactive to make it easy to upgrade to + the latest, current version with `M-x pti-download-latest-plantuml'." + (interactive) + (let* ((version (pti-latest-github-release "plantuml/plantuml")) + (url (format + "https://github.com/plantuml/plantuml/releases/download/%s/plantuml-%s.jar" + version (substring version 1)))) + (message "Downloading PlantUML version %s from %s" version url) + (url-copy-file + url + (concat user-emacs-directory "plantuml.jar") + t))) + + (let ((plantuml-jar (concat user-emacs-directory "plantuml.jar"))) + (if (not (file-exists-p plantuml-jar)) + (pti-download-latest-plantuml)) + + (setq org-plantuml-jar-path plantuml-jar)) +#+END_SRC + +#+RESULTS: +: /home/pti/.config/emacs/plantuml.jar + +**** Configure Babel Languages +#+BEGIN_SRC emacs-lisp + ;; configure babel languages + (use-package org-babel + :no-require + :after '(ob-verb ob-mermaid) + :config + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (shell . t) + (python . t) + (latex . t) + (verb . t) + (scheme . t) + (plantuml . t) + (mermaid . t) + (dot . t)))) +#+END_SRC + +**** Temporary Patches for Org Babel + +***** Fix Scheme Babel Bug +#+BEGIN_SRC emacs-lisp + ;; fix a bug in ob-scheme which causes an error to be thrown when evaluating + ;; a cons cell or improper list + ;; see https://list.orgmode.org/87bkk3x1bu.fsf@gajsin.name/T/ + (defun org-babel-scheme--table-or-string (results) + "Convert RESULTS into an appropriate elisp value. + If the results look like a list or tuple, then convert them into an + Emacs-lisp table, otherwise return the results as a string." + (let ((res (org-babel-script-escape results))) + (cond ((proper-list-p res) + (mapcar (lambda (el) + (if (or (null el) (eq el 'null)) + org-babel-scheme-null-to + el)) + res)) + (t res)))) +#+END_SRC + +#+RESULTS: +: org-babel-scheme--table-or-string + +**** TODO Move babel test file to emacs config folder + +Alternatively I might add a sample after each configured block to keep +it in the same context. Hmmm.... sounds even better. + + +*** Org Export +#+BEGIN_SRC emacs-lisp + (use-package ox + :ensure nil) + +#+END_SRC + +**** Org Export to Markdown +#+BEGIN_SRC emacs-lisp + (use-package ox-md + :ensure nil + :after ox + ) +#+END_SRC +**** Org Latex Export +***** Syntax Highlighting requires Multiple Passes +#+BEGIN_SRC emacs-lisp + ;; support for minted in LaTeX for code highlighting + (use-package ox-latex + :ensure nil + :after ox + :config + (setq org-latex-compiler "lualatex") + (setq org-latex-pdf-process + '("%latex -shell-escape -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f" + "%latex -interaction nonstopmode -output-directory %o %f")) + ) +#+END_SRC +***** Load Customer Latex Classes +#+BEGIN_SRC emacs-lisp + ;; Customer LaTeX classes + (setq mlx-latex-classes + '( + ("mlx-beamer" "\\documentclass{mlx-beamer} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("mlx-book" "\\documentclass{mlx-book} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\part{%s}" . "\\part*{%s}") + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("mlx-report" "\\documentclass{mlx-report} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\part{%s}" . "\\part*{%s}") + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("mlx-article" "\\documentclass{mlx-article} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) + ("mlx-project-charter" "\\documentclass{mlx-project-charter} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s} + \\begin{mdframed}" "\\end{mdframed}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) +#+END_SRC +***** Load My Latex Classes +#+BEGIN_SRC emacs-lisp + (setq snm-latex-classes + '( + ("snm-beamer" "\\documentclass{snm-beamer} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("snm-book" "\\documentclass{snm-book} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\part{%s}" . "\\part*{%s}") + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("snm-report" "\\documentclass{snm-report} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\part{%s}" . "\\part*{%s}") + ("\\chapter{%s}" . "\\chapter*{%s}") + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}")) + ("snm-invoice" "\\documentclass{snm-invoice} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")) + ("snm-article" "\\documentclass{snm-article} + [NO-DEFAULT-PACKAGES] + [NO-PACKAGES]" + ("\\section{%s}" . "\\section*{%s}") + ("\\subsection{%s}" . "\\subsection*{%s}") + ("\\subsubsection{%s}" . "\\subsubsection*{%s}") + ("\\paragraph{%s}" . "\\paragraph*{%s}") + ("\\subparagraph{%s}" . "\\subparagraph*{%s}")))) + + (with-eval-after-load 'ox-latex + (dolist + (class (append mlx-latex-classes snm-latex-classes)) + (add-to-list 'org-latex-classes class))) +#+END_SRC +**** Blogging with Zola + +gicrisf has [[https://github.com/gicrisf/ox-zola][created a package]] to export org files to Zola. + +#+BEGIN_SRC emacs-lisp + (use-package ox-hugo + :ensure t + :after ox) + (use-package ox-zola + :ensure (ox-zola :host github :repo "gicrisf/ox-zola" :files (:defaults "*.el" "backend" "stylesheets")) + :after ox-hugo + :config + (require 'ox-hugo) + :general + (" o z" 'ox-zola-export-wim-to-md)) +#+END_SRC + +#+RESULTS: + +It is a wrapper around ~ox-hugo~ to export org files to Zola. It +supports most features of it and directs the user to the [[https://ox-hugo.scripter.co/][the hugo +exporter manual.]] + + +*** Org Capture Customization +#+BEGIN_SRC emacs-lisp + (use-package org-capture + :ensure nil + :config (progn + (setq org-capture-templates '()) + (add-to-list 'org-capture-templates + '("t" "Todo" entry (file+headline +org-capture-todo-file "Tasks") + "* TODO %?\n %i\n %a")) + (add-to-list 'org-capture-templates + '("n" "Note" entry (file+headline +org-capture-todo-file "Notes") + "* %?\n %i\n %a")) + (add-to-list 'org-capture-templates + '("j" "Journal" entry (file+datetree +org-capture-journal-file) + "* %?\nEntered on %U\n %i\n %a")) + (add-to-list 'org-capture-templates + '("b" "Blog Post" entry + (file+headline "~/org/snamellit/blog.org" "Blog Posts") + "** %^{Blog Title:}\n:PROPERTIES:\n:EXPORT_FILE_NAME %^{Export Filename:}\n:EXPORT_DATE: %t\n:END:\n%i%?")) + + ;; configure support for recipes + (add-to-list 'org-capture-templates + '("c" "Cookbook" entry (file "~/org/cookbook.org") + "%(org-chef-get-recipe-from-url)" + :empty-lines 1)) + (add-to-list 'org-capture-templates + '("m" "Manual Cookbook" entry (file "~/org/cookbook.org") + "* %^{Recipe title: }\n :PROPERTIES:\n :source-url:\n :servings:\n :prep-time:\n :cook-time:\n :ready-in:\n :END:\n** Ingredients\n %?\n** Directions\n\n"))) + :bind (("X" . org-capture))) + +#+END_SRC + +#+RESULTS: +: t +*** Evil Support for Org + +Better keybinding for evil mode from [[https://github.com/Somelauw/evil-org-mode][the evil-org github repo]]. +#+BEGIN_SRC emacs-lisp + (use-package evil-org + :ensure t + :after org + :hook + (org-mode . evil-org-mode) + :config + (require 'evil-org-agenda) + (evil-org-agenda-set-keys)) +#+END_SRC + +Here is a snapshot of the keybindings dd <2024-07-30 Tue>. + +**** Quick overview + + |----------------+---------------------------| + | key | explanation | + |----------------+---------------------------| + | gh, gj, gk, gl | navigate between elements | + | vae | select an element | + |----------------+---------------------------| + +**** Headings and items + + |--------------+------------------------| + | key | explanation | + |--------------+------------------------| + | M-ret | insert heading | + | , g TAB | fold / unfold headings | + | M-h or << | promote a heading | + | M-l or >> | demote a heading | + | M-k | move subtree up | + | M-j | move subtree down | + | M-S-h or aR | demote a subtree | + | vaR | select a subtree | + |--------------+------------------------| + +**** Tables + + |-----------+--------------------------------| + | key | explanation | + |-----------+--------------------------------| + | ( | previous table cell | + | ) | next table cell | + | { | beginning of table | + | } | end of table | + | M-h / M-l | move table column left / right | + | M-k / M-j | move table column up / down | + | vae | select table cell | + | vaE | select table row | + | var | select whole table | + |-----------+--------------------------------| + +**** Agenda + + |-------------------------+-------------------------+-----------------------------------------------------------------------------------| + | Evil key | Emacs key | explanation | + |-------------------------+-------------------------+-----------------------------------------------------------------------------------| + | gH | | Move cursor to the top of window | + | gM | | Move cursor to the middle of window | + | gL | | Move cursor to the bottom of window | + | , S- | | go to the corresponding entry at point | + | g TAB | | go to the corresponding entry at point | + | | | go to the Org mode file which contains the item at point | + | M- | L | Display Org file and center around the item | + | | | scroll up | + | or | or | scroll down | + | j, k | n, p | next, previous line | + | gj, gk, C-j, C-k | N, P | next, previous item | + | [, ] | b, f | previous, next week | + | J, K | -, +, S-down, S-up | down, up priority | + | H, L | S-left, S-right | modify date to earlier, later | + | t | t | cycle TODO keywords | + | M-j, M-k | M-down, M-up | drag line forward, backward | + | C-S-h, C-S-l | C-S-left, C-S-right | previous, next keyword | + | u | C-_, C-/ | undo | + | dd | C-k | delete item | + | da | a | ask and archive item | + | dA | $ | archive item | + | ct | : | set tags | + | ce | e | set effort | + | cT | ; | set timer | + | i | i | insert entry in diary | + | a | z | add note | + | A | A | append to agenda | + | C | k | capture | + | m | m | mark | + | * | * | toggle all marks | + | % | % | mark regexp | + | M | U | remove all marks | + | x | B | execute action on marks | + | gr | r | refresh agenda | + | gR | g | refresh all agendas | + | ZQ | x | exit agenda | + | ZZ | Q | quit agenda | + | gD | v | tweak display (deadlines, diary, follow/log-mode, entry text, grid, day/week/year | + | ZD | # | dim blocked tasks | + | sc, sr, se, st, s^ | <, =, _, /, ^ | filter by category, regexp, effort, tag, top headline | + | S | \vert | remove all filters | + | ss | ~ | filter/limit interactively | + | I | I | clock in | + | O | O | clock out | + | cg | J | jump to the currently clocked in task within the agenda | + | cc | X | cancel the current running clock | + | cr | R | toggle clocktable mode in an agenda buffer | + | . | . | go to today's date | + | gc | c | pop up calendar | + | gC | C | pop up date converter | + | p | > | pop up date selector | + | gh | H | pop up holiday calendar | + | gm | M | pop up phases of the moon | + | gs | S | pop up sunrise/sunset times | + | gt | T | pop up tag list | + | +, - | [, ] | manipulate the query by adding a search term with positive or negative selection | + |-------------------------+-------------------------+-----------------------------------------------------------------------------------| + +*** Org GCal Support + +#+BEGIN_SRC emacs-lisp + ;; configure support for google calendar + (use-package org-gcal + ;; :ensure t + :custom + (org-gcal-client-id (auth-source-pass-get 'secret "snamellit/org-gcal-client")) + (org-gcal-client-secret (auth-source-pass-get "id" "snamellit/org-gcal-client")) + (org-gcal-fetch-file-alist '(("pti@snamellit.com" . "~/org/schedule.org"))) + :commands (org-gcal-sync org-gcal-fetch) ) +#+END_SRC + +#+RESULTS: + +*** Org Jira Integration + +#+BEGIN_SRC emacs-lisp + ;; configure org-jira + (use-package org-jira + :ensure (:host github :repo "ptillemans/org-jira" :branch "pti_fix_getUsers") + :commands (org-jira-get-issues org-jira-get-projects) + :config + (setq org-jira-users '(("Peter Tillemans". "557058:bdf83521-663b-4ae6-9b71-487bb98e2add"))) + (setq jiralib-agile-page-size 1000) + (setq org-jira-custom-jqls + '( + (:jql " assignee = currentUser() and (created > '2024-01-01' of updated > '2024-01-01) order by created DESC" + :limit 100 :filename "this-year") + (:jql "project = TTRK and (resolution = Unresolved OR updated>=-15d) ORDER BY priority DESC" + :limit 100 :filename "~/Projects/timetrak/jira") + )) + (make-directory "~/.org-jira" 'parents) + (setq jiralib-url (auth-source-pass-get "url" "customer/jira")) + (setq org-jira-custom-jqls + '((:jql " assignee = currentUser() and project = TTRK order by priority DESC " :limit 100 :filename "~/Projects/timetrak/jira") + (:jql " assignee = currentUser() and createdDate >= '2024-01-01' order by created DESC " :limit 100 :filename "this-years-work"))) + (jiralib-login + (auth-source-pass-get "user" "customer/jira") + (auth-source-pass-get 'secret "customer/jira")) + :bind (("C-c ig" . 'org-jira-get-issues) + ("C-c ip" . 'org-jira-get-projects) + ("C-c ij" . 'org-jira-get-issues-from-custom-jql))) +#+END_SRC + +#+RESULTS: +: [nil 26292 53013 676464 nil elpaca-process-queues nil nil 459000 nil] + +It is very useful to create for each active project a custom JQL to +make a snapshot of issues just for that project in the folder of the +project to keep everything in context. + + + +**** Keybindings + +| Key | Command | +|---------+------------------------------------------| +| C-c pg | org-jira-get-projects | +| C-c bg | org-jira-get-boards | +| C-c iv | org-jira-get-issues-by-board | +| C-c ib | org-jira-browse-issue | +| C-c ig | org-jira-get-issues | +| C-c ij | org-jira-get-issues-from-custom-jql | +| C-c ih | org-jira-get-issues-headonly | +| C-c if | org-jira-get-issues-from-filter-headonly | +| C-c iF | org-jira-get-issues-from-filter | +| C-c iu | org-jira-update-issue | +| C-c iw | org-jira-progress-issue | +| C-c in | org-jira-progress-issue-next | +| C-c ia | org-jira-assign-issue | +| C-c isr | org-jira-set-issue-reporter | +| C-c ir | org-jira-refresh-issue | +| C-c iR | org-jira-refresh-issues-in-buffer | +| C-c ic | org-jira-create-issue | +| C-c ik | org-jira-copy-current-issue-key | +| C-c sc | org-jira-create-subtask | +| C-c sg | org-jira-get-subtasks | +| C-c cc | org-jira-add-comment | +| C-c cu | org-jira-update-comment | +| C-c wu | org-jira-update-worklogs-from-org-clocks | +| C-c tj | org-jira-todo-to-jira | +| C-c if | org-jira-get-issues-by-fixversion | + +**** TODO add focused project support +There should be some things we can do to better integrate this with +projects: +- update issues in background when opening the project. +- run custom JQL defined in the project iso globally. + + +*** Daviwil's Productivity Tools + +@daviwil has a set of productivity tools which are very useful. I have + + +**** Find all tasks with a specific tag (or without) + +#+BEGIN_SRC emacs-lisp :tangle no + (setq org-agenda-custom-commands + '(("p" "Planning" tags-todo "+@planning"))) +#+END_SRC + +#+RESULTS: +| p | Planning | tags-todo | +@planning | + +We can remove tasks with a certain tag by adding `-@work` to the pattern. + +**** Find all tasks with a specific tag (or without) + + +#+BEGIN_SRC emacs-lisp :tangle no + (setq org-agenda-custom-commands + '(("u" "Untagged Tasks" tags-todo "-{.*}"))) +#+END_SRC + +#+RESULTS: +| u | Untagged Tasks | tags-todo | -{.*} | + +**** Combine multiple filters + +We can add a list of queries + +#+BEGIN_SRC emacs-lisp :tangle no + (setq org-agenda-custom-commands + '(("p" "Planning" ((tags-todo "+@planning") + (tags-todo "-{.*}"))))) +#+END_SRC + +#+RESULTS: +| p | Planning | ((tags-todo +@planning) (tags-todo -{.*})) | + +**** We can add settings to each filter + +#+BEGIN_SRC emacs-lisp :tangle no + (setq org-agenda-custom-commands + '(("p" "Planning" ((tags-todo "+@planning" + ((org-agenda-overriding-header "Planning Tasks"))) + (tags-todo "-{.*}" + ((org-agenda-overriding-header "Untagged Tasks"))))))) +#+END_SRC + +#+RESULTS: +| p | Planning | ((tags-todo +@planning ((org-agenda-overriding-header Planning Tasks))) (tags-todo -{.*} ((org-agenda-overriding-header Untagged Tasks)))) | + +**** Add support for an input file + +#+BEGIN_SRC emacs-lisp + (setq org-agenda-custom-commands + '(("i" "Inbox" ((todo ".*" + ((org-agenda-files '("~/Nextcloud/org/inbox.org")) + (org-agenda-overriding-header "Unprocessed Inbox Items"))))))) +#+END_SRC + +#+RESULTS: +| i | Inbox | ((todo .* ((org-agenda-files '(~/Nextcloud/org/inbox.org)) (org-agenda-overriding-header Unprocessed Inbox Items)))) | + + +**** Daily Agenda + +#+BEGIN_SRC emacs-lisp + (setq org-agenda-custom-commands + '(("d" "Daily Agenda" + ((agenda "" ((org-agenda-span 'day) + (org-deadline-warning-days 1) + (org-agenda-overriding-header "Today's Agenda"))) + (tags-todo "+PRIORITY=\"A\"" + ((org-agenda-overriding-header "High-Priority Unfinished Tasks") + )))))) +#+END_SRC + +#+RESULTS: +| d | Daily Agenda | ((agenda ((org-agenda-span 'day) (org-deadline-warning-days 1) (org-agenda-overriding-header Today's Agenda))) (tags-todo +PRIORITY="A" ((org-agenda-overriding-header High-priority unfinished tasks)))) | + + +**** Weekly Review + +#+BEGIN_SRC emacs-lisp + (setq org-log-done 'time) ; log the time when a task is completed + (setq org-agenda-start-with-log-mode t) ; show the log mode when starting the agenda + + (setq org-agenda-custom-commands + '(("w" "Weekly Review" + ((agenda "" ((org-agenda-overriding-header "Completed Tasks") + (org-agenda-skip-function (org-agenda-skip-entry-if 'nottodo 'done)) + (org-agenda-span 'week))) + (agenda "" ((org-agenda-overriding-header "Unfinished Scheduled Tasks") + (org-agenda-skip-function (org-agenda-skip-entry-if 'todo 'done)) + (org-agenda-span 'week))) + )))) +#+END_SRC + +#+RESULTS: +| w | Weekly Review | ((agenda ((org-agenda-overriding-header Completed Tasks) (org-agenda-skip-function (org-agenda-skip-entry-if 'nottodo 'done)) (org-agenda-span 'week))) (agenda ((org-agenda-overriding-header Unfinished Scheduled Tasks) (org-agenda-skip-function (org-agenda-skip-entry-if 'todo 'done)) (org-agenda-span 'week)))) | + + +** Denote + +#+BEGIN_SRC emacs-lisp + ;; configure denote + (use-package denote + :ensure t + :init + (setq denote-directory (file-name-concat (expand-file-name "~") "Nextcloud/denote")) + (setq denote-dired-directories + (list denote-directory + (expand-file-name "~/Documents/denote"))) + :hook (dired-mode . denote-dired-mode-in-directories) + :bind ( + (" n d" . (lambda () (interactive) (dired denote-directory))) + (" n n" . #'denote) + (" n N" . #'denote-type) + (" n c" . #'denote-link-or-create) + (" n t" . #'denote-template) + (" n z" . #'denote-signature) + (" n l" . #'denote-link) + (" n L" . #'denote-find-link) + (" n k" . #'denote-keywords-add) + (" n b" . #'denote-link-backlink) + (" n B" . #'denote-find-backlink) + (" n r" . #'denote-rename-file) + (" n R" . #'denote-rename-file-using-front-matter) + (" n f" . (lambda () (interactive) (consult-find denote-directory))))) +#+END_SRC + +**** TODO explain what denote-dired-mode-in-directories does. + * Communication and Interwebs #+BEGIN_SRC emacs-lisp