Miscellaneous
Table of Contents
1. Introduction
Miscellaneous utilities and configurations including email, AI chat integration, PDF tools, and helper functions.
2. Email Configuration
Configuration for reading and sending email using notmuch and msmtp.
2.1. Notmuch
Fast email indexing and searching with notmuch.
;;; misc-conf.el --- Miscellaneous Configuration -*- lexical-binding: t; -*- ;;; Commentary: ;;; Miscellaneous utilities including email, AI chat, PDF tools, and helpers. ;;; Code: ;; Email - Notmuch (use-package notmuch :ensure t :defer t :config (setq mail-user-agent 'notmuch-user-agent))
2.2. Email Sending
Configure email sending with msmtp and authentication.
;; Email - Sending Configuration (setq user-full-name (or (getenv "USER_FULL_NAME") user-full-name) user-mail-address (or (getenv "USER_EMAIL") user-mail-address) auth-sources '("~/.authinfo.gpg" "~/.authinfo")) ;; Use msmtp for sending mail (setq send-mail-function 'sendmail-send-it message-send-mail-function 'message-send-mail-with-sendmail sendmail-program (or (executable-find "msmtp") "/usr/bin/msmtp") message-sendmail-envelope-from 'header)
3. GPTel - AI Chat Integration
Comprehensive AI chat integration with support for multiple providers (OpenAI, Claude, Gemini, etc.) with easy model switching and automatic chat history saving.
3.1. Core Configuration
;; GPTel - AI Chat Integration (use-package gptel :ensure t :custom ;; Default mode for chat buffers (gptel-default-mode 'org-mode) ;; Directory for saving chat history (gptel-chat-history-directory (expand-file-name "gptel-history" user-emacs-directory)) ;; Model settings (gptel-model "claude-opus-4-5-20251101") (gptel-backend nil) ; Will be set by backend setup ;; Streaming responses (gptel-stream t) ;; Display settings (gptel-use-curl t) (gptel-crowdsource-default-mode 'org-mode) :config ;; Ensure chat history directory exists (let ((history-dir (expand-file-name "gptel-history" user-emacs-directory))) (unless (file-directory-p history-dir) (make-directory history-dir t))))
3.2. Backend Configuration
Set up multiple AI backends with API keys from environment variables or auth-sources.
;; GPTel Backend Configuration ;; Helper function to get API key (defun fu/gptel-get-api-key (service) "Get API key for SERVICE from environment or auth-sources. SERVICE should be something like 'OPENAI_API_KEY' or 'ANTHROPIC_API_KEY'." (or (getenv service) (plist-get (car (auth-source-search :host service)) :secret))) ;; Configure backends (with-eval-after-load 'gptel ;; Anthropic (Claude) (when-let ((key (fu/gptel-get-api-key "CLAUDE_API_KEY"))) (setq gptel-anthropic-key key) (unless gptel-backend (setq gptel-backend (gptel-make-anthropic "Claude" :stream t :key key)))) ;; OpenAI (GPT) (when-let ((key (fu/gptel-get-api-key "OPENAI_API_KEY"))) (setq gptel-openai-key key) (gptel-make-openai "ChatGPT" :stream t :key key :models '("gpt-5.1-2025-11-13" "gpt-5.1-codex" "gpt-4.1" "gpt-4.1-mini" "gpt-4.1-nano" "gpt-4o" "gpt-4o-mini" "gpt-4-turbo" "gpt-3.5-turbo"))) ;; Google (Gemini) (when-let ((key (fu/gptel-get-api-key "GEMINI_API_KEY"))) (gptel-make-gemini "Gemini" :stream t :key key :models '("gemini-3-pro-preview" "gemini-2.5-pro" "gemini-2.5-flash" "gemini-2.5-flash-lite-preview" "gemini-2.0-flash-exp" "gemini-1.5-pro" "gemini-1.5-flash"))))
3.3. Easy Model Switching
Convenient functions to switch between different AI models quickly.
;; GPTel Model Switching Functions (defvar fu/gptel-models '(;; Claude models (newest first) ("Claude Opus 4.5" . (anthropic "claude-opus-4-5-20251101")) ("Claude Sonnet 4.5" . (anthropic "claude-sonnet-4-5-20250929")) ("Claude Opus 4.1" . (anthropic "claude-opus-4-1-20250805")) ("Claude Opus 4" . (anthropic "claude-opus-4-20250514")) ("Claude Sonnet 4" . (anthropic "claude-sonnet-4-20250514")) ("Claude 3.5 Sonnet" . (anthropic "claude-3-5-sonnet-20241022")) ("Claude 3 Opus" . (anthropic "claude-3-opus-20240229")) ("Claude 3 Haiku" . (anthropic "claude-3-haiku-20240307")) ;; OpenAI models (newest first) ("GPT-5.1" . (openai "gpt-5.1-2025-11-13")) ("GPT-5.1 Codex" . (openai "gpt-5.1-codex")) ("GPT-4.1" . (openai "gpt-4.1")) ("GPT-4.1 Mini" . (openai "gpt-4.1-mini")) ("GPT-4.1 Nano" . (openai "gpt-4.1-nano")) ("GPT-4o" . (openai "gpt-4o")) ("GPT-4o Mini" . (openai "gpt-4o-mini")) ("GPT-4 Turbo" . (openai "gpt-4-turbo")) ("GPT-3.5 Turbo" . (openai "gpt-3.5-turbo")) ;; Gemini models (newest first) ("Gemini 3 Pro" . (gemini "gemini-3-pro-preview")) ("Gemini 2.5 Pro" . (gemini "gemini-2.5-pro")) ("Gemini 2.5 Flash" . (gemini "gemini-2.5-flash")) ("Gemini 2.5 Flash Lite" . (gemini "gemini-2.5-flash-lite-preview")) ("Gemini 2.0 Flash" . (gemini "gemini-2.0-flash-exp")) ("Gemini 1.5 Pro" . (gemini "gemini-1.5-pro")) ("Gemini 1.5 Flash" . (gemini "gemini-1.5-flash"))) "Alist of model display names to (provider model-id) pairs.") (defun fu/gptel-set-model (model-name) "Switch GPTel to MODEL-NAME from predefined list." (interactive (list (completing-read "Select AI model: " (mapcar #'car fu/gptel-models) nil t))) (when-let* ((model-info (alist-get model-name fu/gptel-models nil nil #'string=)) (provider (car model-info)) (model-id (cadr model-info))) (pcase provider ('anthropic (when-let ((key (fu/gptel-get-api-key "CLAUDE_API_KEY"))) (setq gptel-backend (gptel-make-anthropic "Claude" :stream t :key key) gptel-model model-id) (message "Switched to %s (%s)" model-name model-id))) ('openai (when-let ((key (fu/gptel-get-api-key "OPENAI_API_KEY"))) (setq gptel-backend (gptel-make-openai "ChatGPT" :stream t :key key) gptel-model model-id) (message "Switched to %s (%s)" model-name model-id))) ('gemini (when-let ((key (fu/gptel-get-api-key "GEMINI_API_KEY"))) (setq gptel-backend (gptel-make-gemini "Gemini" :stream t :key key) gptel-model model-id) (message "Switched to %s (%s)" model-name model-id)))))) ;; Quick switch functions (defun fu/gptel-use-claude () "Switch to Claude Opus 4.5 (latest)." (interactive) (fu/gptel-set-model "Claude Opus 4.5")) (defun fu/gptel-use-gpt4 () "Switch to GPT-5.1 (latest)." (interactive) (fu/gptel-set-model "GPT-5.1")) (defun fu/gptel-use-gemini () "Switch to Gemini 3 Pro (latest)." (interactive) (fu/gptel-set-model "Gemini 3 Pro"))
3.4. Automatic Chat History Saving
Automatically save chat conversations to disk with timestamps and model information.
;; GPTel Chat History Management (defun fu/gptel-save-chat () "Save current gptel chat buffer to history directory." (interactive) (when (and (derived-mode-p 'org-mode) (bound-and-true-p gptel-mode)) (let* ((timestamp (format-time-string "%Y%m%d-%H%M%S")) (model-name (replace-regexp-in-string "[^a-zA-Z0-9-]" "-" gptel-model)) (filename (format "%s-%s.org" timestamp model-name)) (filepath (expand-file-name filename gptel-chat-history-directory))) (write-region (point-min) (point-max) filepath) (message "Chat saved to: %s" filepath) filepath))) (defun fu/gptel-auto-save-chat () "Automatically save chat if it has content." (when (and (derived-mode-p 'org-mode) (bound-and-true-p gptel-mode) (> (buffer-size) 100)) ; Only save if buffer has content (fu/gptel-save-chat))) ;; Auto-save chat on buffer kill (add-hook 'kill-buffer-hook #'fu/gptel-auto-save-chat) ;; Periodic auto-save (every 5 minutes) (defvar fu/gptel-auto-save-timer nil "Timer for auto-saving gptel chats.") (defun fu/gptel-enable-auto-save () "Enable periodic auto-saving of gptel chats." (interactive) (when fu/gptel-auto-save-timer (cancel-timer fu/gptel-auto-save-timer)) (setq fu/gptel-auto-save-timer (run-with-idle-timer 300 t (lambda () (dolist (buf (buffer-list)) (with-current-buffer buf (fu/gptel-auto-save-chat)))))) (message "GPTel auto-save enabled (every 5 minutes when idle)")) (defun fu/gptel-disable-auto-save () "Disable periodic auto-saving of gptel chats." (interactive) (when fu/gptel-auto-save-timer (cancel-timer fu/gptel-auto-save-timer) (setq fu/gptel-auto-save-timer nil) (message "GPTel auto-save disabled"))) ;; Load a saved chat (defun fu/gptel-load-chat () "Load a previously saved chat from history." (interactive) (let* ((files (directory-files gptel-chat-history-directory nil "\\.org$")) (file (completing-read "Load chat: " (nreverse files) nil t))) (when file (find-file (expand-file-name file gptel-chat-history-directory)) (gptel-mode 1))))
3.5. Enhanced Chat Interface
Improved chat interface with better defaults and keybindings.
;; GPTel Enhanced Interface (defun fu/gptel-new-chat () "Start a new gptel chat with current model information in header." (interactive) (let* ((model-info (format "Model: %s" gptel-model)) (timestamp (format-time-string "%Y-%m-%d %H:%M")) (buf-name (format "*gptel-%s*" timestamp))) (with-current-buffer (get-buffer-create buf-name) (org-mode) (gptel-mode 1) (insert (format "#+TITLE: AI Chat - %s\n" timestamp)) (insert (format "#+DATE: %s\n" timestamp)) (insert (format "#+MODEL: %s\n" gptel-model)) (insert (format "#+BACKEND: %s\n\n" (gptel-backend-name gptel-backend))) (insert "* Chat\n\n") (goto-char (point-max))) (switch-to-buffer buf-name))) ;; Keybindings for gptel (with-eval-after-load 'gptel (define-key gptel-mode-map (kbd "C-c g s") #'fu/gptel-save-chat) (define-key gptel-mode-map (kbd "C-c g m") #'fu/gptel-set-model) (define-key gptel-mode-map (kbd "C-c g n") #'fu/gptel-new-chat) (define-key gptel-mode-map (kbd "C-c g l") #'fu/gptel-load-chat)) ;; Global keybindings (global-set-key (kbd "C-c a n") #'fu/gptel-new-chat) (global-set-key (kbd "C-c a m") #'fu/gptel-set-model) (global-set-key (kbd "C-c a l") #'fu/gptel-load-chat) (global-set-key (kbd "C-c a c") #'fu/gptel-use-claude) (global-set-key (kbd "C-c a g") #'fu/gptel-use-gpt4) (global-set-key (kbd "C-c a G") #'fu/gptel-use-gemini) ;; Enable auto-save by default (with-eval-after-load 'gptel (fu/gptel-enable-auto-save))
3.6. Usage Guide
Quick reference for using gptel:
3.6.1. Starting a Chat
C-c a n: Start new chat with current modelM-x gptel: Start chat in current buffer
3.6.2. Model Switching
C-c a m: Choose from all available modelsC-c a c: Quick switch to Claude Opus 4.5 (latest)C-c a g: Quick switch to GPT-5.1 (latest)C-c a G: Quick switch to Gemini 3 Pro (latest)
3.6.3. Chat Management
C-c g s: Manually save current chat (in gptel buffer)C-c a l: Load a saved chat from history- Auto-save: Chats automatically save every 5 minutes when idle
- Auto-save on buffer kill: Chats save when you close the buffer
3.6.4. In Chat Buffer
C-c RET: Send messageC-c g m: Switch model mid-conversationC-c g n: Start new chat
3.6.5. Configuration
API keys should be set as environment variables:
CLAUDE_API_KEY: For Claude models (Anthropic)OPENAI_API_KEY: For GPT models (OpenAI)GEMINI_API_KEY: For Gemini models (Google)
Or stored in ~/.authinfo.gpg with host entries matching the key names.
Chat history location: ~/.emacs.d/gptel-history/ (customizable via gptel-chat-history-directory)
4. PDF Tools
Comprehensive PDF viewing and annotation system with powerful search, annotation, bookmark, and navigation features.
Reference: EmacsElements PDF Tools Settings
4.1. Core Features
- High-quality PDF rendering with native performance
- Full-text search with occur mode for document-wide searches
- Rich annotation support (highlight, underline, strikethrough, text notes)
- Bookmarks and outline/TOC navigation
- Region marking and text selection
- Image extraction and manipulation
- Link following and history navigation
- Dark mode support (midnight mode)
- Auto-revert for live-updating PDFs
- Slice mode for cropping margins
4.2. Basic Setup
;; PDF Tools - Core Configuration (use-package pdf-tools :ensure t :mode ("\\.pdf\\'" . pdf-view-mode) :magic ("%PDF" . pdf-view-mode) :config ;; Install pdf-tools (pdf-tools-install :no-query) ;; Custom settings (setq-default pdf-view-display-size 'fit-page) ;; Performance (setq pdf-view-use-scaling t pdf-view-use-imagemagick nil) ;; Annotation settings (setq pdf-annot-activate-created-annotations t) ;; Auto-revert PDFs when file changes (add-hook 'pdf-view-mode-hook #'auto-revert-mode) ;; More frequent auto-revert for PDFs (setq auto-revert-interval 0.5))
4.3. Display and Visual Settings
;; PDF Tools - Display Settings (with-eval-after-load 'pdf-view ;; Midnight mode colors (dark mode) (setq pdf-view-midnight-colors '("#ffffff" . "#000000")) ;; Resize factor (setq pdf-view-resize-factor 1.1) ;; Continuous scroll (setq pdf-view-continuous t) ;; Display options (setq pdf-view-display-size 'fit-width) (setq pdf-view-use-dedicated-register t))
4.4. Search and Navigation
;; PDF Tools - Enhanced Search (with-eval-after-load 'pdf-isearch ;; Search settings (setq pdf-isearch-hyphenation-character "-\u00ad") ;; Batch mode for faster search (setq pdf-isearch-batch-mode t) ;; Custom search face (set-face-attribute 'pdf-isearch-match nil :background "yellow" :foreground "black")) ;; PDF Occur - Search across entire document (with-eval-after-load 'pdf-occur ;; Occur buffer settings (setq pdf-occur-prefer-string-search t))
4.5. Annotations and Markup
;; PDF Tools - Annotations (with-eval-after-load 'pdf-annot ;; Annotation list settings (setq pdf-annot-list-format '((page . 3) (type . 10) (label . 15) (contents . 0))) ;; Annotation highlight colors (setq pdf-annot-default-annotation-properties '((t (label . "User")) (highlight (color . "yellow")) (underline (color . "blue")) (squiggly (color . "orange")) (strike-out (color . "red")) (text (icon . "Note") (color . "gold")))) ;; Minor mode settings (setq pdf-annot-minor-mode-map-prefix (kbd "C-c a"))) ;; Custom annotation functions (defun fu/pdf-annot-add-highlight () "Add highlight annotation to selected region." (interactive) (pdf-annot-add-highlight-markup-annotation (pdf-view-active-region) "yellow")) (defun fu/pdf-annot-add-underline () "Add underline annotation to selected region." (interactive) (pdf-annot-add-underline-markup-annotation (pdf-view-active-region) "blue")) (defun fu/pdf-annot-add-strikeout () "Add strikeout annotation to selected region." (interactive) (pdf-annot-add-strikeout-markup-annotation (pdf-view-active-region) "red")) (defun fu/pdf-annot-add-text-note () "Add text note annotation at point." (interactive) (pdf-annot-add-text-annotation (pdf-view-active-region) (read-string "Note: ")))
4.6. Bookmarks and Links
;; PDF Tools - Bookmarks (with-eval-after-load 'pdf-view ;; Enable bookmark support (setq pdf-view-use-dedicated-register t)) ;; Save place in PDF files (use-package saveplace-pdf-view :ensure t :after pdf-tools :config ;; Remember last position in PDFs (save-place-mode 1)) ;; Custom bookmark functions (defun fu/pdf-bookmark-set () "Set a bookmark in the current PDF." (interactive) (bookmark-set (format "PDF: %s - p%d" (file-name-nondirectory (buffer-file-name)) (pdf-view-current-page)))) (defun fu/pdf-bookmark-jump () "Jump to a PDF bookmark." (interactive) (bookmark-jump (completing-read "PDF Bookmark: " (cl-remove-if-not (lambda (bmk) (string-prefix-p "PDF: " (car bmk))) bookmark-alist))))
4.7. Keybindings
Comprehensive keybinding setup for all PDF operations.
;; PDF Tools - Keybindings (with-eval-after-load 'pdf-view (let ((map pdf-view-mode-map)) ;; Basic navigation (define-key map (kbd "j") 'pdf-view-next-line-or-next-page) (define-key map (kbd "k") 'pdf-view-previous-line-or-previous-page) (define-key map (kbd "h") 'image-backward-hscroll) (define-key map (kbd "l") 'image-forward-hscroll) (define-key map (kbd "J") 'pdf-view-next-page) (define-key map (kbd "K") 'pdf-view-previous-page) ;; (define-key map (kbd "g g") 'pdf-view-first-page) (define-key map (kbd "G") 'pdf-view-last-page) ;; (define-key map (kbd "g t") 'pdf-view-goto-page) ;; Search (define-key map (kbd "C-s") 'isearch-forward) (define-key map (kbd "C-r") 'isearch-backward) (define-key map (kbd "s s") 'pdf-occur) (define-key map (kbd "s r") 'pdf-isearch-batch-mode) ;; Zoom and display (define-key map (kbd "+") 'pdf-view-enlarge) (define-key map (kbd "-") 'pdf-view-shrink) (define-key map (kbd "0") 'pdf-view-scale-reset) (define-key map (kbd "W") 'pdf-view-fit-width-to-window) (define-key map (kbd "H") 'pdf-view-fit-height-to-window) (define-key map (kbd "P") 'pdf-view-fit-page-to-window) (define-key map (kbd "m") 'pdf-view-midnight-minor-mode) (define-key map (kbd "s l") 'pdf-view-set-slice-using-mouse) (define-key map (kbd "s b") 'pdf-view-set-slice-from-bounding-box) (define-key map (kbd "s r") 'pdf-view-reset-slice) ;; Annotations (define-key map (kbd "a h") 'fu/pdf-annot-add-highlight) (define-key map (kbd "a u") 'fu/pdf-annot-add-underline) (define-key map (kbd "a s") 'fu/pdf-annot-add-strikeout) (define-key map (kbd "a t") 'fu/pdf-annot-add-text-note) (define-key map (kbd "a d") 'pdf-annot-delete) (define-key map (kbd "a l") 'pdf-annot-list-annotations) (define-key map (kbd "a n") 'pdf-annot-next-annotation) (define-key map (kbd "a p") 'pdf-annot-previous-annotation) ;; Outline and links (define-key map (kbd "o") 'pdf-outline) (define-key map (kbd "f") 'pdf-links-action-perform) (define-key map (kbd "F") 'pdf-links-isearch-link) ;; Bookmarks (define-key map (kbd "b s") 'fu/pdf-bookmark-set) (define-key map (kbd "b j") 'fu/pdf-bookmark-jump) (define-key map (kbd "b l") 'bookmark-bmenu-list) ;; History (define-key map (kbd "B") 'pdf-history-backward) (define-key map (kbd "N") 'pdf-history-forward) ;; Misc (define-key map (kbd "r") 'pdf-view-revert-buffer) (define-key map (kbd "t") 'pdf-annot-attachment-dired) (define-key map (kbd "n") 'pdf-view-next-page-command) (define-key map (kbd "p") 'pdf-view-previous-page-command) (define-key map (kbd "SPC") 'pdf-view-scroll-up-or-next-page) (define-key map (kbd "DEL") 'pdf-view-scroll-down-or-previous-page) (define-key map (kbd "C-c C-c") 'pdf-misc-display-metadata)))
4.8. Helper Functions
Additional utility functions for enhanced PDF workflow.
;; PDF Tools - Helper Functions (defun fu/pdf-print-buffer () "Print current PDF buffer." (interactive) (pdf-misc-print-document (buffer-file-name))) (defun fu/pdf-copy-region-as-text () "Copy selected region as text." (interactive) (when (pdf-view-active-region-p) (let ((text (pdf-view-active-region-text))) (kill-new (mapconcat 'identity text "\n")) (message "Copied PDF text to clipboard")))) (defun fu/pdf-extract-images () "Extract images from current PDF." (interactive) (let* ((file (buffer-file-name)) (dir (file-name-sans-extension file))) (make-directory dir t) (shell-command (format "pdfimages -all '%s' '%s/image'" file dir)) (message "Extracted images to %s" dir) (dired dir))) (defun fu/pdf-count-pages () "Display the number of pages in current PDF." (interactive) (message "PDF has %d pages" (pdf-cache-number-of-pages))) (defun fu/pdf-rotate-page (degrees) "Rotate current page by DEGREES (90, 180, or 270)." (interactive (list (string-to-number (completing-read "Rotate by degrees: " '("90" "180" "270"))))) (pdf-view-rotate degrees)) ;; Global keybindings for PDF functions (with-eval-after-load 'pdf-view (define-key pdf-view-mode-map (kbd "w") 'fu/pdf-copy-region-as-text) (define-key pdf-view-mode-map (kbd "C-c C-p") 'fu/pdf-print-buffer) (define-key pdf-view-mode-map (kbd "C-c i") 'fu/pdf-extract-images) (define-key pdf-view-mode-map (kbd "C-c n") 'fu/pdf-count-pages) (define-key pdf-view-mode-map (kbd "R") 'fu/pdf-rotate-page))
4.9. PDF Keybinding Reference
Quick reference for PDF Tools keybindings:
| Category | Key | Command |
|---|---|---|
| Navigation | j/k | Line up/down |
| J/K | Page down/up | |
| g g | First page | |
| G | Last page | |
| g t | Go to page | |
| SPC/DEL | Page down/up | |
| h/l | Scroll left/right | |
| B/N | History back/forward | |
| Search | C-s/C-r | Incremental search |
| s s | Search all (occur) | |
| s r | Batch search | |
| Display | +/- | Zoom in/out |
| 0 | Reset zoom | |
| W/H/P | Fit width/height/page | |
| m | Toggle dark mode | |
| s l | Set slice (crop) | |
| s b | Slice from bounding box | |
| s r | Reset slice | |
| R | Rotate page | |
| Annotate | a h | Add highlight |
| a u | Add underline | |
| a s | Add strikeout | |
| a t | Add text note | |
| a d | Delete annotation | |
| a l | List annotations | |
| a n/p | Next/previous annotation | |
| Bookmarks | b s | Set bookmark |
| b j | Jump to bookmark | |
| b l | List bookmarks | |
| Outline | o | Show outline/TOC |
| f | Follow link | |
| F | Search links | |
| Misc | w | Copy region as text |
| r | Revert buffer | |
| C-c C-p | Print PDF | |
| C-c i | Extract images | |
| C-c n | Count pages | |
| C-c C-c | Display metadata |
5. Utility Functions
General utility functions for improved Emacs workflow.
5.1. Open in External Application
Open current file or URL in external application.
;;; misc-conf.el --- Miscellaneous Configuration -*- lexical-binding: t; -*- ;;; Commentary: ;;; Code: ;; Utility Functions (defun fu/open-in-external-app () "Open current file or URL in external application." (interactive) (let ((path (or (buffer-file-name) (when (eq major-mode 'dired-mode) (dired-get-file-for-visit))))) (if path (cond ((eq system-type 'darwin) (call-process "open" nil 0 nil path)) ((eq system-type 'gnu/linux) (call-process "xdg-open" nil 0 nil path)) ((eq system-type 'windows-nt) (w32-shell-execute "open" path))) (message "No file or URL to open")))) (global-set-key (kbd "C-c o") #'fu/open-in-external-app)
5.2. Copy File Path
Copy current file path to clipboard.
(defun fu/copy-file-path () "Copy the current buffer file path to clipboard." (interactive) (when-let* ((path (or (buffer-file-name) default-directory))) (kill-new path) (message "Copied: %s" path))) (global-set-key (kbd "C-c y p") #'fu/copy-file-path)
5.3. Reload Configuration
Quickly reload Emacs configuration.
(defun fu/reload-config () "Reload Emacs configuration." (interactive) (load-file user-init-file) (message "Configuration reloaded!")) (global-set-key (kbd "C-c r c") #'fu/reload-config)
5.4. Kill Other Buffers
Kill all buffers except the current one.
(defun fu/kill-other-buffers () "Kill all buffers except the current one." (interactive) (let ((current-buf (current-buffer))) (dolist (buf (buffer-list)) (unless (or (eq buf current-buf) (string-prefix-p " " (buffer-name buf))) (kill-buffer buf)))) (message "Killed all other buffers")) (global-set-key (kbd "C-c k o") #'fu/kill-other-buffers)
6. Database Configuration (Disabled)
Example database configuration with ejc-sql. Disabled by default.
;; Database Configuration - ejc-sql (use-package ejc-sql :ensure t :defer t :custom (clomacs-httpd-default-port 8888) :config (let ((ojdbc-path "~/.m2/repository/com/oracle/ojdbc8/8/ojdbc8-8.jar") (maria-path "~/.m2/repository/org/mariadb/jdbc/mariadb-java-client/2.6.2/mariadb-java-client-2.6.2.jar")) ;; Oracle connection example (ejc-create-connection "Oracle DB" :classpath ojdbc-path :connection-uri (concat "jdbc:oracle:thin:@" (getenv "DB_HOST") ":" (getenv "DB_PORT") ":" (getenv "DB_NAME")) :user (getenv "DB_USERNAME") :password (getenv "DB_PASSWORD") :separator "/") ;; MariaDB connection example (ejc-create-connection "MariaDB" :classpath maria-path :connection-uri "jdbc:mariadb://host:port/dbname" :user "username" :password "password" :separator "/")))
7. Scratch Buffers
Create temporary scratch buffers with specific major modes for quick testing and experimentation.
(defun create-scratch-with-mode (mode) "Create a new scratch buffer in the specified MODE. Prompts for a major mode interactively and creates a uniquely named scratch buffer in that mode." (interactive (list (intern (completing-read "Major mode for scratch buffer: " (let ((modes nil)) (mapatoms (lambda (symbol) (when (and (functionp symbol) (string-match-p "-mode$" (symbol-name symbol)) (not (string-match-p "-minor-mode$" (symbol-name symbol)))) (push (symbol-name symbol) modes)))) modes) nil nil nil nil "fundamental-mode")))) (let* ((mode-name (replace-regexp-in-string "-mode$" "" (symbol-name mode))) (buffer-name (generate-new-buffer-name (format "*scratch-%s*" mode-name))) (buf (get-buffer-create buffer-name))) (with-current-buffer buf (funcall mode) ;; Use mode's comment character or default to nothing if no comments (when comment-start (let ((comment (string-trim comment-start))) (insert (format "%s Scratch buffer in %s\n%s Evaluate expressions and experiment freely!\n\n" comment (symbol-name mode) comment))))) (switch-to-buffer buf) (message "Created scratch buffer '%s' in %s" buffer-name (symbol-name mode)))) ;; Quick shortcut for common modes (defun scratch-elisp () "Create a scratch buffer in `emacs-lisp-mode'." (interactive) (create-scratch-with-mode 'emacs-lisp-mode)) (defun scratch-org () "Create a scratch buffer in `org-mode'." (interactive) (create-scratch-with-mode 'org-mode)) (defun scratch-text () "Create a scratch buffer in `text-mode'." (interactive) (create-scratch-with-mode 'text-mode)) (defun scratch-python () "Create a scratch buffer in `python-mode'." (interactive) (create-scratch-with-mode 'python-mode)) ;; Bind to a convenient key if desired: ;; (global-set-key (kbd "C-c s") 'create-scratch-with-mode)
8. End of File
(provide 'misc-conf) ;;; misc-conf.el ends here