diff options
| -rw-r--r-- | config.el | 76 | ||||
| -rw-r--r-- | config.org | 76 |
2 files changed, 144 insertions, 8 deletions
@@ -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 { @@ -1726,6 +1726,70 @@ Skips capture tasks and projects." *** org-capture combined with denote #+begin_src emacs-lisp +(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: " @@ -1770,7 +1834,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)))) #+end_src ** org-super-agenda @@ -5320,7 +5388,7 @@ locally. Note: entries no longer present on the server are lost." #+begin_src emacs-lisp (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") #+end_src ** browse-url no-frame guard @@ -5951,7 +6019,7 @@ Privileged ZFS operations stay non-interactive by default. Unlocking runs authen * exp #+begin_src emacs-lisp -(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) @@ -5967,7 +6035,7 @@ Privileged ZFS operations stay non-interactive by default. Unlocking runs authen (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 { |
