summaryrefslogtreecommitdiff
path: root/config.el
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-09-18 13:31:24 +0200
committercashmere <cashmere@autistici.org>2026-09-18 13:31:24 +0200
commit88a99db2884f9be5211cdaf756d7a8a73e8c5905 (patch)
tree71bcfc4d7ab8da6aa6795844721c226429e5a904 /config.el
parenteb2731470034174bb6873e371d2503d576e83382 (diff)
downloademacs-88a99db2884f9be5211cdaf756d7a8a73e8c5905.tar.gz
relic: 2026-09-18T13:31:28+02:00
Diffstat (limited to 'config.el')
-rw-r--r--config.el76
1 files changed, 72 insertions, 4 deletions
diff --git a/config.el b/config.el
index 580039a..0ef30ef 100644
--- a/config.el
+++ b/config.el
@@ -1468,6 +1468,70 @@ Skips capture tasks and projects."
(defun my/org-capture-meeting-to-journal ()
(my/org-capture-to-journal "\n* Meeting: "))
+(defcustom my/org-capture-project-notes-file "notes.org"
+ "File name for source notes captured at the current project root."
+ :type 'string
+ :group 'org-capture)
+
+(defcustom my/org-capture-source-language-alist
+ '((c-mode . "C")
+ (c-ts-mode . "C")
+ (c++-mode . "C++")
+ (c++-ts-mode . "C++")
+ (emacs-lisp-mode . "emacs-lisp")
+ (js-mode . "js")
+ (js-ts-mode . "js")
+ (shell-mode . "shell")
+ (sh-mode . "shell"))
+ "Exceptional major-mode to Org source language mappings used by project captures.
+Modes not listed here are inferred from `org-src-lang-modes' or their mode name."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'org-capture)
+
+(defun my/org-capture-original-buffer ()
+ "Return the live buffer from which the current capture was invoked."
+ (let ((buffer (org-capture-get :original-buffer)))
+ (unless (buffer-live-p buffer)
+ (user-error "The source buffer for this capture is no longer available"))
+ buffer))
+
+(defun my/org-capture-project-notes-path ()
+ "Return the project-root notes file for the current capture."
+ (with-current-buffer (my/org-capture-original-buffer)
+ (let ((root (or (and (fboundp 'projectile-project-root)
+ (ignore-errors (projectile-project-root)))
+ (when-let* ((project (project-current nil default-directory)))
+ (project-root project)))))
+ (unless root
+ (user-error "Cannot capture source note outside a recognized project"))
+ (expand-file-name my/org-capture-project-notes-file root))))
+
+(defun my/org-capture-source-language ()
+ "Return the Org source language for the current capture's source buffer."
+ (with-current-buffer (my/org-capture-original-buffer)
+ (or (alist-get major-mode my/org-capture-source-language-alist)
+ (cl-loop for (language . mode) in org-src-lang-modes
+ for mode-function = (intern (format "%s-mode" mode))
+ when (derived-mode-p mode-function)
+ return (format "%s" language))
+ (string-remove-suffix
+ "-mode"
+ (string-remove-suffix "-ts-mode" (symbol-name major-mode))))))
+
+(defun my/org-capture-source-link ()
+ "Return a file link to the first source line of the current capture."
+ (with-current-buffer (my/org-capture-original-buffer)
+ (unless buffer-file-name
+ (user-error "Cannot link a capture from a buffer without a file"))
+ (let* ((position (if (and (org-capture-get :initial) (mark t))
+ (min (point) (mark t))
+ (point)))
+ (line (line-number-at-pos position t))
+ (file (abbreviate-file-name buffer-file-name)))
+ (org-link-make-string
+ (format "file:%s::%d" file line)
+ (format "%s:%d" (file-name-nondirectory file) line)))))
+
(defun my/org-capture-task-to-journal ()
(let* ((context (read-string "Task: "))
(todo-state (completing-read "TODO state: "
@@ -1512,7 +1576,11 @@ Skips capture tasks and projects."
"" :immediate-finish t :jump-to-captured t)
("m" "Meeting" plain
(function my/org-capture-meeting-to-journal)
- "" :immediate-finish nil :jump-to-captured t))))
+ "" :immediate-finish nil :jump-to-captured t)
+ ("p" "Project source TODO" entry
+ (file+headline my/org-capture-project-notes-path "Inbox")
+ "* TODO %?\n\n#+begin_src %(my/org-capture-source-language)\n%i\n#+end_src\n\n%(my/org-capture-source-link)"
+ :prepend t :empty-lines 1))))
(use-package org-super-agenda
:ensure t
@@ -4436,7 +4504,7 @@ locally. Note: entries no longer present on the server are lost."
(setq browse-url-browser-function 'eww-browse-url
browse-url-secondary-browser-function 'browse-url-generic
- browse-url-generic-program "qutebrowser")
+ browse-url-generic-program "helium-browser")
(defun my/browse-url-no-frame-guard (orig url &rest args)
"Around-advice for `browse-url' that resolves and calls the handler
@@ -4966,7 +5034,7 @@ opening another file in same project does not re-notify."
:ensure nil
:commands (rsync-ui rsync-ui-dired))
-(defun rlr/org-export-html-to-browser ()
+(defun my/org-export-html-to-browser ()
"Export the current Org buffer to a temporary HTML file in the system temp directory, open it, and then delete it when Emacs is killed."
(interactive)
(unless (derived-mode-p 'org-mode)
@@ -4982,7 +5050,7 @@ opening another file in same project does not re-notify."
(lambda () (ignore-errors (delete-file tmp))))
(funcall browse-url-secondary-browser-function
(browse-url-file-url tmp))))
-(defvar rlr/org-preview-css "
+(defvar my/org-preview-css "
<style>
:root { color-scheme: light dark; }
body {