From 9001c45e8bb95e34a4d2a0488984848aa5c46622 Mon Sep 17 00:00:00 2001 From: Thierry Pouplier Date: Thu, 10 Sep 2026 12:30:45 -0400 Subject: [PATCH] doc-view: C-j/C-k page navigation (same as pdf-tools) --- btop/.config/btop/btop.conf | 18 ++- doom/.config/doom/README.org | 111 +++++++++++++++--- doom/.config/doom/config.el | 100 +++++++++++++--- exokortex/.local/bin/exokortex_auto_commit.sh | 8 ++ 4 files changed, 201 insertions(+), 36 deletions(-) diff --git a/btop/.config/btop/btop.conf b/btop/.config/btop/btop.conf index a260723..5fd0d00 100644 --- a/btop/.config/btop/btop.conf +++ b/btop/.config/btop/btop.conf @@ -1,4 +1,4 @@ -#? Config file for btop v.1.4.6 +#? Config file for btop v.1.4.7 #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" @@ -14,6 +14,11 @@ truecolor = true #* Will force 16-color mode and TTY theme, set all graph symbols to "tty" and swap out other non tty friendly symbols. force_tty = false +#* Option to disable presets. Either the default preset, custom presets, or all presets. +#* "Off" All presets are enabled. +#* "Default" preset is disabled.#* "Custom" presets are disabled.#* "All" presets are disabled. +disable_presets = "Off" + #* Define presets for the layout of the boxes. Preset 0 is always all boxes shown with default settings. Max 9 presets. #* Format: "box_name:P:G,box_name:P:G" P=(0 or 1) for alternate positions, G=graph symbol to use for box. #* Use whitespace " " as separator between different presets. @@ -24,6 +29,9 @@ presets = "cpu:1:default,proc:0:default cpu:0:default,mem:0:default,net:0:defaul #* Conflicting keys for h:"help" and k:"kill" is accessible while holding shift. vim_keys = true +#* Disable all mouse events. +disable_mouse = false + #* Rounded corners on boxes, is ignored if TTY mode is ON. rounded_corners = true @@ -92,6 +100,9 @@ proc_left = false #* (Linux) Filter processes tied to the Linux kernel(similar behavior to htop). proc_filter_kernel = false +#* Should the process list follow the selected process when detailed view is open. +proc_follow_detailed = true + #* In tree-view, always accumulate child process resources in the parent process. proc_aggregate = true @@ -208,6 +219,9 @@ io_graph_combined = false #* Example: "/mnt/media:100 /:20 /boot:1". io_graph_speeds = "" +#* Swap the positions of the upload and download speed graphs. When true, upload will be on top. +swap_upload_download = false + #* Set fixed values for network graphs in Mebibits. Is only used if net_auto is also set to False. net_download = 100 @@ -250,7 +264,7 @@ rsmi_measure_pcie_speeds = true #* Horizontally mirror the GPU graph. gpu_mirror_graph = true -#* Set which GPU vendors to show. Available values are "nvidia amd intel" +#* Set which GPU vendors to show. Available values are "nvidia amd intel apple" shown_gpus = "nvidia amd intel" #* Custom gpu0 model name, empty string to disable. diff --git a/doom/.config/doom/README.org b/doom/.config/doom/README.org index eb2e12b..602c3bd 100644 --- a/doom/.config/doom/README.org +++ b/doom/.config/doom/README.org @@ -703,26 +703,27 @@ org-agenda-files (seq-uniq org-agenda-files) (setq org-capture-templates '( - ("t" "TODO" entry (file+olp +org-capture-todo-file "Tasks") + ("t" "Tasks") + ("ti" "Idea" entry (file+olp +org-capture-todo-file "Tasks") "* IDEA %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) - ("c" "Code TODO" entry - (file+olp +org-capture-todo-file "Tasks") - "* TODO %a\n:PROPERTIES:\n:CREATED: %U\n:END:\n":prepend t) + ("tt" "Todo" entry (file+olp +org-capture-todo-file "Tasks") + "* TODO %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) + ("tw" "Wait" entry (file+olp +org-capture-todo-file "Tasks") + "* WAIT %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) + ("tp" "Task at point" entry (file+olp +org-capture-todo-file "Tasks") + "* TODO %? %a\n:PROPERTIES:\n:CREATED: %U\n:END:\n" :prepend t) + ("te" "Emails") + ("tef" "Follow Up" entry (file+olp +org-capture-todo-file "Tasks") "* TODO Follow up with %:fromname on %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("ter" "Read Later" entry (file+olp +org-capture-todo-file "Tasks") "* TODO Read: %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("tew" "Waiting Response" entry + (file+olp +org-capture-todo-file "Tasks") "* WAIT Waiting response from %:toname on %a\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) ("n" "Note" entry (file+olp +org-capture-notes-file "Notes") "* %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") ("w" "Question" entry (file+olp +org-capture-notes-file "Questions") "* [?] %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") - ("j" "Journal" entry (file+olp +org-capture-journal-file "Journal") - "* %?\n%a\n%i") - ("m" "Meeting" entry (file+olp +org-capture-notes-file "Meetings") - "* %? %U :meeting:\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n/Met with: /") - ("a" "Appointment" entry (file+olp +org-capture-journal-file "Appointments") - "* %? :appointment:\n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :time-prompt t) - ("e" "Email Workflow") - ("ef" "Follow Up" entry (file+olp +org-capture-emails-file "Mails" "Follow Up") "* TODO Follow up with %:fromname on %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) - ("er" "Read Later" entry (file+olp +org-capture-emails-file "Mails" "Read Later") "* TODO Read: %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) - ("ew" "Waiting Response" entry - (file+olp +org-capture-emails-file "Mails" "Waiting Response") "* WAIT Waiting response from %:toname on %a\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("e" "Event" entry (file+olp +org-capture-todo-file "Events") + "* %? %^t\n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") + ("C" "Contact" entry (file+olp +org-capture-todo-file "Contacts") "* %?\n:PROPERTIES:\n:EMAIL: %:fromemail\n:ROLE: \n:END:\n%a\n%i") ) ) ) @@ -1434,7 +1435,7 @@ Let me write like a broken engineer, thank you. ;; Fold bindings (after! evil - (define-key evil-motion-state-map (kbd "z C") #'hs-hide-level)) + (define-key evil-motion-state-map (kbd "z M") #'hs-hide-level)) ;; Disable global bindings for C-j and C-k (global-unset-key (kbd "C-j")) @@ -2394,6 +2395,10 @@ Make org task, agenda, tables look nicer, but you need to deactivate it sometime :config (global-org-modern-mode) (setq org-modern-star 'replace) + ;; U+2733 (✳) isn't in JetBrainsMono Nerd Font -> font fallback renders it green. + ;; r/emacs favorite headline list, flower ✿ swapped for hollow ◇ in level 5 (filled ◆ was too big). + ;; NOTE: ✸⁖ may need font fallback in the GUI frame (JetBrainsMono Nerd lacks them). + (setq org-modern-replace-stars "⁖◉○◇✸") (setq org-modern-todo-faces '( ;; Framework @@ -2569,7 +2574,7 @@ Cordialement, (setq mu4e-icalendar-diary-file nil) (setq gnus-icalendar-org-capture-file +org-capture-journal-file - gnus-icalendar-org-capture-headline '("Journal")) + gnus-icalendar-org-capture-headline '("Events")) (gnus-icalendar-org-setup) @@ -2883,6 +2888,17 @@ Really useful to be able to have a buffer with notes, and another with the offic :n "C-k" #'pdf-roll-previous-page)) #+end_src +* Doc-View (docx/odt) +Same page navigation as PDF-Tools (C-j / C-k) for doc-view buffers (renders .docx/.odt via PDF). + +#+begin_src emacs-lisp +(use-package! doc-view + :config + (map! :map doc-view-mode-map + :n "C-j" #'doc-view-next-page + :n "C-k" #'doc-view-previous-page)) +#+end_src + * Custom functions ** Refile to datetree @@ -3803,6 +3819,67 @@ Optional PROJECT-TAG and CONTEXT-TAG can be given to create .projectile and .dir (message "Successfully batch-converted %d directories to ExoKortex nodes!" count)))) #+end_src +** ExoKortex Archive / Restore + +Moves node(s) between categories. Operates on marked Dired items, or the +item at cursor when nothing is marked. +#+begin_src emacs-lisp +(defun gortium/dired-node-dirs () + "Return marked Dired subdirectories, or the cursor dir if nothing marked." + (when (derived-mode-p 'dired-mode) + (let* ((elements (dired-get-marked-files nil nil nil t)) + (has-marks (or (and (listp elements) (> (length elements) 1)) + (and (consp elements) (eq (car elements) t)))) + (marked (when has-marks + (cl-remove-if-not #'file-directory-p + (if (eq (car-safe elements) t) + (cdr elements) + elements))))) + (or marked + (let ((cursor (dired-get-filename nil t))) + (when (and cursor (file-directory-p cursor)) + (list cursor))))))) + +(defun gortium/move-node (src-category dst-category node-dirs) + "Move NODE-DIRS (absolute paths) from SRC-CATEGORY to DST-CATEGORY. +Markers (.projectile/.dir-locals/.hermes-sessions/.git) move with each dir." + (let ((root (expand-file-name gortium/exokortex-root)) + (moved 0)) + (dolist (dir node-dirs) + (let* ((name (file-name-nondirectory (directory-file-name dir))) + (src (expand-file-name name (expand-file-name src-category root))) + (dst (expand-file-name name (expand-file-name dst-category root)))) + (unless (file-directory-p src) + (user-error "No node '%s' in %s" name src-category)) + (when (file-exists-p dst) + (user-error "%s already has a node named '%s'" dst-category name)) + (make-directory (file-name-directory dst) t) + (rename-file src dst) + ;; Stale path: drop from the Projectile cache so the switch-list cleans up. + (when (fboundp 'projectile-remove-known-project) + (projectile-remove-known-project src)) + (cl-incf moved))) + (message "Archived/restored %d node(s): %s → %s" moved src-category dst-category))) + +(defun gortium/archive-node () + "Move marked (or cursor) nodes from 1-Projects to 4-Archives." + (interactive) + (let ((dirs (gortium/dired-node-dirs))) + (unless dirs + (user-error "No node under Dired cursor / no marked directories")) + (gortium/move-node "1-Projects" "4-Archives" dirs))) + +(defun gortium/restore-node (category) + "Move marked (or cursor) archived nodes back into CATEGORY." + (interactive + (list (completing-read "Restore to category: " + '("1-Projects" "2-Areas" "3-Resources")))) + (let ((dirs (gortium/dired-node-dirs))) + (unless dirs + (user-error "No node under Dired cursor / no marked directories")) + (gortium/move-node "4-Archives" category dirs))) +#+end_src + ** Project-Aware Agenda Reads =.dir-locals.el= from the current Projectile root and injects the diff --git a/doom/.config/doom/config.el b/doom/.config/doom/config.el index 3348a45..0324ebb 100644 --- a/doom/.config/doom/config.el +++ b/doom/.config/doom/config.el @@ -548,26 +548,27 @@ org-agenda-files (seq-uniq org-agenda-files) (setq org-capture-templates '( - ("t" "TODO" entry (file+olp +org-capture-todo-file "Tasks") + ("t" "Tasks") + ("ti" "Idea" entry (file+olp +org-capture-todo-file "Tasks") "* IDEA %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) - ("c" "Code TODO" entry - (file+olp +org-capture-todo-file "Tasks") - "* TODO %a\n:PROPERTIES:\n:CREATED: %U\n:END:\n":prepend t) + ("tt" "Todo" entry (file+olp +org-capture-todo-file "Tasks") + "* TODO %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) + ("tw" "Wait" entry (file+olp +org-capture-todo-file "Tasks") + "* WAIT %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :prepend t) + ("tp" "Task at point" entry (file+olp +org-capture-todo-file "Tasks") + "* TODO %? %a\n:PROPERTIES:\n:CREATED: %U\n:END:\n" :prepend t) + ("te" "Emails") + ("tef" "Follow Up" entry (file+olp +org-capture-todo-file "Tasks") "* TODO Follow up with %:fromname on %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("ter" "Read Later" entry (file+olp +org-capture-todo-file "Tasks") "* TODO Read: %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("tew" "Waiting Response" entry + (file+olp +org-capture-todo-file "Tasks") "* WAIT Waiting response from %:toname on %a\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) ("n" "Note" entry (file+olp +org-capture-notes-file "Notes") "* %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") ("w" "Question" entry (file+olp +org-capture-notes-file "Questions") "* [?] %? \n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") - ("j" "Journal" entry (file+olp +org-capture-journal-file "Journal") - "* %?\n%a\n%i") - ("m" "Meeting" entry (file+olp +org-capture-notes-file "Meetings") - "* %? %U :meeting:\n:PROPERTIES:\n:CREATED: %U\n:END:\n\n/Met with: /") - ("a" "Appointment" entry (file+olp +org-capture-journal-file "Appointments") - "* %? :appointment:\n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i" :time-prompt t) - ("e" "Email Workflow") - ("ef" "Follow Up" entry (file+olp +org-capture-emails-file "Mails" "Follow Up") "* TODO Follow up with %:fromname on %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) - ("er" "Read Later" entry (file+olp +org-capture-emails-file "Mails" "Read Later") "* TODO Read: %a\nSCHEDULED:%t\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) - ("ew" "Waiting Response" entry - (file+olp +org-capture-emails-file "Mails" "Waiting Response") "* WAIT Waiting response from %:toname on %a\nDEADLINE:%(org-insert-time-stamp (org-read-date nil t \"+2d\"))\n\n%i" :immediate-finish t) + ("e" "Event" entry (file+olp +org-capture-todo-file "Events") + "* %? %^t\n:PROPERTIES:\n:CREATED: %U\n:END:\n%a\n%i") + ("C" "Contact" entry (file+olp +org-capture-todo-file "Contacts") "* %?\n:PROPERTIES:\n:EMAIL: %:fromemail\n:ROLE: \n:END:\n%a\n%i") ) ) ) @@ -908,7 +909,7 @@ Handles org-clock and context link capture for tasks." ;; Fold bindings (after! evil - (define-key evil-motion-state-map (kbd "z C") #'hs-hide-level)) + (define-key evil-motion-state-map (kbd "z M") #'hs-hide-level)) ;; Disable global bindings for C-j and C-k (global-unset-key (kbd "C-j")) @@ -1562,6 +1563,10 @@ If SESSION-ID is empty, show a menu of recent sessions to browse." :config (global-org-modern-mode) (setq org-modern-star 'replace) + ;; U+2733 (✳) isn't in JetBrainsMono Nerd Font -> font fallback renders it green. + ;; r/emacs favorite headline list, flower ✿ swapped for hollow ◇ in level 5 (filled ◆ was too big). + ;; NOTE: ✸⁖ may need font fallback in the GUI frame (JetBrainsMono Nerd lacks them). + (setq org-modern-replace-stars "⁖◉○◇✸") (setq org-modern-todo-faces '( ;; Framework @@ -1719,7 +1724,7 @@ Cordialement, (setq mu4e-icalendar-diary-file nil) (setq gnus-icalendar-org-capture-file +org-capture-journal-file - gnus-icalendar-org-capture-headline '("Journal")) + gnus-icalendar-org-capture-headline '("Events")) (gnus-icalendar-org-setup) @@ -1988,6 +1993,12 @@ only injects when the project's context-tag matches current mu4e context." :n "C-j" #'pdf-roll-next-page :n "C-k" #'pdf-roll-previous-page)) +(use-package! doc-view + :config + (map! :map doc-view-mode-map + :n "C-j" #'doc-view-next-page + :n "C-k" #'doc-view-previous-page)) + ;;Refile in datetree function (defun org-refile-to-datetree (&optional file) "Refile a subtree to a datetree corresponding to its timestamp. @@ -2874,6 +2885,61 @@ Optional PROJECT-TAG and CONTEXT-TAG can be given to create .projectile and .dir (message "Directory successfully converted to ExoKortex node.") (message "Successfully batch-converted %d directories to ExoKortex nodes!" count)))) +(defun gortium/dired-node-dirs () + "Return marked Dired subdirectories, or the cursor dir if nothing marked." + (when (derived-mode-p 'dired-mode) + (let* ((elements (dired-get-marked-files nil nil nil t)) + (has-marks (or (and (listp elements) (> (length elements) 1)) + (and (consp elements) (eq (car elements) t)))) + (marked (when has-marks + (cl-remove-if-not #'file-directory-p + (if (eq (car-safe elements) t) + (cdr elements) + elements))))) + (or marked + (let ((cursor (dired-get-filename nil t))) + (when (and cursor (file-directory-p cursor)) + (list cursor))))))) + +(defun gortium/move-node (src-category dst-category node-dirs) + "Move NODE-DIRS (absolute paths) from SRC-CATEGORY to DST-CATEGORY. +Markers (.projectile/.dir-locals/.hermes-sessions/.git) move with each dir." + (let ((root (expand-file-name gortium/exokortex-root)) + (moved 0)) + (dolist (dir node-dirs) + (let* ((name (file-name-nondirectory (directory-file-name dir))) + (src (expand-file-name name (expand-file-name src-category root))) + (dst (expand-file-name name (expand-file-name dst-category root)))) + (unless (file-directory-p src) + (user-error "No node '%s' in %s" name src-category)) + (when (file-exists-p dst) + (user-error "%s already has a node named '%s'" dst-category name)) + (make-directory (file-name-directory dst) t) + (rename-file src dst) + ;; Stale path: drop from the Projectile cache so the switch-list cleans up. + (when (fboundp 'projectile-remove-known-project) + (projectile-remove-known-project src)) + (cl-incf moved))) + (message "Archived/restored %d node(s): %s → %s" moved src-category dst-category))) + +(defun gortium/archive-node () + "Move marked (or cursor) nodes from 1-Projects to 4-Archives." + (interactive) + (let ((dirs (gortium/dired-node-dirs))) + (unless dirs + (user-error "No node under Dired cursor / no marked directories")) + (gortium/move-node "1-Projects" "4-Archives" dirs))) + +(defun gortium/restore-node (category) + "Move marked (or cursor) archived nodes back into CATEGORY." + (interactive + (list (completing-read "Restore to category: " + '("1-Projects" "2-Areas" "3-Resources")))) + (let ((dirs (gortium/dired-node-dirs))) + (unless dirs + (user-error "No node under Dired cursor / no marked directories")) + (gortium/move-node "4-Archives" category dirs))) + (defun gortium/read-dir-local (var) "Read variable VAR from .dir-locals.el in `default-directory'. Returns nil if file doesn't exist or VAR isn't set." diff --git a/exokortex/.local/bin/exokortex_auto_commit.sh b/exokortex/.local/bin/exokortex_auto_commit.sh index f75d466..45aa886 100755 --- a/exokortex/.local/bin/exokortex_auto_commit.sh +++ b/exokortex/.local/bin/exokortex_auto_commit.sh @@ -17,6 +17,14 @@ if [ ${#TARGETS[@]} -eq 0 ]; then exit 0 fi +# Root ExoKortex repo (root-level org files only; see ~/ExoKortex/.gitignore) +if git -C "$HOME/ExoKortex" rev-parse --is-inside-work-tree >/dev/null 2>&1; then + if [ -n "$(git -C "$HOME/ExoKortex" status --porcelain)" ]; then + git -C "$HOME/ExoKortex" add -A + git -C "$HOME/ExoKortex" commit -m "System: Automated background sweep $(date +'%Y-%m-%d %H:%M')" + fi +fi + # Execute strict structural scanning on active paths only find "${TARGETS[@]}" -mindepth 2 -maxdepth 2 -type d -name ".git" | while read -r gitdir; do repo_dir=$(dirname "$gitdir")