From 46b5b761bf161539c3f44cd7dbecf4114c4372ea Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 10 Jul 2020 17:46:20 +0200 Subject: Set visible Bell --- emacs-init.org | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 77a5662..fe10500 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -237,9 +237,10 @@ only. #+end_src ** GUI Interface Disable most of the user interface. - #+BEGIN_SRC emacs-lisp (use-package emacs + :custom + <> :config (tooltip-mode -1) (tool-bar-mode -1) @@ -247,6 +248,12 @@ Disable most of the user interface. (scroll-bar-mode -1) ) #+END_SRC + +Audible bell is useless when the sound is turned off and annoying when sound is on. Instead use visible bell. +#+begin_src emacs-lisp :tangle no :noweb-ref emacs-custom +(visible-bell t) +#+end_src + In /awesomewm/ and other tiling window managers the emacs window leaves a gap at the bottom. This removes it. #+BEGIN_SRC emacs-lisp -- cgit v1.2.3 From b31b02c8b881e9554db2c839924fc7883b61382c Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 10 Jul 2020 17:47:02 +0200 Subject: Increase refile targets level some more No performance impact yet.. --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index fe10500..0e9a27d 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2832,8 +2832,8 @@ As refile only works on file-visiting buffers, we need to filter all other org b #+begin_src emacs-lisp :noweb-ref org-custom :tangle no (org-refile-use-outline-path 'file) -(org-refile-targets '((buffer-file-name :maxlevel . 8) - (org-agenda-files :maxlevel . 5) +(org-refile-targets '((buffer-file-name :maxlevel . 12) + (org-agenda-files :maxlevel . 10) (fpi/org-file-buffer-list :maxlevel . 2))) #+end_src *** Time budgets -- cgit v1.2.3 From fb1790bd6228617b18aa7b43913078f985cfbcc4 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 10 Jul 2020 17:47:28 +0200 Subject: Add function to open bibtex pdf or directory Fallback to dired to let me execute `git annex get` on the missing pdf --- emacs-init.org | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 0e9a27d..5ce60a9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3333,12 +3333,26 @@ A small function to toggle the encryption state of the current entry. #+begin_src emacs-lisp (use-package org-ref :straight t + :bind (:map org-mode-map (("C-c n p" . fpi/open-bibtex-pdf-or-directory))) :custom (org-ref-bibliography-notes nil) (org-ref-notes-function 'org-ref-notes-function-many-files) (org-ref-notes-directory "~/git/projects/zettel/Lit") (org-ref-default-bibliography '("~/git/projects/personal/bib.bib")) - (org-ref-pdf-directory "~/git/projects/personal/Lit/")) + (org-ref-pdf-directory "~/git/projects/personal/Lit/") + :config + (defun fpi/open-bibtex-pdf-or-directory () + (interactive) + (save-excursion + (bibtex-beginning-of-entry) + (let* ((bibtex-expand-strings t) + (entry (bibtex-parse-entry t)) + (key (reftex-get-bib-field "=key=" entry)) + (pdf (funcall org-ref-get-pdf-filename-function key))) + (if (file-exists-p pdf) + (org-open-link-from-string (format "[[file:%s]]" pdf)) + (dired (file-name-directory pdf)) + (ding)))))) #+end_src ***** Capturing entries I store my bibtex references in an org file together with my notes. In -- cgit v1.2.3 From 160090f58e9e2b3a6d535f41008f8aca63a1bf95 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 13 Jul 2020 16:28:54 +0200 Subject: Update org-time-budgets definition to :blocks syntax --- emacs-init.org | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 5ce60a9..75dedac 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2843,9 +2843,9 @@ Gives an overview of time spent on defined budgets this week. Great to track if :straight (:host github :repo "fpiper/org-time-budgets" :branch "develop") :custom - (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :block workweek) - (:title "Research" :match "+work+research" :budget "24:00" :block total-only) - (:title "Teaching" :match "+work+teaching" :budget "8:00" :block total-only)))) + (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) + (:title "Research" :match "+work+research" :budget "24:00" :blocks (nil week)) + (:title "Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) #+end_src *** Column view #+begin_src emacs-lisp -- cgit v1.2.3 From b91ce7e27af3c0163d21cff34a17a554fef527e2 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 13 Jul 2020 19:15:03 +0200 Subject: Refile custom agendas & add fancy "o" agenda --- emacs-init.org | 172 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 123 insertions(+), 49 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 75dedac..e2b134c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2635,55 +2635,12 @@ Switch projects and subprojects from NEXT back to TODO" ;; See emacs.christianbaeuerlein.com/my-org-config.html (org-agenda-block-separator 9472) (org-agenda-custom-commands - `(("d" "Day agenda" - ((agenda "" ((org-agenda-span 'day))) - (org-time-budgets-in-agenda-maybe) - (tags-todo "/+INPROGRESS" - ((org-agenda-overriding-header "Active Tasks"))))) - ("w" . "Week agendas") - ("ww" "Standard week agenda" - ((agenda "" ((org-agenda-span 'week))))) - ("wn" "Next Week's agenda" - ((agenda "" ((org-agenda-span 'week) - (org-agenda-start-day "mon"))) - (tags-todo "+work"))) - ("n" "Agenda and all TODOs" - ((todo "INPROGRESS" - ((org-agenda-overriding-header "Inprogress Tasks"))) - (agenda) - (tags-todo "+soon+LEVEL=2" - ((org-agenda-overriding-header "2nd Level /Soon/ Tasks"))) - (tags-todo "+soon" - ((org-agenda-overriding-header "All /Soon/ Tasks"))) - (tags-todo "+shelve") - (tags-todo "+habit") - (todo "IDLE") - (tags-todo "-habit-shelve-soon-idle"))) - ("r" "Refile entries" ((tags "+REFILE"))) - ("i" "Idle Actions" - ((tags-todo "IDLE-READLIST-WATCH" - ((org-agenda-overriding-header "Idle Tasks") - (org-agenda-skip-function 'bh/skip-project-tasks) - (org-agenda-sorting-strategy - '(todo-state-down effort-up)))) - (tags-todo "READLIST" - ((org-agenda-overriding-header "Idle Reading List") - (org-agenda-sorting-strategy - '(todo-state-down effort-up)))) - (tags-todo "WATCH" - ((org-agenda-overriding-header "Things to Watch") - (org-agenda-skip-function 'bh/skip-project-tasks) - (org-agenda-sorting-strategy - '(todo-state-down effort-up)))))) - ("z" "Todos in org-roam-dir" - ((alltodo "" - ((org-agenda-files (fpi/collect-org-directories-recursively org-roam-directory)))))) - ("c" "Agenda and all todos in current directory" - ((agenda "" - ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))) - (alltodo "" - ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))))))) - ) + `( + <> + ))) +#+end_src + +#+begin_src emacs-lisp (use-package ob-core :custom (org-confirm-babel-evaluate nil)) @@ -2693,6 +2650,7 @@ Switch projects and subprojects from NEXT back to TODO" (use-package ol-notmuch) (use-package org-habit) #+end_src + #+begin_src emacs-lisp (use-package org-inlinetask) #+end_src @@ -2719,6 +2677,122 @@ Use imagemagick and standalone class for latex preview. (use-package org-num :delight) #+end_src +*** Org agenda custom commands +**** Task-related agendas +Simple day agenda with =INPROGRESS= tasks +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("d" "Day agenda" + ((agenda "" ((org-agenda-span 'day))) + (org-time-budgets-in-agenda-maybe) + (tags-todo "/+INPROGRESS" + ((org-agenda-overriding-header "Active Tasks"))))) +#+end_src +Agenda with all open tasks +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("n" "Agenda and all TODOs" + ((todo "INPROGRESS" + ((org-agenda-overriding-header "Inprogress Tasks"))) + (agenda) + (tags-todo "+soon+LEVEL=2" + ((org-agenda-overriding-header "2nd Level /Soon/ Tasks"))) + (tags-todo "+soon" + ((org-agenda-overriding-header "All /Soon/ Tasks"))) + (tags-todo "+shelve") + (tags-todo "+habit") + (todo "IDLE") + (tags-todo "-habit-shelve-soon-idle"))) +#+end_src +***** Fancy agenda to choose todays tasks +Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("o" "My Agenda" + ((agenda "" ((org-agenda-block-separator ? ) + (org-agenda-overriding-header "\n⚡ Deadlines:\n⎺⎺⎺⎺⎺⎺⎺⎺⎺") + (org-agenda-skip-function '(org-agenda-skip-entry-if 'notdeadline)) + (org-agenda-format-date (lambda (date) "")))) + (agenda* "" ((org-agenda-block-separator ? ) + (org-agenda-skip-function '(fpi/org-agenda-skip-if-not-today)) + (org-deadline-warning-days 0) + (org-agenda-todo-ignore-timestamp 'all) + (org-agenda-start-day "+0d") + (org-agenda-span 1) + (org-agenda-overriding-header "⚡ Schedule:\n⎺⎺⎺⎺⎺⎺⎺⎺⎺") + (org-agenda-repeating-timestamp-show-all nil) + (org-agenda-remove-tags t) + (org-agenda-use-time-grid t) + ;; (org-agenda-prefix-format " %-3i %30b %t%s") + (org-agenda-todo-keyword-format " ☐ ") + (org-agenda-current-time-string "⮜┈┈┈┈┈┈┈ now") + (org-agenda-scheduled-leaders '("" "")) + (org-agenda-time-grid (quote ((daily today remove-match) + (0900 1200 1500 1800 2100) + " " "┈┈┈┈┈┈┈┈┈┈┈┈┈"))))) + (org-time-budgets-in-agenda-maybe) + (agenda "" ((org-agenda-block-separator ? ) + (org-agenda-overriding-header "\n⚡ Scheduled Tasks:\n⎺⎺⎺⎺⎺⎺⎺⎺⎺") + (org-agenda-skip-function '(org-agenda-skip-entry-if 'notscheduled)) + (org-agenda-use-time-grid nil) + (org-agenda-format-date (lambda (date) "")))) + )) +#+end_src +#+begin_src emacs-lisp +(defun fpi/org-agenda-skip-if-not-today () + "Skip all scheduled entries and deadlines not due for today." + (let ((subtree-end (save-excursion (org-end-of-subtree t))) + (deadline-day + (when (org-entry-get nil "DEADLINE") + (time-to-days + (org-time-string-to-time + (org-entry-get nil "DEADLINE"))))) + (scheduled-day + (when (org-entry-get nil "SCHEDULED") + (time-to-days + (org-time-string-to-time + (org-entry-get nil "SCHEDULED"))))) + (now (time-to-days (current-time)))) + (and (or (and deadline-day + (not (= deadline-day now))) + (and scheduled-day + (not (= scheduled-day now)))) + subtree-end))) +#+end_src +**** Week agendas +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("w" . "Week agendas") +("ww" "Standard week agenda" + ((agenda "" ((org-agenda-span 'week))))) +("wn" "Next Week's agenda" + ((agenda "" ((org-agenda-span 'week) + (org-agenda-start-day "mon"))) + (tags-todo "+work"))) +#+end_src +**** Misc agendas +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("r" "Refile entries" ((tags "+REFILE"))) +("i" "Idle Actions" + ((tags-todo "IDLE-READLIST-WATCH" + ((org-agenda-overriding-header "Idle Tasks") + (org-agenda-skip-function 'bh/skip-project-tasks) + (org-agenda-sorting-strategy + '(todo-state-down effort-up)))) + (tags-todo "READLIST" + ((org-agenda-overriding-header "Idle Reading List") + (org-agenda-sorting-strategy + '(todo-state-down effort-up)))) + (tags-todo "WATCH" + ((org-agenda-overriding-header "Things to Watch") + (org-agenda-skip-function 'bh/skip-project-tasks) + (org-agenda-sorting-strategy + '(todo-state-down effort-up)))))) +("z" "Todos in org-roam-dir" + ((alltodo "" + ((org-agenda-files (fpi/collect-org-directories-recursively org-roam-directory)))))) +("c" "Agenda and all todos in current directory" + ((agenda "" + ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))) + (alltodo "" + ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))))) +#+end_src *** org-checklist #+begin_quote This file provides some functions for handing repeated tasks which involve -- cgit v1.2.3 From 70e238d8fc6cf67d7e413f15b657d67a6a400b72 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 14 Jul 2020 11:18:00 +0200 Subject: Update variable name --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index e2b134c..1ca6195 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2498,7 +2498,7 @@ Hansen's]] configs. ("omap" . "http://nominatim.openstreetmap.org/search?q=%s&polygon=1"))) (org-ellipsis " ") (org-outline-path-complete-in-steps nil) - (org-log-state-notes-into-drawer "NOTES") + (org-log-into-drawer "NOTES") (org-clock-into-drawer "LOGBOOK") (org-log-done 'time) (org-log-redeadline 'time) -- cgit v1.2.3 From bbe9ac6ad57ee8225f1310af620d6fea8ed1d919 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 14 Jul 2020 11:18:52 +0200 Subject: Fix biblio mode map key binding --- emacs-init.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 1ca6195..fc57fa7 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3474,7 +3474,9 @@ Here's a function to easily copy a doi from the results of =crossref-lookup=. (let ((doi (alist-get 'doi (cdr (biblio--selection-metadata-at-point))))) (kill-new doi) (message "Copied doi %s" doi))) -(define-key biblio-selection-mode-map "d" #'fpi/biblio-get-doi) +(use-package biblio + :bind (:map biblio-selection-mode-map + ("d" . fpi/biblio-get-doi))) #+end_src *** Todo settings - WAITING tasks are waiting on the completion of other tasks -- cgit v1.2.3 From 4caf1bae12abfb55dfe2ba43e4640e5044e5ef08 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 16 Jul 2020 22:49:33 +0200 Subject: Add support function for org-babel workflow --- emacs-init.org | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index fc57fa7..5831b64 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2980,6 +2980,14 @@ Gives an overview of time spent on defined budgets this week. Great to track if ("" . org-clock-convenience-fill-gap) ("" . org-clock-convenience-fill-gap-both))) #+end_src +*** Babel +This function is handy to use in header arguments to create names based on the current org heading. E.g. =:var data=(fpi/format-headline "/tmp/prefix_")= +#+begin_src emacs-lisp +(defun fpi/format-headline (&optional pre post) + (let ((pre (or pre "")) + (post (or post ""))) + (format "%s%s%s" pre (nth 4 (org-heading-components)) post))) +#+end_src *** ox-reveal #+BEGIN_SRC emacs-lisp (use-package ox-reveal -- cgit v1.2.3 From 4b28a9ac4cee99d10acdaf7b1af2ae409b5b02e8 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 17 Jul 2020 17:02:00 +0200 Subject: Add keyboard-quit-strong to avoid C-g C-g C-g C-g --- emacs-init.org | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 5831b64..87e9c03 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1469,8 +1469,29 @@ Goes backward if ARG is negative; error if CHAR not found." (backward-char) (forward-char)) (point)))) + <> :bind (:map global-map - ("M-z" . zap-up-to-char))) + ("M-z" . zap-up-to-char) + <> + )) +#+end_src +Use a hard ~keyboard-quit~. This is from Jeff Norden ([[https://lists.gnu.org/archive/html/emacs-devel/2020-07/msg00326.html][Message on emacs-devel]]). +#+begin_src emacs-lisp :tangle no :noweb-ref simple-config +(defun keyboard-quit-strong () + "Run `keyboard-quit' to return emacs to a more responsive state. +If repeated twice in a row, run `top-level' instead, to also exit +any recursive editing levels." + (interactive) + (when (eq last-command 'keyboard-quit-strong) + (setq this-command 'top-level) ;dis-arm a 3rd C-g + (ding) + (top-level)) + ;; Not reached after `top-level'. (A rare behavior in lisp.) + (keyboard-quit)) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref simple-bindings +("C-g" . keyboard-quit-strong) #+end_src * Selection and search methods ** Completion frameworks -- cgit v1.2.3 From 4b463f72a0483fb0bdd217c5df7a7f849c6a5f60 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 15 Jul 2020 13:26:23 +0200 Subject: Bundle task organization related settings --- emacs-init.org | 330 +++++++++++++++++++++++++++------------------------------ 1 file changed, 155 insertions(+), 175 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 87e9c03..f3a0f44 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2521,25 +2521,6 @@ Hansen's]] configs. (org-outline-path-complete-in-steps nil) (org-log-into-drawer "NOTES") (org-clock-into-drawer "LOGBOOK") - (org-log-done 'time) - (org-log-redeadline 'time) - (org-log-reschedule 'time) - (org-todo-keywords '((sequence "PLANNING(p)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") - (sequence "S(s)" "DONE(d)") - (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)") - (sequence "TODO(t)" "|" "DONE(d)") - (sequence "IDLE(a)"))) - (org-use-fast-todo-selection t) - (org-todo-keyword-faces - '(("NEXT" :foreground "light blue" :weight bold) - ("INPROGRESS" :foreground "burlywood" :weight bold) - ("DONE" :foreground "forest green" :weight bold) - ("WAITING" :foreground "orange" :weight bold) - ("ICEBOX" :foreground "orange" :weight normal) - ("CANCELLED" :foreground "forest green" :weight bold) - ("MEETING" :foreground "yellow" :weight bold) - ("PHONE" :foreground "yellow" :weight bold) - ("IDLE" :foreground "magenta" :weight bold))) (org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) (org-tags-column 0) <> @@ -2698,8 +2679,86 @@ Use imagemagick and standalone class for latex preview. (use-package org-num :delight) #+end_src -*** Org agenda custom commands -**** Task-related agendas +*** Task organization +**** Todo settings +- WAITING tasks are waiting on the completion of other tasks +- NEXT tasks can be picked up +- INPROGRESS are current tasks with time clocked +- DONE are complete tasks +- ICEBOX tasks are on ice for whatever reason + +TODO->DONE cycle is for habits.\\ +Idle states cover things to do for time in between, checking the +inbox, reading news, … + +Phonecalls? + +#+BEGIN_SRC dot :file /tmp/todo.png +digraph hierarch{ + node [shape=box] + // Tasks, Projects + PLANNING -> NEXT, INPROGRESS, ICEBOX + WAITING -> NEXT -> INPROGRESS -> DONE, WAITING, ICEBOX + NEXT -> WAITING -> INPROGRESS, ICEBOX + NEXT -> ICEBOX, DONE + + // stuff for idle time + IDLE -> IDLE + //NEXT -> DONE + + // Phonecalls, Meetings + PHONE -> DONE, CANCELED + MEETING -> DONE, CANCELED +} +#+END_SRC + +#+RESULTS: +[[file:/tmp/todo.png]] + +#+begin_src emacs-lisp :noweb-ref org-custom :tangle no +(org-todo-keywords '((sequence "PLANNING(p)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") + (sequence "S(s)" "DONE(d)") + (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)") + (sequence "TODO(t)" "|" "DONE(d)") + (sequence "IDLE(a)"))) +(org-use-fast-todo-selection t) +(org-todo-keyword-faces + '(("NEXT" :foreground "light blue" :weight bold) + ("INPROGRESS" :foreground "burlywood" :weight bold) + ("DONE" :foreground "forest green" :weight bold) + ("WAITING" :foreground "orange" :weight bold) + ("ICEBOX" :foreground "orange" :weight normal) + ("CANCELLED" :foreground "forest green" :weight bold) + ("MEETING" :foreground "yellow" :weight bold) + ("PHONE" :foreground "yellow" :weight bold) + ("IDLE" :foreground "magenta" :weight bold))) +#+end_src + +Switch a todo entry from NEXT to INPROGRESS when clocking in. +#+begin_src emacs-lisp :tangle no +(setq org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) +(defun bh/clock-in-to-inprogress (kw) + "Switch a task from NEXT to INPROGRESS when clocking in. +Skips capture tasks, projects, and subprojects. +Switch projects and subprojects from NEXT back to TODO" + (when (not (and (boundp 'org-capture-mode) org-capture-mode)) + (cond + ((and (member (org-get-todo-state) (list "NEXT")) + (bh/is-task-p)) + "INPROGRESS") + ((and (member (org-get-todo-state) (list "NEXT")) + (bh/is-project-p)) + "INPROGRESS")))) +#+end_src +***** State changes +Track state changes to done & changes to schedules and deadlines. +#+begin_src emacs-lisp :tangle no :noweb-ref org-custom +(org-log-done 'time) +(org-log-redeadline 'time) +(org-log-reschedule 'time) +#+end_src +**** Org agenda custom commands +***** Task-related agendas Simple day agenda with =INPROGRESS= tasks #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("d" "Day agenda" @@ -2723,7 +2782,7 @@ Agenda with all open tasks (todo "IDLE") (tags-todo "-habit-shelve-soon-idle"))) #+end_src -***** Fancy agenda to choose todays tasks +****** Fancy agenda to choose todays tasks Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("o" "My Agenda" @@ -2777,7 +2836,7 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (not (= scheduled-day now)))) subtree-end))) #+end_src -**** Week agendas +***** Week agendas #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("w" . "Week agendas") ("ww" "Standard week agenda" @@ -2787,7 +2846,7 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (org-agenda-start-day "mon"))) (tags-todo "+work"))) #+end_src -**** Misc agendas +***** Misc agendas #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("r" "Refile entries" ((tags "+REFILE"))) ("i" "Idle Actions" @@ -2814,6 +2873,78 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (alltodo "" ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))))) #+end_src +**** Refile +Use the full outline path so I can distinguish headlines with the same name & disable step-wise completion as I think from the refile target backwards, not from top-level downwards. Also include the current file's headings as a refile targets up to a deep level, all agenda files up to a small level and all open org files up to an even smaller level. + +As refile only works on file-visiting buffers, we need to filter all other org buffers from ~(org-buffer-list)~. +#+begin_src emacs-lisp +(defun fpi/org-file-buffer-list () + "Return a list of org buffers which visit files." + (seq-filter 'buffer-file-name (org-buffer-list))) +#+end_src + +#+begin_src emacs-lisp :noweb-ref org-custom :tangle no +(org-refile-use-outline-path 'file) +(org-refile-targets '((buffer-file-name :maxlevel . 12) + (org-agenda-files :maxlevel . 10) + (fpi/org-file-buffer-list :maxlevel . 2))) +#+end_src +**** Time budgets +Gives an overview of time spent on defined budgets this week. Great to track if you've worked enough hours. To use it add ~(org-time-budgets-in-agenda-maybe)~ after ~(agenda)~ in a custom agenda command. +#+begin_src emacs-lisp +(use-package org-time-budgets + :straight (:host github :repo "fpiper/org-time-budgets" + :branch "develop") + :custom + (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) + (:title "Research" :match "+work+research" :budget "24:00" :blocks (nil week)) + (:title "Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) +#+end_src +**** Column view +#+begin_src emacs-lisp +(setq org-columns-default-format + "%50ITEM(Task) %5Effort(Effort){:} %5CLOCKSUM %3PRIORITY %20DEADLINE %20SCHEDULED %20TIMESTAMP %TODO %CATEGORY %TAGS") +#+end_src +**** Clocking +***** Combine adjacent clock lines +#+begin_src emacs-lisp +(defun fpi/org-clock-join-last-clock () + "Join current clock with last one if start/end point match." + (save-mark-and-excursion + (beginning-of-line) + (let* ((eol (save-excursion (end-of-line) (point))) + (boi (progn (re-search-forward "\\[" eol t) (backward-char) (point))) + (eoi (progn (re-search-forward "\\]" eol t) (point))) + (i (buffer-substring-no-properties boi eoi)) ;; last clock-in-time + (boc (progn (re-search-forward "\\[" eol t) (backward-char) (point))) + (eoc (progn (re-search-forward "\\]" eol t) (point))) + (c (buffer-substring-no-properties boc eoc))) ;; last clock-out-time (equals org-clock-out-time if last clock) + (next-line) + (end-of-line) + (let* ((bol (save-excursion (beginning-of-line) (point))) + (eoo (progn (re-search-backward "\\]" bol t) (forward-char) (point))) + (boo (progn (re-search-backward "\\[" bol t) (point))) + (o (buffer-substring-no-properties boo eoo))) ;; last-last clock-out-time + (when (equal i o) + (delete-region boo eoo) + ;; (insert (format-time-string (org-time-stamp-format t t) org-clock-out-time)) + (insert c) + (org-evaluate-time-range) + (previous-line) + (delete-region (save-excursion (beginning-of-line) (backward-char) (point)) eol) + (message (format "Joined nearby clocks at %s" i))))))) +(add-hook 'org-clock-out-hook 'fpi/org-clock-join-last-clock) +#+end_src +***** org-clock-convenience +#+begin_src emacs-lisp +(use-package org-clock-convenience + :straight t + :bind (:map org-agenda-mode-map + ("" . org-clock-convenience-timestamp-up) + ("" . org-clock-convenience-timestamp-down) + ("" . org-clock-convenience-fill-gap) + ("" . org-clock-convenience-fill-gap-both))) +#+end_src *** org-checklist #+begin_quote This file provides some functions for handing repeated tasks which involve @@ -2915,38 +3046,6 @@ Also display remote images by downloading them. #+begin_src emacs-lisp :noweb-ref ob-hooks :tangle no (org-babel-after-execute . org-display-inline-images) #+end_src -*** Refile -Use the full outline path so I can distinguish headlines with the same name & disable step-wise completion as I think from the refile target backwards, not from top-level downwards. Also include the current file's headings as a refile targets up to a deep level, all agenda files up to a small level and all open org files up to an even smaller level. - -As refile only works on file-visiting buffers, we need to filter all other org buffers from ~(org-buffer-list)~. -#+begin_src emacs-lisp -(defun fpi/org-file-buffer-list () - "Return a list of org buffers which visit files." - (seq-filter 'buffer-file-name (org-buffer-list))) -#+end_src - -#+begin_src emacs-lisp :noweb-ref org-custom :tangle no -(org-refile-use-outline-path 'file) -(org-refile-targets '((buffer-file-name :maxlevel . 12) - (org-agenda-files :maxlevel . 10) - (fpi/org-file-buffer-list :maxlevel . 2))) -#+end_src -*** Time budgets -Gives an overview of time spent on defined budgets this week. Great to track if you've worked enough hours. To use it add ~(org-time-budgets-in-agenda-maybe)~ after ~(agenda)~ in a custom agenda command. -#+begin_src emacs-lisp -(use-package org-time-budgets - :straight (:host github :repo "fpiper/org-time-budgets" - :branch "develop") - :custom - (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) - (:title "Research" :match "+work+research" :budget "24:00" :blocks (nil week)) - (:title "Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) -#+end_src -*** Column view -#+begin_src emacs-lisp -(setq org-columns-default-format - "%50ITEM(Task) %5Effort(Effort){:} %5CLOCKSUM %3PRIORITY %20DEADLINE %20SCHEDULED %20TIMESTAMP %TODO %CATEGORY %TAGS") -#+end_src *** org-caldav #+begin_src emacs-lisp (use-package org-caldav @@ -2961,46 +3060,6 @@ Gives an overview of time spent on defined budgets this week. Great to track if (org-caldav-exclude-tags '(nocal)) ) #+end_src -*** Clocking -**** Combine adjacent clock lines -#+begin_src emacs-lisp -(defun fpi/org-clock-join-last-clock () - "Join current clock with last one if start/end point match." - (save-mark-and-excursion - (beginning-of-line) - (let* ((eol (save-excursion (end-of-line) (point))) - (boi (progn (re-search-forward "\\[" eol t) (backward-char) (point))) - (eoi (progn (re-search-forward "\\]" eol t) (point))) - (i (buffer-substring-no-properties boi eoi)) ;; last clock-in-time - (boc (progn (re-search-forward "\\[" eol t) (backward-char) (point))) - (eoc (progn (re-search-forward "\\]" eol t) (point))) - (c (buffer-substring-no-properties boc eoc))) ;; last clock-out-time (equals org-clock-out-time if last clock) - (next-line) - (end-of-line) - (let* ((bol (save-excursion (beginning-of-line) (point))) - (eoo (progn (re-search-backward "\\]" bol t) (forward-char) (point))) - (boo (progn (re-search-backward "\\[" bol t) (point))) - (o (buffer-substring-no-properties boo eoo))) ;; last-last clock-out-time - (when (equal i o) - (delete-region boo eoo) - ;; (insert (format-time-string (org-time-stamp-format t t) org-clock-out-time)) - (insert c) - (org-evaluate-time-range) - (previous-line) - (delete-region (save-excursion (beginning-of-line) (backward-char) (point)) eol) - (message (format "Joined nearby clocks at %s" i))))))) -(add-hook 'org-clock-out-hook 'fpi/org-clock-join-last-clock) -#+end_src -**** org-clock-convenience -#+begin_src emacs-lisp -(use-package org-clock-convenience - :straight t - :bind (:map org-agenda-mode-map - ("" . org-clock-convenience-timestamp-up) - ("" . org-clock-convenience-timestamp-down) - ("" . org-clock-convenience-fill-gap) - ("" . org-clock-convenience-fill-gap-both))) -#+end_src *** Babel This function is handy to use in header arguments to create names based on the current org heading. E.g. =:var data=(fpi/format-headline "/tmp/prefix_")= #+begin_src emacs-lisp @@ -3507,85 +3566,6 @@ Here's a function to easily copy a doi from the results of =crossref-lookup=. :bind (:map biblio-selection-mode-map ("d" . fpi/biblio-get-doi))) #+end_src -*** Todo settings -- WAITING tasks are waiting on the completion of other tasks -- NEXT tasks can be picked up -- INPROGRESS are current tasks with time clocked -- DONE are complete tasks -- ICEBOX tasks are on ice for whatever reason - -TODO->DONE cycle is for habits.\\ -Idle states cover things to do for time in between, checking the -inbox, reading news, … - -Phonecalls? - -#+BEGIN_SRC dot :file /tmp/todo.png -digraph hierarch{ - node [shape=box] - // Tasks, Projects - PLANNING -> NEXT, INPROGRESS, ICEBOX - WAITING -> NEXT -> INPROGRESS -> DONE, WAITING, ICEBOX - NEXT -> WAITING -> INPROGRESS, ICEBOX - NEXT -> ICEBOX, DONE - - // stuff for idle time - IDLE -> IDLE - //NEXT -> DONE - - // Phonecalls, Meetings - PHONE -> DONE, CANCELED - MEETING -> DONE, CANCELED -} -#+END_SRC - -#+RESULTS: -[[file:/tmp/todo.png]] - -#+BEGIN_SRC emacs-lisp :tangle no -(setq org-todo-keywords '((sequence "PLANNING(p)" "NEXT(n)" "INPROGRESS(i)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") - (sequence "S(s)" "DONE(d)") - (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)") - (sequence "TODO(t)" "|" "DONE(d)") - (sequence "IDLE(a)"))) -(setq org-use-fast-todo-selection t) - - -(setq org-todo-keyword-faces - '(("NEXT" :foreground "light blue" :weight bold) - ("INPROGRESS" :foreground "burlywood" :weight bold) - ("DONE" :foreground "forest green" :weight bold) - ("WAITING" :foreground "orange" :weight bold) - ("ICEBOX" :foreground "orange" :weight normal) - ("CANCELLED" :foreground "forest green" :weight bold) - ("MEETING" :foreground "yellow" :weight bold) - ("PHONE" :foreground "yellow" :weight bold) - ("IDLE" :foreground "magenta" :weight bold))) -#+END_SRC - -Switch a todo entry from NEXT to INPROGRESS when clocking in. -#+begin_src emacs-lisp :tangle no -(setq org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) -(defun bh/clock-in-to-inprogress (kw) - "Switch a task from NEXT to INPROGRESS when clocking in. -Skips capture tasks, projects, and subprojects. -Switch projects and subprojects from NEXT back to TODO" - (when (not (and (boundp 'org-capture-mode) org-capture-mode)) - (cond - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-task-p)) - "INPROGRESS") - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-project-p)) - "INPROGRESS")))) -#+end_src -**** State changes -Track state changes to done & changes to schedules and deadlines. -#+begin_src emacs-lisp :tangle no -(setq org-log-done 'time) -(setq org-log-redeadline 'time) -(setq org-log-reschedule 'time) -#+end_src *** Toggle drawer visibility #+begin_src emacs-lisp (setq fpi/org-meta-heading-info-store nil) -- cgit v1.2.3 From 401a3d11b8a155d9f75507c3e5faa020d33ad961 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 16 Jul 2020 08:39:19 +0200 Subject: Update todo keywords for projects, ... Add ACTIVE keyword to use for projects. HOLD for project tasks waiting for other tasks. --- emacs-init.org | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index f3a0f44..dd7a764 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2716,21 +2716,23 @@ digraph hierarch{ [[file:/tmp/todo.png]] #+begin_src emacs-lisp :noweb-ref org-custom :tangle no -(org-todo-keywords '((sequence "PLANNING(p)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") - (sequence "S(s)" "DONE(d)") - (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)") - (sequence "TODO(t)" "|" "DONE(d)") - (sequence "IDLE(a)"))) +(org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos + (sequence "PLANNING(p)" "TODO(t)" "ACTIVE(a)" "|" "CANCELLED(c)" "DONE(d)") ;;projects + (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)" "DONE(d)") + (sequence "TODO(t)" "|" "DONE(d)") ;;habits + (sequence "IDLE(b)"))) (org-use-fast-todo-selection t) (org-todo-keyword-faces - '(("NEXT" :foreground "light blue" :weight bold) + '(("HOLD" :foreground "light gray" :weight bold) + ("NEXT" :foreground "light blue" :weight bold) ("INPROGRESS" :foreground "burlywood" :weight bold) + ("ACTIVE" :foreground "chocolate" :weight bold) ("DONE" :foreground "forest green" :weight bold) ("WAITING" :foreground "orange" :weight bold) ("ICEBOX" :foreground "orange" :weight normal) ("CANCELLED" :foreground "forest green" :weight bold) - ("MEETING" :foreground "yellow" :weight bold) - ("PHONE" :foreground "yellow" :weight bold) + ("MEETING" :foreground "yellow3" :weight bold) + ("PHONE" :foreground "yellow3" :weight bold) ("IDLE" :foreground "magenta" :weight bold))) #+end_src -- cgit v1.2.3 From 7429d4edea4219ba0b5b8565ad2bd6752c20e2c7 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 20 Jul 2020 11:03:11 +0200 Subject: Collect safe-local-variable-values definitions --- emacs-init.org | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index dd7a764..59e3812 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -92,8 +92,7 @@ header argument in the source code. ;; package.el to enable use of list-packages <> -;; (setq safe-local-variable-values (list (cons 'buffer-auto-save-file-name nil) - ;; (cons 'header-line-format " "))) + (setq vc-follow-symlinks t) ;; For use on Windows via SSH X-Forwarding @@ -1406,6 +1405,29 @@ Remember where point is in a file. (kept-old-versions 2) (create-lockfiles nil)) #+end_src +** Local variables +#+begin_src emacs-lisp +(use-package files + :custom + <> + ) +#+end_src + +[[info:emacs#File Variables][File Variables]] are useful to ensure same behaviour in some files with different emacs configurations or to change behaviour from the default for one file. +Some settings could be harmful to emacs and the underlying system. Therefore many settings have to be declared as safe before using them. +#+begin_src emacs-lisp :tangle no :noweb-ref files-custom +(safe-local-variable-values + '((whitespace-style face trailing space-before-tab indentation empty space-after-tab newline-mark) + (eval set-window-buffer nil (current-buffer)) + (right-margin-width . 2) + (left-margin-width . 2) + (line-spacing . 0.2) + (after-save-hook org-babel-tangle) + (header-line-format . " ") + (after-save-hook . (org-babel-tangle)) + <> +)) +#+end_src ** Personal keymap Unfortunately =C-c [a-z]= is not always a safe place for user-defined @@ -2160,15 +2182,12 @@ some safe local variable values. :delight :straight t :custom - (gac-automatically-push-p nil) - :config - (add-to-list 'safe-local-variable-values - '(eval add-hook - (quote after-save-hook) - (quote gac-after-save-func) - t t)) - (add-to-list 'safe-local-variable-values - '(git-auto-commit-mode . t))) + (gac-automatically-push-p nil)) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref safe-local-variable-values +(git-auto-commit-mode . t) +(gac-debounce-interval . 600) #+end_src ** Projectile -- cgit v1.2.3 From 37ea381b194325aeab99dc0fe5b3e41e6c15e960 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 20 Jul 2020 10:57:57 +0200 Subject: Enable twoway org <-> caldav sync --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 59e3812..2ef5161 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3076,9 +3076,9 @@ Also display remote images by downloading them. (org-caldav-calendar-id private/calendar-id) (org-caldav-inbox "~/sync/w.org") (org-caldav-files nil) - (org-caldav-sync-direction 'cal->org) + (org-caldav-sync-direction 'twoway) (org-caldav-delete-calendar-entries 'never) - (org-caldav-exclude-tags '(nocal)) + (org-caldav-exclude-tags nil) ) #+end_src *** Babel -- cgit v1.2.3 From 86378d27977c5220f01b6b63fbfeca1add6d18e5 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 20 Jul 2020 10:58:10 +0200 Subject: Disable byte-compilation for org-time-budgets Byte compiling breaks due to my poorly defined function. --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 2ef5161..8944598 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2915,7 +2915,8 @@ Gives an overview of time spent on defined budgets this week. Great to track if #+begin_src emacs-lisp (use-package org-time-budgets :straight (:host github :repo "fpiper/org-time-budgets" - :branch "develop") + :branch "develop" + :no-byte-compile t) :custom (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) (:title "Research" :match "+work+research" :budget "24:00" :blocks (nil week)) -- cgit v1.2.3 From fef3d648c965670e832888a8aa41b5621437cbe6 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:26:49 +0200 Subject: Set no-inheritance tags in the proper location --- emacs-init.org | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 8944598..ee1e26b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -30,10 +30,13 @@ disable ~buffer-auto-save-file-name~ for the files. (use-package org-crypt :config (org-crypt-use-before-save-magic) :custom - (org-tags-exclude-from-inheritance (quote ("crypt"))) (org-crypt-key "F1EF502F9E81D81381B1679AF973BBEA6994521B")) #+END_SRC +#+BEGIN_SRC emacs-lisp :noweb-ref org-custom-no-inheritance-tags :tangle no +"crypt" +#+END_SRC + I use =.org= configuration files also for my other dotfiles. To ensure they are tangled upon save I use this function. #+NAME: tangle-hook @@ -2542,11 +2545,14 @@ Hansen's]] configs. (org-clock-into-drawer "LOGBOOK") (org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) (org-tags-column 0) + (org-tags-exclude-from-inheritance '( + <> + )) <> :config (add-hook 'org-mode-hook 'turn-on-org-cdlatex) (add-to-list 'org-structure-template-alist (cons "f" "figure")) - (add-to-list 'org-tags-exclude-from-inheritance "MARKED") + ;; (add-to-list 'org-tags-exclude-from-inheritance "MARKED") (defun bh/clock-in-to-inprogress (kw) "Switch a task from NEXT to INPROGRESS when clocking in. Skips capture tasks, projects, and subprojects. -- cgit v1.2.3 From 769cd83a080d9babe7433ac524a08127cdb8e755 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:27:10 +0200 Subject: Use other-window for org src edits --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index ee1e26b..c4c4923 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2631,7 +2631,7 @@ Switch projects and subprojects from NEXT back to TODO" ) (use-package org-src :custom - (org-src-window-setup 'current-window) + (org-src-window-setup 'other-window) (org-src-fontify-natively t) (org-src-tab-acts-natively t) (org-edit-src-content-indentation 0)) -- cgit v1.2.3 From e618ef15ef52fd5af24705b0993659e7ce4396b2 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:27:40 +0200 Subject: Delight org-edna --- emacs-init.org | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index c4c4923..432ff48 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3158,17 +3158,12 @@ Fix for hanging emacs. The original function calls file-exist-p which opens a sl :PROPERTIES: :ID: fd3936c7-9fc5-42d0-990d-32024e23b22f :END: -=Org-edna= is a great tool to manage =TODO= dependencies. I mainly use -it to mark tasks as =NEXT= after switching another task to =DONE=. The -functions below are taken from Josh's Emacs Config over at [[https://github.com/mm--/dot-emacs/blob/master/jmm-org-config.org][Github]]. He -wrote wrote a =edna-finder= which allows link descriptions and a nice -hydra to manage the various =org-edna= properties. I call it in my -[[id:22750e48-aaee-4f60-bdce-1d511ebe3375][context aware hydra]] when on an org headline. For more functions and -explanations checkout his config. +=Org-edna= is a great tool to manage =TODO= dependencies. I mainly use it to mark tasks as =NEXT= after switching another task to =DONE=. The functions below are taken from Josh's Emacs Config over at [[https://github.com/mm--/dot-emacs/blob/master/jmm-org-config.org][Github]]. He wrote a =edna-finder= which allows link descriptions and a nice hydra to manage the various =org-edna= properties. I call it in my [[id:22750e48-aaee-4f60-bdce-1d511ebe3375][context aware hydra]] when on an org headline. For more functions and explanations checkout his config. #+begin_src emacs-lisp (use-package org-edna :straight t :after org + :delight :config (org-edna-load) (defun org-edna-finder/link-ids (&rest ids) -- cgit v1.2.3 From d530df8b9ae88d15a6426b9008e25fbe5de82ebc Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:27:46 +0200 Subject: Make time-budgets display fancier --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 432ff48..7eee49c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2925,8 +2925,8 @@ Gives an overview of time spent on defined budgets this week. Great to track if :no-byte-compile t) :custom (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) - (:title "Research" :match "+work+research" :budget "24:00" :blocks (nil week)) - (:title "Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) + (:title "├Research" :match "+work+research" :budget "24:00" :blocks (nil week)) + (:title "╰Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) #+end_src **** Column view #+begin_src emacs-lisp -- cgit v1.2.3 From ad75caf16749bf2435ffa7a12661059f133cfad2 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:32:03 +0200 Subject: Add git annex support Mostly copied from https://github.com/mm--/dot-emacs/blob/master/jmm-emacs.org --- emacs-init.org | 334 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 333 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 7eee49c..660e3be 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1946,7 +1946,10 @@ confines of word boundaries (e.g. multiple words)." :hook (dired-mode . dired-hide-details-mode) (dired-mode . hl-line-mode) - (dired-mode . auto-revert-mode)) + (dired-mode . auto-revert-mode) + :bind (:map dired-mode-map + <> + )) (use-package find-dired :after dired @@ -2074,6 +2077,335 @@ of src_shell{getconf "PATH"}. See [[elisp:(describe-variable (add-to-list 'tramp-remote-path 'tramp-own-remote-path)) #+end_src ** Git +*** Git annex +There are some great ressources on [[https://git-annex.branchable.com/][git-annex]] integration in emacs in [[https://github.com/mm--/dot-emacs/blob/master/jmm-emacs.org][Josh's config]]. Most of my configuration is copied from there. +#+begin_src emacs-lisp +(use-package git-annex + :straight t + :config + <> + :bind + (:map git-annex-dired-map + <>) + :after (dired)) +#+end_src +**** Actions to lock/unlock files +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("l" . git-annex-dired-lock-files) +("u" . git-annex-dired-unlock-files) +#+end_src +=git-annex.el= defines a handy macro to define generic =git-annex= CLI calls. +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-config +(git-annex-dired-do-to-files "lock" "Annex: locked %d file(s)") +(git-annex-dired-do-to-files "unlock" "Annex: unlocked %d file(s)") +#+end_src +**** Fix faces +=git-annex.el= kinda clobbers ~dired-marked-face~ and ~dired-flagged-face~. This fixes that. +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-config +(progn + (add-to-list 'dired-font-lock-keywords + (list "^[*].+ -> .*\\.git/annex/" + '("\\(.+\\)\\( -> .+\\)" (dired-move-to-filename) nil + (1 dired-marked-face) + (2 git-annex-dired-annexed-invisible)))) + (add-to-list 'dired-font-lock-keywords + (list "^[D].+ -> .*\\.git/annex/" + '("\\(.+\\)\\( -> .+\\)" (dired-move-to-filename) nil + (1 dired-flagged-face) + (2 git-annex-dired-annexed-invisible))))) +#+end_src +**** Make it easy to add metadata tags in git-annex +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("t" . jmm/dired-git-annex-tag) +#+end_src +Git-annex has a pretty cool ability to tag files and filter directory views based on metadata. It's kind of a pain to tag files, though, so here's a function that adds some autocompletion to tagging files. +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +(defvar-local jmm/git-annex-directory-tags nil + "Current git-annex tags set in the directory, as a list.") + +(defun jmm/dired-git-annex-current-tags (file-list &optional intersection) + "Get current git-annex tag for each file in FILE-LIST. With + optional argument INTERSECTION, only show tags all files share in common." + (let* ((metadata (with-output-to-string + (with-current-buffer + standard-output + (apply #'process-file "git" nil t nil "annex" "metadata" "--json" file-list)))) + (json-array-type 'list) + (jsonout (-map 'json-read-from-string (split-string metadata "\n" t)))) + (-reduce (if intersection '-intersection '-union) (--map (cdr (assoc 'tag (cdr (assoc 'fields it)))) jsonout)))) + +(defun jmm/dired-git-annex-tag (file-list tags &optional arg) + "Add git-annex TAGS to each file in FILE-LIST. +Used as an interactive command, prompt for a list of tags for all +files, showing the current tags all files currently have in common." + (interactive + (let* ((files (dired-get-marked-files t current-prefix-arg)) + (shared-tags (jmm/dired-git-annex-current-tags files t)) + ;; Cache directory tags + (current-tags (or jmm/git-annex-directory-tags + (setq jmm/git-annex-directory-tags + (or (jmm/dired-git-annex-current-tags '("--all")) '(""))))) + (crm-separator " ") + (crm-local-completion-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map crm-local-completion-map) + (define-key map " " 'self-insert-command) + map)) + (tags (completing-read-multiple + "Tags: " (--map (concat it crm-separator) current-tags) + nil nil + (when shared-tags (mapconcat 'identity shared-tags " "))))) + (setq jmm/git-annex-directory-tags (-union tags jmm/git-annex-directory-tags)) + (list files tags current-prefix-arg))) + (let ((args (cl-loop for x in tags + append (list "-t" x)))) + (-each file-list + (lambda (file) + (apply #'call-process "git" nil nil nil "annex" "metadata" (append args (list file))))) + (message (format "Tagged %d file(s)" (length file-list))))) +#+END_SRC +**** Mark unavailable files +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("*") +("* a" . jmm/dired-mark-git-annex-available-files) +("* u" . jmm/dired-mark-git-annex-unavailable-files) +#+end_src + +When you use this in combination with ~dired-do-kill-lines~ (by default bound to ~k~), it's easy to hide files that aren't present in the current annex repository. +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +(defun jmm/dired-mark-git-annex-unavailable-files () + "Mark git-annex files that are not present." + (interactive) + (dired-mark-if + (and (looking-at-p ".* -> \\(.*\\.git/annex/.+\\)") + (not (file-exists-p (file-truename (dired-get-filename t))))) + "unavailable file")) + +(defun jmm/dired-mark-git-annex-available-files () + "Mark git-annex files that are present." + (interactive) + (dired-mark-if + (and (looking-at-p ".* -> \\(.*\\.git/annex/.+\\)") + (file-exists-p (file-truename (dired-get-filename t)))) + "available file")) +#+END_SRC +**** Mark git-annex files with git-annex-matching-options +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref dired-bindings +("% a" . jmm/dired-mark-files-git-annex-matching) +#+END_SRC + +This command makes it easy to mark dired files using ~git-annex-matching-options~. + +For instance, you could find files that are in a certain remote using ~--in=remote~ or mark/unmark files that have a certain tag using ~--metadata tag=sometag~. +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +(defun jmm/dired-mark-files-git-annex-matching (matchingoptions &optional marker-char) + "Mark all files that match git annex's MATCHINGOPTIONS for use in later commands. +A prefix argument means to unmark them instead. +`.' and `..' are never marked." + (interactive + (list (read-string (concat (if current-prefix-arg "Unmark" "Mark") + " files matching (git annex match expression): ") + nil 'jmm-dired-annex-matchingoptions-history) + (if current-prefix-arg ?\040))) + (let ((dired-marker-char (or marker-char dired-marker-char))) + (dired-mark-if + (and (not (looking-at-p dired-re-dot)) + (not (eolp)) ; empty line + (let ((fn (dired-get-filename nil t))) + (when (and fn (not (file-directory-p fn))) + (message "Checking %s" fn) + (s-present? (shell-command-to-string + (mapconcat + #'identity + (list "git annex find" matchingoptions (shell-quote-argument fn)) + " ")))))) + "matching file"))) +#+END_SRC +**** Real file size +:PROPERTIES: +:header-args:emacs-lisp: :tangle no +:END: +Dired by default only shows the symlink file size. While it can be told to dereference symbolic links with the =-L= flag this only works on annexed files if they are present on the current machine. +Settings this flag causes more problems than it solves. Instead Josh has derived the functions below to determine the file size. I do not use them for now, but copied them here for future reference/usage. +***** Get git-annex file sizes +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("s" . jmm/dired-git-annex-print-human-file-size) +#+end_src +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +(defun jmm/git-annex-file-target (filename) + "If FILENAME is a git annex file, return its symlink target." + (-when-let (symname (and filename + (file-symlink-p filename))) + (when (string-match-p ".*\\.git/annex/.+" symname) + symname))) + +(defun jmm/dired-git-annex-file-target () + "If the dired file at point is a git annex file, return its symlink target." + (jmm/git-annex-file-target (dired-get-filename nil t))) + +(defun jmm/git-annex-file-size (filename) + "Try to determine the size of the git annex file FILENAME." + (-when-let (target (jmm/git-annex-file-target filename)) + (or (save-match-data + (when (string-match "SHA256E-s\\([0-9]+\\)--" target) + (string-to-number (match-string 1 target)))) + (-some-> (expand-file-name target (file-name-directory filename)) + file-attributes + file-attribute-size)))) + +(defun jmm/dired-git-annex-print-human-file-size () + "Try to print the human readable file size of the dired git-annex file at point." + (interactive) + (let* ((filename (dired-get-filename nil t)) + (string-file (file-name-nondirectory filename))) + (-if-let (filesize (-some-> (jmm/git-annex-file-size filename) + file-size-human-readable)) + (message "%s - %s" filesize string-file) + (message "Can't determine git annex file size of %s" string-file)))) +#+END_SRC +***** Show git-annex file sizes in dired +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("S" . jmm/dired-git-annex-add-real-file-sizes) +#+end_src + +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +;; Based off of `dired--align-all-files' +(defun jmm/dired-git-annex-add-real-file-sizes () + "Go through all the git-annex files in dired, replace the +symlink file size with the real file size, then try to align +everything." + (interactive) + (require 'dired-aux) + (let ((regexp directory-listing-before-filename-regexp)) + (save-excursion + (goto-char (point-min)) + (dired-goto-next-file) + (while (or (dired-move-to-filename) + (progn (save-restriction + (narrow-to-region (dired-subdir-min) (dired-subdir-max)) + (dired--align-all-files)) + (dired-next-subdir 1 t) + (dired-goto-next-file) + (dired-move-to-filename))) + (let ((inhibit-read-only t)) + (when (and (jmm/dired-git-annex-file-target) + (re-search-backward regexp (line-beginning-position) t)) + (goto-char (match-beginning 0)) + (-when-let (newsize (-some-> (jmm/git-annex-file-size (dired-get-filename nil t)) + file-size-human-readable)) + (search-backward-regexp "[[:space:]]" nil t) + (when (re-search-forward "[[:space:]]+\\([^[:space:]]+\\)[[:space:]]" nil t) + (goto-char (match-beginning 1)) + (delete-region (point) (match-end 1)) + (insert-and-inherit newsize)))) + (forward-line)))))) +#+END_SRC + +#+BEGIN_SRC emacs-lisp :tangle no +;; (add-hook 'dired-mode-hook #'jmm/dired-git-annex-add-real-file-sizes) +;; (add-hook 'dired-after-readin-hook #'jmm/dired-git-annex-add-real-file-sizes) +#+END_SRC +***** Sort dired by file size +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-config +(defun jmm/dired-dir-files-beginning () + "First point where there's a filename on the line. Beginning of line." + (save-excursion + (goto-char (dired-subdir-min)) + (dired-goto-next-file) + (beginning-of-line) + (point))) + +(defun jmm/dired-dir-files-end () + "Last point where there's a filename. End of line." + (save-excursion + (goto-char (dired-subdir-max)) + (while (not (dired-get-filename nil t)) + (dired-previous-line nil)) + (end-of-line) + (point))) + +(defun jmm/dired-file-size () + "Return the file size of a file at point (for sorting). Takes +into account git-annex files." + (let* ((filename (dired-get-filename nil t)) + (string-file (file-name-nondirectory filename))) + (or (jmm/git-annex-file-size filename) + (file-attribute-size (file-attributes filename))))) + +;; TODO: Should just try to directly use the field listed. +(defun jmm/dired-sort-size (&optional ascending) + "Sort some dired lines by size (consider annex sizes). +With optional argument ASCENDING, sort by ascending file size. (I +like going the other way around usually.)" + (interactive "P") + (let (buffer-read-only + (beg (jmm/dired-dir-files-beginning)) + (end (jmm/dired-dir-files-end))) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (sort-subr (not ascending) + 'forward-line 'end-of-line + #'jmm/dired-file-size nil))))) +#+END_SRC +**** Browsing URLs for git-annex files +#+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings +("b" . jmm/git-annex-browse-url) +#+end_src +#+BEGIN_SRC emacs-lisp +;; TODO: Process multiple files at once? +(defun jmm/git-annex-whereis-info (filename) + "Get information about where a git-annex file exists. +Returns a parsed json list from whereis." + (let* ((json-array-type 'list) + (whereisdata (shell-command-to-string + (mapconcat + #'identity + (list "git annex whereis --json" (shell-quote-argument filename)) + " ")))) + (when (s-present? whereisdata) + (json-read-from-string whereisdata)))) + +(defun jmm/git-annex-urls (filename) + "Get the git-annex web urls for FILENAME." + (-some->> (jmm/git-annex-whereis-info filename) + (assoc-default 'whereis) + (-mapcat (lambda (x) (assoc-default 'urls x))) + (-map (lambda (s) (s-chop-prefix "yt:" s))))) + +(defun jmm/git-annex-browse-url () + "Browse the first git-annex web urls for file at point." + (interactive) + (let* ((filename (dired-get-filename nil t)) + (filestr (file-name-nondirectory filename))) + (-if-let (url (car (jmm/git-annex-urls filename))) + (progn + (message "Opening url: %s" url) + (jmm/org-open-link-alternate-browser #'browse-url url)) + (user-error "No url found for %s" filestr)))) +#+END_SRC +**** Eshell helper functions +Helper functions to open dired view from eshell or list =git-annex= files which match a search. +#+BEGIN_SRC emacs-lisp +(defun jmm/git-annex-find-files (&rest args) + "Generate a list of git annex files that match ARGS. +For example, ARGS could be \"--in=here\"" + (-remove #'s-blank? + (s-split "\0" + (shell-command-to-string (mapconcat #'identity + (append '("git annex find --print0") args) + " "))))) +(defun eshell/dga (&rest args) + "Show a `dired' buffer of git annex files that match ARGS. +For example, ARGS could be \"--in=here\"" + (dired (cons "." (apply #'jmm/git-annex-find-files args)))) + +(defun eshell/gaf (&rest args) + "Return a list of git annex files that match ARGS. +For example, ARGS could be \"--in=here\"" + (apply #'jmm/git-annex-find-files args)) +#+END_SRC *** Magit #+BEGIN_SRC emacs-lisp (use-package magit -- cgit v1.2.3 From ce3fac717205457c35eb486501754cc681127c9e Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 23 Jul 2020 10:38:59 +0200 Subject: [WIP] Add basic version of async tangling --- .dir-locals.el | 7 +++++++ emacs-init.org | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .dir-locals.el diff --git a/.dir-locals.el b/.dir-locals.el new file mode 100644 index 0000000..05bfae2 --- /dev/null +++ b/.dir-locals.el @@ -0,0 +1,7 @@ +;;; Directory Local Variables +;;; For more information see (info "(emacs) Directory Variables") + +((org-mode . ((eval . (add-hook 'before-save-hook + (lambda nil + (fpi/tangle-async)) + nil t))))) diff --git a/emacs-init.org b/emacs-init.org index 660e3be..abff790 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -47,8 +47,21 @@ they are tangled upon save I use this function. (expand-file-name "git/projects/dotfiles/" (getenv "HOME"))) (org-babel-tangle) (message "%s tangled" buffer-file-name))) +(defmacro fpi/tangle-async (&optional file) + "Tangle FILE with a separate emacs instance. -(add-hook 'org-mode-hook (lambda () (add-hook 'before-save-hook #'fpi/tangle-dotfiles nil t)) t) +Note that this does not respect any customization of the tangle +process in your init file as it is not loaded. This uses the +emacs-async library." + (interactive) + (let ((file (or file (buffer-file-name)))) + (and file + (not (file-remote-p file)) + `(async-start + (lambda () + (require 'org) + (org-babel-tangle-file ,file) + 'ignore))))) #+END_SRC As I use =org-crypt= all =.org= files need to be decrypted before tangling, saved without encrypting and encrypted after tangling and -- cgit v1.2.3 From dbb51aa392c3a13ebaa9bcfe31b67814a2424686 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 23 Jul 2020 10:39:28 +0200 Subject: Add capture template which gets link title from web --- emacs-init.org | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index abff790..29df84a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3333,6 +3333,16 @@ print the list. :after org :straight (org-plus-contrib)) #+end_src +*** Handling web urls +**** org-web-tools +:PROPERTIES: +:ID: dc4129ff-6d76-4f12-926f-c62a687a39ec +:END: +This provides functions to get webpage title or content for org mode links. +#+begin_src emacs-lisp +(use-package org-web-tools + :straight t) +#+end_src *** Gnorb :PROPERTIES: :ID: 990e2668-11d6-45eb-9c9b-1dc0b89b556d @@ -3603,25 +3613,38 @@ Templates '( <>)))) #+END_SRC + **** Templates +:PROPERTIES: +:header-args:emacs-lisp: :eval never +:END: ***** Journal Capture templates for journal entries. Mostly to just keep track of things I have looked at and which may be interesting later, but do not warrant a zettel right now. #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates ("j" "Journal") -("jj" "Journal Entry (Link)" +("jj" "Link Current buffer" entry (file+olp+datetree ,org-journal-file) ;; "** %<%H:%M> %a\n %i%? \n%:description\n%:elfeed-entry-content\n%:elfeed-entry-date\n%:elfeed-entry-meta\n%:elfeed-entry-title\n%:elfeed-entry-enclosures\n%:elfeed-entry-tags" ) "** %<%H:%M> %a %i%?" ) -("je" "Journal Entry" +("je" "Manual Entry" entry (file+olp+datetree ,org-journal-file) "** %<%H:%M> %? %i" ) #+END_SRC +To get the title from the url in =kill-ring= I use [[id:dc4129ff-6d76-4f12-926f-c62a687a39ec][org-web-tools]]. +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates +("jw" "Web Link from kill-ring" + entry + (file+olp+datetree + ,org-journal-file) + "** %<%H:%M> %(org-web-tools--org-link-for-url (org-web-tools--get-first-url))%? +%i") +#+END_SRC ***** Interrupts For interruptions. These are saved in a global refile file and to be sorted to their appropriate place. #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates -- cgit v1.2.3 From c14e6cbe6cf89151b1b32e0f98512ce646a5ecfb Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 11:11:32 +0200 Subject: Add olivetti mode --- emacs-init.org | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 29df84a..b8cc871 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4615,6 +4615,16 @@ Support for HTML code blocks with proper syntax highlighting. See [[https://gith (advice-add 'eww-display-html :around 'eww-display-html--override-shr-external-rendering-functions)))) #+END_SRC +** Writing Setup +*** Olivetti Mode +#+begin_src emacs-lisp +(use-package olivetti + :straight t + :custom + (olivetti-body-width 0.65) + ;; (olivetti-minimum-body-width 70) + ) +#+end_src ** Email For the setup of external mail specific programs see [[file:mail.org]]. *** Sending mail -- cgit v1.2.3 From 4feeef8a1dc4394315ad84a0db2af0fe7b22556d Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 11:11:42 +0200 Subject: Make org only show h:mm durations and no days --- emacs-init.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index b8cc871..ac8ebcd 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3451,6 +3451,13 @@ This function is handy to use in header arguments to create names based on the c (post (or post ""))) (format "%s%s%s" pre (nth 4 (org-heading-components)) post))) #+end_src +*** Durations +#+begin_src emacs-lisp +(use-package org-duration + :after org + :custom + (org-duration-format '(("h" . t) ("min" . t) (special . h:mm)))) +#+end_src *** ox-reveal #+BEGIN_SRC emacs-lisp (use-package ox-reveal -- cgit v1.2.3 From 3d0579ebe218bfe2a2bef553579465b92f88a9c2 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 11:11:58 +0200 Subject: Make gnorb use org-refile-targets --- emacs-init.org | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index ac8ebcd..5200e15 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3414,7 +3414,11 @@ Default keybindings: '(progn (define-key message-mode-map (kbd "C-c t") #'gnorb-gnus-outgoing-do-todo))) #+end_example - +**** More refile targets +Make gnorb consider the same refile targets as org. +#+begin_src emacs-lisp :tangle no :noweb-ref gnorb-custom +(gnorb-gnus-trigger-refile-targets org-refile-targets) +#+end_src *** Inline images Resize inline images to 400px but respect width specifications in attribute lines. -- cgit v1.2.3 From da22c0447699fa864413b0758483a29735fd8de2 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 11:12:09 +0200 Subject: Add automatic table of contents --- emacs-init.org | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 5200e15..7c6c155 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1,4 +1,65 @@ #+PROPERTY: header-args:emacs-lisp :tangle tangle/emacs-init.el :results silent :noweb yes +* Contents :QUOTE:TOC_2_gh: +#+BEGIN_QUOTE +- [[#overview][Overview]] + - [[#about-this-document][About this document]] +- [[#base-settings][Base settings]] + - [[#setup-load-path][Setup load path]] + - [[#meta-packages][Meta packages]] + - [[#gui-interface][GUI Interface]] + - [[#font][Font]] + - [[#theme--faces][Theme & Faces]] + - [[#user-info][User info]] + - [[#desktop-module][Desktop module]] + - [[#customize][Customize]] + - [[#file-and-input-history][File and input history]] + - [[#local-variables][Local variables]] + - [[#personal-keymap][Personal keymap]] + - [[#base-commands-simpleel][Base commands (simple.el)]] +- [[#selection-and-search-methods][Selection and search methods]] + - [[#completion-frameworks][Completion frameworks]] + - [[#isearch-enhancements][isearch enhancements]] +- [[#directory-project-buffer-window-management][Directory, project, buffer, window management]] + - [[#dired][Dired]] + - [[#tramp][Tramp]] + - [[#git][Git]] + - [[#projectile][Projectile]] + - [[#working-with-buffers][Working with buffers]] + - [[#window-configuration][Window configuration]] + - [[#file-encryption][File encryption]] +- [[#applications-and-utilities][Applications and utilities]] + - [[#calendar][Calendar]] + - [[#pdfs][PDFs]] + - [[#latex][Latex]] + - [[#programming-languages][Programming languages]] + - [[#org-mode][Org mode]] + - [[#deft][Deft]] + - [[#shell][Shell]] + - [[#grep][Grep]] + - [[#proced][Proced]] + - [[#pass][Pass]] + - [[#ledger][Ledger]] + - [[#elfeed][Elfeed]] + - [[#plotting-data][Plotting data]] + - [[#html-renderer][HTML renderer]] + - [[#writing-setup][Writing Setup]] + - [[#email][Email]] + - [[#footnote-mode][Footnote Mode]] + - [[#bbdb][BBDB]] + - [[#spellcheck][Spellcheck]] + - [[#compile][Compile]] + - [[#context-aware-hydra][Context aware hydra]] +- [[#language-settings][Language settings]] +- [[#interface][Interface]] + - [[#general][General]] + - [[#rainbow-mode][Rainbow mode]] + - [[#parentheses][Parentheses]] + - [[#whitespace][Whitespace]] + - [[#undo][Undo]] + - [[#electric-stuff][Electric stuff]] +- [[#wrapping-up][Wrapping up]] +#+END_QUOTE + * Overview ** About this document This files contains all the elisp code normally placed in the .emacs @@ -4005,6 +4066,12 @@ Here's a function to easily copy a doi from the results of =crossref-lookup=. (mw-org-hide-meta-heading-info))) (define-key fpi/toggle-map "m" #'fpi/org-toggle-meta-info-lines) #+end_src +*** Table of contents in org +#+begin_src emacs-lisp +(use-package toc-org + :straight t + :hook (org-mode . toc-org-mode)) +#+end_src *** Workflow My current workflow is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt Hansen's]] configs. -- cgit v1.2.3 From 03bbd2ce46baf5ab4a900c12b6f5453e1662e427 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 29 Jul 2020 11:35:28 +0200 Subject: Disable twoway caldav sync.. It sucks --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 7c6c155..12d036e 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3503,7 +3503,7 @@ Also display remote images by downloading them. (org-caldav-calendar-id private/calendar-id) (org-caldav-inbox "~/sync/w.org") (org-caldav-files nil) - (org-caldav-sync-direction 'twoway) + (org-caldav-sync-direction 'cal->org) (org-caldav-delete-calendar-entries 'never) (org-caldav-exclude-tags nil) ) -- cgit v1.2.3 From c7415dcfcb4282902996125399bd1261d9372b37 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 29 Jul 2020 11:35:42 +0200 Subject: Add a keybinding for olivetti mode --- emacs-init.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 12d036e..2de6bbd 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4703,6 +4703,10 @@ Support for HTML code blocks with proper syntax highlighting. See [[https://gith ;; (olivetti-minimum-body-width 70) ) #+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings +(define-key fpi/toggle-map "do" #'olivetti-mode) +#+end_src ** Email For the setup of external mail specific programs see [[file:mail.org]]. *** Sending mail -- cgit v1.2.3 From de9a2d58187d81731d36d358a71fae6b8f53918f Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 11:24:25 +0200 Subject: Fix some text --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 2de6bbd..94de490 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3673,7 +3673,6 @@ content syncing upon commit. (org-attach-git-annex-cutoff 0)) #+end_src *** Org-Capture -Templates #+BEGIN_SRC emacs-lisp (use-package org-capture :custom @@ -3842,7 +3841,8 @@ Templates I no longer use, but may be interesting. "* %i%? %(and (org-id-get-create) nil) :PROPERTIES:\n:CREATED: %u\n:END:\n") #+END_SRC -**** Setup for floating capture window. For reference see [[https://www.windley.com/archives/2010/12/capture_mode_and_emacs.shtml][here]]. +**** Setup for floating capture window +For reference see [[https://www.windley.com/archives/2010/12/capture_mode_and_emacs.shtml][here]]. #+begin_src emacs-lisp (defun fpi/make-floating-frame (&optional width height minibuffer name) (interactive) -- cgit v1.2.3 From 7935118c35c5f4a6f7b9928556dd402e1a6380c7 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:12:30 +0200 Subject: Add notification upon finish async tangling --- emacs-init.org | 2 ++ 1 file changed, 2 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 94de490..84e3375 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -121,7 +121,9 @@ emacs-async library." `(async-start (lambda () (require 'org) + (require 'org-clock) (org-babel-tangle-file ,file) + (org-notify (format "Tangled %s" ,file)) 'ignore))))) #+END_SRC As I use =org-crypt= all =.org= files need to be decrypted before -- cgit v1.2.3 From c989b777886f10b5835f9aa6effc0245f8dacbf3 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:12:52 +0200 Subject: Adjust org-scheduled-previously face --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 84e3375..e119110 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -975,7 +975,7 @@ This call now creates a custom theme based on the settings in the sections (:foreground "#1c661c")))) '(org-scheduled-previously ((t - (:foreground "#002000")))) + (:foreground "#002900")))) '(org-agenda-done ((t (:foreground "#727280")))) @@ -1125,7 +1125,7 @@ ln -siv $(pwd)/tangle/spacemacs-light-customizations-theme.el ~/.emacs.d/ (dark-cyan "#008b8b") (light-green "#4f774f") ;;#3f773f (dark-green "#1c661c") - (dark-green2 "#002000") + (dark-green2 "#002900") (region-dark "#2d2e2e") (region "#39393d") (slate "#8FA1B3") -- cgit v1.2.3 From a1c1db3c72b10a9953fdacf34377be62581becb6 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:18:46 +0200 Subject: Add more safe local variables --- emacs-init.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index e119110..f6667a6 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1497,7 +1497,11 @@ Some settings could be harmful to emacs and the underlying system. Therefore man #+begin_src emacs-lisp :tangle no :noweb-ref files-custom (safe-local-variable-values '((whitespace-style face trailing space-before-tab indentation empty space-after-tab newline-mark) + (whitespace-style face trailing space-before-tab indentation empty space-after-tab) (eval set-window-buffer nil (current-buffer)) + (eval add-hook 'before-save-hook (lambda nil (fpi/tangle-async)) nil t) + (org-attach-preferred-new-method . dir) + (org-attach-use-inheritance . t) (right-margin-width . 2) (left-margin-width . 2) (line-spacing . 0.2) -- cgit v1.2.3 From 7bec659f21b54e23f6f46fe184e5e910d652b07e Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:19:05 +0200 Subject: Add a key to insert org link for the url in clipboard --- emacs-init.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index f6667a6..2f4505b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3410,6 +3410,10 @@ This provides functions to get webpage title or content for org mode links. (use-package org-web-tools :straight t) #+end_src +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(define-key fpi-map "l" #'org-web-tools-insert-link-for-url) +#+end_src + *** Gnorb :PROPERTIES: :ID: 990e2668-11d6-45eb-9c9b-1dc0b89b556d -- cgit v1.2.3 From 01e2ce0b94fa3a4964cbb5ee96ec5a88a94d7cfb Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:23:20 +0200 Subject: Fix header arg in capture templates section --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 2f4505b..8b16237 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3697,7 +3697,7 @@ content syncing upon commit. **** Templates :PROPERTIES: -:header-args:emacs-lisp: :eval never +:header-args:emacs-lisp: :eval never :noweb yes :END: ***** Journal Capture templates for journal entries. Mostly to just keep track of things I have looked at and which may be interesting later, but do not warrant a zettel right now. -- cgit v1.2.3 From d2fee18824c17bc325a1760ccaca3a6e90454a1e Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 19:02:29 +0200 Subject: Refile spellcheck section & auto turn on flyspell --- emacs-init.org | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 8b16237..76af5f5 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -46,10 +46,10 @@ - [[#email][Email]] - [[#footnote-mode][Footnote Mode]] - [[#bbdb][BBDB]] - - [[#spellcheck][Spellcheck]] - [[#compile][Compile]] - [[#context-aware-hydra][Context aware hydra]] - [[#language-settings][Language settings]] + - [[#spellcheck][Spellcheck]] - [[#interface][Interface]] - [[#general][General]] - [[#rainbow-mode][Rainbow mode]] @@ -4886,16 +4886,6 @@ For now I use this bad code. (lambda () (define-key gnus-summary-mode-map (kbd ";") 'bbdb-mua-edit-field))) #+end_src -** Spellcheck -#+begin_src emacs-lisp -(use-package ispell - :config - (setq ispell-program-name "/usr/bin/hunspell") - (setq ispell-dictionary "en_US,de_DE") - (ispell-set-spellchecker-params) - (ispell-hunspell-add-multi-dic "en_US,de_DE") - ) -#+end_src ** Compile Fix ansi colors in compile buffers. From [[https://endlessparentheses.com/ansi-colors-in-the-compilation-buffer-output.html][endlessparentheses]]. #+begin_src emacs-lisp @@ -5121,6 +5111,28 @@ End sentences with single spaces. #+begin_src emacs-lisp (setq sentence-end-double-space nil) #+end_src +** Spellcheck +#+begin_src emacs-lisp +(use-package ispell + :config + (setq ispell-program-name "/usr/bin/hunspell") + (setq ispell-dictionary "en_US,de_DE") + (ispell-set-spellchecker-params) + (ispell-hunspell-add-multi-dic "en_US,de_DE") + ) +#+end_src +*** Flyspell +Setup mainly from [[https://github.com/howardabrams/dot-files/blob/master/emacs.org][Howard Abrams]]. +#+begin_src emacs-lisp +(use-package flyspell + :delight + :init + (add-hook 'prog-mode-hook 'flyspell-prog-mode) + (dolist (hook '(text-mode-hook org-mode-hook)) + (add-hook hook (lambda () (flyspell-mode 1)))) + (dolist (hook '(change-log-mode-hook log-edit-mode-hook org-agenda-mode-hook)) + (add-hook hook (lambda () (flyspell-mode -1))))) +#+end_src * Interface ** General #+begin_src emacs-lisp -- cgit v1.2.3 From 4fb2d2ad96d062e197fa860ce81981a25ff88cb7 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 19:03:01 +0200 Subject: Refile writing setup section --- emacs-init.org | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 76af5f5..125bcb7 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -42,7 +42,6 @@ - [[#elfeed][Elfeed]] - [[#plotting-data][Plotting data]] - [[#html-renderer][HTML renderer]] - - [[#writing-setup][Writing Setup]] - [[#email][Email]] - [[#footnote-mode][Footnote Mode]] - [[#bbdb][BBDB]] @@ -57,6 +56,7 @@ - [[#whitespace][Whitespace]] - [[#undo][Undo]] - [[#electric-stuff][Electric stuff]] + - [[#writing-setup][Writing Setup]] - [[#wrapping-up][Wrapping up]] #+END_QUOTE @@ -4703,20 +4703,6 @@ Support for HTML code blocks with proper syntax highlighting. See [[https://gith (advice-add 'eww-display-html :around 'eww-display-html--override-shr-external-rendering-functions)))) #+END_SRC -** Writing Setup -*** Olivetti Mode -#+begin_src emacs-lisp -(use-package olivetti - :straight t - :custom - (olivetti-body-width 0.65) - ;; (olivetti-minimum-body-width 70) - ) -#+end_src - -#+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings -(define-key fpi/toggle-map "do" #'olivetti-mode) -#+end_src ** Email For the setup of external mail specific programs see [[file:mail.org]]. *** Sending mail @@ -5224,6 +5210,20 @@ temporary buffer is created. (electric-pair-mode 1) (electric-quote-mode -1)) #+end_src +** Writing Setup +*** Olivetti Mode +#+begin_src emacs-lisp +(use-package olivetti + :straight t + :custom + (olivetti-body-width 0.65) + ;; (olivetti-minimum-body-width 70) + ) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings +(define-key fpi/toggle-map "do" #'olivetti-mode) +#+end_src * Wrapping up Some stuff that is run after everything else. -- cgit v1.2.3 From 5e21e29be6e91a1ef82cfa5c48dfb39cc6fb36e6 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 20:00:43 +0200 Subject: Disable customize based theme loading After load-theme customize recalculates user set variables. Including the current-theme variable, calling the set function several times & messing it up.. --- emacs-init.org | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 125bcb7..6ab1606 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -401,8 +401,9 @@ defined, for example ~pdf-view-midnight-colors~. (defcustom fpi/dark-theme-list '(spacemacs-dark spacemacs-dark-customizations) "List of themes to activate when using a dark theme.") (defcustom fpi/current-theme 'light - "Currently activated theme variation." - :set #'fpi/set-and-reload-theme) + "Currently activated theme variation.") + +(fpi/load-themes) #+end_src Functions to load themes based on the ~fpi/current-theme~ setting and to toggle the current theme between light and dark. @@ -418,20 +419,15 @@ of `(format \"fpi/%s-theme-list\" fpi/current-theme)'" (let* ((theme-variation (or theme-variation fpi/current-theme)) (themes (eval (intern (format "fpi/%s-theme-list" theme-variation))))) (mapc (lambda (theme) (load-theme theme t)) themes))) -(defun fpi/set-and-reload-theme (symbol value) - "Set SYMBOL to VALUE and update themes. - -Set SYMBOL to VALUE with `set-default'if it is not already set to -that value and update the loaded themes afterwards." - (when (not (and (boundp symbol) (eq (eval symbol) value))) - (set-default symbol value) - (fpi/load-themes))) (defun fpi/toggle-theme () "Toggle between light and dark theme." (interactive) (if (eq fpi/current-theme 'light) - (customize-save-variable 'fpi/current-theme 'dark) - (customize-save-variable 'fpi/current-theme 'light))) + (progn + (customize-save-variable 'fpi/current-theme 'dark) + (fpi/load-themes)) + (customize-save-variable 'fpi/current-theme 'light) + (fpi/load-themes))) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings (define-key fpi/toggle-map "dt" #'fpi/toggle-theme) @@ -2836,8 +2832,12 @@ Advice =load-theme= to update the colors for =pdf-view-midnight-mode= after the theme changes. #+NAME: theme-dependent-vars #+begin_src emacs-lisp :tangle no -(defadvice load-theme (after update-pdf-view-midnight-color activate) - (customize-save-variable 'pdf-view-midnight-colors `(,(face-attribute 'default :foreground) . ,(face-attribute 'default :background)))) +(defun update-pdf-view-midnight-color (&rest arg) + (customize-save-variable + 'pdf-view-midnight-colors + `(,(face-attribute 'default :foreground) . ,(face-attribute 'default :background)))) +(advice-add 'load-theme :after + #'update-pdf-view-midnight-color) #+end_src ** Latex -- cgit v1.2.3 From 1c2942bbbb3fcf035fd9788407eeab33673737ae Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:23:46 +0200 Subject: Make olivetti mode scale better in small windows --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 6ab1606..e4ccc74 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5215,8 +5215,9 @@ temporary buffer is created. #+begin_src emacs-lisp (use-package olivetti :straight t + :delight :custom - (olivetti-body-width 0.65) + (olivetti-body-width 80) ;; (olivetti-minimum-body-width 70) ) #+end_src -- cgit v1.2.3 From 077cde89d72ea895ddb7b9624a4d6336f6d9e6ae Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 27 Jul 2020 20:33:46 +0200 Subject: [WIP] Improve font setup --- emacs-init.org | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 232 insertions(+), 28 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index e4ccc74..b8e8047 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -384,6 +384,218 @@ Instead of the above code I set the font directly using (set-face-attribute 'default nil :font "Hack-11") #+end_src +#+begin_src emacs-lisp +(use-package emacs + :commands (prot/font-set-face-attribute + prot/font-set-fonts + prot/font-set-font-size-family + prot/font-fonts-dwim) + :config + (setq x-underline-at-descent-line t) + (setq underline-minimum-offset 1) + + (defconst prot/font-fontconfig-params + "embeddedbitmap=false:autohint=false:hintstyle=hintslight" + "Additional parameters for the given font family. +These are specific to the fontconfig backend for GNU/Linux systems.") + + (defvar prot/font-set-fonts-hook nil + "Hook that is called after setting fonts. +See, for example, `prot/font-set-fonts'.") + + ;; The idea with this association list is to use font combinations + ;; that are suitable to the given point size and intended function. + ;; Basically, I have three modes: my laptop's small screen, my laptop + ;; attached to a larger external monitor in a desktop setup (my normal + ;; case), and when I do presentations (i.e. my videos on Emacs). + ;; + ;; I find that at smaller sizes the open and wide proportions of + ;; Hack+FiraGO combined with their more intense typographic colour + ;; work best, while the more compact Iosevka+Source Sans Pro are + ;; better at larger point sizes. The "desktop" combo is ideal for use + ;; on a larger monitor at a regular point size. The latter is what I + ;; typically use to write prose or code. + ;; + ;; Note that the "Hack" typeface mentioned here is my patched version + ;; of it, which uses some alternative glyphs, is built on top of the + ;; latest dev branch, and is meant to improve both the Roman and + ;; Italic variants (alt glyphs are part of the Hack project): + ;; https://gitlab.com/protesilaos/hackfontmod + (defconst prot/font-sizes-families-alist + '(("laptop" . (10.5 "Hack" "Source Sans Pro" 1)) + ("desktop" . (13 "Hack" "Alegreya" 4)) + ("presentation" . (19 "Iosevka SS08" "Source Sans Pro" 1))) + "Alist of desired point sizes and their typefaces. +Each association consists of a display type mapped to a point +size, followed by monospaced and proportionately-spaced font +names, and a difference in desired size between the latter two to +account for their innate differences in proportions (this number +represents pixels and is found empirically). + +The monospaced typeface is meant to be applied to the `default' +and `fixed-pitch' faces. The proportionately-space font is +intended for the `variable-pitch' face.") + + (defun prot/font-set-face-attribute (face family size &optional params) + "Set FACE font to FAMILY at SIZE with optional PARAMS." + (let ((params (if params + params + prot/font-fontconfig-params))) + (set-face-attribute + `,face nil :font + (format "%s-%s:%s" family (number-to-string size) params)))) + + + + + + (defun prot/font-set-fonts (&optional points font-mono font-var) + "Set default font size using presets. + +POINTS is the font's point size, represented as either '10' or +'10.5'. FONT-MONO should be a monospaced typeface, due to the +alignment requirements of the `fixed-pitch' face. FONT-VAR could +be a proportionately-spaced typeface or even a monospaced one, +since the `variable-pitch' it applies to is not supposed to be +spacing-sensitive. Both families must be represented as a string +holding the family's name." + (interactive) + (let* ((data prot/font-sizes-families-alist) + (displays (mapcar #'car data)) + (choice (if points + points + (completing-read "Pick display size: " displays nil t))) + (size (if points + points + (nth 1 (assoc `,choice data)))) + (mono (if font-mono + font-mono + (if (member choice displays) + (nth 2 (assoc `,choice data)) + nil))) + (var (if font-var + font-var + (if (member choice displays) + (nth 3 (assoc `,choice data)) + nil))) + (adjust (nth 4 (assoc `,choice data)))) + (when window-system + (dolist (face '(default fixed-pitch)) + (prot/font-set-face-attribute `,face mono size)) + (prot/font-set-face-attribute 'variable-pitch var (+ size adjust)))) + (run-hooks 'prot/font-switch-fonts-hook)) + + (defvar prot/font-monospaced-fonts-list + '("Hack" "Iosevka SS08" "Iosevka Slab" "Source Code Pro" + "Ubuntu Mono" "Fantasque Sans Mono" "DejaVu Sans Mono" + "Fira Code" "Victor Mono" "Roboto Mono") + "List of typefaces for coding. +See `prot/font-set-font-size-family' for how this is used.") + + (defun prot/font-set-font-size-family () + "Set point size and main typeface. +This command is intended for testing various font families at +some common point sizes. + +See `prot/font-set-fonts' for the function I would normally use +or `prot/font-fonts-dwim' which just wraps this one with that." + (interactive) + (let* ((fonts prot/font-monospaced-fonts-list) + (font (completing-read "Select main font: " fonts nil t)) + (nums (list 13 14 15 16)) + (sizes (mapcar 'number-to-string nums)) + (size (completing-read "Select or insert number: " sizes nil)) + (var (face-attribute 'variable-pitch :family))) + (dolist (face '(default fixed-pitch)) + (prot/font-set-face-attribute face font (string-to-number size))) + (prot/font-set-face-attribute 'variable-pitch var (string-to-number size)) + (run-hooks 'prot/font-switch-fonts-hook))) + + (defun prot/font-fonts-dwim (&optional arg) + "Set fonts interactively. +This is just a wrapper around `prot/font-set-fonts' and +`prot/font-set-font-size-family', whose sole purpose is to +economise on dedicated key bindings." + (interactive "P") + (if arg + (prot/font-set-font-size-family) + (prot/font-set-fonts))) + + (defvar prot/font-fonts-line-spacing-alist + '(("Iosevka SS08" . 1) + ("Iosevka Slab" . 1) + ("Source Code Pro" . 1) + ("Ubuntu Mono" . 2)) + "Font families in need of extra `line-spacing'. +See `prot/font-line-spacing' for how this is used.") + + (defvar prot/font-fonts-bold-weight-alist + '(("Source Code Pro" . semibold)) + "Font families in need of a variegated weight for `bold'. +See `prot/font-bold-face' for how this is used.") + + (defmacro prot/font-adjustment (fn doc alist cond1 cond2) + "Macro for functions that employ `prot/font-switch-fonts-hook'. +NAME is the name of the resulting function. DOC is its +docstring. ALIST is an assosiation list of cons cells. COND1 +and COND2 is the body of an `if' statement's 'if' and 'then' part +respectively." + `(defun ,fn () + ,doc + (let* ((data ,alist) + (fonts (mapcar #'car data)) + ;; REVIEW This should be adjusted to account for the + ;; possibility of a distinct font family for the `bold' + ;; face. + (font (face-attribute 'default :family)) + (x (cdr (assoc font data)))) + (if (member font fonts) + ,cond1 + ,cond2)))) + + (prot/font-adjustment + prot/font-line-spacing + "Determine desirable `line-spacing', based on font family." + prot/font-fonts-line-spacing-alist + (setq-default line-spacing `,x) + (setq-default line-spacing nil)) + + ;; XXX This will not work with every theme, but only those that + ;; inherit the `bold' face instead of specifying a weight property. + ;; The intent is to configure this once and have it propagate wherever + ;; a heavier weight is displayed. My Modus themes handle this + ;; properly. + (prot/font-adjustment + prot/font-bold-face + "Determine weight for the `bold' face, based on font family." + prot/font-fonts-bold-weight-alist + (set-face-attribute 'bold nil :weight `,x) + (set-face-attribute 'bold nil :weight 'bold)) + + (defun prot/font-fonts-per-monitor () + "Use font settings based on screen size. +Meant to be used at some early initialisation stage, such as with +`after-init-hook'." + (let* ((display (if (<= (display-pixel-width) 1366) + "laptop" + "desktop")) + (data prot/font-sizes-families-alist) + (size (cadr (assoc `,display data))) + (mono (nth 2 (assoc `,display data))) + (var (nth 3 (assoc `,display data))) + (adjust (nth 4 (assoc `,display data)))) + (dolist (face '(default fixed-pitch)) + (prot/font-set-face-attribute face mono size)) + (prot/font-set-face-attribute 'variable-pitch var (+ size adjust)) + (run-hooks 'prot/font-switch-fonts-hook))) + + :hook ((after-init-hook . prot/font-fonts-per-monitor) + (prot/font-set-fonts-hook . prot/font-line-spacing) + (prot/font-set-fonts-hook . prot/font-bold-face)) + ;; Awkward key because I do not need it very often. Maybe once a day. + ;; The "C-c f" is used elsewhere. + :bind ("C-c F" . prot/font-fonts-dwim)) +#+end_src ** Theme & Faces =hc-zenburn= is the theme I chose for a long time. Lately I started to appreciate light themes more. [[https://gitlab.com/protesilaos/modus-themes][modus-operandi]] is an interesting light @@ -825,12 +1037,6 @@ This call now creates a custom theme based on the settings in the sections (progn (deftheme spacemacs-light-customizations "My customizations to spacemacs-light (Created 2020-06-27)") (custom-theme-set-faces 'spacemacs-light-customizations - '(default - ((t - (:family "Hack" :background "#fbf8ef" :foreground "#1c1e1f")))) - '(variable-pitch - ((t - (:family "EtBookOt" :background nil :foreground "#1c1e1f" :height 1.2)))) '(header-line ((t (:background nil :inherit nil)))) @@ -872,7 +1078,7 @@ This call now creates a custom theme based on the settings in the sections ((t nil))) '(org-document-title ((t - (:inherit nil :family "EtBookOt" :height 1.8 :foreground "#1c1e1f" :underline nil)))) + (:inherit nil :height 1.8 :foreground "#1c1e1f" :underline nil)))) '(org-document-info ((t (:height 1.2 :slant italic)))) @@ -881,16 +1087,16 @@ This call now creates a custom theme based on the settings in the sections (:inherit shadow :height 0.6)))) '(org-level-1 ((t - (:inherit nil :family "EtBookOt" :height 1.6 :weight normal :slant normal :foreground "#1c1e1f")))) + (:height 1.6 :weight normal :slant normal :foreground "#1c1e1f")))) '(org-level-2 ((t - (:inherit nil :family "EtBookOt" :weight normal :height 1.3 :slant italic :foreground "#1c1e1f")))) + (:weight normal :height 1.3 :slant italic :foreground "#1c1e1f")))) '(org-level-3 ((t - (:inherit nil :family "EtBookOt" :weight normal :slant italic :height 1.2 :foreground "#1c1e1f")))) + (:weight normal :slant italic :height 1.2 :foreground "#1c1e1f")))) '(org-level-4 ((t - (:inherit nil :family "EtBookOt" :weight normal :slant italic :height 1.1 :foreground "#1c1e1f")))) + (:weight normal :slant italic :height 1.1 :foreground "#1c1e1f")))) '(org-level-5 ((t nil))) '(org-level-6 @@ -899,9 +1105,6 @@ This call now creates a custom theme based on the settings in the sections ((t nil))) '(org-level-8 ((t nil))) - '(org-headline-done - ((t - (:family "EtBookOt")))) '(org-quote ((t nil))) '(org-block @@ -983,10 +1186,10 @@ This call now creates a custom theme based on the settings in the sections (:foreground "#727280")))) '(org-table ((t - (:family "cmu typewriter text" :height 0.9 :background "#fbf8ef")))) + (:inherit fixed-pitch :height 0.9 :background "#fbf8ef")))) '(org-code ((t - (:inherit nil :family "cmu typewriter text" :foreground "#525254" :height 0.9)))) + (:inherit fixed-pitch :foreground "#525254" :height 0.9)))) '(font-latex-sectioning-0-face ((t nil))) '(font-latex-sectioning-1-face @@ -1148,10 +1351,11 @@ ln -siv $(pwd)/tangle/spacemacs-light-customizations-theme.el ~/.emacs.d/ :END: #+begin_src emacs-lisp :noweb-ref faces-spacemacs-light :tangle no ;; light -'('(default ((t (:family ,sans-mono-font :background ,bg-white :foreground ,bg-dark - ;; :height 75 - )))) - '(variable-pitch ((t (:family ,et-font :background nil :foreground ,bg-dark :height 1.2)))) +'( + ;; '(default ((t (:family ,sans-mono-font :background ,bg-white :foreground ,bg-dark + ;; ;; :height 75 + ;; )))) + ;; '(variable-pitch ((t (:family ,et-font :background nil :foreground ,bg-dark :height 1.2)))) '(header-line ((t (:background nil :inherit nil)))) '(show-paren-match ((t nil))) '(magit-section-heading ((t nil))) @@ -1167,18 +1371,18 @@ ln -siv $(pwd)/tangle/spacemacs-light-customizations-theme.el ~/.emacs.d/ '(powerline-inactive2 ((t (:background ,bg-white)))) '(highlight ((t (:background ,shade-white)))) '(hl-line ((t nil))) - '(org-document-title ((t (:inherit nil :family ,et-font :height 1.8 :foreground ,bg-dark :underline nil)))) + '(org-document-title ((t (:inherit nil :height 1.8 :foreground ,bg-dark :underline nil)))) '(org-document-info ((t (:height 1.2 :slant italic)))) '(org-archived ((t (:inherit shadow :height 0.6)))) - '(org-level-1 ((t (:inherit nil :family ,et-font :height 1.6 :weight normal :slant normal :foreground ,bg-dark)))) - '(org-level-2 ((t (:inherit nil :family ,et-font :weight normal :height 1.3 :slant italic :foreground ,bg-dark)))) - '(org-level-3 ((t (:inherit nil :family ,et-font :weight normal :slant italic :height 1.2 :foreground ,bg-dark)))) - '(org-level-4 ((t (:inherit nil :family ,et-font :weight normal :slant italic :height 1.1 :foreground ,bg-dark)))) + '(org-level-1 ((t (:height 1.6 :weight normal :slant normal :foreground ,bg-dark)))) + '(org-level-2 ((t (:weight normal :height 1.3 :slant italic :foreground ,bg-dark)))) + '(org-level-3 ((t (:weight normal :slant italic :height 1.2 :foreground ,bg-dark)))) + '(org-level-4 ((t (:weight normal :slant italic :height 1.1 :foreground ,bg-dark)))) '(org-level-5 ((t nil))) '(org-level-6 ((t nil))) '(org-level-7 ((t nil))) '(org-level-8 ((t nil))) - '(org-headline-done ((t (:family ,et-font)))) + ;; '(org-headline-done ((t (:family ,et-font)))) '(org-quote ((t nil))) '(org-block ((t (:background nil :height 0.9 :foreground ,bg-dark :family ,sans-mono-font)))) '(org-block-begin-line ((t (:background nil :height 0.8 :family ,sans-mono-font :foreground ,slate)))) @@ -1208,8 +1412,8 @@ ln -siv $(pwd)/tangle/spacemacs-light-customizations-theme.el ~/.emacs.d/ '(org-agenda-done ((t (:foreground ,doc)))) '(org-ellipsis ((t (:underline nil :foreground ,comment)))) '(org-tag ((t (:foreground ,doc)))) - '(org-table ((t (:family ,serif-mono-font :height 0.9 :background ,bg-white)))) - '(org-code ((t (:inherit nil :family ,serif-mono-font :foreground ,comment :height 0.9)))) + '(org-table ((t (:inherit fixed-pitch :height 0.9 :background ,bg-white)))) + '(org-code ((t (:inherit fixed-pitch :foreground ,comment :height 0.9)))) '(font-latex-sectioning-0-face ((t nil))) '(font-latex-sectioning-1-face ((t nil))) '(font-latex-sectioning-2-face ((t nil))) -- cgit v1.2.3 From f6cb4d704a31f9d23edd9644d34a863ff14aacb0 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:24:22 +0200 Subject: [WIP] Add first base version of prose minor mode --- emacs-init.org | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index b8e8047..a91a2ea 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3190,7 +3190,9 @@ Switch projects and subprojects from NEXT back to TODO" (use-package org-indent :delight :custom - (org-startup-indented t)) + (org-startup-indented t) + <> + ) #+end_src #+begin_src emacs-lisp (use-package ob @@ -5415,7 +5417,33 @@ temporary buffer is created. (electric-quote-mode -1)) #+end_src ** Writing Setup -*** Olivetti Mode +I gather all settings related to writing in a minor mode. +#+begin_src emacs-lisp +(define-minor-mode prose-mode + "Toggle some settings for text based buffers." + :init-value nil + :lighter " ✎" + (if prose-mode + (progn + (olivetti-mode 1) + (set-window-fringes (selected-window) 0 0) + (variable-pitch-mode 1) + ) + (olivetti-mode -1) + (set-window-fringes (selected-window) nil) + (variable-pitch-mode -1) + )) +#+end_src +The mode is enabled for all =text-mode= based buffers by default. +#+begin_src emacs-lisp +(add-hook 'text-mode-hook 'prose-mode) +#+end_src +Also set an easy keybinding to toggle it manually. +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(define-key fpi/toggle-map "p" #'prose-mode) +#+end_src + +Olivetti mode is used to center text in the buffer. This somehow helps with writing. #+begin_src emacs-lisp (use-package olivetti :straight t @@ -5426,8 +5454,16 @@ temporary buffer is created. ) #+end_src -#+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings -(define-key fpi/toggle-map "do" #'olivetti-mode) +For org-mode also reduce indentation by =org-indent-mode= as described [[https://explog.in/notes/writingsetup.html][here]]. +#+begin_src emacs-lisp :noweb-ref org-indent-custom :tangle no +(org-indent-indentation-per-level 1) +#+end_src +These settings are also from the above blog post, but mainly manually set what =org-indent-mode= does anyway. +#+begin_src emacs-lisp :noweb-ref org-custom :tangle no +(org-adapt-indentation nil) +(org-hide-leading-stars t) +(org-hide-emphasis-markers t) +(org-cycle-separator-lines 1) #+end_src * Wrapping up -- cgit v1.2.3 From 9f362946f2b94a93fb63f0865f2ceff2b85af03e Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 3 Aug 2020 10:57:44 +0200 Subject: [Testing] Disable format=flowed --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index a91a2ea..bf2d1c0 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4983,7 +4983,7 @@ Hard new lines are identified using a ~hard~ text property and displayed as =⏎=. We need to make sure all newlines inserted by message initialization (signature, ...) also have this text property. For now I use this bad code. -#+BEGIN_SRC emacs-lisp +#+BEGIN_SRC emacs-lisp :tangle no (use-package messages-are-flowing :straight t :config (add-hook 'message-mode-hook 'messages-are-flowing-use-and-mark-hard-newlines)) -- cgit v1.2.3 From 65ece137e8505e59bd52ff0f0e12bea16b14c7bc Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 3 Aug 2020 18:05:14 +0200 Subject: Rebind shell-pop --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index bf2d1c0..cd8ee60 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4633,7 +4633,7 @@ To open and hide a shell quickly I use =shell-pop=. #+begin_src emacs-lisp (use-package shell-pop :straight t - :bind (("C-!" . shell-pop)) + :bind (("C->" . shell-pop)) :custom (shell-pop-shell-type (quote ("eshell" "*eshell*" (lambda nil (eshell)))))) #+end_src -- cgit v1.2.3 From cc23eaf639fbf2c8d8d05e223f15701a82135ee5 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 5 Aug 2020 12:06:56 +0200 Subject: Add more time budget definitions --- emacs-init.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index cd8ee60..ec3d73f 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3544,7 +3544,10 @@ Gives an overview of time spent on defined budgets this week. Great to track if :custom (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) (:title "├Research" :match "+work+research" :budget "24:00" :blocks (nil week)) - (:title "╰Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week))))) + (:title "├Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week)) + (:title "├Reading" :match "+work+read" :budget "0" :blocks (day week)) + (:title "╰Shaved Yaks" :match "+work+nonprod" :budget "0" :blocks (day week)) + (:title "Personal" :match "+nowork-nonprod" :budget "5:00" :blocks (nil week))))) #+end_src **** Column view #+begin_src emacs-lisp -- cgit v1.2.3 From 4f36e2c080825f43eb7afa5f0592711ac97cc9c7 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 22 Aug 2020 18:13:47 +0200 Subject: Set ox-icalendar to always create ids for caldav --- emacs-init.org | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index ec3d73f..8995856 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3713,20 +3713,6 @@ Also display remote images by downloading them. #+begin_src emacs-lisp :noweb-ref ob-hooks :tangle no (org-babel-after-execute . org-display-inline-images) #+end_src -*** org-caldav -#+begin_src emacs-lisp -(use-package org-caldav - :straight t - :custom - (org-caldav-url private/calendar-url) - (org-caldav-calendar-id private/calendar-id) - (org-caldav-inbox "~/sync/w.org") - (org-caldav-files nil) - (org-caldav-sync-direction 'cal->org) - (org-caldav-delete-calendar-entries 'never) - (org-caldav-exclude-tags nil) -) -#+end_src *** Babel This function is handy to use in header arguments to create names based on the current org heading. E.g. =:var data=(fpi/format-headline "/tmp/prefix_")= #+begin_src emacs-lisp @@ -3755,6 +3741,29 @@ This function is handy to use in header arguments to create names based on the c #+begin_src emacs-lisp (use-package ol-bbdb) #+end_src +*** icalendar support +While =org-caldav= offers syncing with caldav servers it relies on =ox-icalendar= to convert between org entries and icalendar events. +**** org-caldav +#+begin_src emacs-lisp +(use-package org-caldav + :straight t + :custom + (org-caldav-url private/calendar-url) + (org-caldav-calendar-id private/calendar-id) + (org-caldav-inbox "~/sync/w.org") + (org-caldav-files nil) + (org-caldav-sync-direction 'cal->org) + (org-caldav-delete-calendar-entries 'never) + (org-caldav-exclude-tags nil) +) +#+end_src +**** ox-icalendar +#+begin_src emacs-lisp +(use-package ox-icalendar + :after org + :custom + (org-icalendar-store-UID t)) +#+end_src *** prettify symbols Set some prettify symbols for org mode. #+begin_src emacs-lisp -- cgit v1.2.3 From fdbc4e7f214335e39bddd2842808e0871ef666aa Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 22 Aug 2020 18:35:43 +0200 Subject: Add function to create svg screenshots --- emacs-init.org | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 8995856..c7025e3 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -47,6 +47,7 @@ - [[#bbdb][BBDB]] - [[#compile][Compile]] - [[#context-aware-hydra][Context aware hydra]] + - [[#minor-utilities][Minor utilities]] - [[#language-settings][Language settings]] - [[#spellcheck][Spellcheck]] - [[#interface][Interface]] @@ -5310,6 +5311,23 @@ _q_ quit _r_ remove result _e_ examplify region ("/" ibuffer-filter-disable "disable") ("b" hydra-ibuffer-main/body "back" :color blue)) #+END_SRC +** Minor utilities +*** Screenshots / -casts +[[https://gitlab.com/ambrevar/emacs-gif-screencast][Here]] is a guide to creating emacs gif screencasts. + +If compiled with =cairo= support emacs can directly create svg screenshots ([[https://www.reddit.com/r/emacs/comments/idz35e/emacs_27_can_take_svg_screenshots_of_itself/][source]]). +#+begin_src emacs-lisp +(defun screenshot-svg () + "Save a screenshot of the current frame as an SVG image. +Saves to a temp file and puts the filename in the kill ring." + (interactive) + (let* ((filename (make-temp-file "Emacs-" nil ".svg")) + (data (x-export-frames nil 'svg))) + (with-temp-file filename + (insert data)) + (kill-new filename) + (message filename))) +#+end_src * Language settings End sentences with single spaces. #+begin_src emacs-lisp -- cgit v1.2.3 From fb7a691e9638874382adae288299b5193368cbaa Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 23 Aug 2020 12:54:57 +0200 Subject: Do not save journal creation date in the headline --- emacs-init.org | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index c7025e3..d2492e2 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3927,13 +3927,19 @@ Capture templates for journal entries. Mostly to just keep track of things I hav (file+olp+datetree ,org-journal-file) ;; "** %<%H:%M> %a\n %i%? \n%:description\n%:elfeed-entry-content\n%:elfeed-entry-date\n%:elfeed-entry-meta\n%:elfeed-entry-title\n%:elfeed-entry-enclosures\n%:elfeed-entry-tags" ) - "** %<%H:%M> %a + "** %a +:PROPERTIES: +:CREATED: %U +:END: %i%?" ) ("je" "Manual Entry" entry (file+olp+datetree ,org-journal-file) - "** %<%H:%M> %? + "** %? +:PROPERTIES: +:CREATED: %U +:END: %i" ) #+END_SRC To get the title from the url in =kill-ring= I use [[id:dc4129ff-6d76-4f12-926f-c62a687a39ec][org-web-tools]]. @@ -3942,7 +3948,10 @@ To get the title from the url in =kill-ring= I use [[id:dc4129ff-6d76-4f12-926f- entry (file+olp+datetree ,org-journal-file) - "** %<%H:%M> %(org-web-tools--org-link-for-url (org-web-tools--get-first-url))%? + "** %(org-web-tools--org-link-for-url (org-web-tools--get-first-url))%? +:PROPERTIES: +:CREATED: %U +:END: %i") #+END_SRC ***** Interrupts -- cgit v1.2.3 From bcfafcfd59a5f88116d4f1cd47839d1698cc5e3c Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:49:27 +0200 Subject: Exclude ATTACH from tag inheritance --- emacs-init.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index d2492e2..519cf20 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3901,6 +3901,10 @@ content syncing upon commit. :custom (org-attach-git-annex-cutoff 0)) #+end_src +Also exclude =ATTACH= from the inherited tags +#+begin_src emacs-lisp :tangle no :noweb-ref org-custom-no-inheritance-tags +"ATTACH" +#+end_src *** Org-Capture #+BEGIN_SRC emacs-lisp (use-package org-capture -- cgit v1.2.3 From 5fb3e577358ad0be302e1d0fc8dba515d2204692 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:49:40 +0200 Subject: Don't refill text with eww Let prose-mode to the refilling instead --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 519cf20..1123872 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4916,7 +4916,7 @@ tools. (browse-url-browser-function 'eww-browse-url) (browse-url-generic-program "firefox") (shr-external-browser 'browse-url-generic) - (shr-width (current-fill-column)) + (shr-width 900) (shr-max-image-proportion 0.4) (shr-use-colors nil) (shr-use-fonts nil) ) -- cgit v1.2.3 From 0deffbcd9a115168e1d2f355ee54f69a349d427b Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:50:33 +0200 Subject: Smaller contact info in bbdb pop up --- emacs-init.org | 1 + 1 file changed, 1 insertion(+) diff --git a/emacs-init.org b/emacs-init.org index 1123872..deef3bd 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5087,6 +5087,7 @@ For now I use this bad code. (bbdb-mua-auto-update-init 'gnus 'message) (setq bbdb-mua-pop-up 'horiz) +(setq bbdb-pop-up-layout 'one-line) ;; size of the bbdb popup (setq bbdb-pop-up-window-size 0.15) (setq bbdb-mua-pop-up-window-size 0.15) -- cgit v1.2.3 From 8c8987aa86993c100b20414a46e3dfcf7dc57cd0 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:51:14 +0200 Subject: Add whole-line-or-region & redtick packages --- emacs-init.org | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index deef3bd..40bb8ff 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5342,6 +5342,20 @@ Saves to a temp file and puts the filename in the kill ring." (kill-new filename) (message filename))) #+end_src +*** Whole-line-or-region +#+begin_src emacs-lisp +(use-package whole-line-or-region + :straight t + :config + (whole-line-or-region-global-mode 1) + (delight 'whole-line-or-region-local-mode nil t)) +#+end_src +*** Pomodoro / Redtick +#+begin_src emacs-lisp +(use-package redtick + :straight t + :config (redtick-mode 1)) +#+end_src * Language settings End sentences with single spaces. #+begin_src emacs-lisp -- cgit v1.2.3 From 409e09d585c974038801b62f9c9909e109136810 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:51:30 +0200 Subject: Add a mode to toggle between space and tab indentation --- emacs-init.org | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 40bb8ff..1e337eb 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5416,8 +5416,33 @@ I do not really care about spaces versus tabs most of the time. I only want it to be consistent within a file. #+begin_src emacs-lisp (use-package emacs + :config + (define-minor-mode tab-mode + "Toggle tab and space based indentation." + :init-value nil + :lighter " »" + (if tab-mode + (progn + (setq indent-tabs-mode t) + (setq tab-width 4) + ) + (setq indent-tabs-mode nil) + (setq tab-width 8) + )) + (defun enable-tab-mode () + (tab-mode 1)) + (defun disable-tab-mode () + (tab-mode -1)) :custom - (indent-tabs-mode nil)) + (indent-tabs-mode nil) + ;; (tab-width 4) + ;; (tab-mode 1) + :hook + (prog-mode . enable-tab-mode) + (emacs-lisp-mode . disable-tab-mode) + (lisp-mode . disable-tab-mode) + (matlab-mode . enable-tab-mode) + ) #+end_src Instead of =$= use =⏎= to indicate newlines #+begin_src emacs-lisp -- cgit v1.2.3 From f860cc0d756a713e9371892bb51cf33a5c767692 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:52:20 +0200 Subject: Add functions to split window left and above --- emacs-init.org | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 1e337eb..6f6badd 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2885,13 +2885,24 @@ better performance. =fit-window-to-buffer= automatically shrinks the current buffer based on the amount of displayed text. #+begin_src emacs-lisp - (use-package window - :init - <> - :custom - (fit-window-to-buffer-horizontally t) - :bind (:map fpi-map ("s" . fit-window-to-buffer)) - ) +(use-package emacs % windows.el does not (provide 'windows) + :init + <> + :custom + (fit-window-to-buffer-horizontally t) + :config + (defun split-window-left (&optional size) + (interactive "P") + (split-window-right size) + (other-window 1)) + (defun split-window-above (&optional size) + (interactive "P") + (split-window-below size) + (other-window 1)) + :bind + (:map global-map ("C-x C-3" . split-window-left)) + (:map global-map ("C-x C-2" . split-window-above)) + (:map fpi-map ("s" . fit-window-to-buffer))) #+end_src *** Window rules #+begin_src emacs-lisp :noweb-ref window -- cgit v1.2.3 From 4116684e3b3d900bfa77fef1f99d602fec088f04 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:53:29 +0200 Subject: Slim down time budgets as it was too slow --- emacs-init.org | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 6f6badd..9f7705b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3557,8 +3557,7 @@ Gives an overview of time spent on defined budgets this week. Great to track if (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) (:title "├Research" :match "+work+research" :budget "24:00" :blocks (nil week)) (:title "├Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week)) - (:title "├Reading" :match "+work+read" :budget "0" :blocks (day week)) - (:title "╰Shaved Yaks" :match "+work+nonprod" :budget "0" :blocks (day week)) + (:title "╰Reading" :match "+work+read" :budget "5:00" :blocks (workday week)) (:title "Personal" :match "+nowork-nonprod" :budget "5:00" :blocks (nil week))))) #+end_src **** Column view -- cgit v1.2.3 From 71b8eb226d6eea7226cfbb7ceb760f5a2ffc8e5a Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:49:14 +0200 Subject: Add org-protocol capture templates --- emacs-init.org | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 9f7705b..4b15bd1 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4016,7 +4016,7 @@ Instead of project related capture templates, I use the same template for all ta #+END_SRC ***** Plans & Ideas #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates -("p" "Plans/Ideas" +("P" "Plans/Ideas" entry (file "~/sync/refile.org") "*** PLANNING %? @@ -4069,6 +4069,21 @@ Instead of project related capture templates, I use the same template for all ta :empty-lines 1 :immediate-finish t) #+END_SRC +***** org-protocol +#+begin_src emacs-lisp :tangle no :noweb-ref org-capture-templates + ("p" "Protocol" entry (file+olp+datetree ,org-journal-file) + "* %^{Title} +:PROPERTIES: +:SOURCE: %c +:CREATED: %U +:END: +#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?") +("L" "Protocol Link" entry (file+olp+datetree ,org-journal-file) + "* %? [[%:link][%:description]] +:PROPERTIES: +:CREATED: %U +:END:") +#+end_src ***** Old templates Templates I no longer use, but may be interesting. #+BEGIN_SRC emacs-lisp :tangle no -- cgit v1.2.3 From 6550179743ed2f8a9958ec731d63c7b74aa8bddd Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 1 Sep 2020 12:54:46 +0200 Subject: Delight whitespace-mode, which-key-mode --- emacs-init.org | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 4b15bd1..4237164 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -300,9 +300,10 @@ to get a list of available commands. =which-key= shows these in a small popup, which I think is more handy. #+begin_src emacs-lisp (use-package which-key - :delight :straight t - :custom (which-key-idle-delay 0.4) + :custom + (which-key-idle-delay 0.4) + (which-key-lighter "") :config (which-key-mode 1)) #+end_src *** Try @@ -5472,6 +5473,7 @@ want it to be consistent within a file. Instead of =$= use =⏎= to indicate newlines #+begin_src emacs-lisp (use-package whitespace + :delight :custom (whitespace-display-mappings '((space-mark 32 [183] [46]) -- cgit v1.2.3 From 569d7a8415f8a593b98818d095e18c0d2c4ab67d Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:34:18 +0200 Subject: Add header-info package --- emacs-init.org | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 4237164..6883fa3 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -339,7 +339,15 @@ leaves a gap at the bottom. This removes it. #+BEGIN_SRC emacs-lisp (setq frame-resize-pixelwise t) #+END_SRC -*** Remove mode line clutter +*** Mode Line & Header Line +=header-info= is an easy way to move part of the mode line information to the header line instead. + +#+begin_src emacs-lisp +(use-package header-info + :straight (:host github :repo "fpiper/header-info" + :branch "master")) +#+end_src +**** Remove mode line clutter #+begin_src emacs-lisp (use-package delight :straight t -- cgit v1.2.3 From 7132df64865d81a89472f1c1dae19e6b0ce35dbc Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:34:41 +0200 Subject: Try setting projectile cache & disable it for now projectile causes lag on remote files due to repeatedly calling `file-remote-p` --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 6883fa3..e07a8ab 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2825,8 +2825,9 @@ some safe local variable values. (setq projectile-indexing-method 'alien) (setq projectile-enable-caching t) (setq projectile-completion-system 'ido) + (setq projectile-file-exists-local-cache-expire (* 5 60)) :config - (projectile-mode 1) + ;; (projectile-mode 1) :bind (("C-c p" . projectile-command-map))) #+END_SRC ** Working with buffers -- cgit v1.2.3 From 37d825800e780a241a5fbd8c4e8d66e960a20cb1 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 16:23:08 +0200 Subject: Fix comment syntax --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index e07a8ab..89201f9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2895,7 +2895,7 @@ better performance. =fit-window-to-buffer= automatically shrinks the current buffer based on the amount of displayed text. #+begin_src emacs-lisp -(use-package emacs % windows.el does not (provide 'windows) +(use-package emacs ;; windows.el does not (provide 'windows) :init <> :custom -- cgit v1.2.3 From 96d05ed465c3d3ec2ca6a86e0f62f348f86af452 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:07:43 +0200 Subject: Enable use of hi-lock map in matlab-mode --- emacs-init.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 89201f9..e256e1d 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3103,7 +3103,9 @@ area. *** Matlab #+begin_src emacs-lisp (use-package matlab - :straight matlab-mode) + :straight matlab-mode + :config + (unbind-key "M-s" matlab-mode-map)) #+end_src ** Org mode Org is the mode you never need to leave, if you do not want to. My org -- cgit v1.2.3 From 6449e821e8c7bceedb221d36765a9c51659ea515 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:09:34 +0200 Subject: Make fit-window-to-buffer consider olivetti mode --- emacs-init.org | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index e256e1d..36afbf4 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2892,6 +2892,9 @@ better performance. (ibuffer-do-sort-by-alphabetic))))) #+end_src ** Window configuration +:PROPERTIES: +:ID: 99f1af26-1383-43c1-8408-9a13c495925e +:END: =fit-window-to-buffer= automatically shrinks the current buffer based on the amount of displayed text. #+begin_src emacs-lisp @@ -2912,7 +2915,8 @@ on the amount of displayed text. :bind (:map global-map ("C-x C-3" . split-window-left)) (:map global-map ("C-x C-2" . split-window-above)) - (:map fpi-map ("s" . fit-window-to-buffer))) + <> + ) #+end_src *** Window rules #+begin_src emacs-lisp :noweb-ref window @@ -5586,6 +5590,24 @@ These settings are also from the above blog post, but mainly manually set what = (org-hide-emphasis-markers t) (org-cycle-separator-lines 1) #+end_src + +While I generally use ~fit-window-to-buffer~ (bound to =C-z s=) to fit a buffer to its content width (see [[id:99f1af26-1383-43c1-8408-9a13c495925e][Window configuration]]), buffers in =prose-mode= can reduced to ~olivetti-body-width~ if it is an integer. +#+begin_src emacs-lisp +(defun fpi/fit-window-to-buffer (&optional WINDOW MAX-HEIGHT MIN-HEIGHT MAX-WIDTH MIN-WIDTH PRESERVE-SIZE) + "Wrapper around `fit-window-to-buffer' which considers `olivetti-mode'. + +If `olivetti-body-width' is a number fit the window width to it instead of the actual line width." + (interactive) + (let ((max-width (when (and olivetti-mode (numberp olivetti-body-width)) + (round (* 1.03 olivetti-body-width))))) + (fit-window-to-buffer (selected-window) nil nil max-width nil) + )) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings +(define-key 'fpi-map (kbd "s") 'fpi/fit-window-to-buffer) +#+end_src + * Wrapping up Some stuff that is run after everything else. -- cgit v1.2.3 From 6c2f7b38c00515575617a639177d8b1a9a0f6ae3 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 21 Sep 2020 10:25:48 +0200 Subject: Forward messages as mime type --- emacs-init.org | 1 + 1 file changed, 1 insertion(+) diff --git a/emacs-init.org b/emacs-init.org index 36afbf4..49605d5 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4994,6 +4994,7 @@ I use =msmtp= to send mail. (message-sendmail-envelope-from 'header) (message-sendmail-f-is-evil nil) (message-kill-buffer-on-exit t) + (message-forward-as-mime t) :hook (message-mode . footnote-mode)) (use-package sendmail :custom -- cgit v1.2.3 From 56a173029321ad033c2326c3d3dddd3022dc95cb Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:13:50 +0200 Subject: Add general org-protocol setup --- emacs-init.org | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 49605d5..de60cf7 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4086,6 +4086,41 @@ Instead of project related capture templates, I use the same template for all ta :immediate-finish t) #+END_SRC ***** org-protocol +:PROPERTIES: +:ID: 28704dfb-7647-43ac-b96f-5967383d1188 +:END: +Org-protocol is an easy way to capture stuff from outside emacs. +#+begin_src emacs-lisp +(use-package org-protocol) +#+end_src +To install the handler for =org-protocol://= URIs under linux you probably need a =.desktop= file similar to the one below. Place it under =~/.local/share/applications= and run src_shell{update-desktop-database}. +# #+HEADER: :tangle ~/.local/share/applications/org-protocol.desktop +#+begin_src conf +[Desktop Entry] +Version=1.0 +Encoding=UTF-8 +Name=Org Protocol +Comment=OrgProtocol URI handler +Exec=/home/fpi/.local/bin/emacsclient %u +Type=Application +Terminal=false +MimeType=x-scheme-handler/org-protocol;⏎ +#+end_src +Under Windows install a registry key. The example below works for Emacs running under WSL. Place it in a =.reg= file and open it with the registry editor to install. +# #+HEADER: :tangle ~/win/tmp/org-protocol.reg +#+begin_src conf +REGEDIT4 + +[HKEY_CLASSES_ROOT\org-protocol] +@="URL:Org Protocol" +"URL Protocol"="" +[HKEY_CLASSES_ROOT\org-protocol\shell] +[HKEY_CLASSES_ROOT\org-protocol\shell\open] +[HKEY_CLASSES_ROOT\org-protocol\shell\open\command] +@="\"C:\\Windows\\System32\\wsl.exe\" emacsclient \"%1\"" +#+end_src + +To be compatible with [[https://github.com/sprig/org-capture-extension][this chromium/firefox extension]] I use these capture templates: #+begin_src emacs-lisp :tangle no :noweb-ref org-capture-templates ("p" "Protocol" entry (file+olp+datetree ,org-journal-file) "* %^{Title} -- cgit v1.2.3 From c359bbf6aedb1b8ba3a764889e3d8cfa18c13abe Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:15:44 +0200 Subject: Add Functions to create zettel from IEEE capture --- emacs-init.org | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index de60cf7..f5f0d20 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4292,10 +4292,14 @@ A small function to toggle the encryption state of the current entry. (entry (bibtex-parse-entry t)) (key (reftex-get-bib-field "=key=" entry)) (pdf (funcall org-ref-get-pdf-filename-function key))) + (message "%s" pdf) (if (file-exists-p pdf) (org-open-link-from-string (format "[[file:%s]]" pdf)) - (dired (file-name-directory pdf)) - (ding)))))) + ;; try to get pdf + (or (let ((doi-utils-open-pdf-after-download t)) + (doi-utils-get-bibtex-entry-pdf)) + (progn (dired (file-name-directory pdf)) + (ding)))))))) #+end_src ***** Capturing entries I store my bibtex references in an org file together with my notes. In @@ -4347,6 +4351,93 @@ Here's a function to easily copy a doi from the results of =crossref-lookup=. :bind (:map biblio-selection-mode-map ("d" . fpi/biblio-get-doi))) #+end_src +***** org-protocol conversion +Capturing new entries with org-protocol is convenient. To convert the result of [[id:28704dfb-7647-43ac-b96f-5967383d1188][my capture templates]] to a valid entry, we have to extract the doi. +#+begin_src emacs-lisp +(defun fpi/ieee-to-doi (url) + "Get doi from an ieeexplore.ieee.org page." + (let* ((meta (with-current-buffer (url-retrieve-synchronously url) + (goto-char 1) + (search-forward "global.document.metadata=") + (kill-sexp) + (pop kill-ring))) + (json (json-read-from-string meta))) + (alist-get 'doi json))) +#+end_src +Other keys which IEEE returns are: +#+begin_example +(mapcar (lambda (l) (car l)) json) +(userInfo authors isbn articleNumber dbTime metrics purchaseOptions getProgramTermsAccepted sections formulaStrippedArticleTitle allowComments pdfUrl keywords abstract pubLink doiLink rightsLink pdfPath startPage endPage publicationTitle displayPublicationTitle doi issueLink isGetArticle isGetAddressInfoCaptured isMarketingOptIn applyOUPFilter pubTopics publisher isOUP isFreeDocument isSAE isNow isCustomDenial conferenceDate isDynamicHtml isStandard displayDocTitle isNotDynamicOrStatic isPromo htmlAbstractLink xploreDocumentType chronOrPublicationDate isConference isOpenAccess persistentLink isEarlyAccess htmlLink publicationDate isJournal isBook isBookWithoutChapters isChapter isStaticHtml isMorganClaypool isProduct isEphemera accessionNumber dateOfInsertion isACM isSMPTE startPage openAccessFlag ephemeraFlag title confLoc accessionNumber html_flag ml_html_flag sourcePdf content_type mlTime chronDate xplore-pub-id pdfPath isNumber rightsLinkFlag dateOfInsertion contentType publicationDate publicationNumber citationCount xplore-issue articleId publicationTitle sections onlineDate conferenceDate publicationYear subType _value lastupdate mediaPath endPage displayPublicationTitle doi) +#+end_example +Combining this with other functions allows us to do the whole conversion. In the future the citation information can be directly from extracted from the retrieved webpage instead of over the doi. +#+begin_src emacs-lisp +(defun fpi/convert-capture-bib () + "Convert current org-protocol ieee capture to bib." + (interactive) + (let ((rep (fpi/get-capture-bib-replacement))) + (kill-region (point-min) (point-max)) + (insert rep) + )) +(defun fpi/get-capture-bib-replacement () + (save-excursion + (goto-char (point-min)) + (org-next-link) + (let* ((link (org-element-context)) + (url (concat (org-element-property :type link) + ":" + (org-element-property :path link)))) + (fpi/add-org-from-doi + (fpi/ieee-to-doi url))))) + +(defun fpi/format-org-roam-from-doi (&optional doi) + "Get bibtex entry from doi and format for org-roam. Also downloads the +pdf if available." + (let* ((doi (or doi (read-string "Enter doi: "))) + (content (replace-regexp-in-string "\n$" "" (doi-utils-doi-to-bibtex-string doi))) + (cleaned (with-temp-buffer + (insert content) + (org-ref-clean-bibtex-entry) + (org-bibtex-read) + (buffer-substring (point-min) (point-max)))) + (parsed (reftex-parse-bibtex-entry cleaned)) + (key (org-ref-reftex-get-bib-field "&key" parsed)) + (first (when (string-match "^\\(.*?\\)_" key) (match-string 1 key))) + (title (org-ref-reftex-get-bib-field "title" parsed))) + (setq fpi//capture-bibtex-key key) + (with-temp-buffer + (org-mode) + (insert (format "#+TITLE: %s: %s\n" first title)) + (insert (format "#+ROAM_KEY: cite:%s\n\n" key)) + ;; (org-bibtex-write) + (goto-char (point-max)) + (insert "#+BEGIN_SRC bibtex\n") + (insert cleaned) + (insert "\n#+END_SRC\n") + (list key + (buffer-substring (point-min) (point-max)))))) + +(defun fpi/create-org-roam-from-doi (&optional doi) + (interactive) + (let* ((resp (fpi/format-org-roam-from-doi doi)) + (key (car resp)) + (content (cadr resp))) + (find-file (expand-file-name (format "Lit/%s.org" key) org-roam-directory)) + (org-mode) + (insert content))) + +(defun fpi/create-org-roam-from-protocol-capture () + "Create a org-roam entry from an org-protocol capture buffer." + (interactive) + (save-excursion + (goto-char (point-min)) + (org-next-link) + (let* ((link (org-element-context)) + (url (concat (org-element-property :type link) + ":" + (org-element-property :path link)))) + (fpi/create-org-roam-from-doi + (fpi/ieee-to-doi url))))) +#+end_src *** Toggle drawer visibility #+begin_src emacs-lisp (setq fpi/org-meta-heading-info-store nil) -- cgit v1.2.3 From 5809819860236e5fa36cce5f20624668fd46f88d Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 30 Sep 2020 10:59:33 +0200 Subject: Disable auto-fill-mode in message-mode --- emacs-init.org | 1 + 1 file changed, 1 insertion(+) diff --git a/emacs-init.org b/emacs-init.org index f5f0d20..df2f765 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5121,6 +5121,7 @@ I use =msmtp= to send mail. (message-sendmail-f-is-evil nil) (message-kill-buffer-on-exit t) (message-forward-as-mime t) + (message-fill-column nil) ;; to disable auto-fill-mode :hook (message-mode . footnote-mode)) (use-package sendmail :custom -- cgit v1.2.3 From 6517bb2063a7a537588925f7d6fb8346fb73bc5a Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 30 Sep 2020 10:59:48 +0200 Subject: Add spice-mode to auto-mode-alist --- emacs-init.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index df2f765..737c385 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5135,7 +5135,10 @@ I use =msmtp= to send mail. (use-package mm-decode :config (use-package spice-mode - :straight t) + :straight t + :config + (add-to-list 'auto-mode-alist '("\\.cir$" . spice-mode)) + (add-to-list 'auto-mode-alist '("\\.scs$" . spice-mode))) (defun mm-display-spice-inline (handle) "Show an spice mode text from HANDLE inline." (mm-display-inline-fontify handle 'spice-mode)) -- cgit v1.2.3 From 13017cef0b63e4669ff1d3a039fd3380c8e404aa Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 6 Oct 2020 11:31:34 +0200 Subject: Fix git-annex use-package call Apparently :bind is called before :config --- emacs-init.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 737c385..0b60ada 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2374,10 +2374,12 @@ There are some great ressources on [[https://git-annex.branchable.com/][git-anne :straight t :config <> + :after (dired)) +(use-package git-annex :bind (:map git-annex-dired-map <>) - :after (dired)) + ) #+end_src **** Actions to lock/unlock files #+begin_src emacs-lisp :tangle no :noweb-ref git-annex-dired-bindings -- cgit v1.2.3 From 74b3176c568479d630a2887c5c1a9d8c8200cbd5 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 6 Oct 2020 11:33:39 +0200 Subject: Match size of org inline images to olivetti width At least on my display resolution.. --- emacs-init.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 0b60ada..546bb5f 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3732,7 +3732,7 @@ Make gnorb consider the same refile targets as org. Resize inline images to 400px but respect width specifications in attribute lines. #+begin_src emacs-lisp :noweb-ref org-custom :tangle no -(org-image-actual-width '(400)) +(org-image-actual-width '(600)) #+end_src Also display remote images by downloading them. #+begin_src emacs-lisp :noweb-ref org-custom :tangle no @@ -5675,6 +5675,9 @@ temporary buffer is created. (electric-quote-mode -1)) #+end_src ** Writing Setup +:PROPERTIES: +:ID: 9746c4dd-52d9-47fa-943b-7aa58601f22b +:END: I gather all settings related to writing in a minor mode. #+begin_src emacs-lisp (define-minor-mode prose-mode -- cgit v1.2.3 From 34f73c6877c195b5b0dedfa44d77e473a503147e Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 9 Oct 2020 12:30:45 +0200 Subject: Add ob-spice and ob-spectre packages --- emacs-init.org | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 546bb5f..782542f 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3225,6 +3225,16 @@ Switch projects and subprojects from NEXT back to TODO" ) #+end_src #+begin_src emacs-lisp +(use-package ob-spice + :straight (:host github :repo "fpiper/ob-spice" + :branch "master")) +#+end_src + +#+begin_src emacs-lisp +(use-package ob-spectre + :load-path "~/git/projects/ob-spectre") +#+end_src +#+begin_src emacs-lisp (use-package ob :config (org-babel-do-load-languages 'org-babel-load-languages @@ -3236,6 +3246,7 @@ Switch projects and subprojects from NEXT back to TODO" (gnuplot . t) (dot . t) (spice . t) + (spectre . t) (C . t) (calc . t) (latex . t) -- cgit v1.2.3 From 35f5af8a2d271c4993b269a9e8b69653106673a8 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 9 Oct 2020 12:33:23 +0200 Subject: Extend org-roam config --- emacs-init.org | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 782542f..be80a69 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3821,6 +3821,7 @@ Set some prettify symbols for org mode. (add-hook 'org-mode-hook 'fpi/add-org-prettify-symbols) #+end_src *** org-roam +Org-roam mainly provides a display of backlinks to the current file. This allows the creation of a one-subject-per-file Zettelkasten. #+begin_src emacs-lisp (use-package org-roam :straight t @@ -3829,18 +3830,56 @@ Set some prettify symbols for org mode. (after-init . org-roam-mode) :custom (org-roam-directory "~/git/projects/zettel/") + (org-roam-tag-sources '(prop last-directory)) + (org-roam-buffer-width 0.2) + (org-roam-graph-exclude-matcher "index.org") + (org-roam-graph-viewer + (lambda (file) + (let ((org-roam-graph-viewer "/mnt/c/Program Files/Mozilla Firefox/firefox.exe")) + (org-roam-graph--open (concat "file://///wsl$/Debian" file))))) + (org-roam-capture-templates + '(("d" "default" plain #'org-roam-capture--get-point "%?" :file-name "%<%Y%m%d%H%M%S>-${slug}" :head "#+title: ${title} +" :unnarrowed t) + ("b" "bib" plain #'org-roam-capture--get-point + "%(fpi/org-roam-get-last-content)" + :file-name "Lit/%(fpi/org-roam-get-key \"${title}\")" + :head "" + :unnarowed t))) + (org-roam-capture-ref-templates + '(("r" "ref" plain #'org-roam-capture--get-point "%?" :file-name "Ref/${slug}" :head "#+title: ${title}\n#+ROAM_KEY: ${ref}\n " :unnarrowed t))) :bind (:map org-roam-mode-map (("C-c n l" . org-roam) + ("C-c n u" . org-roam-unlinked-references) ("C-c n f" . org-roam-find-file) - ("C-c n g" . org-roam-show-graph)) + ("C-c n g" . org-roam-graph) + ("C-c n d" . org-roam-doctor) + ("C-c n G" . fpi/org-roam-graph-with-exclude) + ("C-c n t g" . fpi/org-roam-toggle-graph-executable) + ("C-c n x" . org-roam-jump-to-index) + ) :map org-mode-map (("C-c n i" . org-roam-insert))) - :config (defun org-roam--roam-file-link-face (path) - "Return `org-link'" - 'org-link) - ) + :config + (defun org-roam--file-link-face (path) + "Return `org-link'" + 'org-link) + (defun fpi/org-roam-toggle-graph-executable () + (interactive) + (setq org-roam-graph-executable (if (equal org-roam-graph-executable "dot") + "neato" + "dot")) + (message "Set org-roam graphing tool to %s" org-roam-graph-executable)) + (defun fpi/org-roam-graph-with-exclude (&optional arg file node-query) + (interactive "P") + (let ((org-roam-graph-exclude-matcher (completing-read "Exclude matcher to use: " nil))) + (org-roam-graph arg file node-query))) +) +#+end_src +Overwriting ~org-roam--file-link-face~ is a crude fix for hanging emacs. The original function calls file-exist-p which opens a slow tramp connection. +**** org-roam-protocol +#+begin_src emacs-lisp +(use-package org-roam-protocol) #+end_src -Fix for hanging emacs. The original function calls file-exist-p which opens a slow tramp connection. **** org-roam-bibtex #+begin_src emacs-lisp :tangle no (use-package org-roam-bibtex @@ -4429,6 +4468,31 @@ pdf if available." (list key (buffer-substring (point-min) (point-max)))))) +(defun fpi/org-roam-format-from-doi (&optional doi) + (let* ((doi (or doi (read-string "Enter doi: ")))) + (setq fpi/org-roam-last-captured-doi doi) + (fpi/format-org-roam-from-doi doi))) + +(defvar fpi/org-roam-last-content nil) +(defvar fpi/org-roam-last-key nil) +(defun fpi/org-roam-get-key (doi) + (let* ((resp (fpi/format-org-roam-from-doi doi)) + (key (car resp)) + (content (cadr resp))) + (setq fpi/org-roam-last-content content) + key)) +(defun fpi/org-roam-get-last-content () + fpi/org-roam-last-content) +(defun fpi/org-roam-get-last-key () + fpi/org-roam-last-key) +(defun fpi/org-roam-get-content (doi) + (let* ((resp (fpi/format-org-roam-from-doi doi)) + (key (car resp)) + (content (cadr resp))) + (setq fpi/org-roam-last-content content) + (setq fpi/org-roam-last-key key) + content)) + (defun fpi/create-org-roam-from-doi (&optional doi) (interactive) (let* ((resp (fpi/format-org-roam-from-doi doi)) -- cgit v1.2.3 From 378a1aece7e821f5b397201b38dada6aec2ce047 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 9 Oct 2020 12:33:57 +0200 Subject: Reenable org-roam-bibex & fix bibtex paths --- emacs-init.org | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index be80a69..e55cf9a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3881,13 +3881,24 @@ Overwriting ~org-roam--file-link-face~ is a crude fix for hanging emacs. The ori (use-package org-roam-protocol) #+end_src **** org-roam-bibtex -#+begin_src emacs-lisp :tangle no +#+begin_src emacs-lisp (use-package org-roam-bibtex :straight t + :delight :hook (org-roam-mode . org-roam-bibtex-mode) :bind (:map org-mode-map - (("C-c n a" . orb-note-actions)))) -#+end_src + (("C-c n a" . orb-note-actions))) + :after bibtex + :config + (defun bibtex-autokey-get-year () + "Return year field contents as a string obeying `bibtex-autokey-year-length'." + (let* ((yearfield (bibtex-autokey-get-field "year")) + (yearfield (when (equal yearfield "") + (substring (bibtex-autokey-get-field "date") 0 4)))) + (substring yearfield (max 0 (- (length yearfield) + bibtex-autokey-year-length)))))) +#+end_src +Rewrite of ~bibtex-autokey-get-year~ is a crude way to get bibtex to recognize =date= fields as year. *** Org-edna :PROPERTIES: :ID: fd3936c7-9fc5-42d0-990d-32024e23b22f @@ -4316,10 +4327,11 @@ A small function to toggle the encryption state of the current entry. (bibtex-autokey-titlewords 3) (bibtex-autokey-titlewords-stretch 1) (bibtex-autokey-titleword-length 5) + (bibtex-completion-library-path "~/git/projects/personal/Lit") :config (bibtex-set-dialect 'BibTeX)) -(setq bibtex-completion-bibliography "~/git/projects/zettel/Lit/bib.bib") +(setq bibtex-completion-bibliography "~/git/projects/personal/bib.bib") (setq bibtex-completion-notes-path "~/git/projects/zettel/Lit") (setq bibtex-completion-notes-extension ".org") -- cgit v1.2.3 From 02a6837efe67fac64d0e93a294e1ba86bb59e297 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 13 Oct 2020 14:53:57 +0200 Subject: Add magit to project.el prompt --- emacs-init.org | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index e55cf9a..46372d3 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -23,7 +23,7 @@ - [[#dired][Dired]] - [[#tramp][Tramp]] - [[#git][Git]] - - [[#projectile][Projectile]] + - [[#projects][Projects]] - [[#working-with-buffers][Working with buffers]] - [[#window-configuration][Window configuration]] - [[#file-encryption][File encryption]] @@ -2816,9 +2816,26 @@ some safe local variable values. (git-auto-commit-mode . t) (gac-debounce-interval . 600) #+end_src -** Projectile - -#+BEGIN_SRC emacs-lisp +** Projects +*** project.el +#+begin_src emacs-lisp +(use-package project + :init + (defun fpi/project-magit () + (interactive) + (magit-status (project-root (project-current t)))) + :custom + (project-switch-commands + '((?f "Find file" project-find-file) + (?g "Find regexp" project-find-regexp) + (?d "Dired" project-dired) + (?m "Magit" fpi/project-magit) + (?v "VC-Dir" project-vc-dir) + (?e "Eshell" project-eshell)))) +#+end_src +*** Projectile +Projectile should be fully replaceable with =project.el=. Though some packages may still use projectile as dependency.. +#+BEGIN_SRC emacs-lisp :tangle no (use-package projectile :straight t :delight '(:eval (concat " " (projectile-project-name))) -- cgit v1.2.3 From 9f041083becdcb6d9225054e2185fd43a3f551b0 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 30 Oct 2020 19:33:54 +0100 Subject: Add link as ROAM_KEY for roam-protocol ref captures --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 46372d3..3d6e4ed 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4213,7 +4213,8 @@ To be compatible with [[https://github.com/sprig/org-capture-extension][this chr "* %? [[%:link][%:description]] :PROPERTIES: :CREATED: %U -:END:") +:END: +#+ROAM_KEY: %:link") #+end_src ***** Old templates Templates I no longer use, but may be interesting. -- cgit v1.2.3 From 18d64469d5f0be8f049be0131e07fb2a86c68fca Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 6 Nov 2020 16:56:17 +0100 Subject: Add function to toggle org time budgets --- emacs-init.org | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 3d6e4ed..b0cb36f 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3599,12 +3599,26 @@ Gives an overview of time spent on defined budgets this week. Great to track if :straight (:host github :repo "fpiper/org-time-budgets" :branch "develop" :no-byte-compile t) - :custom - (org-time-budgets '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) + :config + (setq fpi/dense-time-budgets + '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) + (:title "Personal" :match "+nowork-nonprod" :budget "5:00" :blocks (nil week)))) + (setq fpi/wide-time-budgets + '((:title "Work" :match "+work-nowork" :budget "40:00" :blocks (workday week)) (:title "├Research" :match "+work+research" :budget "24:00" :blocks (nil week)) (:title "├Teaching" :match "+work+teaching" :budget "8:00" :blocks (nil week)) (:title "╰Reading" :match "+work+read" :budget "5:00" :blocks (workday week)) - (:title "Personal" :match "+nowork-nonprod" :budget "5:00" :blocks (nil week))))) + (:title "Personal" :match "+nowork-nonprod" :budget "5:00" :blocks (nil week)))) + (setq org-time-budgets fpi/wide-time-budgets) + (defun fpi/toggle-time-budgets () + "Toggle between dense and wide time budgets." + (interactive) + (if (eq org-time-budgets fpi/wide-time-budgets) + (progn + (setq org-time-budgets fpi/dense-time-budgets) + (message "Set dense time budgets")) + (setq org-time-budgets fpi/wide-time-budgets) + (message "Set wide time budgets")))) #+end_src **** Column view #+begin_src emacs-lisp -- cgit v1.2.3 From 8f8f115ad2b7bf024e670ec656e7f478839d2680 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:33:00 +0100 Subject: [WIP] Add basis of s/mime email encryption --- emacs-init.org | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index b0cb36f..9f82340 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5266,6 +5266,28 @@ I use =msmtp= to send mail. (add-to-list 'mm-inline-media-tests '("application/x-wine-extension-cir" mm-display-spice-inline identity)) (add-to-list 'mm-inlined-types "application/x-wine-extension-cir")) #+end_src +**** S/MIME +Mail signing and encrypting with S/MIME needs a =gpgsm= setup and =smime.el=. + +One can either use =EasyPG= or =OpenSSL= as external implementations. +#+begin_src emacs-lisp :tangle no +(mml-smime-use 'epg) +#+end_src + +#+begin_src emacs-lisp :tangle no +(mml-default-encrypt-method "smime") +(mml-default-sign-method "smime") +#+end_src + + + +#+begin_src emacs-lisp :tangle no +(use-package smime + :custom + (smime-CA-directory "~/certs/trusted") + (smime-certificate-directory "~/certs") + ) +#+end_src *** MUA/Notmuch After using =mu4e= as my mail user agent for a while I switched to -- cgit v1.2.3 From 4eb11796e1a1233597476d61fed814550744d365 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:33:27 +0100 Subject: [WIP] Add some notification related packages --- emacs-init.org | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 9f82340..9da3cfd 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5775,6 +5775,15 @@ Instead of =$= use =⏎= to indicate newlines [187 9] [92 9])))) #+end_src +** Notifications +#+begin_src emacs-lisp +(use-package sauron + :straight t) +(use-package alert + :straight t) +(use-package org-alert + :straight t) +#+end_src ** Undo Emacs undo mechanic can be confusing. =undo-tree= is a great package -- cgit v1.2.3 From 7d6798c7e74991a5e79b79faee7e5b4562b3d8d7 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:33:42 +0100 Subject: Make „“ act electric --- emacs-init.org | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 9da3cfd..0b407fb 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5811,10 +5811,13 @@ temporary buffer is created. (use-package electric :init (setq electric-pair-inhibit-predicate 'electric-pair-conservative-inhibit) - (setq electric-pair-pairs '((34 . 34) - (8216 . 8217) - (8220 . 8221) - (171 . 187))) + (setq electric-pair-pairs '((?\" . ?\") + (?‘ . ?’) + (?“ . ?”) + (?« . ?») + (?„ . ?“) + (?‚ . ?‘) + )) (setq electric-pair-skip-self 'electric-pair-default-skip-self) (setq electric-quote-context-sensitive t) (setq electric-quote-paragraph t) -- cgit v1.2.3 From 395363ab7522589a1d98af828376a0d14372449c Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:35:24 +0100 Subject: Make gnus articles use prose-mode --- gnus.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gnus.org b/gnus.org index aebf113..996a1c0 100644 --- a/gnus.org +++ b/gnus.org @@ -411,6 +411,11 @@ See [[info:gnus#Window Layout][info:gnus#Window Layout]]. #+begin_src emacs-lisp (setq gnus-use-full-window nil) #+end_src +**** Article Display +#+begin_src emacs-lisp +(use-package gnus-art + :hook (gnus-article-mode . prose-mode)) +#+end_src **** Modeline indicator From the [[https://www.emacswiki.org/emacs/GnusNotify][emacswiki Gnus Notify]]. #+begin_quote -- cgit v1.2.3 From 67ae5fd1922dcf6d44ca6f337126e810309022ef Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 19 Dec 2020 18:39:05 +0100 Subject: Extract straight recipe for org --- emacs-init.org | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 0b407fb..643d640 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3163,9 +3163,17 @@ Hansen's]] configs. - Align tags left :: Fixes problems with line breaking on small window width. +I use a org version with some custom patches. Rather than using something like =el-patch=, I host my version on github for now and update it every so often. This recipe for org is used in all coming =straight.el= calls. +#+begin_src emacs-lisp :noweb-ref org-recipe :tangle no +(org-plus-contrib :host github :repo "fpiper/org-mode" :branch "develop" + ;;:local-repo "org" :files (:defaults "contrib/lisp/*.el") + ) +#+end_src + #+begin_src emacs-lisp (use-package org - :straight (org-plus-contrib :host github :repo "fpiper/org-mode" :branch "develop" :local-repo "org" :files (:defaults "contrib/lisp/*.el")) + :straight + <> :delight (org-cdlatex-mode) :bind (("C-c c" . org-capture) @@ -3678,7 +3686,8 @@ print the list. #+begin_src emacs-lisp (use-package org-checklist :after org - :straight (org-plus-contrib)) + :straight + <>) #+end_src *** Handling web urls **** org-web-tools @@ -3909,7 +3918,8 @@ Org-roam mainly provides a display of backlinks to the current file. This allows Overwriting ~org-roam--file-link-face~ is a crude fix for hanging emacs. The original function calls file-exist-p which opens a slow tramp connection. **** org-roam-protocol #+begin_src emacs-lisp -(use-package org-roam-protocol) +(use-package org-roam-protocol + :after org-roam) #+end_src **** org-roam-bibtex #+begin_src emacs-lisp @@ -4304,7 +4314,8 @@ CLOSED: %\\1 #+begin_src emacs-lisp (use-package org-expiry :after org - :straight (org-plus-contrib) + :straight + <> :custom (org-expiry-handler-function 'org-expiry-archive-subtree) (org-expiry-inactive-timestamps t) -- cgit v1.2.3 From 8082136f84f474f74c507b9053605ab534a5f3b6 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 19 Dec 2020 18:39:39 +0100 Subject: Remove elfeed in favor of gnus --- emacs-init.org | 144 --------------------------------------------------------- 1 file changed, 144 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 643d640..c19d02a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -39,7 +39,6 @@ - [[#proced][Proced]] - [[#pass][Pass]] - [[#ledger][Ledger]] - - [[#elfeed][Elfeed]] - [[#plotting-data][Plotting data]] - [[#html-renderer][HTML renderer]] - [[#email][Email]] @@ -5040,149 +5039,6 @@ Here is a good [[https://www.reddit.com/r/emacs/comments/8x4xtt][reddit thread]] I also use some =org-capture= templates to quickly capture transactions. They are defined in [[file:emacs-private.el.gpg::4][emacs-private.el.gpg]]. -** Elfeed - -#+BEGIN_SRC emacs-lisp -(use-package elfeed - :straight t - :init - (setq elfeed-db-directory "~/.emacs.d/elfeed") - :custom - (elfeed-enclosure-default-dir "~/Downloads") - (elfeed-search-clipboard-type 'CLIPBOARD) - (elfeed-search-title-max-width (current-fill-column)) - (elfeed-search-title-min-width 30) - (elfeed-search-trailing-width 16) - (elfeed-show-truncate-long-urls t) - (elfeed-show-unique-buffers t) - :config - (defalias 'elfeed-toggle-star - (elfeed-expose #'elfeed-search-toggle-all 'star)) - (defun fpi/elfeed-search-show-entry-in-bg (entry) - (interactive (list (elfeed-search-selected :ignore-region))) - (elfeed-search-show-entry entry) - (bury-buffer)) - :bind - (:map elfeed-search-mode-map - ("m" . elfeed-toggle-star) - ("o" . fpi/elfeed-search-show-entry-in-bg) - ("j" . mz/make-and-run-elfeed-hydra) - )) -#+END_SRC -Some feeds I want to automatically mark as read. This way I can look -at them whenever I want to, but they don't show up in the unread search. -#+BEGIN_SRC emacs-lisp -(defun elfeed-mark-all-as-read () - (interactive) - (save-excursion - (mark-whole-buffer) - (elfeed-search-untag-all-unread))) -(defun elfeed-mark-search-read (search-string) - "Mark all results of SEARCH-STRING as read." - (interactive) - (elfeed) - (let ((filter elfeed-search-filter)) - (elfeed-search-set-filter search-string) - (elfeed-mark-all-as-read) - (elfeed-search-set-filter filter) - (bury-buffer))) -#+END_SRC -Now execute this whenever feeds are fetched -#+BEGIN_SRC emacs-lisp -(defun my/elfeed-mark-read (entry) - "Tag ENTRY as read if it contains certain tags" - (when (member 'tRaffic (elfeed-entry-tags entry)) - (elfeed-untag entry 'unread) - )) -(add-hook 'elfeed-new-entry-hook 'my/elfeed-mark-read) -#+END_SRC -*** Elfeed Org -Load elfeed org after adding ~my/elfeed-mark-read~ to -~elfeed-new-entry-hook~. New entries need to get tagged by elfeed org -first before marking them unread based on their tag. -#+BEGIN_SRC emacs-lisp -(use-package elfeed-org - :straight t - :config - (elfeed-org) - (setq rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))) -#+END_SRC -*** Hydra -This creates a smart hydra based on all available tags (see -https://cestlaz.github.io/posts/using-emacs-31-elfeed-3/). -#+BEGIN_SRC emacs-lisp -(defun z/hasCap (s) "" - (let ((case-fold-search nil)) - (string-match-p "[[:upper:]]" s) - )) -(defun z/get-hydra-option-key (s) - "returns single upper case letter (converted to lower) or first" - (interactive) - (let ( (loc (z/hasCap s))) - (if loc - (downcase (substring s loc (+ loc 1))) - (substring s 0 1) - ))) - -;; (active blogs cs eDucation emacs local misc sports star tech unread webcomics) -(defun mz/make-elfeed-cats (tags) - "Returns a list of lists. Each one is line for the hydra configuratio in the form - (c function hint)" - (interactive) - (mapcar (lambda (tag) - (let* ( - (tagstring (symbol-name tag)) - (c (z/get-hydra-option-key tagstring)) - ) - (list c (append '(elfeed-search-set-filter) (list (format "@6-months-ago +%s" tagstring) ))tagstring ))) - tags)) -(defmacro mz/make-elfeed-hydra () - `(defhydra mz/hydra-elfeed () - "filter" - ,@(mz/make-elfeed-cats (elfeed-db-get-all-tags)) - ("*" (elfeed-search-set-filter "@6-months-ago +star") "Starred") - ("M" elfeed-toggle-star "Mark") - ("A" (elfeed-search-set-filter "@6-months-ago") "All") - ("T" (elfeed-search-set-filter "@1-day-ago") "Today") - ("Q" bjm/elfeed-save-db-and-bury "Quit Elfeed" :color blue) - ("q" nil "quit" :color blue) - )) -(defun mz/make-and-run-elfeed-hydra () - "" - (interactive) - (mz/make-elfeed-hydra) - (mz/hydra-elfeed/body)) -#+END_SRC - -*** Youtube to Vlc -Open a entry with vlc -#+BEGIN_SRC emacs-lisp -(defface elfeed-youtube - '((t :foreground "#a9f")) - "Marks YouTube videos in Elfeed." - :group 'elfeed) - -(push '(youtube elfeed-youtube) - elfeed-search-face-alist) - -(defun elfeed-show-vlc () - "Play the current entry with vlc." - (interactive) - (pop-to-buffer (shell-command (format "vlc %s &" (elfeed-entry-link elfeed-show-entry))))) - -(defun elfeed-search-vlc () - "Play the current entry with vlc." - (interactive) - (let ((entries (elfeed-search-selected))) - (dolist (entry entries) - (shell-command (format "vlc %s &" (elfeed-entry-link entry))) - (elfeed-untag entry 'unread) - (elfeed-search-update-entry entry) - (unless (use-region-p) (forward-line))))) - -(define-key elfeed-show-mode-map "v" 'elfeed-show-vlc) -(define-key elfeed-search-mode-map "v" 'elfeed-search-vlc) -#+END_SRC ** Plotting data =gnuplot= is a great option for plotting any kind of data, no matter -- cgit v1.2.3 From fc055499f305d0a3d2d961bc875d8d7f2ac733b8 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 19 Dec 2020 18:36:30 +0100 Subject: Add symlinks for gnus state files --- gnus.org | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gnus.org b/gnus.org index 996a1c0..d3dc7c3 100644 --- a/gnus.org +++ b/gnus.org @@ -4,7 +4,14 @@ ln -siv $(pwd)/tangle/gnus.el ~/.gnus.el #+end_src -Load private settings +I use =nextcloud= to synchronize gnus state files across devices. Alternatively one may use [[info:gnus#The Gnus Cloud][info:gnus#Gnus Cloud]]. Here i symlink the relevant files/directories to my synchronization directory. +#+begin_src shell :results silent :tangle tangle/symlink.sh :shebang "#!/bin/bash" +ln -siv ~/sync/gnus/News ~/News +ln -siv ~/sync/gnus/.newsrc.eld ~/.newsrc.eld +ln -siv ~/sync/gnus/.gnus.registry.eieio ~/.gnus.registry.eieio +#+end_src + +Load private settings. #+begin_src emacs-lisp (setq secret-file (expand-file-name "emacs-private.el.gpg" user-emacs-directory)) -- cgit v1.2.3 From d76076020b849ffc2c0fdf2cd67b55269aa8ae99 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 2 Jan 2021 15:20:13 +0100 Subject: Add bbdb symlink --- emacs-init.org | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index c19d02a..84e6840 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -66,11 +66,13 @@ This files contains all the elisp code normally placed in the .emacs file. It and the =init.el= file are then symlinked to my =~/.emacs.d/= directory. Instead of symlinking the files could also be directly tangled to =~/.emacs.d/=. -#+BEGIN_SRC shell :results silent :tangle tangle/symlink.sh :shebang "#!/bin/bash" +#+BEGIN_SRC shell :results silent :tangle tangle/symlink.sh :shebang "#!/bin/bash" :noweb yes ln -siv $(pwd)/emacs-init.org ~/.emacs.d/ ln -siv $(pwd)/tangle/emacs-init.el ~/.emacs.d/ +ln -siv $(pwd)/tangle/init-exwm.el ~/.emacs.d/ ln -siv $(pwd)/emacs-private.el.gpg ~/.emacs.d/ ln -siv $(pwd)/tangle/init.el ~/.emacs.d/ +<> #+END_SRC An often seen setup is to use ~org-babel-load-file~ in =init.el= to @@ -5287,6 +5289,10 @@ For now I use this bad code. (lambda () (define-key gnus-summary-mode-map (kbd ";") 'bbdb-mua-edit-field))) #+end_src +To synchronize the database across devices I symlink it to my central synchronization directory: +#+begin_src shell :noweb-ref symlinks :tangle no +ln -siv ~/sync/bbdb/bbdb ~/.emacs.d/1 +#+end_src ** Compile Fix ansi colors in compile buffers. From [[https://endlessparentheses.com/ansi-colors-in-the-compilation-buffer-output.html][endlessparentheses]]. #+begin_src emacs-lisp -- cgit v1.2.3 From 7a2846be0bdc8fee0259b145e2557bf18e779f5a Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 2 Jan 2021 15:20:23 +0100 Subject: Remove ~/.emacs.d/lisp from load path --- emacs-init.org | 6 ------ 1 file changed, 6 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 84e6840..3171aec 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4,7 +4,6 @@ - [[#overview][Overview]] - [[#about-this-document][About this document]] - [[#base-settings][Base settings]] - - [[#setup-load-path][Setup load path]] - [[#meta-packages][Meta packages]] - [[#gui-interface][GUI Interface]] - [[#font][Font]] @@ -198,11 +197,6 @@ Notable configs: - [[http://doc.norang.ca/org-mode.html][Bernt Hansen]] * Base settings -** Setup load path -Folder for additional lisp files I may want to load. -#+BEGIN_SRC emacs-lisp -(add-to-list 'load-path "~/.emacs.d/lisp") -#+END_SRC ** Meta packages Packages that don't do anything by themselves, but can be used to help with other package definition and customization. -- cgit v1.2.3 From 6146afda7e492d8308ec3e0369b78a89eedaaa5c Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 2 Jan 2021 15:21:48 +0100 Subject: Disable save password prompt from auth-source --- emacs-init.org | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 3171aec..ea8b991 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -36,7 +36,7 @@ - [[#shell][Shell]] - [[#grep][Grep]] - [[#proced][Proced]] - - [[#pass][Pass]] + - [[#passwords][Passwords]] - [[#ledger][Ledger]] - [[#plotting-data][Plotting data]] - [[#html-renderer][HTML renderer]] @@ -4973,7 +4973,13 @@ Built-in process monitor. (proced-descend t) (proced-filter 'user)) #+END_SRC -** Pass +** Passwords +*** [[info:auth#Top][auth-source]] +#+begin_src emacs-lisp +(use-package auth-source + :custom (auth-source-save-behavior nil)) +#+end_src +*** Pass Emacs interface & mode for the password manager [[https://www.passwordstore.org/][pass/password-store]]. The emacs =pass= package provides a nice buffer listing all stored passwords files and also a good mode to edit them. The @@ -4999,7 +5005,7 @@ prefix to my custom keymap. (call-interactively 'password-store-copy))) :bind (:map fpi-map ("p" . fpi/password-store-copy-pass-or-field))) #+end_src -*** auth-password-store/auth-source-pass +**** auth-password-store/auth-source-pass A password-store backend for the Emacs [[info:auth#Top][auth-source]] library which normally uses the =~/.authinfo= file. For correct setup of password-store files see [[https://rkm.id.au/2015/07/07/integrating-password-store-with-emacs/#fnr.1][here]] and in its [[https://github.com/DamienCassou/auth-password-store][github repo]]. For remote hosts -- cgit v1.2.3 From 06889c7c95969d6c79d1af53e1374838a91593c8 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 2 Jan 2021 15:22:04 +0100 Subject: Add clock capture which clocks into any heading --- emacs-init.org | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index ea8b991..407625e 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4083,6 +4083,13 @@ To get the title from the url in =kill-ring= I use [[id:dc4129ff-6d76-4f12-926f- :END: %i") #+END_SRC +***** Clock +#+begin_src emacs-lisp :tangle no :noweb-ref org-capture-templates +("c" "Clock" + plain + (file "~/sync/refile.org") + "%(fpi/org-clock-in-heading)") +#+end_src ***** Interrupts For interruptions. These are saved in a global refile file and to be sorted to their appropriate place. #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates @@ -4159,8 +4166,8 @@ Instead of project related capture templates, I use the same template for all ta #+END_SRC ***** Interesting stuff I have to look at later #+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-capture-templates -("c" "Checkout") -("cr" ".. & read" +("C" "Checkout") +("Cr" ".. & read" entry (file "~/sync/refile.org") "* TODO %a :READLIST: -- cgit v1.2.3 From 51ed178f7993ca3042f2fabbb4c999d9db8fa976 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 2 Jan 2021 15:22:27 +0100 Subject: Add basic support for custom device configurations Each device config is stored in the form ("hostname" (:type desktop :wm awesome :key value)) --- emacs-init.org | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 407625e..844abb0 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -6,6 +6,9 @@ - [[#base-settings][Base settings]] - [[#meta-packages][Meta packages]] - [[#gui-interface][GUI Interface]] + - [[#devices][Devices]] + - [[#server][Server]] + - [[#exwm][Exwm]] - [[#font][Font]] - [[#theme--faces][Theme & Faces]] - [[#user-info][User info]] @@ -362,6 +365,51 @@ it calls ~force-mode-line-update~. (help-mode . hide-mode-line-mode)) (global-set-key (kbd "C-c m") 'hide-mode-line-mode) #+end_src +** Devices +To support different settings on different devices storing some device information seems useful. +#+begin_src emacs-lisp +(setq fpi/current-device (system-name)) +(setq fpi/devices + '(("pan" + (:type desktop + :wm exwm)) + ("xcarb" + (:type mobile)) + )) +(defun fpi/device-info (device prop) + "Return property PROP of DEVICE as stored in `fpi/devices'." + (let ((info (cadr (assoc device fpi/devices)))) + (plist-get info prop))) +(defun fpi/current-device-info (prop) + "Return property PROP of current device." + (let ((info (cadr (assoc fpi/current-device fpi/devices)))) + (plist-get info prop))) +#+end_src +Now we can easily extract info on the current device. +#+begin_src emacs-lisp :tangle no :exports both :results replace +(fpi/device-info "pan" :type) +#+end_src + +#+RESULTS: +: desktop + +** Server +#+begin_src emacs-lisp :tangle no +(use-package server + :config + (unless (server-running-p) (server-start))) +#+end_src +** Exwm +The previous sections cover all basic settings which may be useful when loading =exwm=. +My =exwm= configurations are in [[file:init-exwm.org][init-exwm.org]] and we can load the tangled version here. In the future I may convert it into a standalone package. +#+begin_src emacs-lisp +(when (eq (fpi/current-device-info :wm) 'exwm) + (load (concat user-emacs-directory "init-exwm.el")) +#+end_src +Also enable =exwm=. This does nothing if =emacs= is not started +#+begin_src emacs-lisp + (exwm-enable)) +#+end_src ** Font I am still not quite sure on my choice of font. -- cgit v1.2.3 From 5fdea9cabfb29645af73d9a36c37a2fbc1f9dea1 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 15:46:32 +0100 Subject: Add org-roam-todo --- emacs-init.org | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 844abb0..99ce35c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3939,6 +3939,7 @@ Org-roam mainly provides a display of backlinks to the current file. This allows ("C-c n G" . fpi/org-roam-graph-with-exclude) ("C-c n t g" . fpi/org-roam-toggle-graph-executable) ("C-c n x" . org-roam-jump-to-index) + <> ) :map org-mode-map (("C-c n i" . org-roam-insert))) @@ -3956,9 +3957,25 @@ Org-roam mainly provides a display of backlinks to the current file. This allows (interactive "P") (let ((org-roam-graph-exclude-matcher (completing-read "Exclude matcher to use: " nil))) (org-roam-graph arg file node-query))) -) + <> + ) #+end_src Overwriting ~org-roam--file-link-face~ is a crude fix for hanging emacs. The original function calls file-exist-p which opens a slow tramp connection. + +The idea of ~fpi/org-roam-todo~ is from a post by [[https://oremacs.com/2020/12/31/happy-new-year/][aboabo]]. It lists all open todos in zettelkasten entries and is a (faster) alternative to running an todo agenda with ~org-agenda-files~ set to ~org-roam-directory~. +#+begin_src emacs-lisp :tangle no :noweb-ref org-roam-config +(defun fpi/org-roam-todo () + (interactive) + (setq unread-command-events + (listify-key-sequence (kbd "C-c C-o M->"))) + (counsel-rg "^\\*+ \\(NEXT\\|TODO\\)" org-roam-directory "--sort modified")) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref org-roam-bindings +("C-c n t" . fpi/org-roam-todo) +#+end_src + + **** org-roam-protocol #+begin_src emacs-lisp (use-package org-roam-protocol -- cgit v1.2.3 From 1253da5efb3a9f212d806336cdc4e790677f7aea Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 15:48:30 +0100 Subject: Show sauron in same frame when using exwm --- emacs-init.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 99ce35c..4392955 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -56,6 +56,7 @@ - [[#rainbow-mode][Rainbow mode]] - [[#parentheses][Parentheses]] - [[#whitespace][Whitespace]] + - [[#notifications][Notifications]] - [[#undo][Undo]] - [[#electric-stuff][Electric stuff]] - [[#writing-setup][Writing Setup]] @@ -5723,7 +5724,9 @@ Instead of =$= use =⏎= to indicate newlines ** Notifications #+begin_src emacs-lisp (use-package sauron - :straight t) + :straight t + :custom + (sauron-separate-frame (not (eq (fpi/current-device-info :wm) 'exwm)))) (use-package alert :straight t) (use-package org-alert -- cgit v1.2.3 From 609e78703b9c796f23b921309636140d29fafe87 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 15:49:21 +0100 Subject: Fix sentence --- emacs-init.org | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 4392955..568e2bb 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -393,7 +393,6 @@ Now we can easily extract info on the current device. #+RESULTS: : desktop - ** Server #+begin_src emacs-lisp :tangle no (use-package server @@ -407,7 +406,7 @@ My =exwm= configurations are in [[file:init-exwm.org][init-exwm.org]] and we can (when (eq (fpi/current-device-info :wm) 'exwm) (load (concat user-emacs-directory "init-exwm.el")) #+end_src -Also enable =exwm=. This does nothing if =emacs= is not started +Also enable =exwm=. This does nothing if =emacs= is not started as window manager. #+begin_src emacs-lisp (exwm-enable)) #+end_src -- cgit v1.2.3 From 569f39e08cb584160754896ed72ee84aa5045b72 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 15:49:55 +0100 Subject: Update exwm config & add .desktop entry, exwm-start --- init-exwm.org | 92 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/init-exwm.org b/init-exwm.org index 792dcbe..73a4500 100644 --- a/init-exwm.org +++ b/init-exwm.org @@ -1,19 +1,59 @@ #+PROPERTY: header-args:emacs-lisp :results silent -,#+PROPERTY: header-args:emacs-lisp :tangle tangle/init-exwm.el +#+PROPERTY: header-args:emacs-lisp :tangle tangle/init-exwm.el -When stating the client from .xinitrc, `save-buffer-kill-terminal' will +* Starting EXWM +Either start exwm in =.xinitrc= or if using a display manager setup a desktop file similar to this: +#+HEADER: :tangle /sudo::/usr/share/xsessions/exwm.desktop +#+begin_src conf +[Desktop Entry] +Name=EXWM +Comment=Emacs X Window Manager +TryExec=exwm-start +Exec=exwm-start +Type=Application +#+end_src +With the =exwm-start= script: +#+HEADER: :tangle /sudo::/usr/local/bin/exwm-start +#+begin_src shell :tangle-mode (identity #o755) +#!/usr/bin/env sh + +export VISUAL=emacsclient +export EDITOR="$VISUAL" + +# exec dbus-launch --exit-with-session emacs --eval "(progn (load \"/home/fpi/git/projects/dotfiles/tangle/init-exwm.el\") (exwm-enable))" +# exec dbus-launch --exit-with-session emacs +gpg-agent --daemon +export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) + +exec dbus-launch --exit-with-session /home/fpi/.local/bin/emacs +#+end_src +* EXWM config +#+begin_src emacs-lisp +(use-package exwm + :straight t) +#+end_src +When starting the client from .xinitrc, `save-buffer-kill-terminal' will force-kill Emacs before it can run through `kill-emacs-hook'. #+BEGIN_SRC emacs-lisp (global-set-key (kbd "C-x C-c") 'save-buffers-kill-emacs) #+END_SRC - - set keyboard #+BEGIN_SRC emacs-lisp (shell-command "setxkbmap -layout \"de(neo),us,ru,de\"") #+END_SRC -* functions + +** Monitor setup +#+BEGIN_SRC emacs-lisp +(use-package exwm-randr + :config + (setq exwm-randr-workspace-output-plist '(0 "DP1" 1 "DisplayPort-5")) + ;; (when (equal system-name "pan") + ;; (start-process-shell-command "xrandr" nil "xrandr --output DisplayPort-0 --off --output DisplayPort-1 --off --output DisplayPort-2 --off --output HDMI-A-0 --off --output DisplayPort-3 --mode 2560x1440 --pos 0x612 --rotate normal --output DisplayPort-4 --off --output DisplayPort-5 --mode 2560x1440 --pos 2560x0 --rotate right --output DisplayPort-6 --off") + ;; (exwm-workspace-add)) + (exwm-randr-enable)) +#+END_SRC +** functions #+BEGIN_SRC emacs-lisp (defun ambrevar/switch-to-last-buffer () "Switch to last open buffer in current window." @@ -72,7 +112,7 @@ configuration was previously save, restore that configuration." (setq single-window--last-configuration (current-window-configuration)) (delete-other-windows))) #+END_SRC -** Window swapping +*** Window swapping #+BEGIN_SRC emacs-lisp (defun ambrevar/swap-windows (&optional w1 w2) "If 2 windows are up, swap them. @@ -119,7 +159,7 @@ If W2 is a window too, swap both." (interactive) (ambrevar/swap-windows (window-in-direction 'right))) #+END_SRC -** Volume & Brightness +*** Volume & Brightness #+BEGIN_SRC emacs-lisp (defun exwm-brightness (incdec) (shell-command (concat "xbacklight " incdec "10")) @@ -151,13 +191,13 @@ If W2 is a window too, swap both." :urgency 'low :timeout 550)) #+END_SRC -** XF86 Multimedia keys +*** XF86 Multimedia keys #+BEGIN_SRC emacs-lisp (defun exwm-xf86audio (cmd) ;; Control Spotify (shell-command (concat "dbus-send --type=method_call --dest=org.mpris.MediaPlayer2.spotify /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player." cmd))) #+END_SRC -** Browser switching +*** Browser switching #+BEGIN_SRC emacs-lisp (defun fpi/helm-exwm-switch (class &optional program other-window) "Switch to some EXWM windows belonging to CLASS. @@ -198,11 +238,12 @@ See `helm-exwm-switch'." "firefox")) browse-url-generic-program)) #+END_SRC -* config +** config Time & Battery display #+BEGIN_SRC emacs-lisp (display-time) -(display-battery-mode) +(when (eq (fpi/current-device-info :type) 'mobile) + (display-battery-mode)) #+END_SRC Rename buffer to window title.\\ Spotify's title does not include "spotify" while playing music so just @@ -229,7 +270,8 @@ Non-floating resizing with mouse #+END_SRC System tray #+BEGIN_SRC emacs-lisp -(require 'exwm-systemtray) +(use-package exwm-systemtray + :straight exwm) (exwm-systemtray-enable) (setq exwm-systemtray-height 16) #+END_SRC @@ -243,7 +285,7 @@ List all buffers (setq exwm-workspace-show-all-buffers t) (setq exwm-layout-show-all-buffers t) #+END_SRC -** Helm +*** Helm #+BEGIN_SRC emacs-lisp :results silent (with-eval-after-load 'helm ;; Need `with-eval-after-load' here since 'helm-map is not defined in 'helm-config. @@ -259,11 +301,12 @@ List all buffers ;;(exwm-input-set-key (kbd "s-G") 'ambrevar/helm-grep-git-all-or-ag) ) -(use-package helm-exwm) +(use-package helm-exwm + :straight t) (exwm-input-set-key (kbd "s-w") #'fpi/helm-exwm-switch-browser) (exwm-input-set-key (kbd "s-W") #'helm-exwm-switch-browser-other-window) #+END_SRC -** Keys +*** Keys Global bindings #+BEGIN_SRC emacs-lisp (exwm-input-set-key (kbd "s-K") #'exwm-reset) @@ -313,7 +356,7 @@ XF86 Multimedia Keys (exwm-input--set-key [XF86AudioNext] (lambda () (interactive) (exwm-xf86audio "Next"))) (exwm-input--set-key [XF86AudioPrev] (lambda () (interactive) (exwm-xf86audio "Previous"))) #+END_SRC -*** Local bindings +**** Local bindings #+BEGIN_SRC emacs-lisp (push ?\s- exwm-input-prefix-keys) (define-key exwm-mode-map (kbd "s-SPC") #'exwm-floating-toggle-floating) @@ -328,7 +371,7 @@ Allow access to my personal keymap. (push ?\C-z exwm-input-prefix-keys) #+END_SRC -*** Simulation keys +**** Simulation keys #+BEGIN_SRC emacs-lisp (setq exwm-input-simulation-keys '(([?\C-b] . [left]) @@ -342,14 +385,7 @@ Allow access to my personal keymap. ([?\C-d] . [delete]))) ;;([?\C-k] . [S-end delete]))) ; doesn't work in tilix #+END_SRC -** Multiple monitors -#+BEGIN_SRC emacs-lisp -(require 'exwm-randr) -(setq exwm-randr-workspace-output-plist - '(0 "DP1" 1 "HDMI1" 2 "HDMI2" 3 "eDP1")) -(exwm-randr-enable) -#+END_SRC -** Configure helm-raise-command +*** Configure helm-raise-command ~(shell-command "emacsclient -e ...")~ does not work. Advice ~helm-run-or-raise~ instead and overshadow ~shell-command~. @@ -372,7 +408,7 @@ For now ~helm-run-or-raise~ is redefined after helm is loaded in ;; (setq helm-raise-command "emacsclient -e '(fpi/switch-to-proc-buffer \"%s\")'") (setq helm-raise-command t) #+end_src -** Screenshots +*** Screenshots UncleDave has a nice exwm configuration in his [[https://github.com/daedreth/UncleDavesEmacs/blob/master/config.org][config]]. These snippets are taken from there. @@ -380,7 +416,7 @@ A nice alternative for screenshots in org-mode is ~org-screenshot.el~. It uses ~scrot~ to take screenshots of windows and insert a link the image into the current org buffer. -*** Screenshotting the entire screen +**** Screenshotting the entire screen #+BEGIN_SRC emacs-lisp (defun daedreth/take-screenshot () "Takes a fullscreen screenshot of the current workspace" @@ -398,7 +434,7 @@ image into the current org buffer. (global-set-key (kbd "") 'daedreth/take-screenshot) #+END_SRC -*** Screenshotting a region +**** Screenshotting a region #+BEGIN_SRC emacs-lisp (defun daedreth/take-screenshot-region () "Takes a screenshot of a region selected by the user." -- cgit v1.2.3 From ff54dbbaa1087db7d45aaf5725801098eed20618 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 15:50:51 +0100 Subject: [WIP] Add local maildir --- gnus.org | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gnus.org b/gnus.org index d3dc7c3..6f069f8 100644 --- a/gnus.org +++ b/gnus.org @@ -55,19 +55,36 @@ Noweb the primary server settings together. )) #+end_src -Setup a secondary imap server and a local nntp server I use to fetch -RSS/Atom Feeds asynchronously. +To avoid confusion I enable namespaces for imap groups. +#+begin_src emacs-lisp +(setq nnimap-use-namespaces t) +#+end_src +*** Secondary servers #+begin_src emacs-lisp +<> +#+end_src +**** Personal mailbox +#+begin_src emacs-lisp :tangle no :noweb-ref secondary-select-methods (add-to-list 'gnus-secondary-select-methods `(nnimap ,@private/personal-imap-info (nnimap-stream ssl) (nnir-search-engine imap) (nnimap-inbox "INBOX"))) +#+end_src +**** RSS/Atom over nntp +Setup a secondary imap server and a local nntp server I use to fetch +RSS/Atom Feeds asynchronously. +#+begin_src emacs-lisp :tangle no :noweb-ref secondary-select-methods (add-to-list 'gnus-secondary-select-methods '(nntp "localhost" 4321)) -<> #+end_src -#+begin_src emacs-lisp -(setq nnimap-use-namespaces t) +**** Harddrive Maildir +This is still WIP, because the =nnmaildir= backend sucks. +#+begin_src emacs-lisp :tangle no +(add-to-list 'gnus-secondary-select-methods + '(nnmaildir "Local Maildir" + (directory "~/.nnmaildir") + (gnus-search-engine gnus-search-notmuch + (config-file "~/.notmuch-config")))) #+end_src ** Options *** General -- cgit v1.2.3 From 47fac1cc9670e13f18fab2677adcc097633ffdce Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 21 Jan 2021 15:52:33 +0100 Subject: Enable exwm if $DESKTOP_SESSION is exwm ... and not a TUI --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 568e2bb..d4b3d02 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -403,7 +403,8 @@ Now we can easily extract info on the current device. The previous sections cover all basic settings which may be useful when loading =exwm=. My =exwm= configurations are in [[file:init-exwm.org][init-exwm.org]] and we can load the tangled version here. In the future I may convert it into a standalone package. #+begin_src emacs-lisp -(when (eq (fpi/current-device-info :wm) 'exwm) +(when (and (equal (getenv "DESKTOP_SESSION") "exwm") + (eq window-system 'x)) (load (concat user-emacs-directory "init-exwm.el")) #+end_src Also enable =exwm=. This does nothing if =emacs= is not started as window manager. -- cgit v1.2.3 From 539d52ecf1bf96b95129e881afd032c7d2b3564c Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 21 Jan 2021 15:53:09 +0100 Subject: Fix conflict in C-c n t binding --- emacs-init.org | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index d4b3d02..6d5d674 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3972,8 +3972,9 @@ The idea of ~fpi/org-roam-todo~ is from a post by [[https://oremacs.com/2020/12/ (counsel-rg "^\\*+ \\(NEXT\\|TODO\\)" org-roam-directory "--sort modified")) #+end_src +As =C-c n t= is already taken as prefix for roam related toggle commands, use =o= (mnemonic: “open”) instead. #+begin_src emacs-lisp :tangle no :noweb-ref org-roam-bindings -("C-c n t" . fpi/org-roam-todo) +("C-c n o" . fpi/org-roam-todo) #+end_src -- cgit v1.2.3 From a8e61222ba0aa56839bcad50a00910872986cdbd Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 21 Jan 2021 15:56:40 +0100 Subject: Add spray for speed reading --- emacs-init.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 6d5d674..e4e08c4 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -47,6 +47,7 @@ - [[#footnote-mode][Footnote Mode]] - [[#bbdb][BBDB]] - [[#compile][Compile]] + - [[#speed-reading][Speed reading]] - [[#context-aware-hydra][Context aware hydra]] - [[#minor-utilities][Minor utilities]] - [[#language-settings][Language settings]] @@ -5382,6 +5383,12 @@ Fix ansi colors in compile buffers. From [[https://endlessparentheses.com/ansi-c compilation-filter-start (point)))) :hook (compilation-filter . endless/colorize-compilation)) #+END_src +** Speed reading +=spray= offers an interface similar to the [[https://ds300.github.io/jetzt/][jetzt]] browser based speed reader. +#+begin_src emacs-lisp +(use-package spray + :straight (:host nil :repo "https://git.sr.ht/~iank/spray/")) +#+end_src ** Context aware hydra :PROPERTIES: :ID: 22750e48-aaee-4f60-bdce-1d511ebe3375 -- cgit v1.2.3 From b9cb7037b581f1ea35d0948c9c27b0d28fdd06ef Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 21 Jan 2021 16:00:07 +0100 Subject: Add garbage collection settings --- emacs-init.org | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index e4e08c4..c4b3f3b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -12,6 +12,7 @@ - [[#font][Font]] - [[#theme--faces][Theme & Faces]] - [[#user-info][User info]] + - [[#garbage-collection][Garbage collection]] - [[#desktop-module][Desktop module]] - [[#customize][Customize]] - [[#file-and-input-history][File and input history]] @@ -1670,7 +1671,15 @@ Set ~user-full-name~ and ~user-mail-address~. These are set in (setq user-full-name private/user-full-name user-mail-address private/user-mail-address) #+end_src - +** Garbage collection +Give a message when Emacs does garbage collection and increase the thresholds for triggering it. +#+begin_src emacs-lisp +(use-package emacs + :custom + (garbage-collection-messages t) + (gc-cons-threshold 800000000) + (gc-cons-percentage 0.3)) +#+end_src ** Desktop module This saves the state emacs was in. #+begin_src emacs-lisp -- cgit v1.2.3 From 7a0b6415eac5416cef37a0325b6bd4cc1e63fbcc Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 21 Jan 2021 16:31:17 +0100 Subject: Rename gnus group buffer --- emacs-init.org | 7 +++++++ gnus.org | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index c4b3f3b..326bc1c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5338,6 +5338,13 @@ For now I use this bad code. (goto-char (point-max)) (or (bolp) (newline))))) #+END_SRC +*** Gnus +The customization for gnus is located in [[file:gnus.org][gnus.org]] and loaded from there upon startup. + +I change the group buffer to something more memorable. This needs to be set before gnus is started and therefore only setting it in gnus.org is not sufficient. +#+begin_src emacs-lisp +(setq gnus-group-buffer "*Gnus*") +#+end_src ** Footnote Mode #+begin_src emacs-lisp (use-package footnote diff --git a/gnus.org b/gnus.org index 6f069f8..c2a47c3 100644 --- a/gnus.org +++ b/gnus.org @@ -370,6 +370,10 @@ Unicode reply symbol #+begin_src emacs-lisp (setq gnus-summary-to-prefix "→ ") #+end_src +Rename the group buffer to something more memorable. This is not intended to be customized. So some bugs may occur. So far it only seems important to set it before starting gnus the first time. So e.g. set it in your main emacs =init.el=. +#+begin_src emacs-lisp +(setq gnus-group-buffer "*Gnus*") +#+end_src **** On threads Gather loose threads, whose parent is currently not displayed, under a dummy article. I find the default ~'adopt~ to be too confusing. -- cgit v1.2.3 From a2ea0847bb39932338b73428f38863084cd2c96d Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 4 Jan 2021 16:11:50 +0100 Subject: Add another device configuration --- emacs-init.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 326bc1c..3ecbe4a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -378,6 +378,9 @@ To support different settings on different devices storing some device informati :wm exwm)) ("xcarb" (:type mobile)) + ("DESKTOP-PM1PPEC" + (:type mobile) + (:os win10)) )) (defun fpi/device-info (device prop) "Return property PROP of DEVICE as stored in `fpi/devices'." -- cgit v1.2.3 From 7477fa02cdcef50f802bf070cac288fb922edc6f Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 25 Jan 2021 13:50:34 +0100 Subject: Add magit forge support for private gitlab instances --- emacs-init.org | 8 +++++++- emacs-private.el.gpg | Bin 1139 -> 1184 bytes 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 3ecbe4a..de5fbe3 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -2798,7 +2798,13 @@ Only highlight the changes within a line, not the whole line. #+begin_src emacs-lisp (use-package forge :after magit - :straight t) + :straight t + :config + <>) +#+end_src +Non-standard forges need to be added to ~forge-alist~ manually. +#+begin_src emacs-lisp :tangle no :noweb-ref forge-config +(append forge-alist private/magit-forges) #+end_src **** gitflow Add support for [[https://nvie.com/posts/a-successful-git-branching-model/][gitflow]]. diff --git a/emacs-private.el.gpg b/emacs-private.el.gpg index 916e28e..1deb591 100644 Binary files a/emacs-private.el.gpg and b/emacs-private.el.gpg differ -- cgit v1.2.3 From 434192837a0acdc4fecee9204352c40e63626820 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 31 Jan 2021 15:10:23 +0100 Subject: Reduce garbage collection threshold --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index de5fbe3..c241fc9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1680,7 +1680,7 @@ Give a message when Emacs does garbage collection and increase the thresholds fo (use-package emacs :custom (garbage-collection-messages t) - (gc-cons-threshold 800000000) + (gc-cons-threshold 80000000) (gc-cons-percentage 0.3)) #+end_src ** Desktop module -- cgit v1.2.3 From f8da89ee31f287410ee1503702af8f9256d27046 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 27 Jan 2021 11:00:07 +0100 Subject: Make scoring section more generic --- gnus.org | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/gnus.org b/gnus.org index c2a47c3..1a7f454 100644 --- a/gnus.org +++ b/gnus.org @@ -171,8 +171,20 @@ Background fetching for gnus. See the manual and [[https://www.emacswiki.org/ema (gnus-demon-add-handler 'gnus-demon-scan-news-4 130 1) (gnus-demon-add-handler 'gnus-demon-scan-news-5 140 1) #+end_src -**** Adaptive scoring -See [[info:gnus#Adaptive Scoring][info:gnus#Adaptive Scoring]] and this [[https://notes.whatthefuck.computer/1417593600.0-note.html][blog post]] by Ryan Rix. +**** Scoring +To define different scoring files for different groups I set [[info:gnus#Home Score File][home score files]] based on the group name. +#+begin_src emacs-lisp +(setq gnus-home-score-file + '(("^nnimap" "nnimap.SCORE") ;; w/ author scoring + ("gmane" "nntp_gmane.SCORE") ;; w/ author scoring + ("^nntp\\+localhost" "nntp_global.SCORE") ;; w/o author scoring + )) +(setq gnus-home-adapt-file + '(("^nnimap" "nnimap.ADAPT") + ("gmane" "nntp_gmane.ADAPT") + ("^nntp\\+localhost" "nntp_global.ADAPT"))) +#+end_src +For information about adaptive scoring see [[info:gnus#Adaptive Scoring][info:gnus#Adaptive Scoring]] and this [[https://notes.whatthefuck.computer/1417593600.0-note.html][blog post]] by Ryan Rix. ***** Score File Setup #+begin_src emacs-lisp (setq gnus-use-adaptive-scoring '(word line)) @@ -190,19 +202,7 @@ See [[info:gnus#Adaptive Scoring][info:gnus#Adaptive Scoring]] and this [[https: ) ;; (setq gnus-adaptive-word-score-alist gnus-default-adaptive-word-score-alist) #+end_src -****** Using different (adaptive) scoring files for different groups -To define different adaptive scoring files for different groups I set [[info:gnus#Home Score File][home score files]] based on the group name. -#+begin_src emacs-lisp -(setq gnus-home-score-file - '(("^nnimap" "nnimap.SCORE") ;; w/ author scoring - ("gmane" "nntp_gmane.SCORE") ;; w/ author scoring - ("^nntp\\+localhost" "nntp_global.SCORE") ;; w/o author scoring - )) -(setq gnus-home-adapt-file - '(("^nnimap" "nnimap.ADAPT") - ("gmane" "nntp_gmane.ADAPT") - ("^nntp\\+localhost" "nntp_global.ADAPT"))) -#+end_src +****** Scoring rules Scoring based on the =from= header does not make sense for rss feeds with only one author or newsgroups with unset author. These files therefore contain my default adaptive scoring rules with or without =from= scoring. #+NAME: gnus-adaptive-scoring-w-from #+begin_src emacs-lisp :tangle no :eval never @@ -245,7 +245,7 @@ Slow scoring decay prevents huge scores from building up. Only run on =.ADAPT= s gnus-score-decay-constant 1 gnus-score-decay-scale 0.01) #+end_src -****** Ignored Words +***** Ignored Words Do not score on some common german words. I extracted these from my score file after a few weeks of using scoring. #+begin_src emacs-lisp (setq gnus-ignored-adaptive-words -- cgit v1.2.3 From 1ff5fcde58d3fee13476307f775f6a4cd9ead7af Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 31 Jan 2021 15:09:56 +0100 Subject: Keep temporary score rules for longer --- gnus.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gnus.org b/gnus.org index 1a7f454..d0bc434 100644 --- a/gnus.org +++ b/gnus.org @@ -185,6 +185,11 @@ To define different scoring files for different groups I set [[info:gnus#Home Sc ("^nntp\\+localhost" "nntp_global.ADAPT"))) #+end_src For information about adaptive scoring see [[info:gnus#Adaptive Scoring][info:gnus#Adaptive Scoring]] and this [[https://notes.whatthefuck.computer/1417593600.0-note.html][blog post]] by Ryan Rix. + +Temporary scores by default expire after 7 days. I want a slightly longer threshold. +#+begin_src emacs-lisp +(setq gnus-score-expiry-days 14) +#+end_src ***** Score File Setup #+begin_src emacs-lisp (setq gnus-use-adaptive-scoring '(word line)) -- cgit v1.2.3 From f50caf82a207c8af3a1c337685af7665bede1888 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 9 Mar 2021 13:03:35 +0100 Subject: Set orb-template to auto-format notes from org-ref --- emacs-init.org | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index c241fc9..3deb808 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4011,6 +4011,8 @@ As =C-c n t= is already taken as prefix for roam related toggle commands, use =o :bind (:map org-mode-map (("C-c n a" . orb-note-actions))) :after bibtex + :custom + <> :config (defun bibtex-autokey-get-year () "Return year field contents as a string obeying `bibtex-autokey-year-length'." @@ -4018,9 +4020,37 @@ As =C-c n t= is already taken as prefix for roam related toggle commands, use =o (yearfield (when (equal yearfield "") (substring (bibtex-autokey-get-field "date") 0 4)))) (substring yearfield (max 0 (- (length yearfield) - bibtex-autokey-year-length)))))) + bibtex-autokey-year-length))))) + <>) #+end_src Rewrite of ~bibtex-autokey-get-year~ is a crude way to get bibtex to recognize =date= fields as year. + +Upon showing the notes of an entry with org-ref an appropriate org-roam note file is automatically created using ~orb-edit-notes~. Here I customize the template for my use. +#+begin_src emacs-lisp :tangle no :noweb-ref orb-custom +(orb-templates + '(("r" "ref" plain #'org-roam-capture--get-point + "\n%?\n\n#+BEGIN_SRC bibtex\n%(fpi/orb-capture--get-bibtex-entry)\n#+END_SRC" + :file-name "${citekey}" :head "#+TITLE: %(fpi/orb-capture--get-first-citekey): ${title}\n#+ROAM_KEY: ${ref} +" :unnarrowed t)) +) +#+END_SRC +Here are the functions used. +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref orb-config +(defun fpi/orb-capture--get-bibtex-entry () + "Return bibtex entry for the roam citekey in current buffer" + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "^#\\+ROAM_KEY: cite:\\(.*?\\)[\s\n]") + (let ((key (match-string 1))) + (org-ref-get-bibtex-entry key))))) +(defun fpi/orb-capture--get-first-citekey () + "Return first part of the roam citekey in current buffer" + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "^#\\+ROAM_KEY: cite:\\(.*?\\)[\s\n]") + (let ((key (match-string 1))) + (when (string-match "^\\(.*?\\)_" key) (match-string 1 key)))))) +#+end_src *** Org-edna :PROPERTIES: :ID: fd3936c7-9fc5-42d0-990d-32024e23b22f -- cgit v1.2.3 From ffc4549e70b4ad87de574f8cd411caf6d972d29d Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:08:58 +0100 Subject: Add lsp-mode (and other programming utilities) --- emacs-init.org | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 3deb808..aba9ad3 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3171,6 +3171,21 @@ does not have it. So =auctex= has to deliver this dependency instead. '("circuitikz" "\\begin{circuitikz}\nAUTOLABEL\n?\n\\end{circuitikz}" nil)))) #+end_src ** Programming languages +*** Utilities +Various utilities which ease programming in some languages. +#+begin_src emacs-lisp +(use-package yasnippet + :straight t) +(use-package yasnippet-snippets + :straight t) +(use-package company + :straight t) +#+end_src + +#+begin_src emacs-lisp +(use-package lsp-mode + :straight t) +#+end_src *** Emacs lisp =Speed of thought= makes writing lisp so easy. No more snippets needed. -- cgit v1.2.3 From 43a1cdad4f6d1ea0bba53fe907d99fca165ffe1e Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:09:19 +0100 Subject: Add support for rust development Due to the support for org-babel, rustic-mode requires org and therefore needs to be loaded after it. (As org needs to be initialized by the use-package call to work properly with straight.el) --- emacs-init.org | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index aba9ad3..372078b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3208,6 +3208,12 @@ area. :config (unbind-key "M-s" matlab-mode-map)) #+end_src +*** Rust +#+begin_src emacs-lisp +(use-package rustic + :straight t + :after org) +#+end_src ** Org mode Org is the mode you never need to leave, if you do not want to. My org TODO and clocking setup is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt -- cgit v1.2.3 From a25a41213fb9948d5e99f122a3e7e51589a741db Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:10:14 +0100 Subject: Strip some meta information from deft results --- emacs-init.org | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 372078b..8e4a986 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5058,7 +5058,31 @@ creation. (deft-default-extension "org") (deft-use-filename-as-title nil) (deft-recursive t) - (deft-use-filter-string-for-filename t))) + (deft-use-filter-string-for-filename t) + <>)) +#+end_src +Most org files start with meta information on lines starting with ~#+~, but also sometimes ~:PROPERTIES:~ drawers. We can exclude these lines from the preview content =Deft= displays with regular expressions. I first noticed this setting in [[https://github.com/hsinhaoyu/.emacs.d/blob/master/config.org][this config by hsin-hao yu]]. Define ~deft-strip-summary-regexp~ to match a group of expressions. +#+begin_src emacs-lisp :tangle no :noweb-ref deft-custom +(deft-strip-summary-regexp + (rx (group (or + space + <> + )))) +#+end_src + +Match ~#+~ based meta lines. +#+begin_src emacs-lisp :tangle no :noweb-ref deft-strip-summary-regexps +(seq bol "#+" (+ (any alpha ?_)) ?: (* any) eol) +#+end_src +Match all drawer lines, including the content. +#+begin_src emacs-lisp :tangle no :noweb-ref deft-strip-summary-regexps +(seq bol ?: (*? (not ?:)) ?: (*? (or any "\n")) ":END:") +#+end_src +Match some formatted standard additional information at the start of files. +#+begin_src emacs-lisp :tangle no :noweb-ref deft-strip-summary-regexps +(seq bol "- tags ::" (* any) eol) +(seq bol "- links ::" (* any) eol) +(seq bol "- source ::" (* any) eol) #+end_src [[https://github.com/EFLS/zetteldeft][Zetteldeft]] provides further functions to search and link between -- cgit v1.2.3 From c59024357406d9d8e2a4d3d0e75a55f0fe018028 Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:10:50 +0100 Subject: Add vterm --- emacs-init.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 8e4a986..0fc8a7c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5125,6 +5125,11 @@ To open and hide a shell quickly I use =shell-pop=. :custom (shell-pop-shell-type (quote ("eshell" "*eshell*" (lambda nil (eshell)))))) #+end_src +Vterm is the emacs terminal emulator, which is closest to standard terminal emulators. +#+begin_src emacs-lisp +(use-package vterm + :straight t) +#+end_src ** Grep #+begin_src emacs-lisp (use-package grep -- cgit v1.2.3 From e47aee7a409431e4b34ab1bf55634f59ee838e9d Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:11:22 +0100 Subject: Update sauron config --- emacs-init.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 0fc8a7c..2aa3393 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5839,7 +5839,10 @@ Instead of =$= use =⏎= to indicate newlines (use-package sauron :straight t :custom - (sauron-separate-frame (not (eq (fpi/current-device-info :wm) 'exwm)))) + (sauron-separate-frame (not (eq (fpi/current-device-info :wm) 'exwm))) + (sauron-notifications-urgency-to-priority-plist '(:low 2 :normal 4 :critical 5 :otherwise 2)) + :config + (add-to-list 'sauron-modules 'sauron-dbus)) (use-package alert :straight t) (use-package org-alert -- cgit v1.2.3 From 831cd793e0bca9b2d1008ccb8ecbe1396a2cce0d Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:25:55 +0100 Subject: Add a fallback font (for emojis) --- emacs-init.org | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 2aa3393..e3aff7c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -655,6 +655,17 @@ Meant to be used at some early initialisation stage, such as with ;; The "C-c f" is used elsewhere. :bind ("C-c F" . prot/font-fonts-dwim)) #+end_src +*** Emoji +For undefined characters in the default font, we can set a fallback font using [[info:emacs#Fontsets][fontsets]]. + +Here we set it to use the google icons as fallback. +#+begin_src emacs-lisp +(set-fontset-font "fontset-default" 'unicode "Noto Color Emoji") +#+end_src +Alternatively we could use =OpenMoji= or other icon sets. +#+begin_src emacs-lisp :tangle no +(set-fontset-font "fontset-default" 'unicode "OpenMoji") +#+end_src ** Theme & Faces =hc-zenburn= is the theme I chose for a long time. Lately I started to appreciate light themes more. [[https://gitlab.com/protesilaos/modus-themes][modus-operandi]] is an interesting light -- cgit v1.2.3 From 334933c6db07b834861cd8fc1adfd5dfa5a6058f Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 11 Mar 2021 16:54:28 +0100 Subject: EXWM: No longer try to start dbus --- init-exwm.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/init-exwm.org b/init-exwm.org index 73a4500..01e8bc5 100644 --- a/init-exwm.org +++ b/init-exwm.org @@ -25,7 +25,9 @@ export EDITOR="$VISUAL" gpg-agent --daemon export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) -exec dbus-launch --exit-with-session /home/fpi/.local/bin/emacs +# exec dbus-launch --exit-with-session /home/fpi/.local/bin/emacs +export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus +exec /home/fpi/.local/bin/emacs #+end_src * EXWM config #+begin_src emacs-lisp -- cgit v1.2.3 From 326d6d59953becd4ddd2146b38e309805e9665bd Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 11 Mar 2021 16:56:38 +0100 Subject: EXWM: Set randr outputs based on device & use vterm --- init-exwm.org | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/init-exwm.org b/init-exwm.org index 01e8bc5..8acf733 100644 --- a/init-exwm.org +++ b/init-exwm.org @@ -49,7 +49,8 @@ set keyboard #+BEGIN_SRC emacs-lisp (use-package exwm-randr :config - (setq exwm-randr-workspace-output-plist '(0 "DP1" 1 "DisplayPort-5")) + (setq exwm-randr-workspace-output-plist + (when (equal fpi/current-device "pan") '(0 "DisplayPort-3" 1 "DisplayPort-5"))) ;; (when (equal system-name "pan") ;; (start-process-shell-command "xrandr" nil "xrandr --output DisplayPort-0 --off --output DisplayPort-1 --off --output DisplayPort-2 --off --output HDMI-A-0 --off --output DisplayPort-3 --mode 2560x1440 --pos 0x612 --rotate normal --output DisplayPort-4 --off --output DisplayPort-5 --mode 2560x1440 --pos 2560x0 --rotate right --output DisplayPort-6 --off") ;; (exwm-workspace-add)) @@ -319,7 +320,6 @@ Global bindings (exwm-input-set-key (kbd "s-r") #'windmove-up) (exwm-input-set-key (kbd "s-t") #'windmove-right) -(exwm-input-set-key (kbd "M-s") #'ace-jump-word-mode) (exwm-input-set-key (kbd "s-B") #'ibuffer-list-buffers) (exwm-input-set-key (kbd "s-X") #'kill-this-buffer) @@ -332,7 +332,8 @@ Global bindings (exwm-input-set-key (kbd "s-T") 'ambrevar/swap-windows-right) (exwm-input-set-key (kbd "s-") #'ambrevar/switch-to-last-buffer) -(exwm-input-set-key (kbd "s-") (lambda () +(exwm-input-set-key (kbd "s-") #'vterm) +(exwm-input-set-key (kbd "S-s-") (lambda () (interactive) (start-process "term" nil "tilix"))) (exwm-input-set-key (kbd "s-h") 'bury-buffer) -- cgit v1.2.3 From 9135f3323604647618f8413309495c54117d25ff Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 22 Mar 2021 19:39:49 +0100 Subject: Add vundo --- emacs-init.org | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index e3aff7c..ddc9153 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5865,6 +5865,14 @@ Emacs undo mechanic can be confusing. =undo-tree= is a great package but is prone to corruption and also does not allow undo based on the active region. +*** Vundo +=Vundo= is a promising alternative to =undo-tree=, that is compatible with the default emacs undo/redo system. Its function is described in detail in [[https://archive.casouri.cat/note/2021/visual-undo-tree/index.html][this blogpost]]. +#+begin_src emacs-lisp +(use-package vundo + :straight (:host github :repo "casouri/vundo" + :branch "master") + :bind (("M-_" . vundo))) +#+end_src *** Undo-propose :ARCHIVE: =undo-propose= shows undo changes in a temporary buffer. For the keybindings see [[elisp:(which-key-show-full-keymap -- cgit v1.2.3 From 761bceeb742c9146a36f194f07df4ef378f46c25 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 6 May 2021 11:32:41 +0200 Subject: Add openscad support --- emacs-init.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index ddc9153..78f7e78 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -35,6 +35,7 @@ - [[#pdfs][PDFs]] - [[#latex][Latex]] - [[#programming-languages][Programming languages]] + - [[#cad][CAD]] - [[#org-mode][Org mode]] - [[#deft][Deft]] - [[#shell][Shell]] @@ -3225,6 +3226,12 @@ area. :straight t :after org) #+end_src +** CAD +[[https://www.openscad.org/][OpenSCAD]] is a programmable CAD Modeller. +#+begin_src emacs-lisp +(use-package scad-mode + :straight t) +#+end_src ** Org mode Org is the mode you never need to leave, if you do not want to. My org TODO and clocking setup is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt -- cgit v1.2.3 From 2669d58c761575546d05767006eb7b433fd7f168 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 10 Mar 2021 18:11:21 +0100 Subject: Add binding for org-ref --- emacs-init.org | 3 +++ 1 file changed, 3 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 78f7e78..cb67655 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4565,6 +4565,9 @@ A small function to toggle the encryption state of the current entry. (progn (dired (file-name-directory pdf)) (ding)))))))) #+end_src +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(define-key fpi-map "r" #'org-ref-helm-insert-cite-link) +#+end_src ***** Capturing entries I store my bibtex references in an org file together with my notes. In addition to saving the meta information in properties using the same -- cgit v1.2.3 From 5763b128be647f91da16300ae33240b838ca8551 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 29 May 2021 14:07:22 +0200 Subject: Add calc settings for decibel --- emacs-init.org | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index cb67655..fd97f20 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -36,6 +36,7 @@ - [[#latex][Latex]] - [[#programming-languages][Programming languages]] - [[#cad][CAD]] + - [[#calc][Calc]] - [[#org-mode][Org mode]] - [[#deft][Deft]] - [[#shell][Shell]] @@ -3232,6 +3233,13 @@ area. (use-package scad-mode :straight t) #+end_src +** Calc +#+begin_src emacs-lisp +(use-package calc + :custom + (calc-lu-field-reference "1 V") + (calc-lu-power-reference "1 mW")) +#+end_src ** Org mode Org is the mode you never need to leave, if you do not want to. My org TODO and clocking setup is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt -- cgit v1.2.3 From dcdb0fc297d395cb04687b10275910a0680d2696 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 28 Jun 2021 13:03:02 +0200 Subject: Add org-mime --- emacs-init.org | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index fd97f20..3708819 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4493,6 +4493,15 @@ CLOSED: %\\1 ;; (buffer-string)))) #+end_src (org-read-date nil nil ".") +*** org-mime +Set ~:preserve-breaks~ to keep line breaks in the html output. =org-mime-export-options= supports the same options as documented in =org-export-options-alist=. +#+begin_src emacs-lisp +(use-package org-mime + :straight t + :custom ((org-mime-export-options + '(:with-latex dvipng + :preserve-breaks t)))) +#+end_src *** Ricing #+begin_src emacs-lisp (setq line-spacing 0.1) -- cgit v1.2.3 From 752cb4b2dd35d44a8fdc456b7a687af7b409cdbe Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 28 Jun 2021 13:03:18 +0200 Subject: Update redtick settings --- emacs-init.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 3708819..bdfa91b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5766,6 +5766,13 @@ Saves to a temp file and puts the filename in the kill ring." #+begin_src emacs-lisp (use-package redtick :straight t + :custom + ((redtick-sound-volume "20") + (redtick-play-sound t) + (redtick-work-interval (* 60 20)) + (redtick-rest-interval (* 60 5)) + (redtick--workbar-interval (/ redtick-work-interval 8.0)) + (redtick--restbar-interval (/ redtick-rest-interval 8.0))) :config (redtick-mode 1)) #+end_src * Language settings -- cgit v1.2.3 From f8dabdea0773838c7a91302eefaba16a2cf3c967 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 28 Jun 2021 13:07:14 +0200 Subject: Add ssh-tunnels package --- emacs-init.org | 14 ++++++++++++++ emacs-private.el.gpg | Bin 1184 -> 1247 bytes 2 files changed, 14 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index bdfa91b..5355518 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -52,6 +52,7 @@ - [[#compile][Compile]] - [[#speed-reading][Speed reading]] - [[#context-aware-hydra][Context aware hydra]] + - [[#ssh-tunnels][SSH tunnels]] - [[#minor-utilities][Minor utilities]] - [[#language-settings][Language settings]] - [[#spellcheck][Spellcheck]] @@ -5737,6 +5738,19 @@ _q_ quit _r_ remove result _e_ examplify region ("/" ibuffer-filter-disable "disable") ("b" hydra-ibuffer-main/body "back" :color blue)) #+END_SRC +** SSH tunnels +#+begin_src emacs-lisp +(use-package ssh-tunnels + :straight t + :custom (ssh-tunnels-configurations + (cons `(:name "nntp" + :local-port 4321 + :remote-port 4321 + :login ,private/ssh-host-nntp + :host "localhost") + private/ssh-tunnels)) + :config (auto-ssh-tunnels-mode 1)) +#+end_src ** Minor utilities *** Screenshots / -casts [[https://gitlab.com/ambrevar/emacs-gif-screencast][Here]] is a guide to creating emacs gif screencasts. diff --git a/emacs-private.el.gpg b/emacs-private.el.gpg index 1deb591..1ed5e4c 100644 Binary files a/emacs-private.el.gpg and b/emacs-private.el.gpg differ -- cgit v1.2.3 From 09c86c6776cbec5e540d29b5eddb460949dbdd1d Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 17:50:17 +0100 Subject: Rename ssh-tunnel logins/hosts --- emacs-init.org | 2 +- emacs-private.el.gpg | Bin 1247 -> 1250 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 5355518..b0ddc85 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5746,7 +5746,7 @@ _q_ quit _r_ remove result _e_ examplify region (cons `(:name "nntp" :local-port 4321 :remote-port 4321 - :login ,private/ssh-host-nntp + :login ,private/ssh-login-nntp :host "localhost") private/ssh-tunnels)) :config (auto-ssh-tunnels-mode 1)) diff --git a/emacs-private.el.gpg b/emacs-private.el.gpg index 1ed5e4c..23af3d1 100644 Binary files a/emacs-private.el.gpg and b/emacs-private.el.gpg differ -- cgit v1.2.3 From 75974a50c7f0aae39a297808c914cb01da74411b Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 17:50:42 +0100 Subject: Add utf-8-unix encoding header to emacs-init --- emacs-init.org | 1 + 1 file changed, 1 insertion(+) diff --git a/emacs-init.org b/emacs-init.org index b0ddc85..b8a344a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1,3 +1,4 @@ +# -*- coding: utf-8-unix -*- #+PROPERTY: header-args:emacs-lisp :tangle tangle/emacs-init.el :results silent :noweb yes * Contents :QUOTE:TOC_2_gh: #+BEGIN_QUOTE -- cgit v1.2.3 From 91a384abe3d2c45336c633fdb0ae6342c566fbab Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 17:51:10 +0100 Subject: Fix misplaced parentheses in device definition --- emacs-init.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index b8a344a..a5a265a 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -383,8 +383,8 @@ To support different settings on different devices storing some device informati ("xcarb" (:type mobile)) ("DESKTOP-PM1PPEC" - (:type mobile) - (:os win10)) + (:type mobile + :os win10)) )) (defun fpi/device-info (device prop) "Return property PROP of DEVICE as stored in `fpi/devices'." -- cgit v1.2.3 From 4ea4a0dca52927810b2f1f9e5c06d80cfc0728cd Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 17:52:14 +0100 Subject: git-annex: Override recipe and fix package loading --- emacs-init.org | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index a5a265a..5f26a68 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -240,6 +240,10 @@ with other package definition and customization. #+BEGIN_SRC emacs-lisp (setq straight-profiles `((nil . ,(expand-file-name "package-versions.el" "~/git/projects/dotfiles")))) +(setq straight-recipe-overrides + '(nil . ( + <> + ))) #+END_SRC **** straight.el documentation excerpts :PROPERTIES: @@ -2441,16 +2445,21 @@ of src_shell{getconf "PATH"}. See [[elisp:(describe-variable ** Git *** Git annex There are some great ressources on [[https://git-annex.branchable.com/][git-annex]] integration in emacs in [[https://github.com/mm--/dot-emacs/blob/master/jmm-emacs.org][Josh's config]]. Most of my configuration is copied from there. +#+begin_src emacs-lisp :noweb-ref straight-recipe-overrides :tangle no :eval never +(git-annex :type git :flavor melpa :host github :repo "jwiegley/git-annex-el") +#+end_src #+begin_src emacs-lisp (use-package git-annex - :straight t + :straight (:host github :repo "fpiper/git-annex-el" :branch "master") :config <> - :after (dired)) -(use-package git-annex + :after (dired) :bind (:map git-annex-dired-map <>) + (:map dired-mode-map + <> + ) ) #+end_src **** Actions to lock/unlock files @@ -2554,7 +2563,7 @@ When you use this in combination with ~dired-do-kill-lines~ (by default bound to "available file")) #+END_SRC **** Mark git-annex files with git-annex-matching-options -#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref dired-bindings +#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref git-annex-dired-map-bindings ("% a" . jmm/dired-mark-files-git-annex-matching) #+END_SRC -- cgit v1.2.3 From 65271be8bebd41f112a623db7ec6b6d3fbbc6526 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:09:49 +0100 Subject: Add auto-insert package for file header templates --- emacs-init.org | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 5f26a68..f0631b9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -47,6 +47,7 @@ - [[#ledger][Ledger]] - [[#plotting-data][Plotting data]] - [[#html-renderer][HTML renderer]] + - [[#auto-insert][Auto-Insert]] - [[#email][Email]] - [[#footnote-mode][Footnote Mode]] - [[#bbdb][BBDB]] @@ -5314,6 +5315,15 @@ Support for HTML code blocks with proper syntax highlighting. See [[https://gith (advice-add 'eww-display-html :around 'eww-display-html--override-shr-external-rendering-functions)))) #+END_SRC +** Auto-Insert +#+begin_src emacs-lisp +(use-package autoinsert + :config + (define-auto-insert '("\\.sh\\'" . "Shell script skeleton") + '("" + "#!/usr/bin/env bash" \n \n)) + (auto-insert-mode 1)) +#+end_src ** Email For the setup of external mail specific programs see [[file:mail.org]]. *** Sending mail -- cgit v1.2.3 From fcb669cc7bc705bff391fa02ffd6898170b2b26a Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:19:05 +0100 Subject: Redtick make updated intervals work & change recipe --- emacs-init.org | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index f0631b9..9fa2fb9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5799,14 +5799,33 @@ Saves to a temp file and puts the filename in the kill ring." *** Pomodoro / Redtick #+begin_src emacs-lisp (use-package redtick - :straight t + :straight (:host github :repo "fpiper/redtick" + :branch "dev") :custom ((redtick-sound-volume "20") (redtick-play-sound t) (redtick-work-interval (* 60 20)) (redtick-rest-interval (* 60 5)) (redtick--workbar-interval (/ redtick-work-interval 8.0)) - (redtick--restbar-interval (/ redtick-rest-interval 8.0))) + (redtick--restbar-interval (/ redtick-rest-interval 8.0)) + (redtick--bars + `((,redtick--workbar-interval "█" "#ffff66") + (,redtick--workbar-interval "▇" "#ffcc66") + (,redtick--workbar-interval "▆" "#cc9966") + (,redtick--workbar-interval "▅" "#ff9966") + (,redtick--workbar-interval "▄" "#cc6666") + (,redtick--workbar-interval "▃" "#ff6666") + (,redtick--workbar-interval "▂" "#ff3366") + (,redtick--workbar-interval "▁" "#ff0066") + (,redtick--restbar-interval "█" "#00cc66") + (,redtick--restbar-interval "▇" "#33cc66") + (,redtick--restbar-interval "▆" "#66cc66") + (,redtick--restbar-interval "▅" "#00ff66") + (,redtick--restbar-interval "▄" "#33ff66") + (,redtick--restbar-interval "▃" "#66ff66") + (,redtick--restbar-interval "▂" "#99ff66") + (,redtick--restbar-interval "▁" "#ccff66") + (nil "✓" "#cf6a4c")))) :config (redtick-mode 1)) #+end_src * Language settings -- cgit v1.2.3 From 74718e20301e78a5feffbef96e0e4337acc94c44 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:21:26 +0100 Subject: Add auto +x on scripts and move auto-insert --- emacs-init.org | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 9fa2fb9..d388b47 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -47,7 +47,6 @@ - [[#ledger][Ledger]] - [[#plotting-data][Plotting data]] - [[#html-renderer][HTML renderer]] - - [[#auto-insert][Auto-Insert]] - [[#email][Email]] - [[#footnote-mode][Footnote Mode]] - [[#bbdb][BBDB]] @@ -5828,6 +5827,22 @@ Saves to a temp file and puts the filename in the kill ring." (nil "✓" "#cf6a4c")))) :config (redtick-mode 1)) #+end_src +*** Script creation +Automatically make scripts executable upon save if first line is a shebang: +#+begin_src emacs-lisp +(add-hook 'after-save-hook + 'executable-make-buffer-file-executable-if-script-p) +#+end_src + +The =Auto-Insert= package helps inserting header templates upon creating files. +#+begin_src emacs-lisp +(use-package autoinsert + :config + (define-auto-insert '("\\.sh\\'" . "Shell script skeleton") + '("" + "#!/usr/bin/env bash" \n \n)) + (auto-insert-mode 1)) +#+end_src * Language settings End sentences with single spaces. #+begin_src emacs-lisp -- cgit v1.2.3 From eeb68ce022f3b1387d607865a7293dca96c2eb59 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:22:19 +0100 Subject: Add new device --- emacs-init.org | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index d388b47..a445d31 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -381,7 +381,10 @@ To support different settings on different devices storing some device informati #+begin_src emacs-lisp (setq fpi/current-device (system-name)) (setq fpi/devices - '(("pan" + '(("peter" + (:type desktop + :os win10)) + ("pan" (:type desktop :wm exwm)) ("xcarb" @@ -5314,15 +5317,6 @@ Support for HTML code blocks with proper syntax highlighting. See [[https://gith (advice-add 'eww-display-html :around 'eww-display-html--override-shr-external-rendering-functions)))) #+END_SRC -** Auto-Insert -#+begin_src emacs-lisp -(use-package autoinsert - :config - (define-auto-insert '("\\.sh\\'" . "Shell script skeleton") - '("" - "#!/usr/bin/env bash" \n \n)) - (auto-insert-mode 1)) -#+end_src ** Email For the setup of external mail specific programs see [[file:mail.org]]. *** Sending mail -- cgit v1.2.3 From e6c56302241ceef4621502be3d9e52f705e60649 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:27:08 +0100 Subject: Update smime configuration --- emacs-init.org | 31 +++++++++++++++++++++---------- emacs-private.el.gpg | Bin 1250 -> 1271 bytes 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index a445d31..ddfb754 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -5363,25 +5363,36 @@ I use =msmtp= to send mail. **** S/MIME Mail signing and encrypting with S/MIME needs a =gpgsm= setup and =smime.el=. -One can either use =EasyPG= or =OpenSSL= as external implementations. -#+begin_src emacs-lisp :tangle no -(mml-smime-use 'epg) -#+end_src - -#+begin_src emacs-lisp :tangle no -(mml-default-encrypt-method "smime") -(mml-default-sign-method "smime") +One can either use =EasyPG= or =OpenSSL= as external implementations. Still need to document these settings and packages better.. +#+begin_src emacs-lisp +(use-package epg + :custom (epg-pinentry-mode nil)) +(use-package mml-sec + :custom + (mml-default-encrypt-method "smime") + (mml-default-sign-method "smime") + (mml-secure-cache-passphrase nil) + (mml-secure-passphrase-cache-expiry 16) + ) +(use-package mml-smime + :custom + (mml-smime-use 'epg) + (mml-secure-smime-sign-with-sender t) +) #+end_src - - #+begin_src emacs-lisp :tangle no (use-package smime :custom (smime-CA-directory "~/certs/trusted") (smime-certificate-directory "~/certs") + (smime-keys private/smime-keys) ) #+end_src + +#+begin_src emacs-lisp :tangle no +(setq mm-sign-option 'guided) +#+end_src *** MUA/Notmuch After using =mu4e= as my mail user agent for a while I switched to diff --git a/emacs-private.el.gpg b/emacs-private.el.gpg index 23af3d1..a930f89 100644 Binary files a/emacs-private.el.gpg and b/emacs-private.el.gpg differ -- cgit v1.2.3 From 725d9ad283f224f28416cbfcaedba5b20debc735 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 16 Jul 2020 08:39:19 +0200 Subject: Update todo keywords for projects, ... Add ACTIVE keyword to use for projects. HOLD for project tasks waiting for other tasks. --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index ddfb754..ab63576 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3550,7 +3550,7 @@ digraph hierarch{ #+begin_src emacs-lisp :noweb-ref org-custom :tangle no (org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos - (sequence "PLANNING(p)" "TODO(t)" "ACTIVE(a)" "|" "CANCELLED(c)" "DONE(d)") ;;projects + (sequence "PLANNING(p)" "READY(r)" "ACTIVE(a)" "|" "CANCELLED(c)" "DONE(d)") ;;projects (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)" "DONE(d)") (sequence "TODO(t)" "|" "DONE(d)") ;;habits (sequence "IDLE(b)"))) -- cgit v1.2.3 From 280a802ee65020c749a16dfc21bcc08a087ebcfe Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 17 Jul 2020 17:02:48 +0200 Subject: Fix my agenda span definition --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index ab63576..4c978e2 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3630,7 +3630,7 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (org-deadline-warning-days 0) (org-agenda-todo-ignore-timestamp 'all) (org-agenda-start-day "+0d") - (org-agenda-span 1) + (org-agenda-span 'day) (org-agenda-overriding-header "⚡ Schedule:\n⎺⎺⎺⎺⎺⎺⎺⎺⎺") (org-agenda-repeating-timestamp-show-all nil) (org-agenda-remove-tags t) -- cgit v1.2.3 From 8bfe1e0a12543899f9139ce34837579de006627a Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 17 Jul 2020 18:19:55 +0200 Subject: Start work on todo, tag, agenda reorganization --- emacs-init.org | 167 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 67 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 4c978e2..5a77514 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3311,24 +3311,6 @@ I use a org version with some custom patches. Rather than using something like = (org-use-speed-commands (lambda () (and (looking-at org-outline-regexp) (looking-back "^\**")))) (org-pretty-entities t) (org-fast-tag-selection-single-key t) - (org-tag-alist (quote ((:startgroup) - ("@errand" . ?e) - ("@office" . ?o) - ("@home" . ?H) - (:endgroup) - ("IDLE" . ?i) - ("shelf" . ?s) - ("soon" . ?t) - ("project" . ?p) - ;; ("HOLD" . ?h) - ;; ("PERSONAL" . ?P) - ("WORK" . ?W) - ;; ("ORG" . ?O) - ("crypt" . ?E) - ("NOTE" . ?n) - ;; ("CANCELLED" . ?c) - ("FLAGGED" . ??) - ))) (org-link-abbrev-alist '(("google" . "http://www.google.com/search?q=") ("ddg" . "https://duckduckgo.com/?q=") @@ -3338,7 +3320,6 @@ I use a org version with some custom patches. Rather than using something like = (org-outline-path-complete-in-steps nil) (org-log-into-drawer "NOTES") (org-clock-into-drawer "LOGBOOK") - (org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) (org-tags-column 0) (org-tags-exclude-from-inheritance '( <> @@ -3348,18 +3329,8 @@ I use a org version with some custom patches. Rather than using something like = (add-hook 'org-mode-hook 'turn-on-org-cdlatex) (add-to-list 'org-structure-template-alist (cons "f" "figure")) ;; (add-to-list 'org-tags-exclude-from-inheritance "MARKED") - (defun bh/clock-in-to-inprogress (kw) - "Switch a task from NEXT to INPROGRESS when clocking in. -Skips capture tasks, projects, and subprojects. -Switch projects and subprojects from NEXT back to TODO" - (when (not (and (boundp 'org-capture-mode) org-capture-mode)) - (cond - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-task-p)) - "INPROGRESS") - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-project-p)) - "INPROGRESS"))))) + <> + ) <> <> @@ -3513,7 +3484,10 @@ Use imagemagick and standalone class for latex preview. :delight) #+end_src *** Task organization -**** Todo settings +Much of my current task workflow is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt +Hansen's]] configs. +**** =[WIP]= Task Setup +***** Todos - WAITING tasks are waiting on the completion of other tasks - NEXT tasks can be picked up - INPROGRESS are current tasks with time clocked @@ -3524,35 +3498,36 @@ TODO->DONE cycle is for habits.\\ Idle states cover things to do for time in between, checking the inbox, reading news, … -Phonecalls? - #+BEGIN_SRC dot :file /tmp/todo.png -digraph hierarch{ +digraph hierarch { node [shape=box] - // Tasks, Projects - PLANNING -> NEXT, INPROGRESS, ICEBOX - WAITING -> NEXT -> INPROGRESS -> DONE, WAITING, ICEBOX - NEXT -> WAITING -> INPROGRESS, ICEBOX + // Projects + PLANNING -> READY -> ACTIVE -> DONE, ICEBOX + // Tasks + HOLD -> NEXT -> INPROGRESS -> DONE, ICEBOX NEXT -> ICEBOX, DONE + NEXT -> WAITING -> NEXT + INPROGRESS -> WAITING -> INPROGRESS - // stuff for idle time IDLE -> IDLE - //NEXT -> DONE + TODO -> DONE -> TODO - // Phonecalls, Meetings - PHONE -> DONE, CANCELED - MEETING -> DONE, CANCELED + { rank = source; PLANNING; HOLD } + { rank = same; READY; NEXT; TODO; IDLE } + { rank = same; ACTIVE; INPROGRESS } + { rank = sink; ICEBOX; DONE } } #+END_SRC #+RESULTS: [[file:/tmp/todo.png]] + #+begin_src emacs-lisp :noweb-ref org-custom :tangle no (org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos - (sequence "PLANNING(p)" "READY(r)" "ACTIVE(a)" "|" "CANCELLED(c)" "DONE(d)") ;;projects - (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELLED(c)" "DONE(d)") - (sequence "TODO(t)" "|" "DONE(d)") ;;habits + (sequence "PLANNING(p)" "READY(r)" "ACTIVE(a!)" "|" "ICEBOX(x@)" "DONE(d)") ;;projects + ;; (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELED(c)" "DONE(d)") + (sequence "TODO(t)" "|" "DONE(d)") (sequence "IDLE(b)"))) (org-use-fast-todo-selection t) (org-todo-keyword-faces @@ -3563,37 +3538,69 @@ digraph hierarch{ ("DONE" :foreground "forest green" :weight bold) ("WAITING" :foreground "orange" :weight bold) ("ICEBOX" :foreground "orange" :weight normal) - ("CANCELLED" :foreground "forest green" :weight bold) - ("MEETING" :foreground "yellow3" :weight bold) - ("PHONE" :foreground "yellow3" :weight bold) + ;; ("CANCELLED" :foreground "forest green" :weight bold) + ;; ("MEETING" :foreground "yellow3" :weight bold) + ;; ("PHONE" :foreground "yellow3" :weight bold) ("IDLE" :foreground "magenta" :weight bold))) #+end_src - +****** Automatically do =NEXT→INPROGRESS= / =READY→ACTIVE= Switch a todo entry from NEXT to INPROGRESS when clocking in. -#+begin_src emacs-lisp :tangle no -(setq org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) +#+begin_src emacs-lisp :tangle no :noweb-ref org-config (defun bh/clock-in-to-inprogress (kw) "Switch a task from NEXT to INPROGRESS when clocking in. -Skips capture tasks, projects, and subprojects. -Switch projects and subprojects from NEXT back to TODO" +Switch projects from READY to ACTIVE." (when (not (and (boundp 'org-capture-mode) org-capture-mode)) (cond - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-task-p)) + ((member (org-get-todo-state) (list "NEXT")) "INPROGRESS") - ((and (member (org-get-todo-state) (list "NEXT")) - (bh/is-project-p)) - "INPROGRESS")))) + ((member (org-get-todo-state) (list "READY")) + "ACTIVE")))) #+end_src -***** State changes +#+begin_src emacs-lisp :tangle no :noweb-ref org-custom +(org-clock-in-switch-to-state 'bh/clock-in-to-inprogress) +#+end_src +****** State changes Track state changes to done & changes to schedules and deadlines. #+begin_src emacs-lisp :tangle no :noweb-ref org-custom (org-log-done 'time) (org-log-redeadline 'time) (org-log-reschedule 'time) #+end_src -**** Org agenda custom commands -***** Task-related agendas +***** Tags +Inspired by [[https://bzg.fr/en/some-emacs-org-mode-features-you-may-not-know.html/][Bastien Guerry]], [[https://github.com/jwiegley/dot-emacs][John Wiegley]]. +#+begin_src emacs-lisp :tangle no :noweb-ref org-custom +(org-tag-alist (quote (("HOT" . ?h) + (:startgroup) ;; Location + ("@errand" . ?E) ("@office" . ?O) ("@home" . ?H) + (:endgroup) + (:startgrouptag) ;; context tags + ("net" . ?n) ("call" . ?c) ("reply" . ?R) + (:endgrouptag) + (:startgroup) + ("handson" . ?o) ;; For focused/active tasks + (:grouptags) + ;; ("code" . ?c) ("design" . ?d) ("review" . ?v) + (:endgroup) + (:startgroup) + ("handsoff" . ?f) ;; For listening/passive tasks + (:grouptags) + ("read" . ?r) ("watch" . ?w) + (:endgroup) + ("crypt" . ?E) + ("FLAGGED" . ??) + ))) +#+end_src +***** INPROGRESS Custom Agendas +- John Wiegley: Different background colors for different source files +****** General +- "h": Next action for hot projects +- Project Next actions agenda +- "P": All Projects +- "r": uncategorized items (CATEGORY="Inbox"&LEVEL=2) +- "w": waiting/delegated tasks (W-TODO="DONE"|TODO={WAITING\|DELEGATED}) +- Unscheduled tasks (TODO<>""&TODO<>{DONE\|CANCELED\|NOTE\|PROJECT\|DEFERRED\|SOMEDAY}) +- "c": Appointment calendar +****** Task-related agendas Simple day agenda with =INPROGRESS= tasks #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("d" "Day agenda" @@ -3617,7 +3624,7 @@ Agenda with all open tasks (todo "IDLE") (tags-todo "-habit-shelve-soon-idle"))) #+end_src -****** Fancy agenda to choose todays tasks +******* Fancy agenda to choose todays tasks Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("o" "My Agenda" @@ -3671,7 +3678,7 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (not (= scheduled-day now)))) subtree-end))) #+end_src -***** Week agendas +****** Week agendas #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("w" . "Week agendas") ("ww" "Standard week agenda" @@ -3681,7 +3688,7 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (org-agenda-start-day "mon"))) (tags-todo "+work"))) #+end_src -***** Misc agendas +****** Misc agendas #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("r" "Refile entries" ((tags "+REFILE"))) ("i" "Idle Actions" @@ -3708,6 +3715,31 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. (alltodo "" ((org-agenda-files (fpi/collect-org-directories-recursively default-directory)))))) #+end_src +***** Filtering +****** Auto Exclude +#+begin_src emacs-lisp +;; https://github.com/jwiegley/dot-emacs/blob/master/dot-org.el +(defun org-my-auto-exclude-function (tag) + (and (cond + ((string= tag "call") + (let ((hour (nth 2 (decode-time)))) + (or (< hour 8) (> hour 21)))) + ((string= tag "errand") + (let ((hour (nth 2 (decode-time)))) + (or (< hour 12) (> hour 17)))) + ((or (string= tag "home") (string= tag "nasim")) + (with-temp-buffer + (call-process "ifconfig" nil t nil "en0" "inet") + (call-process "ifconfig" nil t nil "en1" "inet") + (call-process "ifconfig" nil t nil "bond0" "inet") + (goto-char (point-min)) + (not (re-search-forward "inet 192\\.168\\.1\\." nil t)))) + ((string= tag "net") + (not (quickping "imap.fastmail.com"))) + ((string= tag "fun") + org-clock-current-task)) + (concat "-" tag))) +#+end_src **** Refile Use the full outline path so I can distinguish headlines with the same name & disable step-wise completion as I think from the refile target backwards, not from top-level downwards. Also include the current file's headings as a refile targets up to a deep level, all agenda files up to a small level and all open org files up to an even smaller level. @@ -4872,6 +4904,7 @@ Basic flow: 3. Do stuff. Change clocks, capture stuff, take notes, take breaks, … 4. At the end of the day clock out with ~bh/punch-out~. +**** Clocking While punched in org continues to clock your time. Each time you clock out of an entry it clocks you in on the parent entry or the default organizational task. @@ -5004,6 +5037,7 @@ Add a note to the current clock (org-clock-goto) (org-add-note))) #+END_SRC +**** General Go to any heading in an agenda file (or more specifically in any file included in 'org-refile-targets) #+begin_src emacs-lisp @@ -5017,7 +5051,6 @@ included in 'org-refile-targets) (org-show-context) (current-buffer))) #+END_SRC - **** Filter functions Various functions to determine if the current entry is a task, a project or neither. -- cgit v1.2.3 From 74c6784508e1e95378711ac331b6af4fa92663c5 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 22 Jul 2020 10:28:39 +0200 Subject: Add general project functions & agendas by jwiegley --- emacs-init.org | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 185 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 5a77514..5d73324 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3414,6 +3414,9 @@ I use a org version with some custom patches. Rather than using something like = (org-src-fontify-natively t) (org-src-tab-acts-natively t) (org-edit-src-content-indentation 0)) +#+end_src + +#+begin_src emacs-lisp (defun fpi/collect-org-directories-recursively (dir) "Return list of all directories which contain .org files of DIR and its subdirectories" (delete-dups (mapcar 'file-name-directory (directory-files-recursively dir "\.org$")))) @@ -3443,7 +3446,10 @@ I use a org version with some custom patches. Rather than using something like = (org-agenda-custom-commands `( <> - ))) + )) + :config + <> + ) #+end_src #+begin_src emacs-lisp @@ -3522,13 +3528,21 @@ digraph hierarch { #+RESULTS: [[file:/tmp/todo.png]] +#+begin_src emacs-lisp :noweb-ref org-config :tangle no +(defvar org-task-keywords + '("HOLD" "NEXT" "INPROGRESS" "WAITING") + "Org todo keywords to demark tasks") +(defvar org-project-keywords + '("PLANNING" "READY" "ACTIVE") + "Org todo keywords to demark projects") +#+end_src #+begin_src emacs-lisp :noweb-ref org-custom :tangle no (org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos (sequence "PLANNING(p)" "READY(r)" "ACTIVE(a!)" "|" "ICEBOX(x@)" "DONE(d)") ;;projects ;; (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELED(c)" "DONE(d)") (sequence "TODO(t)" "|" "DONE(d)") - (sequence "IDLE(b)"))) + (sequence "IDLE(b)" "|"))) (org-use-fast-todo-selection t) (org-todo-keyword-faces '(("HOLD" :foreground "light gray" :weight bold) @@ -3590,6 +3604,28 @@ Inspired by [[https://bzg.fr/en/some-emacs-org-mode-features-you-may-not-know.ht ("FLAGGED" . ??) ))) #+end_src +Exclude =HOT= from inheritance +#+begin_src emacs-lisp :tangle no :noweb-ref org-custom-no-inheritance-tags +"HOT" +#+end_src +***** Creating projects +#+begin_src emacs-lisp +(defun fpi/make-parent-project () + (when (or (string-equal org-state "NEXT") + (string-equal org-state "HOLD") + (string-equal org-state "INPROGRESS") + (string-equal org-state "WAITING")) + ;; Activate parent + (org-up-element) + (let ((todo (org-entry-is-todo-p))) + (when todo + (org-todo "ACTIVE") + ;; (end-of-line) + ;; (insert " [0/0]") + (org-update-statistics-cookies nil) + )) + )) +#+end_src ***** INPROGRESS Custom Agendas - John Wiegley: Different background colors for different source files ****** General @@ -3602,6 +3638,153 @@ Inspired by [[https://bzg.fr/en/some-emacs-org-mode-features-you-may-not-know.ht - "c": Appointment calendar ****** Task-related agendas Simple day agenda with =INPROGRESS= tasks +******* Hot Projects +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("h" "Current Hotlist" tags "TODO={NEXT\\|INPROGRESS\\|WAITING}" + ((org-agenda-overriding-header "Current Hotlist") + (org-agenda-skip-function + (function fpi/org-agenda-skip-all-not-hot)))) +#+end_src +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config +(defun fpi/org-agenda-skip-all-not-hot () + "Skip all not hot entries." + (when (not (member "HOT" (my-org-current-tags 1))) + (or (outline-next-heading) + (goto-char (point-max))))) +(defun fpi/org-agenda-skip-all-not-project () + "Skip all not hot entries." + (when (not (member "HOT" (my-org-current-tags 1))) + (or (outline-next-heading) + (goto-char (point-max))))) +(defun my-org-current-tags (depth) + (save-excursion + (ignore-errors + (let (should-skip) + (while (and (> depth 0) + (not should-skip) + (prog1 + (setq depth (1- depth)) + (not (org-up-element)))) + (if (looking-at "^\*+\\s-+") + (setq should-skip (org-get-local-tags)))) + should-skip)))) +(defun fpi/org-goto-top-project (depth) + "Go to the top project of heading under point" + (save-restriction + (widen) + (let ((top (point))) + (with-demoted-errors + (while (and (> depth 0) + (progn + (setq depth (1- depth)) + (not (org-up-element)))) + (when (fpi/is-not-done-project-p) + (setq top (point))))) + (goto-char top)))) +(defun fpi/parent-is-not-done-project-p () + "Return t if parent heading is a not done project." + (save-excursion + (save-restriction + (widen) + (and (not (org-up-element)) + (fpi/is-not-done-project-p))))) +(defun fpi/is-not-done-project-p () + "Return t if current heading is a not done project." + (save-restriction + (widen) + (let ((todo (org-get-todo-state))) + (member todo org-project-keywords)))) +#+end_src +To narrow the agenda to the currently selected project this function from [[https://github.com/mm--/dot-emacs/blob/master/jmm-org-config.org][Josh's emacs config]] is useful. +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config +(defun fpi/org-agenda-lock-to-parent-project () + "In the org mode agenda, lock the restriction to the current project." + (interactive) + (save-window-excursion + (org-agenda-goto) + (if (fpi/org-goto-top-project 10) + (org-agenda-set-restriction-lock) + (user-error "No parent project found."))) + (org-agenda-redo-all)) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("H" "Hot Projects" tags "HOT&TODO={PLANNING\\|READY\\|ACTIVE}" + ((org-agenda-overriding-header "Hot Projects"))) +("T" "Non-Hot Projects" tags "-HOT&TODO={ACTIVE}" + ((org-agenda-overriding-header "Non-Hot Projects"))) +("P" "All Projects" + ((tags "HOT&TODO={PLANNING\\|READY\\|ACTIVE}" + ((org-agenda-overriding-header "Hot Projects"))) + (tags "-HOT&TODO={PLANNING\\|READY\\|ACTIVE}" + ((org-agenda-overriding-header "Non-Hot Projects"))) + )) +#+end_src +******* +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("n" "Project Next Actions" alltodo "" + ((org-agenda-overriding-header "Current Hotlist") + (org-agenda-skip-function + (function fpi/org-agenda-skip-all-not-hot)))) +#+end_src +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands-wiegley +("A" "Priority #A tasks" agenda "" + ((org-agenda-ndays 1) + (org-agenda-overriding-header "Today's priority #A tasks: ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote notregexp) + "\\=.*\\[#A\\]"))))) +("b" "Priority #A and #B tasks" agenda "" + ((org-agenda-ndays 1) + (org-agenda-overriding-header "Today's priority #A and #B tasks: ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote regexp) + "\\=.*\\[#C\\]"))))) +("r" "Uncategorized items" tags "CATEGORY=\"Inbox\"&LEVEL=2" + ((org-agenda-overriding-header "Uncategorized items"))) +("W" "Waiting/delegated tasks" tags "W-TODO=\"DONE\"|TODO={WAITING\\|DELEGATED}" + ((org-agenda-overriding-header "Waiting/delegated tasks:") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote scheduled)))) + (org-agenda-sorting-strategy + (quote + (todo-state-up priority-down category-up))))) +("D" "Deadlined tasks" tags "TODO<>\"\"&TODO<>{DONE\\|CANCELED\\|NOTE\\|PROJECT}" + ((org-agenda-overriding-header "Deadlined tasks: ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote notdeadline)))) + (org-agenda-sorting-strategy + (quote + (category-up))))) +("S" "Scheduled tasks" tags "TODO<>\"\"&TODO<>{APPT\\|DONE\\|CANCELED\\|NOTE\\|PROJECT}&STYLE<>\"habit\"" + ((org-agenda-overriding-header "Scheduled tasks: ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote notscheduled)))) + (org-agenda-sorting-strategy + (quote + (category-up))))) +("d" "Unscheduled open source tasks (by date)" tags "TODO<>\"\"&TODO<>{DONE\\|CANCELED\\|NOTE\\|PROJECT}" + ((org-agenda-overriding-header "Unscheduled Open Source tasks (by date): ") + (org-agenda-skip-function + (quote + (org-agenda-skip-entry-if + (quote scheduled) + (quote deadline) + (quote timestamp) + (quote regexp) + "\\* \\(DEFERRED\\|SOMEDAY\\)"))))) +#+end_src + #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("d" "Day agenda" ((agenda "" ((org-agenda-span 'day))) -- cgit v1.2.3 From e37bd5af68b9fc4ab60dae924c90f74ff81640d1 Mon Sep 17 00:00:00 2001 From: fpi Date: Wed, 29 Jul 2020 11:34:51 +0200 Subject: Include tasks of subprojects in current hotlist --- emacs-init.org | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 5d73324..ce6b6a6 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3642,13 +3642,14 @@ Simple day agenda with =INPROGRESS= tasks #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("h" "Current Hotlist" tags "TODO={NEXT\\|INPROGRESS\\|WAITING}" ((org-agenda-overriding-header "Current Hotlist") - (org-agenda-skip-function - (function fpi/org-agenda-skip-all-not-hot)))) + (org-agenda-skip-function (function fpi/org-agenda-skip-all-not-hot)) + ;; (org-agenda-prefix-format " %-3i %-12:c%30b %s") + )) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config (defun fpi/org-agenda-skip-all-not-hot () "Skip all not hot entries." - (when (not (member "HOT" (my-org-current-tags 1))) + (when (not (member "HOT" (my-org-current-tags (fpi/org-project-depth 10)))) (or (outline-next-heading) (goto-char (point-max))))) (defun fpi/org-agenda-skip-all-not-project () @@ -3668,6 +3669,14 @@ Simple day agenda with =INPROGRESS= tasks (if (looking-at "^\*+\\s-+") (setq should-skip (org-get-local-tags)))) should-skip)))) +(defun fpi/org-project-depth (depth) + "Return number of subheadings before reaching top project." + (let ((current (org-current-level)) + (top (save-excursion + (fpi/org-goto-top-project depth) + (org-current-level)))) + (- current top) + )) (defun fpi/org-goto-top-project (depth) "Go to the top project of heading under point" (save-restriction -- cgit v1.2.3 From 9d6dc81da42a928200f332b11831479677ceeaa8 Mon Sep 17 00:00:00 2001 From: fpi Date: Sat, 1 Aug 2020 18:14:36 +0200 Subject: Set custom scheduled leaders for the agenda --- emacs-init.org | 1 + 1 file changed, 1 insertion(+) diff --git a/emacs-init.org b/emacs-init.org index ce6b6a6..0206424 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3441,6 +3441,7 @@ I use a org version with some custom patches. Rather than using something like = (org-agenda-skip-scheduled-if-done t) (org-agenda-dim-blocked-tasks t) (org-sort-agenda-notime-is-late t) + (org-agenda-scheduled-leaders '(" ➫" "➫ ")) ;; alternatives if font supports them: 👉🖝🕣🕣 ;; See emacs.christianbaeuerlein.com/my-org-config.html (org-agenda-block-separator 9472) (org-agenda-custom-commands -- cgit v1.2.3 From 7dde44dfe6c35bd1496d7e8faf46fbf64e346ce0 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 3 Aug 2020 18:04:52 +0200 Subject: Customize stuck project definition --- emacs-init.org | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 0206424..4e51fb5 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3448,6 +3448,7 @@ I use a org version with some custom patches. Rather than using something like = `( <> )) + <> :config <> ) @@ -3933,6 +3934,16 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. org-clock-current-task)) (concat "-" tag))) #+end_src +****** Stuck projects +The agenda can also list stuck projects with =C-c a #=. For this to be useful we have define what a stuck project is. + +A stuck project +1. has any todo state of the states listed in ~org-project-keywords~ +2. does /not/ have a subtask with a state of =TODO=, =NEXT= or =INPROGRESS=. + +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom +(org-stuck-projects '("/+{PLANNING\\|READY\\|ACTIVE}" ("TODO" "NEXT" "INPROGRESS") nil "")) +#+end_src **** Refile Use the full outline path so I can distinguish headlines with the same name & disable step-wise completion as I think from the refile target backwards, not from top-level downwards. Also include the current file's headings as a refile targets up to a deep level, all agenda files up to a small level and all open org files up to an even smaller level. -- cgit v1.2.3 From d13d8625e24983bb40f0fa461fc7fb11abbaee50 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 3 Aug 2020 18:05:02 +0200 Subject: Do not show waiting tasks in hotlist --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 4e51fb5..bf3a3a0 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3642,7 +3642,7 @@ Exclude =HOT= from inheritance Simple day agenda with =INPROGRESS= tasks ******* Hot Projects #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands -("h" "Current Hotlist" tags "TODO={NEXT\\|INPROGRESS\\|WAITING}" +("h" "Current Hotlist" tags "TODO={NEXT\\|INPROGRESS}" ((org-agenda-overriding-header "Current Hotlist") (org-agenda-skip-function (function fpi/org-agenda-skip-all-not-hot)) ;; (org-agenda-prefix-format " %-3i %-12:c%30b %s") -- cgit v1.2.3 From 85ee7d8ec0caf486155bb914c6ec84dbf5f3342f Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 4 Aug 2020 15:15:56 +0200 Subject: Add edna trigger for project subtasks --- emacs-init.org | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index bf3a3a0..3fdf738 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4402,14 +4402,21 @@ the newly set value. Open the PROPERTIES drawer." (interactive) (jmm/org-edna-set-trigger-and-point (format "link-ids(\"%s\")%s" (jmm/org-pop-stored-link) (if rest (concat " " rest) "")))) - (defhydra jmm/org-edna-hydra (:color blue) - "Org Edna" - ("l" jmm/org-edna-link "Link") - ("L" (jmm/org-edna-link "todo!(NEXT)") "Link NEXT") - ("n" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT)") "Next sibling NEXT") - ("N" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT) chain!(\"TRIGGER\")") "Chain next-sibling NEXT") - ("p" (jmm/org-edna-set-trigger-and-point "parent todo!(DONE)") "Parent DONE") - ("q" nil "cancel"))) + (defhydra fpi/org-edna-hydra (:color blue :hint nil) + " +Org Edna + _l_: Link _P_: N+p + _L_: Link NEXT _p_: Parent DONE + _n_: Sibling NEXT ^ ^ + _N_: Chain sibling NEXT _q_: quit +" + ("l" jmm/org-edna-link) + ("L" (jmm/org-edna-link "todo!(NEXT)")) + ("n" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT)")) + ("N" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT) chain!(\"TRIGGER\")")) + ("P" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT) chain!(\"TRIGGER\") if siblings then parent todo!(DONE) endif")) + ("p" (jmm/org-edna-set-trigger-and-point "parent todo!(DONE)")) + ("q" nil))) #+end_src *** org-attach =org-attach= is useful to attach reference material to org files. This can be reference images, data or other files. A special link type is available for attached files: ~[[attachment:file]]~. @@ -5810,7 +5817,7 @@ based on the current mode and context around point. (etype (car elem)) (type (org-element-property :type elem))) (cl-case etype - (headline (jmm/org-edna-hydra/body)) + (headline (fpi/org-edna-hydra/body)) (src-block (hydra-babel-helper/body)) (link (hydra-org-link-helper/body)) ((table-row table-cell) (hydra-org-table-helper/body) ) -- cgit v1.2.3 From 0a7af5151e41e1b44803f1dfef5853e8af00774d Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Sep 2020 15:48:30 +0200 Subject: Add a REVIEW todo state & fix project functions --- emacs-init.org | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 3fdf738..bab1714 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3519,6 +3519,7 @@ digraph hierarch { IDLE -> IDLE TODO -> DONE -> TODO + INPROGRESS -> REVIEW -> DONE { rank = source; PLANNING; HOLD } { rank = same; READY; NEXT; TODO; IDLE } @@ -3532,7 +3533,7 @@ digraph hierarch { #+begin_src emacs-lisp :noweb-ref org-config :tangle no (defvar org-task-keywords - '("HOLD" "NEXT" "INPROGRESS" "WAITING") + '("HOLD" "NEXT" "INPROGRESS" "REVIEW" "WAITING") "Org todo keywords to demark tasks") (defvar org-project-keywords '("PLANNING" "READY" "ACTIVE") @@ -3540,7 +3541,7 @@ digraph hierarch { #+end_src #+begin_src emacs-lisp :noweb-ref org-custom :tangle no -(org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos +(org-todo-keywords '((sequence "HOLD(h)" "NEXT(n)" "INPROGRESS(i!)" "WAITING(w@/!)" "REVIEW(r!)" "|" "ICEBOX(x@)" "DONE(d)") ;;todos (sequence "PLANNING(p)" "READY(r)" "ACTIVE(a!)" "|" "ICEBOX(x@)" "DONE(d)") ;;projects ;; (sequence "PHONE(P)" "MEETING(m)" "|" "CANCELED(c)" "DONE(d)") (sequence "TODO(t)" "|" "DONE(d)") @@ -3550,6 +3551,7 @@ digraph hierarch { '(("HOLD" :foreground "light gray" :weight bold) ("NEXT" :foreground "light blue" :weight bold) ("INPROGRESS" :foreground "burlywood" :weight bold) + ("REVIEW" :foreground "light goldenrod" :weight bold) ("ACTIVE" :foreground "chocolate" :weight bold) ("DONE" :foreground "forest green" :weight bold) ("WAITING" :foreground "orange" :weight bold) @@ -3664,12 +3666,11 @@ Simple day agenda with =INPROGRESS= tasks (ignore-errors (let (should-skip) (while (and (> depth 0) - (not should-skip) (prog1 (setq depth (1- depth)) (not (org-up-element)))) (if (looking-at "^\*+\\s-+") - (setq should-skip (org-get-local-tags)))) + (setq should-skip (append should-skip (org-get-local-tags))))) should-skip)))) (defun fpi/org-project-depth (depth) "Return number of subheadings before reaching top project." -- cgit v1.2.3 From 479bf27165a92ee95559e5c83a9c04fb85aef652 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 21 Sep 2020 22:02:43 +0200 Subject: Fix agenda view of all projects --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index bab1714..c209501 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3723,7 +3723,7 @@ To narrow the agenda to the currently selected project this function from [[http #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("H" "Hot Projects" tags "HOT&TODO={PLANNING\\|READY\\|ACTIVE}" ((org-agenda-overriding-header "Hot Projects"))) -("T" "Non-Hot Projects" tags "-HOT&TODO={ACTIVE}" +("T" "Non-Hot Projects" tags "-HOT&TODO={PLANNING\\|READY\\|ACTIVE}" ((org-agenda-overriding-header "Non-Hot Projects"))) ("P" "All Projects" ((tags "HOT&TODO={PLANNING\\|READY\\|ACTIVE}" -- cgit v1.2.3 From aff02836d1cad271c666985db191b5fe5238dd14 Mon Sep 17 00:00:00 2001 From: fpi Date: Mon, 21 Sep 2020 22:19:00 +0200 Subject: Add agenda view to show all non-project tasks --- emacs-init.org | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index c209501..767ef7e 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3656,9 +3656,9 @@ Simple day agenda with =INPROGRESS= tasks (when (not (member "HOT" (my-org-current-tags (fpi/org-project-depth 10)))) (or (outline-next-heading) (goto-char (point-max))))) -(defun fpi/org-agenda-skip-all-not-project () - "Skip all not hot entries." - (when (not (member "HOT" (my-org-current-tags 1))) +(defun fpi/org-agenda-skip-all-project-tasks () + "Skip all entries which belong to a project." + (when (fpi/is-part-of-project-p 10) (or (outline-next-heading) (goto-char (point-max))))) (defun my-org-current-tags (depth) @@ -3693,6 +3693,9 @@ Simple day agenda with =INPROGRESS= tasks (when (fpi/is-not-done-project-p) (setq top (point))))) (goto-char top)))) +(defun fpi/is-part-of-project-p (depth) + "Return t if any parent heading is a project." + (< 0 (fpi/org-project-depth depth))) (defun fpi/parent-is-not-done-project-p () "Return t if parent heading is a not done project." (save-excursion @@ -3732,6 +3735,12 @@ To narrow the agenda to the currently selected project this function from [[http ((org-agenda-overriding-header "Non-Hot Projects"))) )) #+end_src +Some tasks do not go into projects. Let's list only those. +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands +("g" "Non-Project (general) Tasks" tags "TODO={NEXT\\|INPROGRESS\\|REVIEW\\|WAITING}" + ((org-agenda-overriding-header "Non-Project Tasks") + (org-agenda-skip-function (function fpi/org-agenda-skip-all-project-tasks)))) +#+end_src ******* #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("n" "Project Next Actions" alltodo "" -- cgit v1.2.3 From fe089ffb7e260f0a0f19b7f1da3d5277c5a0dafb Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:12:11 +0200 Subject: Collect org clocking settings under one headline --- emacs-init.org | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 767ef7e..d72b954 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3319,7 +3319,6 @@ I use a org version with some custom patches. Rather than using something like = (org-ellipsis " ") (org-outline-path-complete-in-steps nil) (org-log-into-drawer "NOTES") - (org-clock-into-drawer "LOGBOOK") (org-tags-column 0) (org-tags-exclude-from-inheritance '( <> @@ -3400,14 +3399,9 @@ I use a org version with some custom patches. Rather than using something like = (use-package org-id :custom (org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) <>) -(use-package org-clock - :custom - (org-clock-out-remove-zero-time-clocks t) - (org-clock-persist 'history) - (org-clock-history-length 30) - :init - (org-clock-persistence-insinuate) - ) +#+end_src + +#+begin_src emacs-lisp (use-package org-src :custom (org-src-window-setup 'other-window) @@ -3491,6 +3485,28 @@ Use imagemagick and standalone class for latex preview. (use-package org-num :delight) #+end_src +*** Timekeeping & Clocking +- Remove clocks with zero time. +- Save a clocking history of the list 50 clocked items. +- Clock into the =LOGBOOK= drawer (as opposed to log entries going into ~org-log-into-drawer~) +#+begin_src emacs-lisp +(use-package org-clock + :custom + (org-clock-out-remove-zero-time-clocks t) + (org-clock-persist 'history) + (org-clock-history-length 50) + (org-clock-into-drawer "LOGBOOK") + :init + (org-clock-persistence-insinuate) + ) +#+end_src +**** Durations +#+begin_src emacs-lisp +(use-package org-duration + :after org + :custom + (org-duration-format '(("h" . t) ("min" . t) (special . h:mm)))) +#+end_src *** Task organization Much of my current task workflow is largely inspired by [[http://doc.rix.si/cce/cce-org.html][Ryan Rix's]] and [[http://doc.norang.ca/org-mode.html][Bernt Hansen's]] configs. @@ -4171,13 +4187,6 @@ This function is handy to use in header arguments to create names based on the c (post (or post ""))) (format "%s%s%s" pre (nth 4 (org-heading-components)) post))) #+end_src -*** Durations -#+begin_src emacs-lisp -(use-package org-duration - :after org - :custom - (org-duration-format '(("h" . t) ("min" . t) (special . h:mm)))) -#+end_src *** ox-reveal #+BEGIN_SRC emacs-lisp (use-package ox-reveal -- cgit v1.2.3 From 12529bb7e4559684495db9816f2a24d7025fd211 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:13:23 +0200 Subject: Remove READLIST, WATCH tags in favor of read, watch --- emacs-init.org | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index d72b954..e74a26b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3912,16 +3912,16 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom-commands ("r" "Refile entries" ((tags "+REFILE"))) ("i" "Idle Actions" - ((tags-todo "IDLE-READLIST-WATCH" + ((tags-todo "IDLE-read-watch" ((org-agenda-overriding-header "Idle Tasks") (org-agenda-skip-function 'bh/skip-project-tasks) (org-agenda-sorting-strategy '(todo-state-down effort-up)))) - (tags-todo "READLIST" + (tags-todo "read" ((org-agenda-overriding-header "Idle Reading List") (org-agenda-sorting-strategy '(todo-state-down effort-up)))) - (tags-todo "WATCH" + (tags-todo "watch" ((org-agenda-overriding-header "Things to Watch") (org-agenda-skip-function 'bh/skip-project-tasks) (org-agenda-sorting-strategy @@ -4609,7 +4609,7 @@ Instead of project related capture templates, I use the same template for all ta ("Cr" ".. & read" entry (file "~/sync/refile.org") - "* TODO %a :READLIST: + "* TODO %a :read: :PROPERTIES: :CREATED: %U <> -- cgit v1.2.3 From 6c8c25aa4cd015d763ab892be8c0635035b650f6 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 27 Sep 2020 12:12:26 +0200 Subject: Add function to clock in on a refile target --- emacs-init.org | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index e74a26b..1a8fb06 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3500,6 +3500,20 @@ Use imagemagick and standalone class for latex preview. (org-clock-persistence-insinuate) ) #+end_src +Even with the history clocking into the correct item is sometimes difficult. So why not clock in any refile target: +#+begin_src emacs-lisp +(defun fpi/org-clock-in-heading (&optional prompt) + (interactive) + (let* ((location (org-refile-get-location (or prompt "Clock in on"))) + (file (cadr location)) + (marker (car (last location)))) + (save-excursion + (save-restriction + (find-file file) + (goto-char marker) + (org-clock-in) + (current-buffer))))) +#+end_src **** Durations #+begin_src emacs-lisp (use-package org-duration -- cgit v1.2.3 From f2a1b51d43b2861ff2a0096c6866888a2115f759 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 30 Oct 2020 19:30:25 +0100 Subject: Use timestamp based ids --- emacs-init.org | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 1a8fb06..0206230 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3397,10 +3397,17 @@ I use a org version with some custom patches. Rather than using something like = :straight t :hook (org-load . org-pdftools-setup-link)) (use-package org-id - :custom (org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) + :custom + (org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id) <>) #+end_src +I prefer to use timestamp based ID's as they are +#+begin_src emacs-lisp :tangle no :noweb-ref org-id-custom +(org-id-method 'ts) +(org-id-ts-format "%FT%T%z") +#+end_src + #+begin_src emacs-lisp (use-package org-src :custom @@ -4464,10 +4471,18 @@ Org Edna (use-package org-attach :custom (org-attach-use-inheritance nil) + (org-attach-preferred-new-method 'id) + (org-attach-store-link-p t) :config (defun fpi/org-attach-id-folder-format (id) id) - (add-to-list 'org-attach-id-to-path-function-list 'fpi/org-attach-id-folder-format)) + (defun fpi/org-attach-id-ts-folder-format (id) + "Timestamp id converter to ids generated in the \"%FT%T%z\" format." + (format "%s/%s" + (substring id 0 7) + (substring id 8))) + (add-to-list 'org-attach-id-to-path-function-list 'fpi/org-attach-id-folder-format) + (add-to-list 'org-attach-id-to-path-function-list 'fpi/org-attach-id-ts-folder-format)) #+end_src =org-attach-git= auto-commits changes to attachments if the directory is a git repository. I want every attachments to be saved using -- cgit v1.2.3 From b78838697482ce20c282f594647c4c1ba2efc8fb Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 30 Oct 2020 19:32:56 +0100 Subject: Sort some agenda entries by hotness --- emacs-init.org | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 0206230..def36ee 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3684,10 +3684,31 @@ Simple day agenda with =INPROGRESS= tasks ("h" "Current Hotlist" tags "TODO={NEXT\\|INPROGRESS}" ((org-agenda-overriding-header "Current Hotlist") (org-agenda-skip-function (function fpi/org-agenda-skip-all-not-hot)) + (org-agenda-sorting-strategy + '(priority-down category-keep user-defined-down)) + (org-agenda-cmp-user-defined #'fpi/org-agenda-compare-hotness) + (org-agenda-prefix-format " %i {%(fpi/org-hotness)} %-12:c") ;; (org-agenda-prefix-format " %-3i %-12:c%30b %s") )) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config +(defun fpi/org-agenda-compare-hotness (a b) + "Compare level of hot headlines over entries A and B." + (let ((ha (fpi/org-agenda-hotness a)) + (hb (fpi/org-agenda-hotness b))) + (cond + ((> ha hb) +1) + ((< ha hb) -1) + (t nil)))) +(defun fpi/org-agenda-hotness (entry) + "Return level of hot headlines over ENTRY." + (org-agenda-with-point-at-orig-entry entry (fpi/org-hotness))) +(defun fpi/org-hotness () + "Return level of hot headlines over current entry." + (let* ((tags (my-org-current-tags (fpi/org-project-depth 10))) + (l1 (length tags)) + (l2 (length (remove "HOT" tags)))) + (- l1 l2))) (defun fpi/org-agenda-skip-all-not-hot () "Skip all not hot entries." (when (not (member "HOT" (my-org-current-tags (fpi/org-project-depth 10)))) -- cgit v1.2.3 From e900cf26c13478aff3cc942dde20af5ff0944888 Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 30 Oct 2020 19:33:26 +0100 Subject: Set clock checking to tolerate no gap at all --- emacs-init.org | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index def36ee..bd9940b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4062,6 +4062,11 @@ Gives an overview of time spent on defined budgets this week. Great to track if "%50ITEM(Task) %5Effort(Effort){:} %5CLOCKSUM %3PRIORITY %20DEADLINE %20SCHEDULED %20TIMESTAMP %TODO %CATEGORY %TAGS") #+end_src **** Clocking +I try to clock without any gap +#+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-custom +(org-agenda-clock-consistency-checks '(:max-duration "10:00" :min-duration 0 :max-gap "0:00" :gap-ok-around ("4:00") :default-face ((:background "DarkRed") (:foreground "white")) :overlap-face nil :gap-face nil :no-end-time-face nil :long-face nil :short-face nil)) + +#+end_src ***** Combine adjacent clock lines #+begin_src emacs-lisp (defun fpi/org-clock-join-last-clock () -- cgit v1.2.3 From 217867b5efe967704ffdeccfa104a30db82ab39d Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:30:04 +0100 Subject: Add agenda breadcrumbs listing parent projects --- emacs-init.org | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index bd9940b..a012cd8 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3687,11 +3687,42 @@ Simple day agenda with =INPROGRESS= tasks (org-agenda-sorting-strategy '(priority-down category-keep user-defined-down)) (org-agenda-cmp-user-defined #'fpi/org-agenda-compare-hotness) - (org-agenda-prefix-format " %i {%(fpi/org-hotness)} %-12:c") + (org-agenda-prefix-format "%-12:c %-45(fpi/org-breadcrumbs)") ;; (org-agenda-prefix-format " %-3i %-12:c%30b %s") )) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config +(defun fpi/org-breadcrumbs () + "Return projects over current entry. + +Similar to %b in `org-agenda-prefix-format'." + (org-with-wide-buffer + (let ((depth (fpi/org-project-depth 10)) + result) + (while (< (length result) depth) + (fpi/org-goto-parent-project 10) + (add-to-list 'result + (org-trim + (org-link-display-format + (replace-regexp-in-string + "\\[[0-9]+%\\]\\|\\[[0-9]+/[0-9]+\\]" "" + (nth 4 (org-heading-components)) ;; get entry title + ))))) + (if result + (reduce + (lambda (a b) (format "%s/%s" a b)) + (mapcar (lambda (s) (format "%.12s" s)) result) + ) + "") + ))) +(defun fpi/org-goto-parent-project (depth) + "Goto first project over current entry." + (when (fpi/parent-is-not-done-project-p) + (org-up-heading-safe)) + (while (and (> depth 0) + (not (fpi/is-not-done-project-p)) + (org-up-heading-safe)) + )) (defun fpi/org-agenda-compare-hotness (a b) "Compare level of hot headlines over entries A and B." (let ((ha (fpi/org-agenda-hotness a)) -- cgit v1.2.3 From f8f1ffcfb24317c8571121d95cbe8874d73d7281 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:30:50 +0100 Subject: Make fpi/org-agenda-hotness usable on agenda lines --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index a012cd8..99a8826 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3731,7 +3731,7 @@ Similar to %b in `org-agenda-prefix-format'." ((> ha hb) +1) ((< ha hb) -1) (t nil)))) -(defun fpi/org-agenda-hotness (entry) +(defun fpi/org-agenda-hotness (&optional entry) "Return level of hot headlines over ENTRY." (org-agenda-with-point-at-orig-entry entry (fpi/org-hotness))) (defun fpi/org-hotness () -- cgit v1.2.3 From 68ff830dd049455f32bf3d014b93bf1f2a67cb80 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:31:38 +0100 Subject: Add more project related functions --- emacs-init.org | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 99a8826..24dfa7d 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3740,6 +3740,15 @@ Similar to %b in `org-agenda-prefix-format'." (l1 (length tags)) (l2 (length (remove "HOT" tags)))) (- l1 l2))) +(defun fpi/org-agenda-skip-all-not-hot-and-active () + "Skip all not hot entries and not active entries." + (when (not (and + (member "HOT" (my-org-current-tags (fpi/org-project-depth 10))) + (org-with-wide-buffer + (fpi/org-goto-parent-project 10) + (fpi/is-active-project-p)))) + (or (outline-next-heading) + (goto-char (point-max))))) (defun fpi/org-agenda-skip-all-not-hot () "Skip all not hot entries." (when (not (member "HOT" (my-org-current-tags (fpi/org-project-depth 10)))) @@ -3763,25 +3772,21 @@ Similar to %b in `org-agenda-prefix-format'." should-skip)))) (defun fpi/org-project-depth (depth) "Return number of subheadings before reaching top project." - (let ((current (org-current-level)) - (top (save-excursion - (fpi/org-goto-top-project depth) - (org-current-level)))) - (- current top) - )) + (org-with-wide-buffer (fpi/org-goto-top-project depth))) (defun fpi/org-goto-top-project (depth) "Go to the top project of heading under point" (save-restriction (widen) - (let ((top (point))) + (let (top + (count -1)) (with-demoted-errors - (while (and (> depth 0) - (progn - (setq depth (1- depth)) - (not (org-up-element)))) - (when (fpi/is-not-done-project-p) - (setq top (point))))) - (goto-char top)))) + (while (and (> depth 1) + (not (equal top (point)))) + (setq depth (1- depth)) + (setq top (point)) + (fpi/org-goto-parent-project depth) + (setq count (1+ count)))) + count))) (defun fpi/is-part-of-project-p (depth) "Return t if any parent heading is a project." (< 0 (fpi/org-project-depth depth))) @@ -3789,15 +3794,20 @@ Similar to %b in `org-agenda-prefix-format'." "Return t if parent heading is a not done project." (save-excursion (save-restriction - (widen) - (and (not (org-up-element)) - (fpi/is-not-done-project-p))))) + (widen) + (and (not (org-up-element)) + (fpi/is-not-done-project-p))))) (defun fpi/is-not-done-project-p () "Return t if current heading is a not done project." (save-restriction (widen) (let ((todo (org-get-todo-state))) (member todo org-project-keywords)))) +(defun fpi/is-active-project-p () + "Return t if current heading is an active project." + (save-restriction + (widen) + (equal "ACTIVE" (org-get-todo-state)))) #+end_src To narrow the agenda to the currently selected project this function from [[https://github.com/mm--/dot-emacs/blob/master/jmm-org-config.org][Josh's emacs config]] is useful. #+begin_src emacs-lisp :tangle no :noweb-ref org-agenda-config -- cgit v1.2.3 From e39f2094c4568eca1f58cdcd9196401784e6c335 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:32:12 +0100 Subject: Add this weeks agenda --- emacs-init.org | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 24dfa7d..a66879c 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3986,6 +3986,10 @@ Based on https://github.com/psamim/dotfiles/blob/master/doom/config.el#L73. ("w" . "Week agendas") ("ww" "Standard week agenda" ((agenda "" ((org-agenda-span 'week))))) +("wt" "This Week's agenda (starting on last Monday)" + ((agenda "" ((org-agenda-span 'week) + (org-agenda-start-day "-mon"))) + (tags-todo "+work"))) ("wn" "Next Week's agenda" ((agenda "" ((org-agenda-span 'week) (org-agenda-start-day "mon"))) -- cgit v1.2.3 From 651db3f3a3f240210e27f49cdb1a625203bb9be0 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Dec 2020 13:32:26 +0100 Subject: Remove "Interrupt: " prefix from interrupt captures --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index a66879c..635f9a9 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4635,7 +4635,7 @@ For interruptions. These are saved in a global refile file and to be sorted to t ("i" "Interrupt" entry (file "~/sync/refile.org") - "** Interrupt: %? + "** %? :PROPERTIES: :CREATED: %U :SOURCE: %a -- cgit v1.2.3 From 8792acbe9e4f5121b24cb4b0aa6221ca14c340dd Mon Sep 17 00:00:00 2001 From: fpi Date: Tue, 23 Feb 2021 10:09:41 +0100 Subject: Update org-edna project task trigger .. to consider if the next task really needs to be set to NEXT --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 635f9a9..8b82130 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4525,7 +4525,7 @@ Org Edna ("L" (jmm/org-edna-link "todo!(NEXT)")) ("n" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT)")) ("N" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT) chain!(\"TRIGGER\")")) - ("P" (jmm/org-edna-set-trigger-and-point "next-sibling todo!(NEXT) chain!(\"TRIGGER\") if siblings then parent todo!(DONE) endif")) + ("P" (jmm/org-edna-set-trigger-and-point "if next-sibling todo-state?(HOLD) then else next-sibling todo!(NEXT) endif next-sibling chain!(\"TRIGGER\") if siblings then parent todo!(DONE) endif")) ("p" (jmm/org-edna-set-trigger-and-point "parent todo!(DONE)")) ("q" nil))) #+end_src -- cgit v1.2.3 From fc9789b7205e4d00d260915ae884cfe6861f8008 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Feb 2022 18:37:23 +0100 Subject: Disable pinentry loopback on win10 devices Breaks in combination with pinentry-wsl --- emacs-init.org | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 8b82130..0586825 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3077,7 +3077,9 @@ over =windmove=, as it does not interfere with org keybindings. #+begin_src emacs-lisp (use-package epa - :custom (epa-pinentry-mode 'loopback)) + :custom (epa-pinentry-mode (if (equal (fpi/current-device-info :os) 'win10) + nil + 'loopback))) (use-package pinentry :straight t :config (pinentry-start) @@ -3214,6 +3216,11 @@ Various utilities which ease programming in some languages. :straight t) #+end_src *** Emacs lisp +Remap ~eval-last-sexp~ to a pretty print version. Then you can use =C-0 C-x C-e= to insert the values of the last sexp. Use ~pp-macroexpand-last-sexp~ to print a macro expanded version of the last sexp (but not eval it). +#+begin_src emacs-lisp +(global-set-key [remap eval-last-sexp] 'pp-eval-last-sexp) +#+end_src + =Speed of thought= makes writing lisp so easy. No more snippets needed. #+begin_src emacs-lisp -- cgit v1.2.3 From 88124311ceb4a4dfbc8dbd31b2e111a2e8f68168 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:28:01 +0100 Subject: Add descriptions to fpi-map bindings --- emacs-init.org | 124 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 72 insertions(+), 52 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 0586825..8a06392 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -1685,8 +1685,8 @@ When switching between monitors with different resolution, scaling the (message "Default height: %s" new))) #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings -(define-key 'fpi-map (kbd "+") 'fpi/scale-default-face) -(define-key 'fpi-map (kbd "-") (lambda () (interactive) (fpi/scale-default-face t))) +(fpi/define-key fpi-map (kbd "+") #'fpi/scale-default-face "Zoom") +(fpi/define-key fpi-map (kbd "-") (lambda () (interactive) (fpi/scale-default-face t)) "Unzoom") #+end_src ** User info Set ~user-full-name~ and ~user-mail-address~. These are set in @@ -1805,40 +1805,48 @@ Some settings could be harmful to emacs and the underlying system. Therefore man Unfortunately =C-c [a-z]= is not always a safe place for user-defined key bindings. I use a special keymap to aggregate common functions. I rebind the =C-z= binding for this. + +Here is a helper macro to define keys including keymap prompts as described [[https://www.olivertaylor.net/emacs/keymap-prompt.html][here]]. This macro has a signature very similar to the regular ~define-key~ function. +#+begin_src emacs-lisp +(defmacro fpi/define-key (map key func &optional desc) + "Define KEY in MAP with FUNC. Optionally provide DESC." + (if desc + `(define-key ,map ,key (cons ,desc ,func)) + `(define-key ,map ,key ,func))) +#+end_src + *** Toggle map to toggle common options This was inspired from [[http://endlessparentheses.com/the-toggle-map-and-wizardry.html][this post]] and I bind it to a key on my personal keymap. #+BEGIN_SRC emacs-lisp :results silent -(define-prefix-command 'fpi/toggle-map) -(define-key fpi/toggle-map "c" #'column-number-mode) +(define-prefix-command 'fpi/toggle-map nil "Toggle") +(fpi/define-key fpi/toggle-map "c" #'column-number-mode "Column") ;;(define-key fpi/toggle-map "d" #'toggle-debug-on-error) -(define-key fpi/toggle-map "f" #'auto-fill-mode) -(define-key fpi/toggle-map "l" #'scroll-lock-mode) -(define-key fpi/toggle-map "s" #'flyspell-mode) -(define-key fpi/toggle-map "t" #'toggle-truncate-lines) -(define-key fpi/toggle-map "q" #'toggle-debug-on-quit) -(define-key fpi/toggle-map "r" #'dired-toggle-read-only) -(autoload 'dired-toggle-read-only "dired" nil t) -(define-key fpi/toggle-map "v" #'visible-mode) -(define-key fpi/toggle-map "w" #'whitespace-mode) -(define-key fpi/toggle-map "W" #'whitespace-toggle-options) +(fpi/define-key fpi/toggle-map "f" #'auto-fill-mode "Fill") +(fpi/define-key fpi/toggle-map "l" #'scroll-lock-mode "Lock scrolling") +(fpi/define-key fpi/toggle-map "s" #'flyspell-mode "Spelling") +(fpi/define-key fpi/toggle-map "t" #'toggle-truncate-lines "Truncate lines") +(fpi/define-key fpi/toggle-map "q" #'toggle-debug-on-quit "Quit trigger debug") +(fpi/define-key fpi/toggle-map "r" #'dired-toggle-read-only "Read only") +(autoload 'dired-toggle-read-only "dired" nil t ) +(fpi/define-key fpi/toggle-map "v" #'visible-mode "Visible") +(fpi/define-key fpi/toggle-map "w" #'whitespace-mode "Whitespace") +(fpi/define-key fpi/toggle-map "W" #'whitespace-toggle-options "Whitespace Options") #+END_SRC *** fpi-map #+BEGIN_SRC emacs-lisp :noweb yes -(define-prefix-command 'fpi-map) +(define-prefix-command 'fpi-map nil "fpi-map") (unbind-key (kbd "C-z")) (global-set-key (kbd "C-z") 'fpi-map) -;;(define-key fpi-map (kbd "1") 'org-global-cycle) -(define-key fpi-map (kbd "a") 'org-agenda-show-agenda-and-todo) -(define-key fpi-map (kbd "b") 'bury-buffer) -(define-key fpi-map (kbd "c") 'compile) +(fpi/define-key fpi-map (kbd "a") #'org-agenda-show-agenda-and-todo "Agenda") +(fpi/define-key fpi-map (kbd "b") #'bury-buffer "Bury") +(fpi/define-key fpi-map (kbd "c") #'compile "Compile") ;;(define-key fpi-map (kbd "u") 'multiple-cursors-hydra/body) -(define-key fpi-map (kbd "e") 'elfeed) -(define-key fpi-map (kbd "h") 'dfeich/context-hydra-launcher) -(define-key fpi-map (kbd "m") 'notmuch) -(define-key fpi-map (kbd "t") fpi/toggle-map) -(define-key fpi-map (kbd "n") 'sauron-toggle-hide-show) -(define-key fpi-map (kbd "j") (lambda () (interactive) (find-file org-journal-file))) +(fpi/define-key fpi-map (kbd "h") #'dfeich/context-hydra-launcher "Hydra") +;; (define-key fpi-map (kbd "m") 'notmuch) +(fpi/define-key fpi-map (kbd "t") #'fpi/toggle-map "Toggle") +(fpi/define-key fpi-map (kbd "n") #'sauron-toggle-hide-show "Notifications") +(fpi/define-key fpi-map (kbd "j") (lambda () (interactive) (find-file org-journal-file)) "Journal") <> #+END_SRC @@ -2861,7 +2869,6 @@ navigate and revert hunks directly from the buffer. Use =g= to open #+begin_src emacs-lisp (use-package diff-hl :straight t - :bind (:map fpi-map ("g" . hydra-diff-hl/body)) :init (global-diff-hl-mode 1) :config (defhydra hydra-diff-hl (:body-pre (diff-hl-mode 1) :hint nil) @@ -2890,6 +2897,10 @@ navigate and revert hunks directly from the buffer. Use =g= to open :color blue)) ) #+end_src + +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(fpi/define-key fpi-map "g" #'hydra-diff-hl/body "Git diff") +#+end_src *** git-auto-commit Mode to automatically commit on file save. Ensure that automatic pushing is always turned off. To enable this with [[info:emacs#File Variables][File Variables]] set @@ -4185,7 +4196,7 @@ This provides functions to get webpage title or content for org mode links. :straight t) #+end_src #+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no -(define-key fpi-map "l" #'org-web-tools-insert-link-for-url) +(fpi/define-key fpi-map "l" #'org-web-tools-insert-link-for-url "Link (org)") #+end_src *** Gnorb @@ -4917,7 +4928,7 @@ A small function to toggle the encryption state of the current entry. (if (looking-at-p "-----BEGIN PGP MESSAGE-----") (org-decrypt-entry) (org-encrypt-entry)))))) - (define-key fpi/toggle-map "e" #'fpi/org-toggle-crypt-entry)) + (fpi/define-key fpi/toggle-map "e" #'fpi/org-toggle-crypt-entry "Encrypt")) #+end_src *** Reference management **** Bibtex @@ -4966,7 +4977,7 @@ A small function to toggle the encryption state of the current entry. (ding)))))))) #+end_src #+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no -(define-key fpi-map "r" #'org-ref-helm-insert-cite-link) +(fpi/define-key fpi-map "r" #'org-ref-helm-insert-cite-link "Ref") #+end_src ***** Capturing entries I store my bibtex references in an org file together with my notes. In @@ -5165,7 +5176,7 @@ pdf if available." (if fpi/org-meta-heading-info-store (mw-org-show-meta-info-lines) (mw-org-hide-meta-heading-info))) -(define-key fpi/toggle-map "m" #'fpi/org-toggle-meta-info-lines) +(fpi/define-key fpi/toggle-map "m" #'fpi/org-toggle-meta-info-lines "Metalines (org)") #+end_src *** Table of contents in org #+begin_src emacs-lisp @@ -5228,8 +5239,10 @@ _g_: Go to active clock _b_: Break _P_: Insert BBDB _c_: Capture ("t" bh/org-todo) ;; neccessary? ("w" bh/widen) ;; neccessary? ("z" cce/note-to-clock)) +#+end_src -(define-key fpi-map (kbd "f") 'hydra-workflow/body) +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(fpi/define-key fpi-map (kbd "f") 'hydra-workflow/body "Flow") #+end_src Basic flow: 1. Start your work by clocking in with ~bh/punch-in~. This sets a @@ -5515,23 +5528,27 @@ custom link format. #+begin_src emacs-lisp (use-package zetteldeft :straight t - :bind (:map fpi-map (("d d" . deft) - ("d D" . zetteldeft-deft-new-search) - ("d R" . deft-refresh) - ("d s" . zetteldeft-search-at-point) - ("d c" . zetteldeft-search-current-id) - ("d f" . zetteldeft-follow-link) - ("d F" . zetteldeft-avy-file-search-ace-window) - ("d l" . zetteldeft-avy-link-search) - ("d t" . zetteldeft-avy-tag-search) - ("d T" . zetteldeft-tag-buffer) - ("d i" . zetteldeft-find-file-id-insert) - ("d I" . zetteldeft-find-file-full-title-insert) - ("d o" . zetteldeft-find-file) - ("d n" . zetteldeft-new-file) - ("d N" . zetteldeft-new-file-and-link) - ("d r" . zetteldeft-file-rename) - ("d x" . zetteldeft-count-words)))) + ;; :bind (:map fpi-map (("d d" . deft) + ;; ("d D" . zetteldeft-deft-new-search) + ;; ("d R" . deft-refresh) + ;; ("d s" . zetteldeft-search-at-point) + ;; ("d c" . zetteldeft-search-current-id) + ;; ("d f" . zetteldeft-follow-link) + ;; ("d F" . zetteldeft-avy-file-search-ace-window) + ;; ("d l" . zetteldeft-avy-link-search) + ;; ("d t" . zetteldeft-avy-tag-search) + ;; ("d T" . zetteldeft-tag-buffer) + ;; ("d i" . zetteldeft-find-file-id-insert) + ;; ("d I" . zetteldeft-find-file-full-title-insert) + ;; ("d o" . zetteldeft-find-file) + ;; ("d n" . zetteldeft-new-file) + ;; ("d N" . zetteldeft-new-file-and-link) + ;; ("d r" . zetteldeft-file-rename) + ;; ("d x" . zetteldeft-count-words))) + ) +#+end_src +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(fpi/define-key fpi-map "dd" #'deft "Deft") #+end_src ** Shell @@ -5597,8 +5614,11 @@ prefix to my custom keymap. (interactive "P") (if arg (call-interactively 'password-store-copy-field) - (call-interactively 'password-store-copy))) - :bind (:map fpi-map ("p" . fpi/password-store-copy-pass-or-field))) + (call-interactively 'password-store-copy)))) +#+end_src + +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(fpi/define-key fpi-map "p" #'fpi/password-store-copy-pass-or-field "Pass") #+end_src **** auth-password-store/auth-source-pass A password-store backend for the Emacs [[info:auth#Top][auth-source]] library which @@ -6414,7 +6434,7 @@ The mode is enabled for all =text-mode= based buffers by default. #+end_src Also set an easy keybinding to toggle it manually. #+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no -(define-key fpi/toggle-map "p" #'prose-mode) +(fpi/define-key fpi/toggle-map "p" #'prose-mode "Prose") #+end_src Olivetti mode is used to center text in the buffer. This somehow helps with writing. @@ -6454,7 +6474,7 @@ If `olivetti-body-width' is a number fit the window width to it instead of the a #+end_src #+begin_src emacs-lisp :tangle no :noweb-ref fpi-bindings -(define-key 'fpi-map (kbd "s") 'fpi/fit-window-to-buffer) +(fpi/define-key 'fpi-map (kbd "s") 'fpi/fit-window-to-buffer "Size window to buffer") #+end_src * Wrapping up -- cgit v1.2.3 From dc43dc2cf0c311e9de928cdd4a1c62f247d21c7a Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:33:44 +0100 Subject: Replace org headline bullets with org-num-mode --- emacs-init.org | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 8a06392..e08e9e7 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3492,7 +3492,7 @@ Here is a list of nice ones: ◉, ○, ►, •. The default ones are ~'("◉" " #+begin_src emacs-lisp (use-package org-bullets :straight t - :custom (org-bullets-bullet-list '("✧")) + :custom (org-bullets-bullet-list '(" ")) :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) #+end_src Use imagemagick and standalone class for latex preview. @@ -3508,7 +3508,9 @@ Use imagemagick and standalone class for latex preview. #+end_src #+begin_src emacs-lisp (use-package org-num - :delight) + :delight + :after org + :hook (org-mode . org-num-mode)) #+end_src *** Timekeeping & Clocking - Remove clocks with zero time. -- cgit v1.2.3 From f666eac5fddf8932846e71364c5c3e0b6e412f2f Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:36:40 +0100 Subject: Fix redtick configuration --- emacs-init.org | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index e08e9e7..7f0825d 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -6201,27 +6201,7 @@ Saves to a temp file and puts the filename in the kill ring." ((redtick-sound-volume "20") (redtick-play-sound t) (redtick-work-interval (* 60 20)) - (redtick-rest-interval (* 60 5)) - (redtick--workbar-interval (/ redtick-work-interval 8.0)) - (redtick--restbar-interval (/ redtick-rest-interval 8.0)) - (redtick--bars - `((,redtick--workbar-interval "█" "#ffff66") - (,redtick--workbar-interval "▇" "#ffcc66") - (,redtick--workbar-interval "▆" "#cc9966") - (,redtick--workbar-interval "▅" "#ff9966") - (,redtick--workbar-interval "▄" "#cc6666") - (,redtick--workbar-interval "▃" "#ff6666") - (,redtick--workbar-interval "▂" "#ff3366") - (,redtick--workbar-interval "▁" "#ff0066") - (,redtick--restbar-interval "█" "#00cc66") - (,redtick--restbar-interval "▇" "#33cc66") - (,redtick--restbar-interval "▆" "#66cc66") - (,redtick--restbar-interval "▅" "#00ff66") - (,redtick--restbar-interval "▄" "#33ff66") - (,redtick--restbar-interval "▃" "#66ff66") - (,redtick--restbar-interval "▂" "#99ff66") - (,redtick--restbar-interval "▁" "#ccff66") - (nil "✓" "#cf6a4c")))) + (redtick-rest-interval (* 60 5))) :config (redtick-mode 1)) #+end_src *** Script creation -- cgit v1.2.3 From ac49090b505bab463eaa207d68eca860fee06a98 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:43:39 +0100 Subject: Change org timestamp format to include nanosecond Also add some default latex packages to org export --- emacs-init.org | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 7f0825d..d21565b 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3423,7 +3423,7 @@ I use a org version with some custom patches. Rather than using something like = I prefer to use timestamp based ID's as they are #+begin_src emacs-lisp :tangle no :noweb-ref org-id-custom (org-id-method 'ts) -(org-id-ts-format "%FT%T%z") +(org-id-ts-format "%FT%T%z.%6N") #+end_src #+begin_src emacs-lisp @@ -3506,6 +3506,14 @@ Use imagemagick and standalone class for latex preview. [DEFAULT-PACKAGES] \\pagestyle{empty} % do not remove") #+end_src + +Also let us define some more default latex packages. +#+begin_src emacs-lisp :noweb-ref org-config :tangle no +(add-to-list 'org-latex-packages-alist '("" "uniinput")) +(add-to-list 'org-latex-packages-alist '("" "siunitx")) +(add-to-list 'org-latex-packages-alist '("" "tikz")) +(add-to-list 'org-latex-packages-alist '("" "circuitikz")) +#+end_src #+begin_src emacs-lisp (use-package org-num :delight -- cgit v1.2.3 From 510a44abc93058fb50f26816cc8df6fdb1285c2b Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:48:19 +0100 Subject: Replace org-ref with org cite --- emacs-init.org | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index d21565b..304caf1 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4957,37 +4957,18 @@ A small function to toggle the encryption state of the current entry. (setq bibtex-completion-notes-extension ".org") #+end_src -**** org-ref +**** Org Cite +=org-ref= was replaced by =orgcite= which is built into =org=. #+begin_src emacs-lisp -(use-package org-ref - :straight t - :bind (:map org-mode-map (("C-c n p" . fpi/open-bibtex-pdf-or-directory))) +(use-package oc + :after org :custom - (org-ref-bibliography-notes nil) - (org-ref-notes-function 'org-ref-notes-function-many-files) - (org-ref-notes-directory "~/git/projects/zettel/Lit") - (org-ref-default-bibliography '("~/git/projects/personal/bib.bib")) - (org-ref-pdf-directory "~/git/projects/personal/Lit/") - :config - (defun fpi/open-bibtex-pdf-or-directory () - (interactive) - (save-excursion - (bibtex-beginning-of-entry) - (let* ((bibtex-expand-strings t) - (entry (bibtex-parse-entry t)) - (key (reftex-get-bib-field "=key=" entry)) - (pdf (funcall org-ref-get-pdf-filename-function key))) - (message "%s" pdf) - (if (file-exists-p pdf) - (org-open-link-from-string (format "[[file:%s]]" pdf)) - ;; try to get pdf - (or (let ((doi-utils-open-pdf-after-download t)) - (doi-utils-get-bibtex-entry-pdf)) - (progn (dired (file-name-directory pdf)) - (ding)))))))) -#+end_src -#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no -(fpi/define-key fpi-map "r" #'org-ref-helm-insert-cite-link "Ref") + (org-cite-global-bibliography (if (equal fpi/current-device "DESKTOP-PM1PPEC") + '("~/git/projects/personal/bib.bib" + "~/win/Zotero/00_Unsorted.bib" + "~/win/Zotero/01_Annotated.bib" + "~/win/Zotero/99_AllZotero.bib") + '("~/git/projects/personal/bib.bib")))) #+end_src ***** Capturing entries I store my bibtex references in an org file together with my notes. In -- cgit v1.2.3 From 442fc567ffae19ba4d7c12ba2b6e92a1d0dd4f85 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 13:49:16 +0100 Subject: Properly set org-journal-file --- emacs-init.org | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index 304caf1..e288c6e 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4599,9 +4599,11 @@ Also exclude =ATTACH= from the inherited tags #+end_src *** Org-Capture #+BEGIN_SRC emacs-lisp +(setq org-journal-file (format "~/sync/journal/%s.org" (nth 2 (calendar-current-date)))) (use-package org-capture + :after org :custom - ((org-journal-file (format "~/sync/journal/%s.org" (nth 2 (calendar-current-date)))) + ( (org-capture-templates `( <>)) -- cgit v1.2.3 From 73038bb3c973992107d90f0f1342d7f8e209b4da Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 14:16:22 +0100 Subject: Update to new org-contrib location --- emacs-init.org | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index e288c6e..0de42de 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -3305,11 +3305,11 @@ Hansen's]] configs. - Align tags left :: Fixes problems with line breaking on small window width. -I use a org version with some custom patches. Rather than using something like =el-patch=, I host my version on github for now and update it every so often. This recipe for org is used in all coming =straight.el= calls. +I use a org version with some custom patches. Rather than using something like =el-patch=, I host my version on github for now and update it every so often. #+begin_src emacs-lisp :noweb-ref org-recipe :tangle no -(org-plus-contrib :host github :repo "fpiper/org-mode" :branch "develop" - ;;:local-repo "org" :files (:defaults "contrib/lisp/*.el") - ) +(org :host github :repo "fpiper/org-mode" :branch "develop" + ;;:local-repo "org" :files (:defaults "contrib/lisp/*.el") + ) #+end_src #+begin_src emacs-lisp @@ -4192,8 +4192,7 @@ print the list. #+begin_src emacs-lisp (use-package org-checklist :after org - :straight - <>) + :straight (org-contrib)) #+end_src *** Handling web urls **** org-web-tools @@ -4886,7 +4885,7 @@ CLOSED: %\\1 (use-package org-expiry :after org :straight - <> + (org-contrib) :custom (org-expiry-handler-function 'org-expiry-archive-subtree) (org-expiry-inactive-timestamps t) -- cgit v1.2.3 From b1782e8cfd8a9ef18ba847be5c8a04e7942f72de Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 14:26:58 +0100 Subject: Switch to org-roam v2 --- emacs-init.org | 164 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 53 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 0de42de..5e59124 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4360,62 +4360,59 @@ Set some prettify symbols for org mode. #+end_src *** org-roam Org-roam mainly provides a display of backlinks to the current file. This allows the creation of a one-subject-per-file Zettelkasten. -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle tangle/emacs-init.el :noweb yes :results silent (use-package org-roam - :straight t - :delight - :hook - (after-init . org-roam-mode) + :straight (:no-byte-compile t) :custom - (org-roam-directory "~/git/projects/zettel/") - (org-roam-tag-sources '(prop last-directory)) - (org-roam-buffer-width 0.2) - (org-roam-graph-exclude-matcher "index.org") - (org-roam-graph-viewer - (lambda (file) - (let ((org-roam-graph-viewer "/mnt/c/Program Files/Mozilla Firefox/firefox.exe")) - (org-roam-graph--open (concat "file://///wsl$/Debian" file))))) + (org-roam-directory "~/git/projects/zettel") + (org-roam-v2-ack t) + (org-roam-mode-section-functions + '(org-roam-backlinks-section + org-roam-reflinks-section + org-roam-unlinked-references-section)) (org-roam-capture-templates - '(("d" "default" plain #'org-roam-capture--get-point "%?" :file-name "%<%Y%m%d%H%M%S>-${slug}" :head "#+title: ${title} -" :unnarrowed t) - ("b" "bib" plain #'org-roam-capture--get-point - "%(fpi/org-roam-get-last-content)" - :file-name "Lit/%(fpi/org-roam-get-key \"${title}\")" - :head "" - :unnarowed t))) - (org-roam-capture-ref-templates - '(("r" "ref" plain #'org-roam-capture--get-point "%?" :file-name "Ref/${slug}" :head "#+title: ${title}\n#+ROAM_KEY: ${ref}\n " :unnarrowed t))) - :bind (:map org-roam-mode-map - (("C-c n l" . org-roam) - ("C-c n u" . org-roam-unlinked-references) - ("C-c n f" . org-roam-find-file) - ("C-c n g" . org-roam-graph) - ("C-c n d" . org-roam-doctor) - ("C-c n G" . fpi/org-roam-graph-with-exclude) - ("C-c n t g" . fpi/org-roam-toggle-graph-executable) - ("C-c n x" . org-roam-jump-to-index) - <> - ) - :map org-mode-map - (("C-c n i" . org-roam-insert))) + (quote + <> + )) :config - (defun org-roam--file-link-face (path) - "Return `org-link'" - 'org-link) - (defun fpi/org-roam-toggle-graph-executable () - (interactive) - (setq org-roam-graph-executable (if (equal org-roam-graph-executable "dot") - "neato" - "dot")) - (message "Set org-roam graphing tool to %s" org-roam-graph-executable)) - (defun fpi/org-roam-graph-with-exclude (&optional arg file node-query) - (interactive "P") - (let ((org-roam-graph-exclude-matcher (completing-read "Exclude matcher to use: " nil))) - (org-roam-graph arg file node-query))) - <> - ) + (org-roam-db-autosync-mode 1) + (add-to-list 'display-buffer-alist + '("\\*org-roam\\*" + (display-buffer-in-direction) + (direction . below) + (window-height . 0.3))) + :bind + (:map org-roam-mode-map + ( + <> + ) + :map org-mode-map + ( + <> + ))) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref org-roam-bindings +("C-c n f" . org-roam-node-find) +("C-c n i" . org-roam-node-insert) +("C-c n t" . org-roam-buffer-toggle) +("C-c n c" . org-roam-capture) +#+end_src +#+begin_src emacs-lisp :noweb-ref fpi-bindings :tangle no +(fpi/define-key fpi-map "r" #'org-roam-node-find "Roam") +#+end_src + +#+begin_src emacs-lisp +(use-package org-roam-ui + :straight (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out")) + :after org-roam + :custom + (org-roam-ui-browser-function #'browse-url-generic)) +#+end_src + +#+begin_src emacs-lisp :tangle no :noweb-ref org-roam-bindings +("C-c n u" . org-roam-ui-mode) #+end_src -Overwriting ~org-roam--file-link-face~ is a crude fix for hanging emacs. The original function calls file-exist-p which opens a slow tramp connection. The idea of ~fpi/org-roam-todo~ is from a post by [[https://oremacs.com/2020/12/31/happy-new-year/][aboabo]]. It lists all open todos in zettelkasten entries and is a (faster) alternative to running an todo agenda with ~org-agenda-files~ set to ~org-roam-directory~. #+begin_src emacs-lisp :tangle no :noweb-ref org-roam-config @@ -4426,12 +4423,73 @@ The idea of ~fpi/org-roam-todo~ is from a post by [[https://oremacs.com/2020/12/ (counsel-rg "^\\*+ \\(NEXT\\|TODO\\)" org-roam-directory "--sort modified")) #+end_src -As =C-c n t= is already taken as prefix for roam related toggle commands, use =o= (mnemonic: “open”) instead. +As =C-c n t= is already taken, use =o= (mnemonic: “open”) instead. #+begin_src emacs-lisp :tangle no :noweb-ref org-roam-bindings ("C-c n o" . fpi/org-roam-todo) #+end_src +- [ ] ntrdn +**** org-roam capture templates +Here we define some capture templates for roam files. Using variables in the source block header we can define the template contents in quote blocks below. + +#+HEADER: :var default=org-roam-template-default ref=org-roam-template-ref +#+HEADER: :var entities=org-roam-template-entities work=org-roam-template-work +#+HEADER: :var personal=org-roam-template-personal private=org-roam-template-private +#+NAME: org-roam-capture-templates +#+begin_src emacs-lisp :tangle no :noweb yes :results code silent +`( + ("d" "Default (avoid this)" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" ,default) + :unnarrowed t) + ("l" "Link/Reference" plain "%?" + :target (file+head "ref/${slug}.org" ,ref) + :unnarrowed t) + ("e" "Entity (Person, Company, …)" plain "%?" + :target (file+head "Entities/${slug}.org" ,entities) + :unnarrowed t) + ("w" "Work related zettel" plain "%?" + :target (file+head "Work/%<%Y%m%d%H%M%S>-${slug}.org" ,work) + :unnarrowed t) + ("p" "Personal/Non-work related zettel" plain "%?" + :target (file+head "Personal/%<%Y%m%d%H%M%S>-${slug}.org" ,personal) + :unnarrowed t) + ("P" "Private zettel" plain "%?" + :target (file+head "Personal/Private/%<%Y%m%d%H%M%S>-${slug}.org" ,private) + :unnarrowed t) + ) +#+end_src +As capture templates get more complex storing the template itself in a separate file – or org-babel source block – can be helpful. Above are my (all very similar) template definitions; below the template contents. + +#+NAME: org-roam-template-default +#+begin_quote +#+title: ${title} +#+end_quote +#+NAME: org-roam-template-ref +#+begin_quote +#+title: ${title} +#+ROAM_KEY: ${ref} +#+end_quote +#+NAME: org-roam-template-entities +#+begin_quote +#+FILETAGS: entity +#+title: ${title} +#+end_quote +#+NAME: org-roam-template-work +#+begin_quote +#+FILETAGS: work +#+title: ${title} +#+end_quote +#+NAME: org-roam-template-personal +#+begin_quote +#+FILETAGS: personal +#+title: ${title} +#+end_quote +#+NAME: org-roam-template-private +#+begin_quote +#+FILETAGS: personal private +#+title: ${title} +#+end_quote **** org-roam-protocol #+begin_src emacs-lisp (use-package org-roam-protocol @@ -5483,7 +5541,7 @@ creation. :custom ((deft-directory "~/git/projects/zettel") (deft-extensions '("org")) (deft-default-extension "org") - (deft-use-filename-as-title nil) + (deft-use-filename-as-title t) (deft-recursive t) (deft-use-filter-string-for-filename t) <>)) -- cgit v1.2.3 From 307103f6f12276581749b1cfa94f7b8cf71c93e5 Mon Sep 17 00:00:00 2001 From: fpi Date: Thu, 17 Mar 2022 14:27:16 +0100 Subject: Update packages --- package-versions.el | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/package-versions.el b/package-versions.el index d6a3ef5..f9f6001 100644 --- a/package-versions.el +++ b/package-versions.el @@ -7,6 +7,7 @@ ("biblio.el" . "eb9baf1d2bf6a073d24ccb717025baa693e98f3e") ("cdlatex" . "480387b39f6ddd9cd2a9511ecee064ad8e1dd324") ("closql" . "9371635bc3e259b73a075985ebbfc58b45fa5e9d") + ("company-mode" . "5618f28d62cbbdcccdaee1b455fc6e9d1c8bff31") ("dash.el" . "ea4a4cc7cce7c3b93862a22df8bca8b83052ccbf") ("deft" . "fca9ea05ef4fdac825e2ad3921baa7042f6b82c8") ("delight" . "02e73b69708e23053105866a58fe14f75c272dee") @@ -15,27 +16,31 @@ ("dired-git-info" . "b47f2b0c3a6cb9b7a62a4ee2605a492e512d40a9") ("dired-hacks" . "f49a8bbf95f70671a74a24f7f4de453b2686be46") ("dired-sidebar" . "6e569c851418890c21fd37d03a62f85343aa0900") - ("elfeed" . "a2cae98b4f04616c06455b6104d2ca5ff4b86867") - ("elfeed-org" . "77b6bbf222487809813de260447d31c4c59902c9") ("emacs-async" . "86aef2c38e7d35e8509b7feeee3e989d825eba91") ("emacs-hide-mode-line" . "88888825b5b27b300683e662fa3be88d954b1cea") ("emacs-htmlize" . "86f22f211e9230857197c42a9823d3f05381deed") + ("emacs-libvterm" . "f41849c2c9c1899f22d1c3d4f871ec47c82627ce") + ("emacs-request" . "912525c772984c6af0fd84acd6699ee43d91037a") ("emacs-which-key" . "8b49ae978cceca65967f3544c236f32964ddbed0") ("emacsmirror-mirror" . "006fbf082e52dd33cb842c9d5fb181de12736142") ("emacsql" . "a118b6c95af1306f0288a383d274b5dd93efbbda") ("emacsql-sqlite3" . "1e411fd38a0137553986db209642fe93cae96060") - ("epl" . "78ab7a85c08222cd15582a298a364774e3282ce6") + ("esxml" . "193d199305e7abcb5ed795b9bc5434ded20ae60e") ("f.el" . "1814209e2ff43cf2e6d38c4cd476218915f550fb") ("forge" . "048efbba83b1df591de0487202ff968250ea4fc5") ("ghub" . "3da5d8827f6b697ef71dca0a44eb8134689c1dad") + ("git-annex-el" . "c8f7995a232efe643d7acdafcb6370f2d8af8327") ("git-auto-commit-mode" . "dd0c2441de0f5ff8c69c8260d9450d0b607e3e55") ("git-identity.el" . "eec910b2a5459345321b5b9d166383f1323501f5") + ("gnorb" . "260d41f60a6f5ac864ed0cf48a94b546ce71c24a") ("gntp.el" . "767571135e2c0985944017dc59b0be79af222ef5") ("gnu-elpa-mirror" . "f07e244acca36061cc03c63463246b848748e804") ("gnuplot" . "f0001c30010b2899e36d7d89046322467e923088") ("gnuplot-mode" . "601f6392986f0cba332c87678d31ae0d0a496ce7") + ("header-info" . "1482e2f9fe0558acb36e170b627dc46b1f6f6a38") ("helm" . "3ff35503a920d8629cf5c9c07647923661f24ba2") ("helm-bibtex" . "8a0dd9841316793aacddea744d6b8ca4a7857a35") + ("ht.el" . "fff8c43f0e03d5b98deb9f988522b839ce2ca253") ("hydra" . "8a9124f80b6919ad5288172b3e9f46c5332763ca") ("ibuffer-vc" . "1249c1e30cf11badfe032ac3b1058f24ba510ace") ("icomplete-vertical" . "a5871d39c5850ac4d9aac48350eaa1d31f3aaef7") @@ -44,26 +49,21 @@ ("ledger-mode" . "f8463744191b4feb9fea54190917663f7ba26102") ("let-alist" . "ef3c02fa292b6e32769945bbbfb7f2e5ac574b64") ("log4e" . "7df0c1ff4656f8f993b87064b1567618eadb5546") + ("lsp-mode" . "34de3040f01aeda4eceadc1ccd6a723120ee4598") ("magit" . "8b45756390e43bfc3247dd85bf5f7738516e569a") ("magit-gitflow" . "cc41b561ec6eea947fe9a176349fb4f771ed865b") ("magit-popup" . "b8e886c4f2242d6c58f84d4549af712e86360db1") ("markdown-mode" . "399df42755ccf31cecb61c9f5d8ad72bc30d7e4b") ("matlab-mode" . "e14d97df706049ea2e2d6e5b515fdbd08cd94dd3") ("melpa" . "ee055cc258692a92f727633306adf7df31267479") - ("messages-are-flowing" . "d582a564a63b7b90764ffc5c618bc5300225d0ab") ("notmuch" . "963e363a234f1c8bdf1ae68956f80a2538bee7dc") + ("ob-spice" . "a3581400b253330231573e100c39548e5d891cfd") + ("olivetti" . "0bc5e98b8456493084d1bd3df35e92a12c5da3b2") + ("openscad" . "176ea07abba6f5f8fb5a130143f23b397416c789") ("orderless" . "1f1e0380e2a8cd4fc29b8cc2e00cb01b56d86fbc") - ("org" . "583012b5e129ca79c05109ba68c37f17ffca4930") - ("org-bullets" . "767f55feb58b840a5a04eabfc3fbbf0d257c4792") - ("org-caldav" . "8569941a0a5a9393ba51afc8923fd7b77b73fa7a") - ("org-clock-convenience" . "4e522706a90a504c75d377161005f9543575ea02") - ("org-edna" . "8a14af7baadb3e4021d40e2b4ebdcee66dab4783") - ("org-noter" . "9ead81d42dd4dd5074782d239b2efddf9b8b7b3d") - ("org-pdftools" . "8cc15bb8014ed1f047eecc0abd8bf447f86c0505") - ("org-ref" . "9465abc54a296b4b2f745b4bb3a28ec4dad3a0cb") - ("org-reveal" . "84039bb499290926511b04749882ecb5eda45a0c") - ("org-roam" . "87403b330ce713a892e3e35ff4174a8e2727e24d") - ("org-time-budgets" . "207dda6308cfc73e16dcfd84237a560c27428beb") + ("org-roam" . "f819720c510185af713522c592833ec9f2934251") + ("org-time-budgets" . "439e73b730a9e9434c93b3b1892780e5d128246a") + ("org-web-tools" . "ebc7888f4f4cad26ec1298edd7bf606a5ea2d564") ("parsebib" . "3497b6068d78ae15ba1eaf94e4315d18e9ae6b00") ("pass" . "919d8e3826d556433ab67d4ee21a509d209d1baa") ("password-store" . "07b169ec32ad6961ed8625a0b932a663abcb01d2") @@ -71,24 +71,36 @@ ("pdf-tools" . "c510442ab89c8a9e9881230eeb364f4663f59e76") ("peep-dired" . "1d410a4e48db07a942e54d3b83a85c7a7ec0aab3") ("pinentry" . "cd942f755c38a7ac270ce858bb887ebdd59edd26") - ("pkg-info" . "76ba7415480687d05a4353b27fea2ae02b8d9d61") ("popup-el" . "9d104d4bbbcb37bbc9d9ce762e74d41174683f86") - ("projectile" . "33bc91e7518fb8cecd89580f16e0ac21799de2c2") + ("project" . "e4763443d23710559a92748801db5d6de25e6221") ("rainbow-mode" . "f780ddb18c2a73a666d093f606df92058e5601ea") + ("redtick" . "d30637a536533830693eada29978f275af27aa26") + ("rustic" . "ed68fd3bb410869e1a4ce3943b5913ea88d9b509") ("s.el" . "43ba8b563bee3426cead0e6d4ddc09398e1a349d") + ("sauron" . "5daade4836da5b1b2ab26d84128d6c38328a5d52") ("shell-pop-el" . "4b4394037940a890a313d715d203d9ead2d156a6") ("shr-tag-pre-highlight.el" . "6182f43a36b0f82ba6edcf6e423b5f69a46a814e") ("spacemacs-theme" . "6c26717c0ec64af08ab3fd81e88ef03003543c5d") ("speed-of-thought-lisp" . "ed2356a325c7a4a88ec1bd31381c8666e8997e97") ("spice-mode" . "e5e0644f03f9696f56dd69e2b6979da7f30ed600") + ("spinner" . "2daa167bec1c7566d662d48613a94453536b524a") + ("spray" . "74d9dcfa2e8b38f96a43de9ab0eb13364300cb46") + ("ssh-tunnels" . "d32e2072f50bcbde787196abb5862735837dc8be") ("straight.el" . "a7f94876b2bf96d2595706270be6630ecc94f0d3") ("swiper" . "f8b1ab8c0ec331a4f8f6621f9021811075c71332") ("tablist" . "faab7a035ef2258cc4ea2182f67e3aedab7e2af9") + ("toc-org" . "5deaec41ed0e5c51715737d7f74c5ae1b3c00387") ("transient" . "88d935c7cb9f175871c4cfea7eef2c0514d03b06") ("treepy.el" . "306f7031d26e4ebfc9ff36614acdc6993f3e23c3") ("use-package" . "d2640fec376a8458a669e7526e63e5870d875118") ("use-package-hydra" . "8cd55a1128fbdf6327bb38a199d206225896d146") + ("vundo" . "4b6551748b205dde157bccafcfdd4637071939c7") + ("whole-line-or-region" . "79731cbbf173dbb9dcce3457baa1056e906d98db") ("window-numbering.el" . "10809b3993a97c7b544240bf5d7ce9b1110a1b89") ("with-editor" . "48ca9bb49a1a7a37e85606de9d327a14030d4380") + ("xref" . "83cedce58124a81ff7f323d7fbf553fbeadfa4b5") + ("xterm-color" . "1a4012854c69a5cdaeb5a73d2ad705011892fca3") + ("yasnippet" . "5cbdbf0d2015540c59ed8ee0fcf4788effdf75b6") + ("yasnippet-snippets" . "be823d7e1a1a46454d60a9f3dabb16b68b5dd853") ("zetteldeft" . "19943a39e1c5f53dae6fac107ce3a7d2e4c5f2f8")) :alpha -- cgit v1.2.3 From 6c504d10f07a51af0372695d92d144b3440fc4bc Mon Sep 17 00:00:00 2001 From: fpi Date: Fri, 18 Mar 2022 14:47:25 +0100 Subject: Update exwm monitor config --- init-exwm.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init-exwm.org b/init-exwm.org index 8acf733..0ce1f07 100644 --- a/init-exwm.org +++ b/init-exwm.org @@ -50,7 +50,7 @@ set keyboard (use-package exwm-randr :config (setq exwm-randr-workspace-output-plist - (when (equal fpi/current-device "pan") '(0 "DisplayPort-3" 1 "DisplayPort-5"))) + (when (equal fpi/current-device "pan") '(0 "DisplayPort-4" 1 "DisplayPort-6"))) ;; (when (equal system-name "pan") ;; (start-process-shell-command "xrandr" nil "xrandr --output DisplayPort-0 --off --output DisplayPort-1 --off --output DisplayPort-2 --off --output HDMI-A-0 --off --output DisplayPort-3 --mode 2560x1440 --pos 0x612 --rotate normal --output DisplayPort-4 --off --output DisplayPort-5 --mode 2560x1440 --pos 2560x0 --rotate right --output DisplayPort-6 --off") ;; (exwm-workspace-add)) -- cgit v1.2.3 From 1747a88fed064653e52c5da3b83094a53c7bd5d2 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Mar 2022 17:47:39 +0100 Subject: Pull Roam from git & fix templates --- emacs-init.org | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/emacs-init.org b/emacs-init.org index 5e59124..a58f7ad 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4362,7 +4362,11 @@ Set some prettify symbols for org mode. Org-roam mainly provides a display of backlinks to the current file. This allows the creation of a one-subject-per-file Zettelkasten. #+begin_src emacs-lisp :tangle tangle/emacs-init.el :noweb yes :results silent (use-package org-roam - :straight (:no-byte-compile t) + :straight (:host github + :repo "org-roam/org-roam" + :files (:defaults "extensions/*") + :no-byte-compile t) + :after magit :custom (org-roam-directory "~/git/projects/zettel") (org-roam-v2-ack t) @@ -4428,7 +4432,6 @@ As =C-c n t= is already taken, use =o= (mnemonic: “open”) instead. ("C-c n o" . fpi/org-roam-todo) #+end_src -- [ ] ntrdn **** org-roam capture templates Here we define some capture templates for roam files. Using variables in the source block header we can define the template contents in quote blocks below. @@ -4439,22 +4442,22 @@ Here we define some capture templates for roam files. Using variables in the sou #+begin_src emacs-lisp :tangle no :noweb yes :results code silent `( ("d" "Default (avoid this)" plain "%?" - :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" ,default) + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" ,default) :unnarrowed t) ("l" "Link/Reference" plain "%?" - :target (file+head "ref/${slug}.org" ,ref) + :if-new (file+head "Ref/${slug}.org" ,ref) :unnarrowed t) ("e" "Entity (Person, Company, …)" plain "%?" - :target (file+head "Entities/${slug}.org" ,entities) + :if-new (file+head "Entities/${slug}.org" ,entities) :unnarrowed t) ("w" "Work related zettel" plain "%?" - :target (file+head "Work/%<%Y%m%d%H%M%S>-${slug}.org" ,work) + :if-new (file+head "Work/%<%Y%m%d%H%M%S>-${slug}.org" ,work) :unnarrowed t) ("p" "Personal/Non-work related zettel" plain "%?" - :target (file+head "Personal/%<%Y%m%d%H%M%S>-${slug}.org" ,personal) + :if-new (file+head "Personal/%<%Y%m%d%H%M%S>-${slug}.org" ,personal) :unnarrowed t) ("P" "Private zettel" plain "%?" - :target (file+head "Personal/Private/%<%Y%m%d%H%M%S>-${slug}.org" ,private) + :if-new (file+head "Personal/Private/%<%Y%m%d%H%M%S>-${slug}.org" ,private) :unnarrowed t) ) #+end_src @@ -4467,8 +4470,10 @@ As capture templates get more complex storing the template itself in a separate #+end_quote #+NAME: org-roam-template-ref #+begin_quote +:PROPERTIES: +:ROAM_REFS: ${ref} +:END: #+title: ${title} -#+ROAM_KEY: ${ref} #+end_quote #+NAME: org-roam-template-entities #+begin_quote @@ -4493,7 +4498,16 @@ As capture templates get more complex storing the template itself in a separate **** org-roam-protocol #+begin_src emacs-lisp (use-package org-roam-protocol - :after org-roam) + :after org-roam + :custom (org-roam-capture-ref-templates + '(("zr" "roam ref" plain "%?" + :if-new (file+head "Ref/${slug}.org" + "#+title: ${title}") + :unnarrowed t) + ("zf" "roam fleeting ref" plain "%?" + :if-new (file+head "Fleeting/${slug}.org" + "#+title: ${title}") + :unnarrowed t)))) #+end_src **** org-roam-bibtex #+begin_src emacs-lisp @@ -4865,8 +4879,10 @@ To be compatible with [[https://github.com/sprig/org-capture-extension][this chr "* %? [[%:link][%:description]] :PROPERTIES: :CREATED: %U +:ID: %(org-id-new) +:ROAM_REFS: %:link :END: -#+ROAM_KEY: %:link") +") #+end_src ***** Old templates Templates I no longer use, but may be interesting. -- cgit v1.2.3 From 0a71f747129eb8d365dfc384803cc7c6d523b575 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Mar 2022 17:48:00 +0100 Subject: Enable org-protocol --- emacs-init.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/emacs-init.org b/emacs-init.org index a58f7ad..3152d50 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4836,7 +4836,7 @@ Instead of project related capture templates, I use the same template for all ta :ID: 28704dfb-7647-43ac-b96f-5967383d1188 :END: Org-protocol is an easy way to capture stuff from outside emacs. -#+begin_src emacs-lisp +#+begin_src emacs-lisp :tangle tangle/emacs-init.el :eval yes :results silent (use-package org-protocol) #+end_src To install the handler for =org-protocol://= URIs under linux you probably need a =.desktop= file similar to the one below. Place it under =~/.local/share/applications= and run src_shell{update-desktop-database}. -- cgit v1.2.3 From 21359a651b5b405b63cd2de802512de7cb18e810 Mon Sep 17 00:00:00 2001 From: fpi Date: Sun, 20 Mar 2022 17:50:43 +0100 Subject: Add function to create constant, unique filenames --- emacs-init.org | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/emacs-init.org b/emacs-init.org index 3152d50..ea29924 100644 --- a/emacs-init.org +++ b/emacs-init.org @@ -4306,6 +4306,84 @@ This function is handy to use in header arguments to create names based on the c (post (or post ""))) (format "%s%s%s" pre (nth 4 (org-heading-components)) post))) #+end_src + +We can also create unique names based on the source block content and header information. +#+begin_src emacs-lisp +(defun fpi/org-babel-get-src-block-hash (&optional block) + "Return a hash based on src block content and header. + +This function tries to not take any file positions into account +and always return the same hash given the same source code and +same header arguments. + +`org-babel-sha1-hash' may provide the same feature, but I +discovered that function only after writing this." + (save-mark-and-excursion + (if block (org-babel-goto-named-src-block block)) + (let* ((info (org-babel-get-src-block-info t)) + (body (nth 1 info)) + (header (nth 2 info)) + (hashstring (format "%s%s" body header))) + (md5 hashstring)))) + +(setq fpi/org-babel-outfile-directory "/tmp/babel") +(make-directory fpi/org-babel-outfile-directory t) + +(defun fpi/org-babel-src-block-temp-file (&optional suffix prefix directory block) + "Return a unique filename based on src block content and header. + +This function is intended as an alternative to +`org-babel-temp-file' to provide unique and constant output +filenames. Optionally provide SUFFIX or PREFIX of the filename +and the file DIRECTORY. If SUFFIX or PREFIX is a list its content +will be concatenated. Default directory is +`org-babel-temporary-directory'. Optionally provide a source +block name BLOCK. + " + ;; FIXME Way to create really unique names. In case same code can produce different outputs (e.g. based on time, file context) + (let ((hash (fpi/org-babel-get-src-block-hash block)) + (directory (or + directory + fpi/org-babel-outfile-directory)) + (suffix (if (listp suffix) + (mapconcat (lambda (x) + (cond ;; FIXME possible to handle all cases without cond? + ((symbolp x) (symbol-name x)) + ((numberp x) (number-to-string x)) + (t x) + )) suffix "") + suffix)) + (prefix (if (listp prefix) + (mapconcat (lambda (x) + (cond ;; FIXME possible to handle all cases without cond? + ((symbolp x) (symbol-name x)) + ((numberp x) (number-to-string x)) + (t x) + )) prefix "") + prefix)) + (prefix (or prefix "")) + ) + (expand-file-name (format "%s%s%s" prefix hash suffix) directory) + )) +(defalias 'fpi/ob-name #'fpi/org-babel-src-block-temp-file) +#+end_src + +Now wen can set something like ~:file (fpi/ob-name ".png")~ on all source blocks where we do not care about the output file name. + +Some tests for ~fpi/ob-name~: +#+begin_src emacs-lisp :results value replace :tangle no :exports both +(list + (fpi/ob-name) + (fpi/ob-name "-SUFFIX") + (fpi/ob-name nil "PREFIX-") + (fpi/ob-name "-SUFFIX" "PREFIX-") + (fpi/ob-name '("-SUF" 42 FIX)) + ) +#+end_src + +#+RESULTS: +| /tmp/babel-gwZcjh/291f3f60f3e5d467584a3b5bda4d7b05 | /tmp/babel-gwZcjh/291f3f60f3e5d467584a3b5bda4d7b05-SUFFIX | /tmp/babel-gwZcjh/PREFIX-291f3f60f3e5d467584a3b5bda4d7b05 | /tmp/babel-gwZcjh/PREFIX-291f3f60f3e5d467584a3b5bda4d7b05-SUFFIX | /tmp/babel-gwZcjh/291f3f60f3e5d467584a3b5bda4d7b05-SUF42FIX | + *** ox-reveal #+BEGIN_SRC emacs-lisp (use-package ox-reveal -- cgit v1.2.3