summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-10-23 00:15:14 -0500
committerCraig Jennings <c@cjennings.net>2025-10-23 00:15:14 -0500
commitd22d004ed9bdc11dbc21be368f90384ed8b1b795 (patch)
treea8ac1f44845bdd11c442cca3c69a51cfde9c1f8b /modules
parentdb5f40e21b3015c2ce09c9b94e1d14c4ae951b92 (diff)
refactor: unify and simplify key binding setups
Optimized key binding configurations across modules for consistency and reduced redundancy. Improved conditional requiring to handle errors gracefully in `music-config.el`, ensuring robustness across different machine environments. Eliminated comments clutter and adjusted function definitions to adhere to revised standards.
Diffstat (limited to 'modules')
-rw-r--r--modules/ai-config.el372
-rw-r--r--modules/custom-ordering.el5
-rw-r--r--modules/dashboard-config.el33
-rw-r--r--modules/erc-config.el79
-rw-r--r--modules/jumper.el2
-rw-r--r--modules/keyboard-macros.el6
-rw-r--r--modules/music-config.el41
-rw-r--r--modules/selection-framework.el3
-rw-r--r--modules/system-defaults.el27
-rw-r--r--modules/system-utils.el2
-rw-r--r--modules/test-runner.el20
-rw-r--r--modules/user-constants.el1
-rw-r--r--modules/vc-config.el18
-rw-r--r--modules/wip.el65
-rw-r--r--modules/wrap-up.el3
15 files changed, 330 insertions, 347 deletions
diff --git a/modules/ai-config.el b/modules/ai-config.el
index 32a5d53f..004750b6 100644
--- a/modules/ai-config.el
+++ b/modules/ai-config.el
@@ -32,12 +32,14 @@
(autoload 'cj/gptel-load-conversation "ai-conversations" "Load a saved AI conversation." t)
(autoload 'cj/gptel-delete-conversation "ai-conversations" "Delete a saved AI conversation." t)
+
+
(with-eval-after-load 'gptel
(require 'ai-conversations))
;;; ------------------------- AI Config Helper Functions ------------------------
-;; Define all our variables upfront
+;; Define variables upfront
(defvar cj/anthropic-api-key-cached nil "Cached Anthropic API key.")
(defvar cj/openai-api-key-cached nil "Cached OpenAI API key.")
(defvar gptel-claude-backend nil "Claude backend, lazy-initialized.")
@@ -49,70 +51,69 @@
HOST and USER must be strings that identify the credential to return."
(let* ((found (auth-source-search :host host :user user :require '(:secret) :max 1))
- (secret (plist-get (car found) :secret)))
- (cond
- ((functionp secret) (funcall secret))
- ((stringp secret) secret)
- (t (error "No usable secret found for host %s and user %s" host user)))))
+ (secret (plist-get (car found) :secret)))
+ (cond
+ ((functionp secret) (funcall secret))
+ ((stringp secret) secret)
+ (t (error "No usable secret found for host %s and user %s" host user)))))
(defun cj/anthropic-api-key ()
"Return the Anthropic API key, caching the result after first retrieval."
(or cj/anthropic-api-key-cached
- (setq cj/anthropic-api-key-cached
- (cj/auth-source-secret "api.anthropic.com" "apikey"))))
+ (setq cj/anthropic-api-key-cached
+ (cj/auth-source-secret "api.anthropic.com" "apikey"))))
(defun cj/openai-api-key ()
"Return the OpenAI API key, caching the result after first retrieval."
(or cj/openai-api-key-cached
- (setq cj/openai-api-key-cached
- (cj/auth-source-secret "api.openai.com" "apikey"))))
+ (setq cj/openai-api-key-cached
+ (cj/auth-source-secret "api.openai.com" "apikey"))))
(defun cj/ensure-gptel-backends ()
"Initialize GPTel backends if they are not already available.
-
Call this only after loading 'gptel' so the backend constructors exist."
(unless gptel-claude-backend
- (setq gptel-claude-backend
- (gptel-make-anthropic
- "Claude"
- :key (cj/anthropic-api-key)
- :models '(
- "claude-opus-4-1-20250805"
- "claude-3-5-sonnet-20241022"
- "claude-3-opus-20240229"
- "claude-3-5-haiku-20241022"
- )
- :stream t)))
+ (setq gptel-claude-backend
+ (gptel-make-anthropic
+ "Claude"
+ :key (cj/anthropic-api-key)
+ :models '(
+ "claude-opus-4-1-20250805"
+ "claude-3-5-sonnet-20241022"
+ "claude-3-opus-20240229"
+ "claude-3-5-haiku-20241022"
+ )
+ :stream t)))
(unless gptel-chatgpt-backend
- (setq gptel-chatgpt-backend
- (gptel-make-openai
- "ChatGPT"
- :key (cj/openai-api-key)
- :models '(
- "gpt-4o"
- "gpt-5"
- "gpt-4.1"
- "o1"
- )
- :stream t)))
+ (setq gptel-chatgpt-backend
+ (gptel-make-openai
+ "ChatGPT"
+ :key (cj/openai-api-key)
+ :models '(
+ "gpt-4o"
+ "gpt-5"
+ "gpt-4.1"
+ "o1"
+ )
+ :stream t)))
;; Set default backend
(unless gptel-backend
- (setq gptel-backend (or gptel-chatgpt-backend gptel-claude-backend))))
+ (setq gptel-backend (or gptel-chatgpt-backend gptel-claude-backend))))
(autoload 'cj/toggle-gptel "ai-config" "Toggle the AI-Assistant window" t)
-;; ------------------ Gptel Conversation And Utility Commands ------------------
+;; ------------------ GPTel Conversation And Utility Commands ------------------
(defun cj/gptel--available-backends ()
"Return an alist of (NAME . BACKEND), ensuring gptel and backends are initialized."
(unless (featurep 'gptel)
- (require 'gptel))
+ (require 'gptel))
(cj/ensure-gptel-backends)
(delq nil
- (list (and (bound-and-true-p gptel-claude-backend)
- (cons "Anthropic - Claude" gptel-claude-backend))
- (and (bound-and-true-p gptel-chatgpt-backend)
- (cons "OpenAI - ChatGPT" gptel-chatgpt-backend)))))
+ (list (and (bound-and-true-p gptel-claude-backend)
+ (cons "Anthropic - Claude" gptel-claude-backend))
+ (and (bound-and-true-p gptel-chatgpt-backend)
+ (cons "OpenAI - ChatGPT" gptel-chatgpt-backend)))))
(defun cj/gptel--model->string (m)
(cond
@@ -123,62 +124,61 @@ Call this only after loading 'gptel' so the backend constructors exist."
;; Backend/model switching commands (moved out of use-package so they are commandp)
(defun cj/gptel-change-model ()
"Change the GPTel backend and select a model from that backend.
-
Present all available models from every backend, switching backends when
necessary. Prompt for whether to apply the selection globally or buffer-locally."
(interactive)
(let* ((backends (cj/gptel--available-backends))
- (all-models
- (mapcan
- (lambda (pair)
- (let* ((backend-name (car pair))
- (backend (cdr pair))
- (models (when (fboundp 'gptel-backend-models)
- (gptel-backend-models backend))))
- (mapcar (lambda (m)
- (list (format "%s: %s" backend-name (cj/gptel--model->string m))
- backend
- (cj/gptel--model->string m)
- backend-name))
- models)))
- backends))
- (current-backend-name (car (rassoc (bound-and-true-p gptel-backend) backends)))
- (current-selection (format "%s: %s"
- (or current-backend-name "AI")
- (cj/gptel--model->string (bound-and-true-p gptel-model))))
- (scope (completing-read "Set model for: " '("buffer" "global") nil t))
- (selected (completing-read
- (format "Select model (current: %s): " current-selection)
- (mapcar #'car all-models) nil t nil nil current-selection)))
- (let* ((model-info (assoc selected all-models))
- (backend (nth 1 model-info))
- (model (intern (nth 2 model-info))) ;; Convert string to symbol
- (backend-name (nth 3 model-info)))
- (if (string= scope "global")
- (progn
- (setq gptel-backend backend)
- (setq gptel-model model)
- (message "Changed to %s model: %s (global)" backend-name model))
- (setq-local gptel-backend backend)
- (setq-local gptel-model (if (stringp model) (intern model) model))
- (message "Changed to %s model: %s (buffer-local)" backend-name model)))))
+ (all-models
+ (mapcan
+ (lambda (pair)
+ (let* ((backend-name (car pair))
+ (backend (cdr pair))
+ (models (when (fboundp 'gptel-backend-models)
+ (gptel-backend-models backend))))
+ (mapcar (lambda (m)
+ (list (format "%s: %s" backend-name (cj/gptel--model->string m))
+ backend
+ (cj/gptel--model->string m)
+ backend-name))
+ models)))
+ backends))
+ (current-backend-name (car (rassoc (bound-and-true-p gptel-backend) backends)))
+ (current-selection (format "%s: %s"
+ (or current-backend-name "AI")
+ (cj/gptel--model->string (bound-and-true-p gptel-model))))
+ (scope (completing-read "Set model for: " '("buffer" "global") nil t))
+ (selected (completing-read
+ (format "Select model (current: %s): " current-selection)
+ (mapcar #'car all-models) nil t nil nil current-selection)))
+ (let* ((model-info (assoc selected all-models))
+ (backend (nth 1 model-info))
+ (model (intern (nth 2 model-info))) ;; Convert string to symbol
+ (backend-name (nth 3 model-info)))
+ (if (string= scope "global")
+ (progn
+ (setq gptel-backend backend)
+ (setq gptel-model model)
+ (message "Changed to %s model: %s (global)" backend-name model))
+ (setq-local gptel-backend backend)
+ (setq-local gptel-model (if (stringp model) (intern model) model))
+ (message "Changed to %s model: %s (buffer-local)" backend-name model)))))
(defun cj/gptel-switch-backend ()
"Switch the GPTel backend and then choose one of its models."
(interactive)
(let* ((backends (cj/gptel--available-backends))
- (choice (completing-read "Select GPTel backend: " (mapcar #'car backends) nil t))
- (backend (cdr (assoc choice backends))))
- (unless backend
- (user-error "Invalid GPTel backend: %s" choice))
- (let* ((models (when (fboundp 'gptel-backend-models)
- (gptel-backend-models backend)))
- (model (completing-read (format "Select %s model: " choice)
- (mapcar #'cj/gptel--model->string models)
- nil t nil nil (cj/gptel--model->string (bound-and-true-p gptel-model)))))
- (setq gptel-backend backend
- gptel-model model)
- (message "Switched to %s with model: %s" choice model))))
+ (choice (completing-read "Select GPTel backend: " (mapcar #'car backends) nil t))
+ (backend (cdr (assoc choice backends))))
+ (unless backend
+ (user-error "Invalid GPTel backend: %s" choice))
+ (let* ((models (when (fboundp 'gptel-backend-models)
+ (gptel-backend-models backend)))
+ (model (completing-read (format "Select %s model: " choice)
+ (mapcar #'cj/gptel--model->string models)
+ nil t nil nil (cj/gptel--model->string (bound-and-true-p gptel-model)))))
+ (setq gptel-backend backend
+ gptel-model model)
+ (message "Switched to %s with model: %s" choice model))))
;; Clear assistant buffer (moved out so it's always available)
(defun cj/gptel-clear-buffer ()
@@ -188,14 +188,14 @@ Operate only when `gptel-mode' is active in an Org buffer so the heading
can be reinserted."
(interactive)
(let ((is-gptel (bound-and-true-p gptel-mode))
- (is-org (derived-mode-p 'org-mode)))
- (if (and is-gptel is-org)
- (progn
- (erase-buffer)
- (when (fboundp 'cj/gptel--fresh-org-prefix)
- (insert (cj/gptel--fresh-org-prefix)))
- (message "GPTel buffer cleared and heading reset"))
- (message "Not a GPTel buffer in org-mode. Nothing cleared."))))
+ (is-org (derived-mode-p 'org-mode)))
+ (if (and is-gptel is-org)
+ (progn
+ (erase-buffer)
+ (when (fboundp 'cj/gptel--fresh-org-prefix)
+ (insert (cj/gptel--fresh-org-prefix)))
+ (message "GPTel buffer cleared and heading reset"))
+ (message "Not a GPTel buffer in org-mode. Nothing cleared."))))
;; ----------------------------- Context Management ----------------------------
@@ -205,14 +205,14 @@ can be reinserted."
Returns t on success, nil on failure.
Provides consistent user feedback about the context state."
(when (and file-path (file-exists-p file-path))
- (gptel-add-file file-path)
- (let ((context-count (if (boundp 'gptel-context--alist)
- (length gptel-context--alist)
- 0)))
+ (gptel-add-file file-path)
+ (let ((context-count (if (boundp 'gptel-context--alist)
+ (length gptel-context--alist)
+ 0)))
(message "Added %s to GPTel context (%d sources total)"
- (file-name-nondirectory file-path)
- context-count))
- t))
+ (file-name-nondirectory file-path)
+ context-count))
+ t))
(defun cj/gptel-add-file ()
"Add a file to the GPTel context.
@@ -221,19 +221,19 @@ If inside a Projectile project, prompt from that project's file list.
Otherwise, prompt with `read-file-name'."
(interactive)
(let* ((in-proj (and (featurep 'projectile)
- (fboundp 'projectile-project-p)
- (projectile-project-p)))
- (file-name (if in-proj
- (let ((cands (projectile-current-project-files)))
- (if (fboundp 'projectile-completing-read)
- (projectile-completing-read "GPTel add file: " cands)
- (completing-read "GPTel add file: " cands nil t)))
- (read-file-name "GPTel add file: ")))
- (file-path (if in-proj
- (expand-file-name file-name (projectile-project-root))
- file-name)))
- (unless (cj/gptel--add-file-to-context file-path)
- (error "Failed to add file: %s" file-path))))
+ (fboundp 'projectile-project-p)
+ (projectile-project-p)))
+ (file-name (if in-proj
+ (let ((cands (projectile-current-project-files)))
+ (if (fboundp 'projectile-completing-read)
+ (projectile-completing-read "GPTel add file: " cands)
+ (completing-read "GPTel add file: " cands nil t)))
+ (read-file-name "GPTel add file: ")))
+ (file-path (if in-proj
+ (expand-file-name file-name (projectile-project-root))
+ file-name)))
+ (unless (cj/gptel--add-file-to-context file-path)
+ (error "Failed to add file: %s" file-path))))
(defun cj/gptel-add-buffer-file ()
"Select a buffer and add its associated file to the GPTel context.
@@ -243,13 +243,13 @@ a file, that file is added to the GPTel context. Otherwise, an error
message is displayed."
(interactive)
(let* ((buffers (mapcar #'buffer-name (buffer-list)))
- (selected-buffer-name (completing-read "Add file from buffer: " buffers nil t))
- (selected-buffer (get-buffer selected-buffer-name))
- (file-path (and selected-buffer
- (buffer-file-name selected-buffer))))
- (if file-path
- (cj/gptel--add-file-to-context file-path)
- (message "Buffer '%s' is not visiting a file" selected-buffer-name))))
+ (selected-buffer-name (completing-read "Add file from buffer: " buffers nil t))
+ (selected-buffer (get-buffer selected-buffer-name))
+ (file-path (and selected-buffer
+ (buffer-file-name selected-buffer))))
+ (if file-path
+ (cj/gptel--add-file-to-context file-path)
+ (message "Buffer '%s' is not visiting a file" selected-buffer-name))))
(defun cj/gptel-add-this-buffer ()
"Add the current buffer to the GPTel context.
@@ -258,7 +258,7 @@ Works for any buffer, whether it's visiting a file or not."
(interactive)
;; Load gptel-context if needed
(unless (featurep 'gptel-context)
- (require 'gptel-context))
+ (require 'gptel-context))
;; Use gptel-add with prefix arg '(4) to add current buffer
(gptel-add '(4))
(message "Added buffer '%s' to GPTel context" (buffer-name)))
@@ -287,9 +287,9 @@ Works for any buffer, whether it's visiting a file or not."
;; Named backend list for switching
(defvar cj/gptel-backends
- `(("Anthropic - Claude" . ,gptel-claude-backend)
- ("OpenAI - ChatGPT" . ,gptel-chatgpt-backend))
- "Alist of GPTel backends for interactive switching.")
+ `(("Anthropic - Claude" . ,gptel-claude-backend)
+ ("OpenAI - ChatGPT" . ,gptel-chatgpt-backend))
+ "Alist of GPTel backends for interactive switching.")
(setq gptel-confirm-tool-calls nil) ;; allow tool access by default
;;; ---------------------------- Backend Management ---------------------------
@@ -301,35 +301,35 @@ Works for any buffer, whether it's visiting a file or not."
;; Dynamic user prefix for org-mode heading (string, refreshed just before send)
(defun cj/gptel--fresh-org-prefix ()
- "Generate a fresh org-mode header with current timestamp for user messages."
- (concat "* " user-login-name " " (format-time-string "[%Y-%m-%d %H:%M:%S]") "\n"))
+ "Generate a fresh org-mode header with current timestamp for user messages."
+ (concat "* " user-login-name " " (format-time-string "[%Y-%m-%d %H:%M:%S]") "\n"))
;; Initialize as a string (GPTel expectation)
(setf (alist-get 'org-mode gptel-prompt-prefix-alist)
- (cj/gptel--fresh-org-prefix))
+ (cj/gptel--fresh-org-prefix))
;; Refresh immediately before each send for accurate timestamp
(defun cj/gptel--refresh-org-prefix (&rest _)
- "Update the org-mode prefix with fresh timestamp before sending message."
- (setf (alist-get 'org-mode gptel-prompt-prefix-alist)
- (cj/gptel--fresh-org-prefix)))
+ "Update the org-mode prefix with fresh timestamp before sending message."
+ (setf (alist-get 'org-mode gptel-prompt-prefix-alist)
+ (cj/gptel--fresh-org-prefix)))
(advice-add 'gptel-send :before #'cj/gptel--refresh-org-prefix)
;; AI header on each reply: (e.g. "*** AI: <model> [timestamp]")
(defun cj/gptel-backend-and-model ()
- "Return backend, model, and timestamp as a single string."
- (let* ((backend (pcase (bound-and-true-p gptel-backend)
- ((and v (pred vectorp)) (aref v 1)) ;; display name if vector
- (_ "AI")))
- (model (format "%s" (or (bound-and-true-p gptel-model) "")))
- (ts (format-time-string "[%Y-%m-%d %H:%M:%S]")))
- (format "%s: %s %s" backend model ts)))
+ "Return backend, model, and timestamp as a single string."
+ (let* ((backend (pcase (bound-and-true-p gptel-backend)
+ ((and v (pred vectorp)) (aref v 1)) ;; display name if vector
+ (_ "AI")))
+ (model (format "%s" (or (bound-and-true-p gptel-model) "")))
+ (ts (format-time-string "[%Y-%m-%d %H:%M:%S]")))
+ (format "%s: %s %s" backend model ts)))
(defun cj/gptel-insert-model-heading (response-begin-pos _response-end-pos)
- "Insert an Org heading for the AI reply at RESPONSE-BEGIN-POS."
- (save-excursion
- (goto-char response-begin-pos)
- (insert (format "* %s\n" (cj/gptel-backend-and-model)))))
+ "Insert an Org heading for the AI reply at RESPONSE-BEGIN-POS."
+ (save-excursion
+ (goto-char response-begin-pos)
+ (insert (format "* %s\n" (cj/gptel-backend-and-model)))))
(add-hook 'gptel-post-response-functions #'cj/gptel-insert-model-heading))
@@ -339,26 +339,26 @@ Works for any buffer, whether it's visiting a file or not."
"Toggle the visibility of the AI-Assistant buffer, and place point at its end."
(interactive)
(let* ((buf-name "*AI-Assistant*")
- (buffer (get-buffer buf-name))
- (win (and buffer (get-buffer-window buffer))))
- (if win
- (delete-window win)
- ;; Ensure GPTel and our backends are initialized before creating the buffer
- (unless (featurep 'gptel)
- (require 'gptel))
- (cj/ensure-gptel-backends)
- (unless buffer
- ;; Pass backend, not model
- (gptel buf-name gptel-backend))
- (setq buffer (get-buffer buf-name))
- (setq win
- (display-buffer-in-side-window
- buffer
- '((side . right)
- (window-width . 0.4))))
- (select-window win)
- (with-current-buffer buffer
- (goto-char (point-max))))))
+ (buffer (get-buffer buf-name))
+ (win (and buffer (get-buffer-window buffer))))
+ (if win
+ (delete-window win)
+ ;; Ensure GPTel and our backends are initialized before creating the buffer
+ (unless (featurep 'gptel)
+ (require 'gptel))
+ (cj/ensure-gptel-backends)
+ (unless buffer
+ ;; Pass backend, not model
+ (gptel buf-name gptel-backend))
+ (setq buffer (get-buffer buf-name))
+ (setq win
+ (display-buffer-in-side-window
+ buffer
+ '((side . right)
+ (window-width . 0.4))))
+ (select-window win)
+ (with-current-buffer buffer
+ (goto-char (point-max))))))
;; ------------------------------- Clear Context -------------------------------
@@ -367,16 +367,16 @@ Works for any buffer, whether it's visiting a file or not."
(interactive)
(cond
((fboundp 'gptel-context-remove-all)
- (call-interactively 'gptel-context-remove-all)
- (message "GPTel context cleared"))
+ (call-interactively 'gptel-context-remove-all)
+ (message "GPTel context cleared"))
((fboundp 'gptel-context-clear)
- (call-interactively 'gptel-context-clear)
- (message "GPTel context cleared"))
+ (call-interactively 'gptel-context-clear)
+ (message "GPTel context cleared"))
((boundp 'gptel-context--alist)
- (setq gptel-context--alist nil)
- (message "GPTel context cleared"))
+ (setq gptel-context--alist nil)
+ (message "GPTel context cleared"))
(t
- (message "No known GPTel context clearing function available"))))
+ (message "No known GPTel context clearing function available"))))
;;; -------------------------------- GPTel-Magit --------------------------------
@@ -398,22 +398,22 @@ Works for any buffer, whether it's visiting a file or not."
;;; --------------------------------- AI Keymap ---------------------------------
-(define-prefix-command 'cj/ai-keymap nil
- "Keymap for AI operations.")
-(keymap-set cj/custom-keymap "a" #'cj/ai-keymap)
-(keymap-set cj/ai-keymap "B" #'cj/gptel-switch-backend) ;; change the backend (OpenAI, Anthropic, etc.)
-(keymap-set cj/ai-keymap "M" #'gptel-menu) ;; gptel's transient menu
-(keymap-set cj/ai-keymap "d" #'cj/gptel-delete-conversation) ;; delete conversation
-(keymap-set cj/ai-keymap "." #'cj/gptel-add-this-buffer) ;; add buffer to context
-(keymap-set cj/ai-keymap "f" #'cj/gptel-add-file) ;; add a file to context
-(keymap-set cj/ai-keymap "l" #'cj/gptel-load-conversation) ;; load and continue conversation
-(keymap-set cj/ai-keymap "m" #'cj/gptel-change-model) ;; change the LLM model
-(keymap-set cj/ai-keymap "p" #'gptel-system-prompt) ;; change prompt
-(keymap-set cj/ai-keymap "&" #'gptel-rewrite) ;; rewrite a region of code/text
-(keymap-set cj/ai-keymap "r" #'cj/gptel-context-clear) ;; remove all context
-(keymap-set cj/ai-keymap "s" #'cj/gptel-save-conversation) ;; save conversation
-(keymap-set cj/ai-keymap "t" #'cj/toggle-gptel) ;; toggles the ai-assistant window
-(keymap-set cj/ai-keymap "x" #'cj/gptel-clear-buffer) ;; clears the assistant buffer
+(defvar-keymap cj/ai-keymap
+ :doc "Keymap for gptel and other AI operations."
+ "B" #'cj/gptel-switch-backend ;; change the backend (OpenAI, Anthropic, etc.
+ "M" #'gptel-menu ;; gptel's transient menu
+ "d" #'cj/gptel-delete-conversation ;; delete conversation
+ "." #'cj/gptel-add-this-buffer ;; add buffer to context
+ "f" #'cj/gptel-add-file ;; add a file to context
+ "l" #'cj/gptel-load-conversation ;; load and continue conversation
+ "m" #'cj/gptel-change-model ;; change the LLM model
+ "p" #'gptel-system-prompt ;; change prompt
+ "&" #'gptel-rewrite ;; rewrite a region of code/text
+ "r" #'cj/gptel-context-clear ;; remove all context
+ "s" #'cj/gptel-save-conversation ;; save conversation
+ "t" #'cj/toggle-gptel ;; toggles the ai-assistant window
+ "x" #'cj/gptel-clear-buffer) ;; clears the assistant buffer
+(keymap-set cj/custom-keymap "a" cj/ai-keymap)
(provide 'ai-config)
;;; ai-config.el ends here.
diff --git a/modules/custom-ordering.el b/modules/custom-ordering.el
index c0b098f7..8e8a4da6 100644
--- a/modules/custom-ordering.el
+++ b/modules/custom-ordering.el
@@ -82,12 +82,11 @@ Produce a comma-separated list as the result."
(insert text)))
+
;; Ordering & sorting prefix and keymap
(define-prefix-command 'cj/ordering-map nil
- "Keymap for text ordering and sorting operations.")
+ "text ordering and sorting operations.")
(keymap-set cj/custom-keymap "o" #'cj/ordering-map)
-
-
(keymap-set cj/ordering-map "a" #'cj/arrayify)
(keymap-set cj/ordering-map "u" #'cj/unarrayify)
(keymap-set cj/ordering-map "A" #'cj/alphabetize-region)
diff --git a/modules/dashboard-config.el b/modules/dashboard-config.el
index 73a76b6b..3bb6034c 100644
--- a/modules/dashboard-config.el
+++ b/modules/dashboard-config.el
@@ -8,7 +8,9 @@
;;; Code:
-(require 'undead-buffers)
+(eval-when-compile (require 'undead-buffers))
+(declare-function cj/make-buffer-undead "undead-buffers" (string))
+(autoload 'cj/make-buffer-undead "undead-buffers" nil t)
;; ------------------------ Dashboard Bookmarks Override -----------------------
;; overrides the bookmark insertion from the dashboard package to provide an
@@ -17,10 +19,8 @@
;; accompanied by the setting (setq dashboard-bookmarks-show-path nil) in
;; config.
-(defcustom dashboard-bookmarks-item-format "%s"
- "Format to use when showing the base of the file name."
- :type 'string
- :group 'dashboard)
+(defvar dashboard-bookmarks-item-format "%s"
+ "Format to use when showing the base of the file name.")
(defun dashboard-insert-bookmarks (list-size)
"Add the list of LIST-SIZE items of bookmarks."
@@ -53,12 +53,14 @@
(defun cj/dashboard-only ()
"Switch to *dashboard* buffer and kill all other buffers and windows."
(interactive)
- (dired-sidebar-hide-sidebar)
+ (when (fboundp 'dired-sidebar-hide-sidebar)
+ (dired-sidebar-hide-sidebar))
(if (get-buffer "*dashboard*")
(progn
(switch-to-buffer "*dashboard*")
(cj/kill-all-other-buffers-and-windows))
- (dashboard-open)))
+ (when (fboundp 'dashboard-open)
+ (dashboard-open))))
;; --------------------------------- Dashboard ---------------------------------
;; a useful startup screen for Emacs
@@ -66,7 +68,7 @@
(use-package dashboard
:defer t
:hook (emacs-startup . cj/dashboard-only)
- :bind ("<f4>" . cj/dashboard-only)
+ :bind ("<f1>" . cj/dashboard-only)
:custom
(dashboard-projects-backend 'projectile)
@@ -91,15 +93,16 @@
:config
;; == general
- (dashboard-setup-startup-hook) ;; run dashboard post emacs init
+ (dashboard-setup-startup-hook) ;; run dashboard post emacs init
+ (cj/make-buffer-undead "*dashboard*") ;; make this buffer unkillable
(if (< (length command-line-args) 2)
- (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))) ;; don't display dashboard if opening a file
- (setq dashboard-display-icons-p t) ;; display icons on both GUI and terminal
- (setq dashboard-icon-type 'nerd-icons) ;; use `nerd-icons' package
- (setq dashboard-center-content t) ;; horizontally center dashboard content
- (setq dashboard-bookmarks-show-path nil) ;; don't show paths in bookmarks
- (setq dashboard-set-footer nil) ;; don't show footer and quotes
+ (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))) ;; don't display dashboard if opening a file
+ (setq dashboard-display-icons-p t) ;; display icons on both GUI and terminal
+ (setq dashboard-icon-type 'nerd-icons) ;; use `nerd-icons' package
+ (setq dashboard-center-content t) ;; horizontally center dashboard content
+ (setq dashboard-bookmarks-show-path nil) ;; don't show paths in bookmarks
+ (setq dashboard-set-footer nil) ;; don't show footer and quotes
;; == banner
(setq dashboard-startup-banner (concat user-emacs-directory "assets/M-x_butterfly.png"))
diff --git a/modules/erc-config.el b/modules/erc-config.el
index 55b4c9a7..04432947 100644
--- a/modules/erc-config.el
+++ b/modules/erc-config.el
@@ -1,8 +1,8 @@
;;; erc-config --- Preferences for Emacs Relay Chat (IRC Client) -*- lexical-binding: t; coding: utf-8; -*-
;; author Craig Jennings <c@cjennings.net>
-
+;;
;;; Commentary:
-
+;;
;; Enhanced ERC configuration with multi-server support.
;;
;; Main keybindings:
@@ -17,49 +17,8 @@
;; Load cl-lib at compile time and runtime (lightweight, already loaded in most configs)
(require 'cl-lib)
-
-;; Declare ERC functions to avoid byte-compiler warnings
-(declare-function erc-part-from-channel "erc" (&optional reason))
-(declare-function erc-quit-server "erc" (reason))
-(declare-function erc-buffer-list "erc" (&optional predicate proc))
-(declare-function erc-server-process-alive "erc" (&optional buffer))
-(declare-function erc-server-buffer-p "erc" (&optional buffer))
-(declare-function erc-current-nick "erc" ())
-(declare-function erc-join-channel "erc" (channel &optional key))
-(declare-function erc-tls "erc" (&rest r))
-(declare-function erc "erc" (&rest r))
-(declare-function erc-update-modules "erc" ())
-(declare-function erc-get-color-for-nick "erc" (nick))
-
-;; Declare ERC variables
-(defvar erc-server-process)
-(defvar erc-mode-abbrev-table)
-(defvar erc-log-channels-directory)
-(defvar erc-unique-buffers)
-(defvar erc-generate-buffer-name-function)
-(defvar erc-track-exclude-types)
-(defvar erc-track-exclude-server-buffer)
-(defvar erc-track-visibility)
-(defvar erc-track-switch-direction)
-(defvar erc-track-showcount)
-(defvar erc-nick-color-alist)
-(defvar erc-nick-color-function)
-(defvar erc-modules)
-(defvar erc-mode-map)
-(defvar user-whole-name)
-(defvar erc-image-inline-rescale)
-
-;; Keymap for ERC commands (bound in use-package :config to defer loading)
-(defvar cj/erc-command-map
- (let ((map (make-sparse-keymap)))
- (keymap-set map "C" #'cj/erc-connect-server-with-completion) ;; Connect to server (capital C)
- (keymap-set map "c" #'cj/erc-join-channel-with-completion) ;; join channel (lowercase c)
- (keymap-set map "b" #'cj/erc-switch-to-buffer-with-completion) ;; switch Buffer
- (keymap-set map "l" #'cj/erc-connected-servers) ;; print connected servers in echo area
- (keymap-set map "q" #'erc-part-from-channel) ;; quit channel
- (keymap-set map "Q" #'erc-quit-server) ;; Quit ERC entirely
- map)
- "Keymap for ERC-related commands.")
+(eval-when-compile (require 'erc)
+ (require 'user-constants))
;; ------------------------------------ ERC ------------------------------------
;; Server definitions and connection settings
@@ -113,7 +72,7 @@ Change this value to use a different nickname.")
:nick cj/erc-nick
:full-name user-whole-name))))))
-;;;###autoload
+
(defun cj/erc-connect-server-with-completion ()
"Connect to a server using completion for server selection."
(interactive)
@@ -121,7 +80,7 @@ Change this value to use a different nickname.")
(mapcar #'car cj/erc-server-alist))))
(cj/erc-connect-server server-name)))
-;;;###autoload
+
(defun cj/erc-connected-servers ()
"Return a list of currently connected servers and display them in echo area."
(interactive)
@@ -141,7 +100,7 @@ Change this value to use a different nickname.")
server-buffers))
-;;;###autoload
+
(defun cj/erc-switch-to-buffer-with-completion ()
"Switch to an ERC buffer using completion.
If no ERC buffers exist, prompt to connect to a server.
@@ -156,14 +115,14 @@ Buffer names are shown with server context for clarity."
(when (y-or-n-p "Connect to an IRC server? ")
(call-interactively 'cj/erc-connect-server-with-completion)))))
-;;;###autoload
+
(defun cj/erc-server-buffer-active-p ()
"Return t if the current buffer is an active ERC server buffer."
(and (derived-mode-p 'erc-mode)
(erc-server-process-alive)
(erc-server-buffer-p)))
-;;;###autoload
+
(defun cj/erc-get-channels-for-current-server ()
"Get list of channels for the currently connected server."
(when (and (derived-mode-p 'erc-mode) erc-server-process)
@@ -175,10 +134,9 @@ Buffer names are shown with server context for clarity."
(when matching-server
(plist-get (cdr matching-server) :channels)))))
-;;;###autoload
+
(defun cj/erc-join-channel-with-completion ()
"Join a channel on the current server.
-
If not in an active ERC server buffer, reconnect first.
Auto-adds # prefix if missing. Offers completion from configured channels."
(interactive)
@@ -214,7 +172,6 @@ Auto-adds # prefix if missing. Offers completion from configured channels."
(erc-join-channel channel)))
(message "Failed to establish an active ERC connection")))
-
;; Main ERC configuration
(use-package erc
:ensure nil ;; built-in
@@ -381,7 +338,21 @@ NICK is the sender and MESSAGE is the message text."
:after erc
:bind
(:map erc-mode-map
- ("C-y" . erc-yank)))
+ ("C-y" . erc-yank)))
+
+
+
+;; Keymap for ERC commands (bound in use-package :config to defer loading)
+(defvar cj/erc-command-map
+ (let ((map (make-sparse-keymap)))
+ (keymap-set map "C" #'cj/erc-connect-server-with-completion) ;; Connect to server (capital C)
+ (keymap-set map "c" #'cj/erc-join-channel-with-completion) ;; join channel (lowercase c)
+ (keymap-set map "b" #'cj/erc-switch-to-buffer-with-completion) ;; switch Buffer
+ (keymap-set map "l" #'cj/erc-connected-servers) ;; print connected servers in echo area
+ (keymap-set map "q" #'erc-part-from-channel) ;; quit channel
+ (keymap-set map "Q" #'erc-quit-server) ;; Quit ERC entirely
+ map)
+ "Keymap for ERC-related commands.")
(provide 'erc-config)
;;; erc-config.el ends here
diff --git a/modules/jumper.el b/modules/jumper.el
index 787a4973..e1025472 100644
--- a/modules/jumper.el
+++ b/modules/jumper.el
@@ -168,7 +168,7 @@ Note that using M-SPC will override the default binding to just-one-space."
(defun jumper-setup-keys ()
"Setup default keybindings for jumper."
(interactive)
- (global-set-key (kbd jumper-prefix-key) jumper-map))
+ (keymap-global-set jumper-prefix-key jumper-map))
;; Call jumper-setup-keys when the package is loaded
(jumper-setup-keys)
diff --git a/modules/keyboard-macros.el b/modules/keyboard-macros.el
index a18fd694..5cd89f21 100644
--- a/modules/keyboard-macros.el
+++ b/modules/keyboard-macros.el
@@ -34,9 +34,7 @@
;;; Code:
(require 'subr-x) ;; for string-trim
-
-;; Declare external variable to avoid compile warnings
-(defvar macros-file)
+(eval-when-compile (require 'user-constants))
(defvar cj/macros-loaded nil
"Whether saved keyboard macros have been loaded from file.")
@@ -61,7 +59,7 @@ This function is idempotent and fast when macros are already loaded."
(setq cj/macros-loading nil)))
(defun ensure-macros-file (file)
- "Ensure FILE exists and its first line enables \='lexical-binding\='."
+ "Ensure FILE exists and its first line enables `lexical-binding'."
(unless (file-exists-p file)
(with-temp-file file
(insert ";;; -*- lexical-binding: t -*-\n"))))
diff --git a/modules/music-config.el b/modules/music-config.el
index 35273969..0a643729 100644
--- a/modules/music-config.el
+++ b/modules/music-config.el
@@ -16,14 +16,31 @@
;;
;;; Code:
-(eval-when-compile (require 'emms))
-(eval-when-compile (require 'emms-player-mpd))
-(eval-when-compile (require 'emms-playlist-mode))
-(eval-when-compile (require 'emms-setup))
-(eval-when-compile (require 'emms-source-file))
-(eval-when-compile (require 'emms-source-playlist))
-
-(require 'cl-lib)
+(eval-when-compile
+ (condition-case nil
+ (require 'emms)
+ (error nil)))
+(eval-when-compile
+ (condition-case nil
+ (require 'emms-player-mpd)
+ (error nil)))
+(eval-when-compile
+ (condition-case nil
+ (require 'emms-playlist-mode)
+ (error nil)))
+(eval-when-compile
+ (condition-case nil
+ (require 'emms-setup)
+ (error nil)))
+(eval-when-compile
+ (condition-case nil
+ (require 'emms-source-file)
+ (error nil)))
+(eval-when-compile
+ (condition-case nil
+ (require 'emms-source-playlist)
+ (error nil)))
+
(require 'subr-x)
;;; Settings (no Customize)
@@ -348,7 +365,7 @@ Dirs added recursively."
(t (message "Skipping non-music file: %s" file))))
(message "Added %d item(s) to playlist" (length files))))
- (define-key dirvish-mode-map "p" #'cj/music-add-dired-selection))
+ (keymap-set dirvish-mode-map "p" #'cj/music-add-dired-selection))
;;; EMMS setup and keybindings
@@ -436,9 +453,9 @@ Dirs added recursively."
("p" . emms-playlist-mode-go)
("x" . emms-shuffle)))
-;; Quick toggle key
-(global-unset-key (kbd "<f10>"))
-(global-set-key (kbd "<f10>") #'cj/music-playlist-toggle)
+;; Quick toggle key - use autoload to avoid loading emms at startup
+(autoload 'cj/music-playlist-toggle "music-config" "Toggle EMMS playlist window." t)
+(keymap-global-set "<f10>" #'cj/music-playlist-toggle)
;;; Minimal ensure-loaded setup for on-demand use
diff --git a/modules/selection-framework.el b/modules/selection-framework.el
index 9e7e44a3..66ca1cbd 100644
--- a/modules/selection-framework.el
+++ b/modules/selection-framework.el
@@ -129,7 +129,7 @@
(setq completion-in-region-function #'consult-completion-in-region))
(global-unset-key (kbd "C-s"))
-(global-set-key (kbd "C-s") 'consult-line)
+(keymap-global-set "C-s" #'consult-line)
;; Consult integration with Embark
(use-package embark-consult
@@ -149,7 +149,6 @@
;; --------------------------------- Orderless ---------------------------------
;; Advanced completion style - provides space-separated, out-of-order matching
-
(use-package orderless
:demand t
:custom
diff --git a/modules/system-defaults.el b/modules/system-defaults.el
index d8548625..52607121 100644
--- a/modules/system-defaults.el
+++ b/modules/system-defaults.el
@@ -12,7 +12,6 @@
;;; Code:
-
(require 'autorevert)
(require 'server)
(require 'bookmark)
@@ -24,9 +23,7 @@
;; Function in system-utils.el; autoload to avoid requiring it here.
(autoload 'env-bsd-p "host-environment" nil t)
-
;; -------------------------- Native Comp Preferences --------------------------
-;; after async compiler starts, set preferences and warning level
(with-eval-after-load 'comp-run
(setopt native-comp-async-jobs-number 8) ; parallel compile workers
@@ -34,7 +31,6 @@
(setopt native-comp-always-compile t)) ; always native-compile
;; -------------------------- Log Native Comp Warnings -------------------------
-;; log native comp warnings rather than cluttering the buffer
(defvar comp-warnings-log
(expand-file-name "comp-warnings.log" user-emacs-directory)
@@ -42,9 +38,9 @@
(defun cj/log-comp-warning (type message &rest args)
"Log native-comp warnings of TYPE with MESSAGE & ARGS.
-Log to buffer \='comp-warnings-log\='. Suppress warnings from appearing in the
-*Warnings* buffer. If TYPE contains \='comp\+', log the warning with a
-timestamp to the file specified by \+'comp-warnings-log\='. Return non-nil to
+Log to buffer `comp-warnings-log'. Suppress warnings from appearing in the
+*Warnings* buffer. If TYPE contains `comp', log the warning with a
+timestamp to the file specified by `comp-warnings-log'. Return non-nil to
indicate the warning was handled."
(when (memq 'comp (if (listp type) type (list type)))
(with-temp-buffer
@@ -60,7 +56,6 @@ indicate the warning was handled."
(advice-add 'display-warning :before-until #'cj/log-comp-warning)
;; ---------------------------------- Unicode ----------------------------------
-;; unicode everywhere
(set-locale-environment "en_US.UTF-8")
(prefer-coding-system 'utf-8)
@@ -115,7 +110,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq system-time-locale "C") ;; use en_US locale to format time.
;; --------------------------------- Clipboard ---------------------------------
-;; keep the clipboard and kill ring in sync
(setq select-enable-clipboard t) ;; cut and paste using clipboard
(setq yank-pop-change-selection t) ;; update system clipboard when yanking in emacs
@@ -126,7 +120,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq mouse-drag-copy-region nil) ;; don't copy region to clipboard by selecting with mouse
;; -------------------------------- Tab Settings -------------------------------
-;; spaces, not tabs
(setq-default tab-width 4) ;; if tab, make them 4 spaces default
(setq-default indent-tabs-mode nil) ;; but turn off tabs by default
@@ -137,14 +130,12 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
;; ----------------------------- Case Insensitivity ----------------------------
-;; make user interfaces case insensitive
(setq case-fold-search t) ;; case-insensitive searches
(setq completion-ignore-case t) ;; case-insensitive completion
(setq read-file-name-completion-ignore-case t) ;; case-insensitive file completion
;; ------------------------------- Async Commands ------------------------------
-;; always create new async command buffers silently
(setq async-shell-command-buffer 'new-buffer)
@@ -154,7 +145,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
'("*Async Shell Command*" display-buffer-no-window (nil)))
;; ------------------------ Mouse And Trackpad Settings ------------------------
-;; provide smoothest scrolling and avoid accidental gestures
(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
(setq scroll-margin 3) ;; start scrolling at 3 lines from top/bottom
@@ -168,7 +158,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(keymap-global-set "<remap> <mouse-wheel-text-scale>" #'cj/disabled)
;; ------------------------------- Be Quiet(er)! -------------------------------
-;; reduces "helpful" instructions that distract Emacs power users.
(setq-default vc-follow-symlinks) ;; don't ask to follow symlinks if target is version controlled
(setq kill-buffer-query-functions ;; don't ask about killing buffers with processes, just kill them
@@ -185,7 +174,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq server-client-instructions nil) ;; I already know what to do when done with the frame
;; ------------------ Reduce Garbage Collections In Minibuffer -----------------
-;; triggers garbage collection when it won't impact user minibuffer entries
(defun cj/minibuffer-setup-hook ()
"Hook to prevent garbage collection while user's in minibuffer."
@@ -199,7 +187,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(add-hook 'minibuffer-exit-hook #'cj/minibuffer-exit-hook)
;; ----------------------------- Bookmark Settings -----------------------------
-;; keep bookmarks in sync location, and save the file whenever a mark is added
;; place bookmark file sync'd org files
(setq bookmark-default-file (concat org-dir "emacs_bookmarks"))
@@ -208,7 +195,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq bookmark-save-flag 1)
;; -------------------------------- Recent Files -------------------------------
-;; don't suggest bookmarks, packages, indexes, or recentf in recent files.
(use-package recentf
:init
@@ -223,20 +209,18 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(add-to-list 'recentf-exclude "\\ElfeedDB/index"))
;; -------------------------- Autosave And Lock Files --------------------------
-;; don't create lockfiles or autosave (i.e., filename~) files.
(setq auto-save-default nil)
(setq create-lockfiles nil)
;; ------------------------------ Backup Settings ------------------------------
-;; per-save backups can be invaluable, so create them in ~/.emacs.d/backups
-;; BACKUP DIRECTORY CREATION
+;; Backup Directory Creation
(defvar cj/backup-directory (concat user-emacs-directory "backups"))
(if (not (file-exists-p cj/backup-directory))
(make-directory cj/backup-directory t))
-;; BACKUP SETTINGS
+;; Backup Settings
(setq make-backup-files t) ;; do make backup files
(setq backup-directory-alist `(("." . ,cj/backup-directory))) ;; put all originals in backup directory
(setq backup-by-copying t) ;; don't clobber symlinks
@@ -246,7 +230,6 @@ Used to disable functionality with defalias \='somefunc \='cj/disabled)."
(setq vc-make-backup-files t) ;; also backup any files in version control
;; ------------------------------- GNU 'ls' On BSD -------------------------------
-;; when on BSD use the ls from FSF sysutils/coreutils: pkg install coreutils
(when (env-bsd-p)
(setq insert-directory-program "/usr/local/bin/gls"))
diff --git a/modules/system-utils.el b/modules/system-utils.el
index dfc83ce3..6e51c32c 100644
--- a/modules/system-utils.el
+++ b/modules/system-utils.el
@@ -142,7 +142,7 @@ Logs output and exit code to buffer *external-open.log*."
;;; ------------------------ List Buffers With Nerd Icons -----------------------
;; Remap list-buffers to ibuffer (built-in). Keybinding is separate from
-;; nerd-icons-ibuffer package below, which only adds icons to ibuffer.
+;; nerd-icons-ibuffer package, which only adds icons to ibuffer.
(keymap-global-set "<remap> <list-buffers>" #'ibuffer)
(use-package nerd-icons-ibuffer
diff --git a/modules/test-runner.el b/modules/test-runner.el
index 73c4063c..e05a4e0b 100644
--- a/modules/test-runner.el
+++ b/modules/test-runner.el
@@ -254,17 +254,17 @@ Otherwise, message that no test is found."
;; Test runner operations prefix and keymap
(define-prefix-command 'cj/test-map nil
"Keymap for test-runner operations.")
-(define-key cj/custom-keymap "t" 'cj/test-map)
+(keymap-set cj/custom-keymap "t" #'cj/test-map)
-(define-key cj/test-map "L" 'cj/test-load-all)
-(define-key cj/test-map "R" 'cj/test-run-all)
-(define-key cj/test-map "." 'cj/run-test-at-point)
-(define-key cj/test-map "r" 'cj/test-run-smart)
-(define-key cj/test-map "a" 'cj/test-focus-add)
-(define-key cj/test-map "b" 'cj/test-focus-add-this-buffer-file)
-(define-key cj/test-map "c" 'cj/test-focus-clear)
-(define-key cj/test-map "v" 'cj/test-view-focused)
-(define-key cj/test-map "t" 'cj/test-toggle-mode)
+(keymap-set cj/test-map "L" #'cj/test-load-all)
+(keymap-set cj/test-map "R" #'cj/test-run-all)
+(keymap-set cj/test-map "." #'cj/run-test-at-point)
+(keymap-set cj/test-map "r" #'cj/test-run-smart)
+(keymap-set cj/test-map "a" #'cj/test-focus-add)
+(keymap-set cj/test-map "b" #'cj/test-focus-add-this-buffer-file)
+(keymap-set cj/test-map "c" #'cj/test-focus-clear)
+(keymap-set cj/test-map "v" #'cj/test-view-focused)
+(keymap-set cj/test-map "t" #'cj/test-toggle-mode)
(provide 'test-runner)
;;; test-runner.el ends here
diff --git a/modules/user-constants.el b/modules/user-constants.el
index f36a2bb5..59129697 100644
--- a/modules/user-constants.el
+++ b/modules/user-constants.el
@@ -156,7 +156,6 @@ For more information, see org webclipper section of org-capture-config.el")
(defun cj/initialize-user-directories-and-files ()
"Initialize all necessary directories and files.
-
This ensures that all directories and files required by the Emacs configuration
exist, creating them if necessary. This makes the configuration more robust
and portable across different machines."
diff --git a/modules/vc-config.el b/modules/vc-config.el
index ff90ba56..56ba1944 100644
--- a/modules/vc-config.el
+++ b/modules/vc-config.el
@@ -120,15 +120,15 @@
;; Ordering & sorting prefix and keymap
(define-prefix-command 'cj/vc-map nil
"Keymap for version control operations.")
-(define-key cj/custom-keymap "v" 'cj/vc-map)
-(define-key cj/vc-map "d" 'cj/goto-git-gutter-diff-hunks)
-(define-key cj/vc-map "c" 'cj/forge-create-issue)
-(define-key cj/vc-map "f" 'forge-pull)
-(define-key cj/vc-map "i" 'forge-list-issues)
-(define-key cj/vc-map "n" 'git-gutter:next-hunk)
-(define-key cj/vc-map "p" 'git-gutter:previous-hunk)
-(define-key cj/vc-map "r" 'forge-list-pullreqs)
-(define-key cj/vc-map "t" 'cj/git-timemachine)
+(keymap-set cj/custom-keymap "v" #'cj/vc-map)
+(keymap-set cj/vc-map "d" #'cj/goto-git-gutter-diff-hunks)
+(keymap-set cj/vc-map "c" #'cj/forge-create-issue)
+(keymap-set cj/vc-map "f" #'forge-pull)
+(keymap-set cj/vc-map "i" #'forge-list-issues)
+(keymap-set cj/vc-map "n" #'git-gutter:next-hunk)
+(keymap-set cj/vc-map "p" #'git-gutter:previous-hunk)
+(keymap-set cj/vc-map "r" #'forge-list-pullreqs)
+(keymap-set cj/vc-map "t" #'cj/git-timemachine)
(provide 'vc-config)
;;; vc-config.el ends here.
diff --git a/modules/wip.el b/modules/wip.el
index b55774b0..314881d2 100644
--- a/modules/wip.el
+++ b/modules/wip.el
@@ -44,7 +44,7 @@ If CMD is deemed dangerous, ask for confirmation."
(pcase-let ((`(,sym ,cmdstr ,label) (cj/system-cmd--resolve cmd)))
(when (and sym (get sym 'cj/system-confirm)
(memq (read-char-choice
- (format "Run %s now (%s)? (Y/n) " label camdstr)
+ (format "Run %s now (%s)? (Y/n) " label camdstr)
'(?y ?Y ?n ?N ?\r ?\n ?\s))
'(?n ?N)))
(user-error "Aborted"))
@@ -116,12 +116,12 @@ If CONFIRM is non-nil, mark VAR to always require confirmation."
"Present system commands via \='completing-read\='."
(interactive)
(let* ((commands '(("Logout System" . cj/system-cmd-logout)
- ("Lock Screen" . cj/system-cmd-lock)
- ("Suspend System" . cj/system-cmd-suspend)
- ("Shutdown System" . cj/system-cmd-shutdown)
- ("Reboot System" . cj/system-cmd-reboot)
- ("Exit Emacs" . cj/system-cmd-exit-emacs)
- ("Restart Emacs" . cj/system-cmd-restart-emacs)))
+ ("Lock Screen" . cj/system-cmd-lock)
+ ("Suspend System" . cj/system-cmd-suspend)
+ ("Shutdown System" . cj/system-cmd-shutdown)
+ ("Reboot System" . cj/system-cmd-reboot)
+ ("Exit Emacs" . cj/system-cmd-exit-emacs)
+ ("Restart Emacs" . cj/system-cmd-restart-emacs)))
(choice (completing-read "System command: " commands nil t)))
(when-let ((cmd (alist-get choice commands nil nil #'equal)))
(call-interactively cmd))))
@@ -150,15 +150,15 @@ If CONFIRM is non-nil, mark VAR to always require confirmation."
;; ------------------------------ Buffer Same Mode -----------------------------
-(defun cj/buffer-same-mode (&rest modes)
- "Pop to a buffer with a mode among MODES, or the current one if not given."
- (interactive)
- (let* ((modes (or modes (list major-mode)))
- (pred (lambda (b)
- (let ((b (get-buffer (if (consp b) (car b) b))))
- (member (buffer-local-value 'major-mode b) modes)))))
- (pop-to-buffer (read-buffer "Buffer: " nil t pred))))
-(global-set-key (kbd "C-x B") 'cj/buffer-same-mode)
+;; (defun cj/buffer-same-mode (&rest modes)
+;; "Pop to a buffer with a mode among MODES, or the current one if not given."
+;; (interactive)
+;; (let* ((modes (or modes (list major-mode)))
+;; (pred (lambda (b)
+;; (let ((b (get-buffer (if (consp b) (car b) b))))
+;; (member (buffer-local-value 'major-mode b) modes)))))
+;; (pop-to-buffer (read-buffer "Buffer: " nil t pred))))
+;; (keymap-global-set "C-x B" #'cj/buffer-same-mode)
;; ;; --------------------------------- Easy Hugo ---------------------------------
@@ -184,17 +184,30 @@ If CONFIRM is non-nil, mark VAR to always require confirmation."
:bind ("M-p" . pomm)
:commands (pomm pomm-third-time))
-;; --------------------- Debug Code For Package Signatures ---------------------
-;; from https://emacs.stackexchange.com/questions/233/how-to-proceed-on-package-el-signature-check-failure
-
-
-;; Set package-check-signature to nil, e.g., M-: (setq package-check-signature nil) RET.
-;; Download the package gnu-elpa-keyring-update and run the function with the same name, e.g., M-x package-install RET gnu-elpa-keyring-update RET.
-;; Reset package-check-signature to the default value allow-unsigned, e.g., M-: (setq package-check-signature 'allow-unsigned) RET.
-
-;; (setq package-check-signature nil)
-;; (setq package-check-signature 'allow-unsigned)
+;; ----------------------------------- Popper ----------------------------------
+;; (use-package popper
+;; :bind (("C-`" . popper-toggle)
+;; ("M-`" . popper-cycle)
+;; ("C-M-`" . popper-toggle-type))
+;; :custom
+;; (popper-display-control-nil)
+;; :init
+;; (setq popper-reference-buffers
+;; '("\\*Messages\\*"
+;; "Output\\*$"
+;; "\\*Async Shell Command\\*"
+;; ;; "\\*scratch\\*"
+;; help-mode
+;; compilation-mode))
+;; (add-to-list 'display-buffer-alist
+;; '(popper-display-control-p ; Predicate to match popper buffers
+;; (display-buffer-in-side-window)
+;; (side . bottom)
+;; (slot . 0)
+;; (window-height . 0.5))) ; Half the frame height
+;; (popper-mode +1)
+;; (popper-echo-mode +1))
(provide 'wip)
;;; wip.el ends here.
diff --git a/modules/wrap-up.el b/modules/wrap-up.el
index f1841189..b00d56a8 100644
--- a/modules/wrap-up.el
+++ b/modules/wrap-up.el
@@ -23,8 +23,9 @@
(defun cj/bury-buffers-after-delay ()
"Run cj/bury-buffers after a delay."
(run-with-timer 1 nil 'cj/bury-buffers))
-
(add-hook 'emacs-startup-hook 'cj/bury-buffers-after-delay)
+(cj/log-silently "<-- end of init file.")
+
(provide 'wrap-up)
;;; wrap-up.el ends here