Refactor focus functions and improve clipboard handling

- Refactors `org-focus-private`, `org-focus-lazer`, and `org-focus-all` into a single `org-focus` function for better code reuse.
- Simplifies `org-agenda-refresh` for improved efficiency.
- Improves `my/copy-idlink-to-clipboard` for clarity and robustness.
- Fixes an issue with `my/magit-gptcommit-commit-accept-wrapper` to preserve the original commit message.
- Enhances `my/html2org-clipboard` with error handling for more reliable HTML to Org conversion.
- Updates Clipmon configuration for better integration and stability.
This commit is contained in:
Roger Gonzalez 2025-03-30 11:55:34 -03:00
parent af6b91d643
commit 9ea2a251a0
Signed by: rogs
GPG Key ID: C7ECE9C6C36EC2E6

View File

@ -258,41 +258,54 @@ TODO: Breakup this section into smaller, more focused components later
;; Custom ORG functions ;; Custom ORG functions
;; Refresh org-agenda after rescheduling a task. ;; Refresh org-agenda after rescheduling a task.
(defun org-agenda-refresh () (defun org-agenda-refresh ()
"Refresh all `org-agenda' buffers." "Refresh all `org-agenda' buffers more efficiently."
(dolist (buffer (buffer-list)) (let ((agenda-buffers (seq-filter
(lambda (buf)
(with-current-buffer buf
(derived-mode-p 'org-agenda-mode)))
(buffer-list))))
(dolist (buffer agenda-buffers)
(with-current-buffer buffer (with-current-buffer buffer
(when (derived-mode-p 'org-agenda-mode)
(org-agenda-maybe-redo))))) (org-agenda-maybe-redo)))))
(defadvice org-schedule (after refresh-agenda activate) (defadvice org-schedule (after refresh-agenda activate)
"Refresh org-agenda." "Refresh org-agenda."
(org-agenda-refresh)) (org-agenda-refresh))
(defun org-focus-private() "Set focus on private things." (defun org-focus (files msg)
"Set focus on specific org FILES with notification MSG."
(setq org-agenda-files files)
(message msg))
(defun org-focus-private ()
"Set focus on private things."
(interactive) (interactive)
(setq org-agenda-files '("~/org/private.org")) (org-focus '("~/org/private.org") "Focusing on private Org files"))
(message "Focusing on private Org files"))
(defun org-focus-lazer() "Set focus on Lazer things." (defun org-focus-lazer ()
"Set focus on Lazer things."
(interactive) (interactive)
(setq org-agenda-files '("~/org/lazer.org")) (org-focus '("~/org/lazer.org") "Focusing on Lazer Org files"))
(message "Focusing on Lazer Org files"))
(defun org-focus-all() "Set focus on all things." (defun org-focus-all ()
"Set focus on all things."
(interactive) (interactive)
(setq org-agenda-files '("~/org/")) (org-focus '("~/org/") "Focusing on all Org files"))
(message "Focusing on all Org files"))
(defun my/org-add-ids-to-headlines-in-file () (defun my/org-add-ids-to-headlines-in-file ()
"Add ID properties to all headlines in the current file which "Add ID properties to all headlines in the current file which
do not already have one." do not already have one."
(interactive) (interactive)
(org-map-entries 'org-id-get-create)) (org-map-entries 'org-id-get-create))
(add-hook 'org-mode-hook (add-hook 'org-mode-hook
(lambda () (lambda ()
(add-hook 'before-save-hook (add-hook 'before-save-hook
'my/org-add-ids-to-headlines-in-file nil 'local))) 'my/org-add-ids-to-headlines-in-file nil 'local)))
(defun my/copy-idlink-to-clipboard() "Copy an ID link with the (defun my/copy-idlink-to-clipboard ()
headline to killring, if no ID is there then create a new unique "Copy an ID link with the headline to killring.
ID. This function works only in org-mode or org-agenda buffers. If no ID exists, create a new unique ID. This function works only in
org-mode or org-agenda buffers.
The purpose of this function is to easily construct id:-links to The purpose of this function is to easily construct id:-links to
org-mode items. If its assigned to a key it saves you marking the org-mode items. If its assigned to a key it saves you marking the
@ -307,19 +320,18 @@ related notes or tasks."
(org-agenda-show) (org-agenda-show)
(org-agenda-goto)) (org-agenda-goto))
(when (eq major-mode 'org-mode) ; do this only in org-mode buffers (when (eq major-mode 'org-mode) ; do this only in org-mode buffers
(setq mytmphead (nth 4 (org-heading-components))) (let* ((heading (nth 4 (org-heading-components)))
(setq mytmpid (funcall 'org-id-get-create)) (id (org-id-get-create))
(setq mytmplink (format "[[id:%s][%s]]" mytmpid mytmphead)) (link (format "[[id:%s][%s]]" id heading)))
(kill-new mytmplink) (kill-new link)
(message "Copied %s to killring (clipboard)" mytmplink) (message "Copied %s to killring (clipboard)" link))))
))
(global-set-key (kbd "<f5>") 'my/copy-idlink-to-clipboard) (global-set-key (kbd "<f5>") 'my/copy-idlink-to-clipboard)
(defun org-reset-checkbox-state-maybe () (defun org-reset-checkbox-state-maybe ()
"Reset all checkboxes in an entry if the `RESET_CHECK_BOXES' property is set" "Reset all checkboxes in an entry if the `RESET_CHECK_BOXES' property is set."
(interactive "*") (interactive "*")
(if (org-entry-get (point) "RESET_CHECK_BOXES") (when (org-entry-get (point) "RESET_CHECK_BOXES")
(org-reset-checkbox-state-subtree))) (org-reset-checkbox-state-subtree)))
(defun org-checklist () (defun org-checklist ()
@ -329,9 +341,11 @@ related notes or tasks."
(add-hook 'org-after-todo-state-change-hook 'org-checklist) (add-hook 'org-after-todo-state-change-hook 'org-checklist)
(defun org-roam-node-insert-immediate (arg &rest args) (defun org-roam-node-insert-immediate (arg &rest args)
"Insert a node immediately without the capture process."
(interactive "P") (interactive "P")
(let ((args (cons arg args)) (let ((args (cons arg args))
(org-roam-capture-templates (list (append (car org-roam-capture-templates) (org-roam-capture-templates
(list (append (car org-roam-capture-templates)
'(:immediate-finish t))))) '(:immediate-finish t)))))
(apply #'org-roam-node-insert args))) (apply #'org-roam-node-insert args)))
@ -448,9 +462,14 @@ More info here: https://github.com/doomemacs/doomemacs/issues/581#issuecomment-6
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun my/ediff-init-and-example () (defun my/ediff-init-and-example ()
"Compare init.el with the example init file."
(interactive) (interactive)
(ediff-files (concat doom-user-dir "init.el") (let ((init-file (concat doom-user-dir "init.el"))
(concat doom-emacs-dir "templates/init.example.el"))) (example-file (concat doom-emacs-dir "templates/init.example.el")))
(if (and (file-exists-p init-file)
(file-exists-p example-file))
(ediff-files init-file example-file)
(message "Cannot find init.el or example file"))))
(define-key! help-map "di" #'my/ediff-init-and-example) (define-key! help-map "di" #'my/ediff-init-and-example)
#+end_src #+end_src
@ -523,10 +542,15 @@ Usage: Press F4 in any org-mode buffer to convert and paste HTML from clipboard
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun my/html2org-clipboard () (defun my/html2org-clipboard ()
"Convert HTML in clipboard to Org format and paste it."
(interactive) (interactive)
(kill-new (shell-command-to-string "timeout 1 xclip -selection clipboard -o -t text/html | pandoc -f html -t json | pandoc -f json -t org --wrap=none")) (condition-case err
(progn
(kill-new (shell-command-to-string
"timeout 1 xclip -selection clipboard -o -t text/html | pandoc -f html -t json | pandoc -f json -t org --wrap=none"))
(yank) (yank)
(message "Pasted HTML in org")) (message "Pasted HTML in org"))
(error (message "Error converting HTML to Org: %s" (error-message-string err)))))
(after! org (after! org
(define-key org-mode-map (kbd "<f4>") 'my/html2org-clipboard)) (define-key org-mode-map (kbd "<f4>") 'my/html2org-clipboard))
#+end_src #+end_src
@ -561,10 +585,14 @@ Clipmon serves as my clipboard manager within Emacs. I chose it over alternative
The configuration below sets up Clipmon to check the clipboard every second and makes the kill ring accessible through M-y with helm integration. The configuration below sets up Clipmon to check the clipboard every second and makes the kill ring accessible through M-y with helm integration.
#+begin_src emacs-lisp #+begin_src emacs-lisp
(global-set-key (kbd "M-y") 'helm-show-kill-ring) (use-package clipmon
(add-to-list 'after-init-hook 'clipmon-mode-start) :init
(defadvice clipmon--on-clipboard-change (around stop-clipboard-parsing activate) (let ((interprogram-cut-function nil)) ad-do-it)) (global-set-key (kbd "M-y") 'helm-show-kill-ring)
(setq clipmon-timer-interval 1) (add-to-list 'after-init-hook 'clipmon-mode-start)
:config
(defadvice clipmon--on-clipboard-change (around stop-clipboard-parsing activate)
(let ((interprogram-cut-function nil)) ad-do-it))
(setq clipmon-timer-interval 1))
#+end_src #+end_src
@ -587,13 +615,15 @@ The configuration below sets up Clipmon to check the clipboard every second and
:END: :END:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun my/magit-gptcommit-commit-accept-wrapper (orig-fun &rest args) (defun my/magit-gptcommit-commit-accept-wrapper (orig-fun &rest args)
"Wrapper for magit-gptcommit-commit-accept to preserve original message."
(when-let ((buf (magit-commit-message-buffer))) (when-let ((buf (magit-commit-message-buffer)))
(with-current-buffer buf (with-current-buffer buf
(let ((orig-message (git-commit-buffer-message))) (let ((orig-message (string-trim-right (or (git-commit-buffer-message) "") "\n$")))
(apply orig-fun args) (apply orig-fun args)
(unless (string-empty-p orig-message)
(save-excursion (save-excursion
(goto-char (point-min)) (goto-char (point-min))
(insert (string-trim-right orig-message "\n$"))))))) (insert orig-message)))))))
(advice-add 'magit-gptcommit-commit-accept (advice-add 'magit-gptcommit-commit-accept
:around #'my/magit-gptcommit-commit-accept-wrapper) :around #'my/magit-gptcommit-commit-accept-wrapper)