Commit 35e6704e3ebe
Changed files (9)
dots
.config
claude
skills
EmacsLisp
dots/.config/claude/skills/EmacsLisp/workflows/Configure.md
@@ -0,0 +1,452 @@
+# Configure Workflow
+
+Modern Emacs configuration using use-package, package managers, and best practices for Emacs 29+.
+
+## Modern Configuration (2025)
+
+### Recommended Approach
+
+**Emacs 29+**: use-package is built-in
+- No need to install use-package separately
+- Clean, declarative package configuration
+- Lazy loading for fast startup
+
+## Configuration Structure
+
+```
+~/.emacs.d/
+βββ early-init.el # Early initialization (Emacs 27+)
+βββ init.el # Main configuration
+βββ custom.el # Custom-set variables (optional)
+βββ lisp/ # Custom Elisp files
+ βββ my-functions.el
+```
+
+## early-init.el
+
+Runs before package initialization and GUI setup:
+
+```elisp
+;;; early-init.el --- Early initialization -*- lexical-binding: t -*-
+
+;; Disable package.el in favor of straight.el (optional)
+;; Or keep it for use-package with package.el
+(setq package-enable-at-startup t)
+
+;; Improve startup time
+(setq gc-cons-threshold most-positive-fixnum
+ gc-cons-percentage 0.6)
+
+;; Disable unnecessary UI elements early
+(push '(menu-bar-lines . 0) default-frame-alist)
+(push '(tool-bar-lines . 0) default-frame-alist)
+(push '(vertical-scroll-bars) default-frame-alist)
+
+;; Prevent unwanted runtime compilation
+(setq native-comp-deferred-compilation nil)
+
+;;; early-init.el ends here
+```
+
+## init.el (Modern with use-package)
+
+### Basic Setup
+
+```elisp
+;;; init.el --- Emacs configuration -*- lexical-binding: t -*-
+
+;; Reset GC threshold after startup
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (setq gc-cons-threshold (* 16 1024 1024)
+ gc-cons-percentage 0.1)))
+
+;; Package archives
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+(add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
+(package-initialize)
+
+;; Ensure use-package is available
+(unless (package-installed-p 'use-package)
+ (package-refresh-contents)
+ (package-install 'use-package))
+
+(require 'use-package)
+(setq use-package-always-ensure t) ; Auto-install packages
+
+;; Keep customizations in separate file
+(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
+(when (file-exists-p custom-file)
+ (load custom-file))
+
+;;; init.el ends here
+```
+
+### Essential Packages
+
+```elisp
+;; Magit - Git interface
+(use-package magit
+ :bind ("C-x g" . magit-status)
+ :config
+ (setq magit-display-buffer-function
+ #'magit-display-buffer-same-window-except-diff-v1))
+
+;; Company - Completion
+(use-package company
+ :hook (prog-mode . company-mode)
+ :custom
+ (company-idle-delay 0.2)
+ (company-minimum-prefix-length 2)
+ :bind (:map company-active-map
+ ("C-n" . company-select-next)
+ ("C-p" . company-select-previous)))
+
+;; Vertico - Minibuffer completion
+(use-package vertico
+ :init
+ (vertico-mode 1)
+ :custom
+ (vertico-cycle t))
+
+;; Marginalia - Rich annotations
+(use-package marginalia
+ :init
+ (marginalia-mode 1))
+
+;; Orderless - Flexible matching
+(use-package orderless
+ :custom
+ (completion-styles '(orderless basic))
+ (completion-category-overrides '((file (styles basic partial-completion)))))
+
+;; Which-key - Key binding help
+(use-package which-key
+ :init
+ (which-key-mode 1)
+ :custom
+ (which-key-idle-delay 0.5))
+```
+
+### Programming
+
+```elisp
+;; LSP (choose one: eglot or lsp-mode)
+
+;; Eglot (built-in since Emacs 29)
+(use-package eglot
+ :ensure nil ; Built-in
+ :hook ((python-mode . eglot-ensure)
+ (go-mode . eglot-ensure)
+ (rust-mode . eglot-ensure)))
+
+;; OR lsp-mode (more features, heavier)
+(use-package lsp-mode
+ :hook ((python-mode . lsp)
+ (go-mode . lsp))
+ :commands lsp
+ :custom
+ (lsp-headerline-breadcrumb-enable nil))
+
+;; Tree-sitter (built-in since Emacs 29)
+(use-package treesit
+ :ensure nil
+ :config
+ (setq treesit-language-source-alist
+ '((python "https://github.com/tree-sitter/tree-sitter-python")
+ (rust "https://github.com/tree-sitter/tree-sitter-rust")
+ (go "https://github.com/tree-sitter/tree-sitter-go"))))
+```
+
+### Org Mode
+
+```elisp
+(use-package org
+ :ensure nil ; Built-in
+ :custom
+ (org-directory "~/org")
+ (org-agenda-files '("~/org/agenda.org"))
+ (org-startup-indented t)
+ (org-hide-emphasis-markers t)
+ :config
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((emacs-lisp . t)
+ (python . t)
+ (shell . t))))
+
+(use-package org-roam
+ :custom
+ (org-roam-directory "~/org/roam")
+ :bind (("C-c n l" . org-roam-buffer-toggle)
+ ("C-c n f" . org-roam-node-find)
+ ("C-c n i" . org-roam-node-insert))
+ :config
+ (org-roam-db-autosync-mode))
+```
+
+## Alternative: straight.el
+
+For reproducible configuration with pinned versions:
+
+### Bootstrap
+
+```elisp
+;;; init.el with straight.el
+
+;; Bootstrap straight.el
+(defvar bootstrap-version)
+(let ((bootstrap-file
+ (expand-file-name "straight/repos/straight.el/bootstrap.el"
+ user-emacs-directory))
+ (bootstrap-version 6))
+ (unless (file-exists-p bootstrap-file)
+ (with-current-buffer
+ (url-retrieve-synchronously
+ "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
+ 'silent 'inhibit-cookies)
+ (goto-char (point-max))
+ (eval-print-last-sexp)))
+ (load bootstrap-file nil 'nomessage))
+
+;; Install use-package
+(straight-use-package 'use-package)
+(setq straight-use-package-by-default t)
+
+;; Now use packages normally
+(use-package magit)
+(use-package company
+ :hook (prog-mode . company-mode))
+```
+
+### Lockfile
+
+straight.el creates `straight/versions/default.el` with pinned versions:
+
+```elisp
+;; Example lockfile entry
+(("magit" . "abc123...")
+ ("company" . "def456..."))
+```
+
+Commit this file for reproducible installs.
+
+## Performance Optimization
+
+### Startup Time
+
+```elisp
+;; Measure startup time
+(add-hook 'emacs-startup-hook
+ (lambda ()
+ (message "Emacs loaded in %s with %d garbage collections."
+ (format "%.2f seconds"
+ (float-time
+ (time-subtract after-init-time before-init-time)))
+ gcs-done)))
+
+;; Lazy load packages
+(use-package markdown-mode
+ :defer t
+ :mode "\\.md\\'")
+
+(use-package yaml-mode
+ :defer t
+ :mode "\\.ya?ml\\'")
+
+;; Defer non-essential packages
+(use-package dashboard
+ :defer 1 ; Load 1 second after startup
+ :config
+ (dashboard-setup-startup-hook))
+```
+
+### Native Compilation
+
+Emacs 28+ with native compilation:
+
+```elisp
+;; Enable native compilation
+(when (and (fboundp 'native-comp-available-p)
+ (native-comp-available-p))
+ (setq native-comp-async-report-warnings-errors nil)
+ (setq native-comp-deferred-compilation t))
+```
+
+## Configuration Patterns
+
+### Theme
+
+```elisp
+(use-package modus-themes
+ :ensure nil ; Built-in since Emacs 28
+ :config
+ (setq modus-themes-bold-constructs t
+ modus-themes-italic-constructs t)
+ (load-theme 'modus-vivendi t))
+
+;; Or external theme
+(use-package doom-themes
+ :config
+ (load-theme 'doom-one t))
+```
+
+### Keybindings
+
+```elisp
+;; Global keybindings
+(global-set-key (kbd "C-c f") #'find-file)
+(global-set-key (kbd "C-c b") #'switch-to-buffer)
+
+;; With use-package
+(use-package ace-window
+ :bind ("M-o" . ace-window))
+
+;; Define custom keymap
+(defvar my-leader-map (make-sparse-keymap)
+ "Personal leader keymap.")
+
+(global-set-key (kbd "C-c m") my-leader-map)
+(define-key my-leader-map (kbd "f") #'find-file)
+(define-key my-leader-map (kbd "b") #'switch-to-buffer)
+```
+
+### Custom Functions
+
+```elisp
+;; In lisp/my-functions.el
+(defun my/open-config ()
+ "Open init.el."
+ (interactive)
+ (find-file (expand-file-name "init.el" user-emacs-directory)))
+
+(defun my/reload-config ()
+ "Reload init.el."
+ (interactive)
+ (load-file (expand-file-name "init.el" user-emacs-directory)))
+
+(global-set-key (kbd "C-c e c") #'my/open-config)
+(global-set-key (kbd "C-c e r") #'my/reload-config)
+
+;; Load custom functions
+(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
+(require 'my-functions)
+```
+
+## Debugging Configuration
+
+### Profile Startup
+
+```bash
+# Built-in profiler
+emacs --debug-init
+
+# Or use esup (Emacs Start Up Profiler)
+M-x package-install RET esup RET
+M-x esup
+```
+
+### use-package Debug
+
+```elisp
+;; Show what use-package does
+(setq use-package-verbose t)
+(setq use-package-compute-statistics t)
+
+;; View statistics
+M-x use-package-report
+```
+
+## Migration from Old Config
+
+### From require to use-package
+
+```elisp
+;; Old way
+(add-to-list 'load-path "~/.emacs.d/lisp/some-package")
+(require 'some-package)
+(setq some-package-variable value)
+(global-set-key (kbd "C-c s") #'some-package-command)
+
+;; New way
+(use-package some-package
+ :load-path "lisp/some-package"
+ :custom
+ (some-package-variable value)
+ :bind ("C-c s" . some-package-command))
+```
+
+## Best Practices
+
+1. **Use lexical binding**: `;;; -*- lexical-binding: t -*-`
+2. **Lazy load packages**: Use `:defer`, `:hook`, or `:mode`
+3. **Keep customizations separate**: Use `custom-file`
+4. **Organize by category**: Group related packages
+5. **Comment your config**: Explain non-obvious settings
+6. **Version control**: Keep `.emacs.d` in git
+7. **Measure startup time**: Keep it under 2 seconds
+8. **Use built-in features**: Prefer built-in over external packages
+9. **Pin critical packages**: Use straight.el for important configs
+10. **Test incrementally**: Add packages one at a time
+
+## Example Complete Configuration
+
+### Minimal Modern Config
+
+```elisp
+;;; init.el --- Minimal modern Emacs config -*- lexical-binding: t -*-
+
+;; Package setup
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
+(package-initialize)
+
+;; use-package (built-in Emacs 29+)
+(require 'use-package)
+(setq use-package-always-ensure t)
+
+;; UI improvements
+(setq inhibit-startup-screen t
+ initial-scratch-message nil
+ ring-bell-function 'ignore)
+(menu-bar-mode -1)
+(tool-bar-mode -1)
+(scroll-bar-mode -1)
+(show-paren-mode 1)
+(global-hl-line-mode 1)
+(global-display-line-numbers-mode 1)
+
+;; Editing
+(setq-default indent-tabs-mode nil
+ tab-width 4)
+(electric-pair-mode 1)
+(delete-selection-mode 1)
+(save-place-mode 1)
+(global-auto-revert-mode 1)
+
+;; Essential packages
+(use-package magit
+ :bind ("C-x g" . magit-status))
+
+(use-package vertico
+ :init (vertico-mode))
+
+(use-package which-key
+ :init (which-key-mode))
+
+;; Theme
+(use-package modus-themes
+ :ensure nil
+ :config
+ (load-theme 'modus-vivendi t))
+
+;;; init.el ends here
+```
+
+## Resources
+
+- [use-package Documentation](https://github.com/jwiegley/use-package)
+- [straight.el](https://github.com/radian-software/straight.el)
+- [Emacs Package Manager Comparison](https://www.reddit.com/r/emacs/wiki/packages)
+- [Sacha Chua's Emacs Config](https://sachachua.com/dotemacs/)
dots/.config/claude/skills/EmacsLisp/workflows/Debug.md
@@ -0,0 +1,507 @@
+# Debug Workflow
+
+Debug Emacs Lisp code using edebug, the debugger, and diagnostic tools.
+
+## edebug (Recommended)
+
+### Instrument Function
+
+```elisp
+;; Place cursor in function definition
+(defun my-function (arg)
+ "Example function."
+ (let ((result (* arg 2)))
+ (+ result 10)))
+
+;; Instrument for debugging
+C-u C-M-x ; or M-x edebug-defun
+```
+
+### Debug Controls
+
+| Key | Action |
+|-----|--------|
+| `SPC` | Step through (next form) |
+| `n` | Next (skip over function calls) |
+| `i` | Step into function |
+| `o` | Step out of function |
+| `g` | Go (continue execution) |
+| `b` | Set breakpoint |
+| `u` | Unset breakpoint |
+| `e` | Evaluate expression |
+| `q` | Quit debugging |
+| `?` | Show help |
+
+### Breakpoints
+
+```elisp
+(defun my-function (arg)
+ (let ((x (* arg 2)))
+ (edebug) ; Hard-coded breakpoint
+ (+ x 10)))
+
+;; Or set breakpoint interactively
+;; While stopped in edebug, press 'b' at any point
+```
+
+### Conditional Breakpoints
+
+```elisp
+(defun process-list (items)
+ (dolist (item items)
+ (when (edebug-break-when (> item 100)) ; Break if item > 100
+ (process-item item))))
+```
+
+### View Variables
+
+```elisp
+;; While in edebug:
+e ; Evaluate expression
+;; Type: my-var RET
+;; Shows value of my-var
+
+;; Or evaluate any expression
+e (+ 1 2) RET ; Shows 3
+```
+
+## debug (Built-in Debugger)
+
+### Enable Debugger
+
+```elisp
+;; Debug on error
+M-x toggle-debug-on-error
+
+;; Or in code
+(setq debug-on-error t)
+
+;; Debug on quit (C-g)
+(setq debug-on-quit t)
+```
+
+### Trigger Debugger
+
+```elisp
+(debug) ; Explicit breakpoint
+
+;; Or cause an error
+(error "Debug this")
+```
+
+### Debugger Buffer
+
+When debugger activates:
+
+```
+Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p nil)
+ +(nil 5)
+ my-function(nil)
+ eval((my-function nil) nil)
+ ...
+```
+
+Controls:
+- `c` - Continue
+- `d` - Step through
+- `e` - Evaluate expression
+- `q` - Quit
+- `r` - Return value
+- `b` - Set breakpoint
+
+## Diagnostic Tools
+
+### message
+
+```elisp
+(defun my-function (arg)
+ (message "arg: %S" arg) ; Log to *Messages*
+ (let ((result (* arg 2)))
+ (message "result: %S" result)
+ (+ result 10)))
+```
+
+### prin1 / princ
+
+```elisp
+(defun my-function (items)
+ (prin1 items) ; Print to current buffer
+ (terpri) ; Newline
+ ...)
+```
+
+### trace-function
+
+```elisp
+;; Enable tracing
+M-x trace-function RET my-function RET
+
+;; Run function
+(my-function 5)
+
+;; View trace output in *trace-output*
+;; Shows: arguments, return value, depth
+
+;; Disable
+M-x untrace-function RET my-function RET
+
+;; Trace all calls
+M-x trace-function-foreground RET my-function RET
+```
+
+Example trace output:
+```
+1 -> (my-function 5)
+1 <- my-function: 20
+```
+
+### benchmark
+
+```elisp
+(require 'benchmark)
+
+;; Time single call
+(benchmark-run 1
+ (my-expensive-function))
+;; => (0.523 0 0.0) ; seconds, GCs, GC time
+
+;; Time multiple calls
+(benchmark-run 1000
+ (my-function 10))
+
+;; With formatted output
+(benchmark-run-compiled 1000
+ (my-function 10))
+```
+
+### profiler
+
+```elisp
+;; Start CPU profiler
+M-x profiler-start RET cpu RET
+
+;; Run code to profile
+(dotimes (i 10000)
+ (my-function i))
+
+;; View report
+M-x profiler-report
+
+;; Stop profiling
+M-x profiler-stop
+```
+
+Profiler report shows:
+- Function call counts
+- Time spent in each function
+- Call tree
+
+## Common Debugging Patterns
+
+### Check Variable Value
+
+```elisp
+(defun my-function (arg)
+ (let ((result (expensive-calculation arg)))
+ ;; Check value
+ (unless (numberp result)
+ (error "Expected number, got: %S" result))
+ result))
+```
+
+### Assert
+
+```elisp
+(defun my-function (arg)
+ (cl-assert (numberp arg) t "ARG must be a number, got %S" arg)
+ (cl-assert (> arg 0) t "ARG must be positive, got %S" arg)
+ (* arg 2))
+```
+
+### Conditional Logging
+
+```elisp
+(defvar my-package-debug nil
+ "Enable debug logging when non-nil.")
+
+(defun my-package--debug (format-string &rest args)
+ "Log debug message if debugging is enabled."
+ (when my-package-debug
+ (apply #'message (concat "DEBUG: " format-string) args)))
+
+(defun my-function (arg)
+ (my-package--debug "Processing arg: %S" arg)
+ ...)
+```
+
+### Backtrace
+
+```elisp
+(defun my-function ()
+ ;; Print backtrace
+ (message "Backtrace:\n%s" (backtrace-to-string))
+ ...)
+```
+
+## Debugging Macros
+
+### macroexpand
+
+```elisp
+;; Expand macro once
+(macroexpand '(when condition body))
+;; => (if condition (progn body))
+
+;; Expand completely
+(macroexpand-all '(when condition (when other more)))
+
+;; Interactive
+M-x pp-macroexpand-last-sexp
+```
+
+### Example Macro Debugging
+
+```elisp
+(defmacro my-with-temp-buffer (&rest body)
+ `(with-temp-buffer
+ (message "Entering temp buffer")
+ ,@body
+ (message "Exiting temp buffer")))
+
+;; Check expansion
+(macroexpand '(my-with-temp-buffer
+ (insert "test")))
+```
+
+## Interactive Debugging
+
+### eval-expression
+
+```elisp
+M-: (my-function 5) RET
+;; Shows result in minibuffer
+```
+
+### ielm (Emacs Lisp REPL)
+
+```elisp
+M-x ielm
+
+ELISP> (setq x 10)
+10
+ELISP> (* x 2)
+20
+ELISP> (require 'my-package)
+t
+ELISP> (my-package-test-function)
+```
+
+### scratch Buffer
+
+```elisp
+;; In *scratch* buffer
+(defun test ()
+ (* 2 3))
+
+;; Evaluate
+C-x C-e ; At end of form
+;; => 6
+
+;; Evaluate and insert result
+C-u C-x C-e
+;; => (defun test () (* 2 3))6
+```
+
+## Debugging Strategies
+
+### Binary Search
+
+```elisp
+(defun complex-function (arg)
+ (let ((step1 (do-step-1 arg)))
+ (message "After step 1: %S" step1) ; Add checkpoints
+ (let ((step2 (do-step-2 step1)))
+ (message "After step 2: %S" step2)
+ (let ((step3 (do-step-3 step2)))
+ (message "After step 3: %S" step3)
+ step3))))
+```
+
+### Simplify
+
+```elisp
+;; Original complex function
+(defun complex-function (arg)
+ (complicated-logic arg))
+
+;; Simplified version for testing
+(defun complex-function (arg)
+ ;; (complicated-logic arg)
+ 42) ; Replace with simple value
+
+;; Gradually uncomment to find issue
+```
+
+### Isolate
+
+```elisp
+;; Extract problematic code
+(defun test-isolated ()
+ "Test just the problematic part."
+ (let ((test-input '(1 2 3)))
+ (problematic-function test-input)))
+
+;; Run in isolation
+(test-isolated)
+```
+
+## Debugging Hooks
+
+### Trace Hook Execution
+
+```elisp
+(defun trace-hook (hook-var)
+ "Trace execution of hooks in HOOK-VAR."
+ (dolist (func (symbol-value hook-var))
+ (trace-function func)))
+
+;; Example
+(trace-hook 'emacs-lisp-mode-hook)
+```
+
+### Debug Mode Activation
+
+```elisp
+(defun my-mode ()
+ "My mode with debugging."
+ (interactive)
+ (message "Activating my-mode")
+ (message "Hooks: %S" my-mode-hook)
+
+ ;; Wrap hook execution
+ (condition-case err
+ (run-hooks 'my-mode-hook)
+ (error
+ (message "Error in hook: %s" (error-message-string err)))))
+```
+
+## Performance Debugging
+
+### Time Function Calls
+
+```elisp
+(defun time-it (func &rest args)
+ "Time execution of FUNC with ARGS."
+ (let ((start (current-time)))
+ (apply func args)
+ (float-time (time-since start))))
+
+;; Usage
+(time-it #'my-expensive-function arg1 arg2)
+```
+
+### Memory Usage
+
+```elisp
+;; Before
+(garbage-collect)
+(let ((mem-before (memory-use-counts)))
+
+ ;; Run code
+ (my-function)
+
+ ;; After
+ (garbage-collect)
+ (let ((mem-after (memory-use-counts)))
+ (message "Memory used: %S"
+ (cl-mapcar #'- mem-after mem-before))))
+```
+
+## Debugging Buffer Issues
+
+### Inspect Buffer
+
+```elisp
+;; View buffer properties
+(buffer-local-variables)
+
+;; Check major mode
+major-mode
+
+;; Check buffer state
+(buffer-modified-p)
+(buffer-file-name)
+(point)
+(point-min)
+(point-max)
+```
+
+### Debugging Point Movement
+
+```elisp
+(defun my-function ()
+ (save-excursion ; Save point
+ (message "Point before: %d" (point))
+ (goto-char (point-min))
+ (message "Point during: %d" (point))
+ (some-operation)
+ (message "Point after: %d" (point))))
+```
+
+## Common Issues
+
+### Wrong Type Argument
+
+```elisp
+;; Error: (wrong-type-argument number-or-marker-p nil)
+
+;; Debug
+(defun my-function (arg)
+ (unless (numberp arg)
+ (error "Expected number, got: %S (type: %S)"
+ arg (type-of arg)))
+ (+ arg 5))
+```
+
+### Void Variable
+
+```elisp
+;; Error: (void-variable my-var)
+
+;; Check if bound
+(boundp 'my-var) ; => nil
+
+;; Fix
+(defvar my-var nil "Documentation")
+```
+
+### Void Function
+
+```elisp
+;; Error: (void-function my-func)
+
+;; Check if defined
+(fboundp 'my-func) ; => nil
+
+;; Check if it's a macro
+(macrop 'my-func)
+```
+
+## Best Practices
+
+1. **Use edebug**: Most powerful debugging tool
+2. **Add logging**: Strategic `message` calls
+3. **Write tests**: Find bugs early
+4. **Check types**: Validate arguments
+5. **Use assertions**: cl-assert for invariants
+6. **Profile first**: Find real bottlenecks
+7. **Simplify**: Break complex functions
+8. **Read backtraces**: Understand error source
+9. **Test incrementally**: Small changes
+10. **Document assumptions**: Why code should work
+
+## Resources
+
+- [edebug Manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Edebug.html)
+- [Debugging Manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Debugging.html)
+- [Profiler](https://www.gnu.org/software/emacs/manual/html_node/elisp/Profiling.html)
dots/.config/claude/skills/EmacsLisp/workflows/Document.md
@@ -0,0 +1,515 @@
+# Document Workflow
+
+Write comprehensive documentation for Emacs Lisp packages: docstrings, README, and Info manuals.
+
+## Docstrings
+
+### Function Docstrings
+
+```elisp
+(defun my-package-process-file (file &optional verbose callback)
+ "Process FILE and return the result.
+
+FILE should be a path to a readable file. Optional argument
+VERBOSE, when non-nil, enables progress messages. Optional
+argument CALLBACK is called with the result when processing
+completes.
+
+The function reads FILE, processes its contents, and returns
+a list of processed items. If FILE cannot be read, returns nil.
+
+Example usage:
+
+ (my-package-process-file \"input.txt\" t)
+ (my-package-process-file \"data.csv\" nil #'my-callback)
+
+Returns a list of the form (ITEM1 ITEM2 ...), or nil if FILE
+cannot be processed.
+
+Signals an error if FILE does not exist or is not readable.
+
+See also `my-package-process-directory'."
+ ...)
+```
+
+### Docstring Guidelines
+
+1. **First line**: Complete sentence, under 80 characters
+2. **Argument names**: UPPERCASE when mentioned
+3. **Blank line**: After first sentence (for summary)
+4. **Return value**: Document what function returns
+5. **Signals**: Document errors that may be raised
+6. **Examples**: Show typical usage
+7. **See also**: Reference related functions
+
+### Variable Docstrings
+
+```elisp
+(defvar my-package-timeout 30
+ "Timeout in seconds for network operations.
+
+This value controls how long to wait before giving up on
+network requests. A value of 0 means no timeout.
+
+Changing this value affects all future operations but does
+not impact currently running operations.")
+
+(defvar my-package--internal-state nil
+ "Internal state for my-package.
+This variable should not be modified directly.")
+```
+
+### Custom Variables
+
+```elisp
+(defcustom my-package-auto-save t
+ "Whether to automatically save after operations.
+
+When non-nil, files are automatically saved after processing.
+When nil, you must manually save changes.
+
+You can also set this locally per buffer using:
+
+ (setq-local my-package-auto-save nil)"
+ :type 'boolean
+ :safe #'booleanp
+ :group 'my-package)
+
+(defcustom my-package-backends '(backend1 backend2)
+ "List of backends to use for processing.
+
+Each backend should be a symbol recognized by my-package.
+Backends are tried in order until one succeeds.
+
+Available backends:
+ backend1 - Fast but limited
+ backend2 - Slower but more features
+ backend3 - Requires external program"
+ :type '(repeat (choice (const :tag "Backend 1" backend1)
+ (const :tag "Backend 2" backend2)
+ (const :tag "Backend 3" backend3)))
+ :group 'my-package)
+```
+
+## Package Commentary
+
+```elisp
+;;; my-package.el --- Brief description -*- lexical-binding: t -*-
+
+;; [Headers...]
+
+;;; Commentary:
+
+;; My Package provides tools for processing data files.
+;;
+;; Features:
+;;
+;; - Process multiple file formats
+;; - Batch processing support
+;; - Customizable backends
+;; - Integration with other tools
+;;
+;; Basic usage:
+;;
+;; (require 'my-package)
+;; (my-package-enable)
+;; (my-package-process-file "data.csv")
+;;
+;; Configuration:
+;;
+;; (setq my-package-auto-save nil)
+;; (setq my-package-timeout 60)
+;;
+;; For more information, see the Info manual:
+;;
+;; C-h i m My Package RET
+;;
+;; Or visit the project page:
+;;
+;; https://github.com/user/my-package
+
+;;; Code:
+```
+
+## README.md
+
+### Complete README Structure
+
+```markdown
+# My Package
+
+[](https://melpa.org/#/my-package)
+[](https://github.com/user/my-package/actions)
+
+Brief one-sentence description of what the package does.
+
+## Features
+
+- Feature 1
+- Feature 2
+- Feature 3
+
+## Installation
+
+### MELPA
+
+```elisp
+(use-package my-package
+ :ensure t
+ :config
+ (my-package-enable))
+```
+
+### Manual
+
+Clone this repository:
+
+```bash
+git clone https://github.com/user/my-package.git
+```
+
+Add to your `init.el`:
+
+```elisp
+(add-to-list 'load-path "/path/to/my-package")
+(require 'my-package)
+```
+
+## Usage
+
+### Basic Usage
+
+```elisp
+;; Enable globally
+(my-package-mode 1)
+
+;; Or in specific buffers
+(add-hook 'text-mode-hook #'my-package-mode)
+```
+
+### Commands
+
+| Command | Description | Keybinding |
+|---------|-------------|------------|
+| `my-package-enable` | Enable the package | - |
+| `my-package-process` | Process current buffer | `C-c m p` |
+| `my-package-export` | Export to file | `C-c m e` |
+
+### Configuration
+
+```elisp
+;; Set timeout
+(setq my-package-timeout 60)
+
+;; Choose backend
+(setq my-package-backend 'backend2)
+
+;; Disable auto-save
+(setq my-package-auto-save nil)
+```
+
+## Customization
+
+All options can be customized via:
+
+```
+M-x customize-group RET my-package RET
+```
+
+Key options:
+
+- `my-package-timeout` - Operation timeout in seconds
+- `my-package-auto-save` - Automatically save after processing
+- `my-package-backend` - Which backend to use
+
+## Examples
+
+### Example 1: Process File
+
+```elisp
+(my-package-process-file "data.csv" t)
+```
+
+### Example 2: Batch Processing
+
+```elisp
+(my-package-process-directory "~/data/" "\\.csv$")
+```
+
+## Troubleshooting
+
+### Package doesn't load
+
+Make sure the package is in your `load-path`:
+
+```elisp
+(add-to-list 'load-path "/path/to/my-package")
+```
+
+### Command not found
+
+Ensure the package is loaded:
+
+```elisp
+(require 'my-package)
+```
+
+## Contributing
+
+Contributions are welcome! Please:
+
+1. Fork the repository
+2. Create a feature branch
+3. Add tests for new features
+4. Ensure all tests pass
+5. Submit a pull request
+
+## License
+
+GPL-3.0-or-later
+
+## Acknowledgments
+
+- Thanks to contributor1
+- Thanks to contributor2
+```
+
+## Info Manual
+
+### Create Manual
+
+**doc/my-package.texi**:
+
+```texinfo
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename my-package.info
+@settitle My Package Manual
+@documentencoding UTF-8
+@c %**end of header
+
+@copying
+This manual is for My Package version 1.0.
+
+Copyright @copyright{} 2025 Your Name
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3
+or any later version published by the Free Software Foundation.
+@end quotation
+@end copying
+
+@titlepage
+@title My Package Manual
+@subtitle For version 1.0
+@author Your Name
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@contents
+
+@node Top
+@top My Package
+
+My Package provides tools for processing data files.
+
+@menu
+* Introduction:: What is My Package?
+* Installation:: Installing the package
+* Usage:: How to use the package
+* Configuration:: Customization options
+* Index:: Complete index
+@end menu
+
+@node Introduction
+@chapter Introduction
+
+My Package helps you process data files efficiently.
+
+@node Installation
+@chapter Installation
+
+Install from MELPA:
+
+@lisp
+(use-package my-package
+ :ensure t)
+@end lisp
+
+@node Usage
+@chapter Usage
+
+@section Basic Usage
+
+Enable the package:
+
+@lisp
+(my-package-enable)
+@end lisp
+
+@section Commands
+
+@table @code
+@item my-package-enable
+Enable the package globally.
+
+@item my-package-process-file
+Process a single file.
+@end table
+
+@node Configuration
+@chapter Configuration
+
+@defvar my-package-timeout
+Timeout in seconds for operations.
+@end defvar
+
+@defvar my-package-auto-save
+Whether to auto-save after processing.
+@end defvar
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
+```
+
+### Build Info Manual
+
+```bash
+# Generate info file
+makeinfo doc/my-package.texi -o my-package.info
+
+# View
+info -f my-package.info
+
+# Install system-wide
+sudo install-info my-package.info /usr/share/info/dir
+```
+
+### Include in Package
+
+```elisp
+;; In Eask
+(package-file "my-package.el")
+(files "my-package.el" "my-package-utils.el" "my-package.info")
+```
+
+## CHANGELOG.md
+
+```markdown
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+- New feature in development
+
+## [1.2.0] - 2025-01-15
+
+### Added
+- New command `my-package-export` for exporting data
+- Support for CSV format
+- Interactive completion for file selection
+
+### Changed
+- Improved performance of file processing (30% faster)
+- Updated documentation with more examples
+- Refactored backend system for extensibility
+
+### Deprecated
+- `my-package-old-function` - Use `my-package-new-function` instead
+
+### Removed
+- Removed support for deprecated format X
+
+### Fixed
+- Fixed bug in error handling (#42)
+- Fixed memory leak in batch processing (#45)
+- Corrected documentation typo (#48)
+
+### Security
+- Fixed potential security issue with file paths
+
+## [1.1.0] - 2025-01-01
+
+### Added
+- Initial public release
+- Basic file processing
+- Customization options
+
+## [1.0.0] - 2024-12-15
+
+### Added
+- Initial development version
+```
+
+## Documentation Tools
+
+### checkdoc
+
+```elisp
+;; Check docstrings
+M-x checkdoc
+
+;; Check current buffer
+M-x checkdoc-current-buffer
+
+;; Fix automatically
+M-x checkdoc-eval-current-buffer
+```
+
+### package-lint
+
+```bash
+# Check documentation
+eask lint checkdoc
+```
+
+## Best Practices
+
+### Docstrings
+
+1. **Complete sentences**: Start with capital, end with period
+2. **First line summary**: Complete thought, under 80 chars
+3. **Document arguments**: Use UPPERCASE for arg names
+4. **Document return**: What does function return?
+5. **Document signals**: What errors can occur?
+6. **Examples**: Show typical usage
+7. **Cross-references**: Link to related functions
+
+### README
+
+1. **Clear title**: What is the package?
+2. **Installation**: Simple, copy-paste instructions
+3. **Usage examples**: Show common use cases
+4. **Configuration**: List key options
+5. **Screenshots**: If UI-heavy (optional)
+6. **Badges**: MELPA, CI status
+7. **Contributing**: How to help
+8. **License**: Clear license information
+
+### Info Manual
+
+1. **Comprehensive**: More detail than README
+2. **Organized**: Logical chapter structure
+3. **Examples**: Lots of code examples
+4. **Index**: Complete index for searching
+5. **Cross-references**: Link related sections
+
+## Resources
+
+- [Docstring Tips](https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html)
+- [Texinfo Manual](https://www.gnu.org/software/texinfo/manual/texinfo/)
+- [Keep a Changelog](https://keepachangelog.com/)
+- [README Template](https://github.com/othneildrew/Best-README-Template)
dots/.config/claude/skills/EmacsLisp/workflows/Lint.md
@@ -0,0 +1,479 @@
+# Lint Workflow
+
+Check code quality, style, and MELPA compliance using package-lint, checkdoc, and byte-compilation.
+
+## Linting Tools
+
+| Tool | Purpose | When to Use |
+|------|---------|-------------|
+| **package-lint** | MELPA compliance | Before publishing |
+| **checkdoc** | Docstring quality | Always |
+| **byte-compile** | Code correctness | Always |
+| **elisp-lint** | Comprehensive linting | CI/CD |
+| **flycheck** | Real-time linting | Development |
+
+## package-lint (MELPA Compliance)
+
+### Installation
+
+```bash
+# With Eask
+eask install-deps --dev
+
+# Or manually
+M-x package-install RET package-lint RET
+```
+
+### Run
+
+```elisp
+;; Interactive
+M-x package-lint-current-buffer
+
+;; Batch mode
+emacs -batch -l package-lint.el -f package-lint-batch-and-exit my-package.el
+
+;; With Eask
+eask lint package
+```
+
+### Common Issues
+
+#### Missing Package Headers
+
+```elisp
+;; Bad - missing headers
+;;; my-package.el --- Description
+
+;; Good - all required headers
+;;; my-package.el --- Description -*- lexical-binding: t -*-
+;; Author: Name <email>
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: tools
+;; URL: https://github.com/user/repo
+```
+
+#### Package-Requires Format
+
+```elisp
+;; Bad - wrong format
+;; Package-Requires: (emacs "29.1")
+
+;; Good - list of lists
+;; Package-Requires: ((emacs "29.1"))
+
+;; With dependencies
+;; Package-Requires: ((emacs "29.1") (dash "2.19"))
+```
+
+#### Symbol Naming
+
+```elisp
+;; Bad - no package prefix
+(defun enable-feature ()
+ ...)
+
+;; Good - consistent prefix
+(defun my-package-enable-feature ()
+ ...)
+
+;; Bad - inconsistent prefix
+(defun my-pkg-enable () ; Different from package name
+ ...)
+
+;; Good - matches package name
+(defun my-package-enable ()
+ ...)
+```
+
+## checkdoc (Docstring Quality)
+
+### Run
+
+```elisp
+;; Interactive
+M-x checkdoc
+
+;; Current buffer
+M-x checkdoc-current-buffer
+
+;; Batch mode
+emacs -batch -l checkdoc -f checkdoc-file my-package.el
+
+;; With Eask
+eask lint checkdoc
+```
+
+### Docstring Rules
+
+#### Functions
+
+```elisp
+;; Bad - incomplete docstring
+(defun my-package-process (file)
+ "Process file."
+ ...)
+
+;; Good - complete documentation
+(defun my-package-process (file &optional verbose)
+ "Process FILE and return results.
+
+If VERBOSE is non-nil, print progress messages.
+
+FILE should be a readable file path. Returns a list of
+processed items, or nil if FILE cannot be read.
+
+Signals an error if FILE does not exist."
+ ...)
+```
+
+#### Variables
+
+```elisp
+;; Bad
+(defvar my-package-timeout 30)
+
+;; Good
+(defvar my-package-timeout 30
+ "Timeout in seconds for network operations.")
+```
+
+#### Customizable Variables
+
+```elisp
+;; Good
+(defcustom my-package-enable-feature t
+ "Whether to enable the special feature.
+
+When non-nil, the package will automatically enable the
+feature when activated."
+ :type 'boolean
+ :group 'my-package)
+```
+
+### Common Docstring Issues
+
+#### Capitalization
+
+```elisp
+;; Bad - doesn't start with capital
+(defun my-func ()
+ "process the data."
+ ...)
+
+;; Good
+(defun my-func ()
+ "Process the data."
+ ...)
+```
+
+#### Period
+
+```elisp
+;; Bad - no period
+(defun my-func ()
+ "Process the data"
+ ...)
+
+;; Good
+(defun my-func ()
+ "Process the data."
+ ...)
+```
+
+#### Argument Documentation
+
+```elisp
+;; Bad - mentions args in lowercase
+(defun my-func (arg1 arg2)
+ "Process arg1 and arg2."
+ ...)
+
+;; Good - uppercase for arguments
+(defun my-func (arg1 arg2)
+ "Process ARG1 and ARG2."
+ ...)
+```
+
+## Byte Compilation
+
+### Compile
+
+```bash
+# Single file
+emacs -batch -f batch-byte-compile my-package.el
+
+# All .el files
+emacs -batch -f batch-byte-compile *.el
+
+# With Eask
+eask compile
+```
+
+### Common Warnings
+
+#### Undefined Functions
+
+```elisp
+;; Warning: function `some-func' is not known to be defined
+
+;; Fix 1: Require the package
+(require 'some-package)
+
+;; Fix 2: Declare function
+(declare-function some-func "some-package" (arg1 arg2))
+
+;; Fix 3: Suppress if intentional
+(with-no-warnings
+ (some-func args))
+```
+
+#### Unused Variables
+
+```elisp
+;; Warning: Unused lexical variable `unused'
+
+;; Fix: Use underscore prefix
+(defun my-func (_unused arg)
+ (do-something arg))
+```
+
+#### Free Variables
+
+```elisp
+;; Warning: reference to free variable `undefined-var'
+
+;; Fix: Declare or define
+(defvar undefined-var nil
+ "Documentation for the variable.")
+```
+
+## elisp-lint (Comprehensive)
+
+### Installation
+
+```elisp
+;; In Eask
+(development
+ (depends-on "elisp-lint"))
+```
+
+### Run
+
+```bash
+# With Eask
+eask lint elisp-lint
+
+# Direct
+elisp-lint my-package.el
+```
+
+### Configure
+
+```elisp
+;; .elisp-lint.yml (if using directly)
+```
+
+elisp-lint includes:
+- checkdoc
+- package-lint
+- byte-compile checks
+- indentation
+- trailing whitespace
+
+## Flycheck (Real-time Linting)
+
+### Setup
+
+```elisp
+(use-package flycheck
+ :ensure t
+ :init (global-flycheck-mode)
+ :config
+ (setq flycheck-emacs-lisp-load-path 'inherit))
+
+;; Add checkers
+(use-package flycheck-package
+ :ensure t
+ :after flycheck
+ :config
+ (flycheck-package-setup))
+```
+
+### Checkers
+
+- `emacs-lisp` - Byte compilation
+- `emacs-lisp-checkdoc` - Docstrings
+- `emacs-lisp-package` - Package headers
+
+## Eask Linting
+
+### Eask File
+
+```elisp
+(package "my-package" "0.1.0" "Description")
+
+(script "lint" "eask lint package checkdoc")
+(script "lint:all" "eask lint package checkdoc elisp-lint")
+
+(development
+ (depends-on "package-lint")
+ (depends-on "elisp-lint"))
+```
+
+### Run
+
+```bash
+# Run configured lint script
+eask run lint
+
+# Individual linters
+eask lint package
+eask lint checkdoc
+eask lint elisp-lint
+
+# All together
+eask lint package checkdoc elisp-lint
+```
+
+## CI/CD Linting
+
+### GitHub Actions
+
+```yaml
+name: Lint
+
+on: [push, pull_request]
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: jcs090218/setup-emacs@master
+ with:
+ version: '29.2'
+
+ - uses: emacs-eask/setup-eask@master
+
+ - name: Install dependencies
+ run: eask install-deps --dev
+
+ - name: Lint package
+ run: eask lint package
+
+ - name: Check documentation
+ run: eask lint checkdoc
+
+ - name: Byte compile
+ run: eask compile
+
+ - name: Comprehensive lint
+ run: eask lint elisp-lint
+```
+
+## Fix Common Issues
+
+### Indentation
+
+```bash
+# Auto-indent file
+emacs -batch my-package.el \
+ --eval '(indent-region (point-min) (point-max))' \
+ -f save-buffer
+
+# Or in Emacs
+M-x mark-whole-buffer
+M-x indent-region
+```
+
+### Trailing Whitespace
+
+```bash
+# Remove trailing whitespace
+emacs -batch my-package.el \
+ --eval '(delete-trailing-whitespace)' \
+ -f save-buffer
+
+# Or in Emacs
+M-x delete-trailing-whitespace
+```
+
+### Auto-format
+
+```elisp
+;; Auto-remove trailing whitespace on save
+(add-hook 'before-save-hook #'delete-trailing-whitespace)
+
+;; Auto-indent on save
+(add-hook 'emacs-lisp-mode-hook
+ (lambda ()
+ (add-hook 'before-save-hook
+ (lambda ()
+ (when (eq major-mode 'emacs-lisp-mode)
+ (indent-region (point-min) (point-max))))
+ nil t)))
+```
+
+## Pre-commit Hook
+
+**.git/hooks/pre-commit**:
+
+```bash
+#!/bin/bash
+
+echo "Running lint checks..."
+
+# Check if eask is available
+if command -v eask &> /dev/null; then
+ eask lint package checkdoc || exit 1
+ eask compile || exit 1
+else
+ echo "Eask not found, skipping lint"
+fi
+
+exit 0
+```
+
+Make executable:
+```bash
+chmod +x .git/hooks/pre-commit
+```
+
+## Best Practices
+
+1. **Lint before committing**: Catch issues early
+2. **Fix all warnings**: Don't ignore byte-compile warnings
+3. **Complete docstrings**: Document all public functions
+4. **Consistent naming**: Use package prefix everywhere
+5. **CI integration**: Automate linting in CI
+6. **Use lexical binding**: Always `;;; -*- lexical-binding: t -*-`
+7. **Check MELPA compliance**: Use package-lint
+8. **Clean code**: No trailing whitespace
+9. **Proper indentation**: Use Emacs auto-indent
+10. **Declare dependencies**: List all Package-Requires
+
+## Quick Checklist
+
+Before publishing:
+
+- [ ] `eask lint package` passes
+- [ ] `eask lint checkdoc` passes
+- [ ] `eask compile` completes without warnings
+- [ ] All functions have docstrings
+- [ ] All variables have docstrings
+- [ ] Package headers complete and correct
+- [ ] Lexical binding enabled
+- [ ] All symbols properly prefixed
+- [ ] No trailing whitespace
+- [ ] Proper indentation
+- [ ] Tests pass
+
+## Resources
+
+- [package-lint](https://github.com/purcell/package-lint)
+- [checkdoc Manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html)
+- [Flycheck](https://www.flycheck.org/)
+- [elisp-lint](https://github.com/gonewest818/elisp-lint)
dots/.config/claude/skills/EmacsLisp/workflows/Package.md
@@ -0,0 +1,568 @@
+# Package Workflow
+
+Create well-structured Emacs Lisp packages following modern conventions and MELPA requirements.
+
+## Package Types
+
+| Type | Description | Example |
+|------|-------------|---------|
+| **Single-file** | One `.el` file | simple-mode.el |
+| **Multi-file** | Multiple `.el` files | magit (magit.el, magit-*.el) |
+| **With dependencies** | Requires other packages | Uses Package-Requires |
+
+## Creating a Package
+
+### Step 1: Initialize with Eask
+
+```bash
+# Create package directory
+mkdir my-package
+cd my-package
+
+# Initialize Eask project
+eask init
+
+# This creates:
+# - Eask file
+# - my-package.el (with template)
+# - .gitignore
+```
+
+### Step 2: Package File Structure
+
+**my-package.el** (main file):
+
+```elisp
+;;; my-package.el --- Brief description -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Your Name
+
+;; Author: Your Name <your.email@example.com>
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: convenience, tools
+;; URL: https://github.com/yourusername/my-package
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Longer description of what this package does.
+;;
+;; Usage:
+;;
+;; (require 'my-package)
+;; (my-package-enable)
+;;
+;; Customization:
+;;
+;; (setq my-package-option value)
+
+;;; Code:
+
+(require 'cl-lib) ; If using cl-lib functions
+
+(defgroup my-package nil
+ "Customization group for my-package."
+ :group 'tools
+ :prefix "my-package-"
+ :link '(url-link "https://github.com/yourusername/my-package"))
+
+(defcustom my-package-enable-feature t
+ "Whether to enable the feature."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'my-package)
+
+;;;###autoload
+(defun my-package-enable ()
+ "Enable my-package."
+ (interactive)
+ (my-package-mode 1)
+ (message "My Package enabled"))
+
+(defvar my-package-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c m t") #'my-package-toggle)
+ map)
+ "Keymap for `my-package-mode'.")
+
+;;;###autoload
+(define-minor-mode my-package-mode
+ "Minor mode for my-package."
+ :lighter " MyPkg"
+ :keymap my-package-mode-map
+ :global t
+ :group 'my-package
+ (if my-package-mode
+ (my-package--enable)
+ (my-package--disable)))
+
+(defun my-package--enable ()
+ "Internal function to enable my-package."
+ ;; Setup code here
+ )
+
+(defun my-package--disable ()
+ "Internal function to disable my-package."
+ ;; Cleanup code here
+ )
+
+(provide 'my-package)
+;;; my-package.el ends here
+```
+
+### Step 3: Eask Configuration
+
+**Eask** file:
+
+```elisp
+(package "my-package"
+ "0.1.0"
+ "Brief description of my package")
+
+(website-url "https://github.com/yourusername/my-package")
+(keywords "convenience" "tools")
+
+(package-file "my-package.el")
+
+(script "test" "echo \"Run tests..\" && eask test ert")
+(script "lint" "echo \"Linting..\" && eask lint package checkdoc")
+(script "ci" "eask install-deps && eask compile && eask test && eask lint")
+
+(source "gnu")
+(source "melpa")
+
+(depends-on "emacs" "29.1")
+;; Add package dependencies here
+;; (depends-on "dash")
+
+(development
+ (depends-on "ert-runner")
+ (depends-on "package-lint"))
+```
+
+### Step 4: Tests
+
+**my-package-test.el**:
+
+```elisp
+;;; my-package-test.el --- Tests for my-package -*- lexical-binding: t -*-
+
+(require 'ert)
+(require 'my-package)
+
+(ert-deftest my-package-test-enable ()
+ "Test that enabling works."
+ (my-package-mode 1)
+ (should my-package-mode)
+ (my-package-mode -1)
+ (should-not my-package-mode))
+
+(ert-deftest my-package-test-function ()
+ "Test main functionality."
+ ;; Your tests here
+ (should (functionp 'my-package-enable)))
+
+(provide 'my-package-test)
+;;; my-package-test.el ends here
+```
+
+### Step 5: README.md
+
+```markdown
+# My Package
+
+Brief description of what your package does.
+
+## Installation
+
+### MELPA
+
+```elisp
+(use-package my-package
+ :ensure t)
+```
+
+### Manual
+
+Clone this repository and add to your `load-path`:
+
+```elisp
+(add-to-list 'load-path "/path/to/my-package")
+(require 'my-package)
+```
+
+## Usage
+
+```elisp
+;; Enable my-package
+(my-package-enable)
+
+;; Or use minor mode
+(my-package-mode 1)
+```
+
+## Configuration
+
+```elisp
+(setq my-package-enable-feature nil)
+```
+
+## License
+
+GPL-3.0-or-later
+```
+
+## Multi-file Package
+
+For larger packages with multiple files:
+
+### Structure
+
+```
+my-package/
+βββ my-package.el # Main entry point
+βββ my-package-core.el # Core functionality
+βββ my-package-ui.el # UI components
+βββ my-package-utils.el # Utilities
+βββ test/
+β βββ my-package-test.el
+β βββ my-package-core-test.el
+βββ Eask
+βββ README.md
+```
+
+### Main File (my-package.el)
+
+```elisp
+;;; my-package.el --- Main entry point -*- lexical-binding: t -*-
+
+;; [Headers as before]
+
+;;; Code:
+
+(require 'my-package-core)
+(require 'my-package-ui)
+(require 'my-package-utils)
+
+;;;###autoload
+(defun my-package-setup ()
+ "Set up my-package."
+ (interactive)
+ (my-package-core-initialize)
+ (my-package-ui-setup))
+
+(provide 'my-package)
+;;; my-package.el ends here
+```
+
+### Submodule (my-package-core.el)
+
+```elisp
+;;; my-package-core.el --- Core functionality -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Your Name
+;; Author: Your Name <your.email@example.com>
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Core functionality for my-package.
+
+;;; Code:
+
+(defun my-package-core-initialize ()
+ "Initialize core functionality."
+ ;; Implementation
+ )
+
+(provide 'my-package-core)
+;;; my-package-core.el ends here
+```
+
+## Package Headers Reference
+
+### Required Headers
+
+```elisp
+;; Author: Your Name <email@example.com>
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: convenience tools
+;; URL: https://github.com/user/repo
+```
+
+### Optional Headers
+
+```elisp
+;; Maintainer: Different Person <maintainer@example.com>
+;; Created: 2025-01-01
+;; SPDX-License-Identifier: GPL-3.0-or-later
+;; Homepage: https://mypackage.example.com
+```
+
+### Keywords
+
+Standard keywords (for `M-x finder-by-keyword`):
+
+- `abbrev` - Abbreviation handling
+- `calendar` - Calendar and diary
+- `comm` - Communications
+- `convenience` - Convenience features
+- `data` - Data manipulation
+- `docs` - Documentation
+- `emulations` - Emulations of other editors
+- `extensions` - Emacs Lisp language extensions
+- `faces` - Fonts and faces
+- `files` - File handling
+- `frames` - Frame manipulation
+- `games` - Games
+- `hardware` - Hardware support
+- `help` - Help and documentation
+- `hypermedia` - Hypermedia
+- `i18n` - Internationalization
+- `internal` - Internal use
+- `languages` - Programming languages
+- `lisp` - Lisp support
+- `local` - Local customization
+- `maint` - Maintenance tools
+- `mail` - Mail handling
+- `matching` - Pattern matching
+- `mouse` - Mouse support
+- `multimedia` - Multimedia
+- `news` - News handling
+- `outlines` - Outline mode
+- `processes` - Process control
+- `terminals` - Terminal emulation
+- `tex` - TeX and friends
+- `tools` - Programming tools
+- `unix` - Unix features
+- `vc` - Version control
+- `wp` - Word processing
+
+## Common Patterns
+
+### Customization Group
+
+```elisp
+(defgroup my-package nil
+ "Customization for my-package."
+ :group 'tools
+ :prefix "my-package-"
+ :link '(url-link :tag "GitHub" "https://github.com/user/my-package"))
+
+(defcustom my-package-directory "~/.my-package"
+ "Directory for my-package data."
+ :type 'directory
+ :group 'my-package)
+
+(defcustom my-package-backends '(backend1 backend2)
+ "List of backends to use."
+ :type '(repeat (choice (const :tag "Backend 1" backend1)
+ (const :tag "Backend 2" backend2)))
+ :group 'my-package)
+```
+
+### Faces
+
+```elisp
+(defface my-package-highlight
+ '((t :inherit highlight))
+ "Face for highlighted items."
+ :group 'my-package)
+
+(defface my-package-error
+ '((t :inherit error))
+ "Face for errors."
+ :group 'my-package)
+```
+
+### Hooks
+
+```elisp
+(defvar my-package-mode-hook nil
+ "Hook run after `my-package-mode' is enabled.")
+
+(defvar my-package-before-process-hook nil
+ "Hook run before processing.")
+
+;; Run hooks
+(run-hooks 'my-package-mode-hook)
+```
+
+### Autoloads
+
+```elisp
+;;;###autoload
+(defun my-package-enable ()
+ "Enable my-package globally."
+ (interactive)
+ (my-package-mode 1))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.mypkg\\'" . my-package-mode))
+```
+
+## Development Workflow
+
+### 1. Install Dependencies
+
+```bash
+eask install-deps
+```
+
+### 2. Byte Compile
+
+```bash
+eask compile
+```
+
+### 3. Run Tests
+
+```bash
+eask test ert
+```
+
+### 4. Lint
+
+```bash
+eask lint package
+eask lint checkdoc
+```
+
+### 5. Package
+
+```bash
+eask package
+```
+
+Output: `dist/my-package-0.1.0.tar`
+
+## CI/CD with GitHub Actions
+
+**.github/workflows/test.yml**:
+
+```yaml
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ emacs-version: ['29.1', '29.2', 'snapshot']
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: jcs090218/setup-emacs@master
+ with:
+ version: ${{ matrix.emacs-version }}
+
+ - uses: emacs-eask/setup-eask@master
+ with:
+ version: 'snapshot'
+
+ - name: Install dependencies
+ run: eask install-deps
+
+ - name: Byte compile
+ run: eask compile
+
+ - name: Run tests
+ run: eask test ert
+
+ - name: Lint
+ run: |
+ eask lint package
+ eask lint checkdoc
+```
+
+## Versioning
+
+Follow [Semantic Versioning](https://semver.org/):
+
+- **MAJOR**: Incompatible API changes
+- **MINOR**: Add functionality (backwards-compatible)
+- **PATCH**: Bug fixes (backwards-compatible)
+
+Example: `1.2.3` β MAJOR.MINOR.PATCH
+
+### Update Version
+
+```bash
+# In my-package.el header
+;; Version: 1.0.0
+
+# In Eask
+(package "my-package" "1.0.0" "Description")
+
+# Create git tag
+git tag -a v1.0.0 -m "Release version 1.0.0"
+git push origin v1.0.0
+```
+
+## Common Issues
+
+### Package-Requires Format
+
+```elisp
+;; Correct
+;; Package-Requires: ((emacs "29.1") (dash "2.19.1"))
+
+;; Wrong - no spaces
+;; Package-Requires: ((emacs "29.1")(dash "2.19.1"))
+
+;; Wrong - single dep not in list
+;; Package-Requires: (emacs "29.1")
+```
+
+### Lexical Binding
+
+Always use:
+
+```elisp
+;;; my-package.el --- Description -*- lexical-binding: t -*-
+```
+
+### Provide Statement
+
+Must match filename:
+
+```elisp
+;; File: my-package.el
+(provide 'my-package) ; Correct
+
+;; File: my-package.el
+(provide 'my-pkg) ; Wrong!
+```
+
+## Best Practices
+
+1. **Use lexical binding**: `;;; -*- lexical-binding: t -*-`
+2. **Follow naming conventions**: All symbols prefixed with package name
+3. **Complete headers**: All required headers present
+4. **Autoloads**: Mark entry points with `;;;###autoload`
+5. **Tests**: Write tests for all functionality
+6. **Documentation**: Complete docstrings for all public functions
+7. **Version control**: Use git, tag releases
+8. **CI**: Set up automated testing
+9. **CHANGELOG**: Maintain version history
+10. **License**: Include GPL-compatible license
+
+## Resources
+
+- [Emacs Package Development](https://www.gnu.org/software/emacs/manual/html_node/elisp/Packaging.html)
+- [MELPA Contributing Guide](https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org)
+- [Eask Documentation](https://emacs-eask.github.io/)
+- [Package Lint](https://github.com/purcell/package-lint)
dots/.config/claude/skills/EmacsLisp/workflows/Publish.md
@@ -0,0 +1,450 @@
+# Publish Workflow
+
+Publish Emacs Lisp packages to MELPA, GNU ELPA, or NonGNU ELPA.
+
+## Package Archives
+
+| Archive | Requirements | Review | Target Audience |
+|---------|--------------|--------|-----------------|
+| **MELPA** | Public Git repo | Community review | Most packages |
+| **MELPA Stable** | Git tags | Same as MELPA | Stable releases |
+| **GNU ELPA** | Copyright assignment | FSF review | GNU project packages |
+| **NonGNU ELPA** | Free license | FSF review | Non-GNU free software |
+
+## MELPA (Recommended)
+
+### Requirements
+
+1. **Public Git repository**: GitHub, GitLab, SourceHut, etc.
+2. **Package quality**:
+ - Passes `package-lint`
+ - Passes `checkdoc`
+ - Byte-compiles without warnings
+3. **Documentation**: README with usage instructions
+4. **License**: Free software license (GPL recommended)
+5. **Tests**: Recommended but not required
+
+### Step 1: Prepare Package
+
+```bash
+# Lint package
+eask lint package
+
+# Check documentation
+eask lint checkdoc
+
+# Byte compile
+eask compile
+
+# Run tests
+eask test ert
+
+# All checks pass? Continue!
+```
+
+### Step 2: Create MELPA Recipe
+
+Fork MELPA repository:
+```bash
+git clone https://github.com/melpa/melpa.git
+cd melpa
+git checkout -b add-my-package
+```
+
+Create recipe file `recipes/my-package`:
+
+```elisp
+(my-package :fetcher github
+ :repo "username/my-package")
+```
+
+**Recipe Options**:
+
+```elisp
+;; GitHub
+(my-package :fetcher github
+ :repo "username/my-package"
+ :files ("*.el" "dir/*.el"))
+
+;; GitLab
+(my-package :fetcher gitlab
+ :repo "username/my-package")
+
+;; SourceHut
+(my-package :fetcher sourcehut
+ :repo "username/my-package")
+
+;; Git (generic)
+(my-package :fetcher git
+ :url "https://example.com/my-package.git"
+ :branch "main")
+
+;; With specific files
+(my-package :fetcher github
+ :repo "username/my-package"
+ :files ("*.el" "lisp/*.el"
+ (:exclude "lisp/test-*.el")))
+
+;; Multi-file package
+(my-package :fetcher github
+ :repo "username/my-package"
+ :files (:defaults "extensions/*.el"))
+```
+
+### Step 3: Test Recipe Locally
+
+```bash
+# In MELPA directory
+make recipes/my-package
+
+# Test installation
+make sandbox INSTALL=my-package
+
+# Clean up
+make clean
+```
+
+### Step 4: Submit Pull Request
+
+```bash
+git add recipes/my-package
+git commit -m "Add my-package recipe"
+git push origin add-my-package
+```
+
+Create PR at https://github.com/melpa/melpa/pulls
+
+### Step 5: Address Review Feedback
+
+MELPA maintainers will review:
+- Recipe correctness
+- Package quality
+- License
+- Documentation
+
+Common feedback:
+- Fix package-lint warnings
+- Improve docstrings
+- Add missing headers
+- Simplify recipe
+
+### Step 6: Approval and Publication
+
+Once approved:
+- PR is merged
+- Package builds automatically
+- Available in MELPA within 24 hours
+
+## MELPA Stable
+
+### Requirements
+
+Same as MELPA, plus:
+- Git tags for releases
+- Semantic versioning
+
+### Create Release
+
+```bash
+# Tag release
+git tag -a v1.0.0 -m "Release version 1.0.0"
+git push origin v1.0.0
+```
+
+### Recipe
+
+```elisp
+(my-package :fetcher github
+ :repo "username/my-package"
+ :version-regexp "v\\([0-9.]+\\)") ; Optional
+```
+
+MELPA Stable automatically uses tags.
+
+## GNU ELPA
+
+### Requirements
+
+1. **Copyright assignment**: For packages >300 lines
+2. **License**: GPL-compatible
+3. **Code quality**: High standards
+4. **No external dependencies**: Prefer built-in features
+
+### Process
+
+1. **Email proposal**: Send to `emacs-devel@gnu.org`
+ ```
+ Subject: [ELPA] New package: my-package
+
+ I would like to submit my-package to GNU ELPA.
+
+ Description: [Brief description]
+ Repository: [Git URL]
+ License: GPL-3.0-or-later
+
+ [Additional details]
+ ```
+
+2. **Copyright assignment**:
+ - If >300 lines, complete FSF copyright assignment
+ - Process takes 2-4 weeks
+ - Forms available from FSF
+
+3. **Code review**:
+ - FSF maintainers review code
+ - May request changes
+ - Higher standards than MELPA
+
+4. **Integration**:
+ - Package added to GNU ELPA
+ - Automatically built and published
+
+## NonGNU ELPA
+
+### Requirements
+
+1. **Free license**: GPL, MIT, Apache, etc.
+2. **No copyright assignment**: Unlike GNU ELPA
+3. **Code quality**: Good standards
+4. **No proprietary dependencies**
+
+### Process
+
+1. **Email proposal**: Send to `emacs-devel@gnu.org`
+ ```
+ Subject: [NonGNU ELPA] New package: my-package
+
+ I would like to submit my-package to NonGNU ELPA.
+
+ Description: [Brief description]
+ Repository: [Git URL]
+ License: MIT
+
+ The package provides [features]...
+ ```
+
+2. **Review**: Less strict than GNU ELPA
+3. **Integration**: Added to NonGNU ELPA repository
+
+## Version Management
+
+### Semantic Versioning
+
+Follow [SemVer](https://semver.org/):
+
+- **MAJOR**: Incompatible API changes (1.0.0 β 2.0.0)
+- **MINOR**: New features, backwards-compatible (1.0.0 β 1.1.0)
+- **PATCH**: Bug fixes, backwards-compatible (1.0.0 β 1.0.1)
+
+### Update Version
+
+```elisp
+;; In package file header
+;; Version: 1.2.3
+
+;; In Eask
+(package "my-package" "1.2.3" "Description")
+```
+
+### Create Release
+
+```bash
+# Update version in files
+# Update CHANGELOG.md
+
+git add .
+git commit -m "Bump version to 1.2.3"
+git tag -a v1.2.3 -m "Release version 1.2.3"
+git push origin main
+git push origin v1.2.3
+```
+
+## CHANGELOG
+
+Maintain `CHANGELOG.md`:
+
+```markdown
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [Unreleased]
+
+### Added
+- Feature in development
+
+## [1.2.0] - 2025-01-15
+
+### Added
+- New command `my-package-export`
+- Support for custom backends
+
+### Changed
+- Improved performance of parsing
+- Updated documentation
+
+### Fixed
+- Bug in file handling
+
+## [1.1.0] - 2025-01-01
+
+### Added
+- Initial public release
+```
+
+## Package Distribution
+
+### Create Package Tarball
+
+```bash
+# With Eask
+eask package
+
+# Output: dist/my-package-1.0.0.tar
+
+# Manual
+tar -cf my-package-1.0.0.tar my-package.el my-package-utils.el README.md
+```
+
+### Test Package Installation
+
+```elisp
+;; Install local package
+M-x package-install-file RET /path/to/my-package-1.0.0.tar RET
+
+;; Or from directory
+M-x package-install-file RET /path/to/package-directory RET
+```
+
+## Post-Publication
+
+### Monitor Issues
+
+- Watch GitHub issues
+- Respond to bug reports
+- Merge pull requests
+
+### Update Package
+
+```bash
+# Fix bugs, add features
+git commit -am "Fix issue #123"
+git push
+
+# MELPA rebuilds automatically
+# No PR needed for updates
+```
+
+### Deprecation
+
+If deprecating package:
+
+```elisp
+;; Add to package file
+(make-obsolete 'my-package-old-function
+ 'my-package-new-function
+ "1.5.0")
+
+(define-obsolete-function-alias
+ 'my-old-function
+ 'my-new-function
+ "1.5.0")
+
+(define-obsolete-variable-alias
+ 'my-old-var
+ 'my-new-var
+ "1.5.0")
+```
+
+## Quality Checklist
+
+Before publishing:
+
+### Code Quality
+- [ ] All functions have docstrings
+- [ ] All variables have docstrings
+- [ ] Lexical binding enabled
+- [ ] No byte-compile warnings
+- [ ] package-lint passes
+- [ ] checkdoc passes
+
+### Documentation
+- [ ] README with installation and usage
+- [ ] CHANGELOG with version history
+- [ ] License file (GPL-3.0-or-later recommended)
+- [ ] Code comments where needed
+
+### Testing
+- [ ] Tests cover main functionality
+- [ ] Tests pass
+- [ ] CI configured (GitHub Actions)
+
+### Package Metadata
+- [ ] All required headers present
+- [ ] Package-Requires correct
+- [ ] Keywords appropriate
+- [ ] URL points to repository
+
+### Repository
+- [ ] .gitignore includes build artifacts
+- [ ] Clean git history
+- [ ] Tagged releases
+- [ ] Issues/PR templates (optional)
+
+## Common Issues
+
+### Recipe Rejected
+
+**Wrong :files**:
+```elisp
+;; Bad - includes test files
+(my-package :fetcher github
+ :repo "user/my-package"
+ :files ("*.el"))
+
+;; Good - excludes tests
+(my-package :fetcher github
+ :repo "user/my-package"
+ :files (:defaults (:exclude "test-*.el")))
+```
+
+### Package Fails to Build
+
+Check MELPA build log:
+- https://melpa.org/#/my-package
+
+Common causes:
+- Missing dependencies
+- Byte-compile errors
+- Wrong file paths
+
+### Version Mismatch
+
+```elisp
+;; Version in package file
+;; Version: 1.0.0
+
+;; Must match git tag
+git tag v1.0.0
+```
+
+## Best Practices
+
+1. **Start with MELPA**: Easiest to publish
+2. **Tag releases**: For MELPA Stable
+3. **Semantic versioning**: Clear version scheme
+4. **Maintain CHANGELOG**: Document changes
+5. **Respond to issues**: Help users
+6. **Keep dependencies minimal**: Easier maintenance
+7. **Test thoroughly**: Before each release
+8. **Document well**: README and docstrings
+9. **Follow conventions**: MELPA guidelines
+10. **CI/CD**: Automate testing
+
+## Resources
+
+- [MELPA Contributing Guide](https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org)
+- [GNU ELPA](https://elpa.gnu.org/)
+- [NonGNU ELPA](https://elpa.nongnu.org/)
+- [Semantic Versioning](https://semver.org/)
+- [Package Archives Wiki](https://www.emacswiki.org/emacs/ELPA)
dots/.config/claude/skills/EmacsLisp/workflows/Script.md
@@ -0,0 +1,428 @@
+# Script Workflow
+
+Write standalone Emacs Lisp scripts for automation, batch processing, and command-line tools.
+
+## Batch Mode Basics
+
+### Simple Script
+
+```elisp
+#!/usr/bin/emacs --script
+;;; process-files.el --- Process files in batch mode
+
+(message "Script started")
+
+(dolist (file command-line-args-left)
+ (message "Processing: %s" file)
+ (with-temp-buffer
+ (insert-file-contents file)
+ (message "Size: %d bytes" (buffer-size))))
+
+(message "Script completed")
+```
+
+Make executable:
+```bash
+chmod +x process-files.el
+./process-files.el file1.txt file2.txt
+```
+
+## Shebang Options
+
+### Direct Script
+
+```elisp
+#!/usr/bin/emacs --script
+;; Runs directly, no interactive mode
+```
+
+### With Options
+
+```elisp
+#!/bin/sh
+":"; exec emacs --quick --script "$0" "$@" # -*-emacs-lisp-*-
+;; --quick: Skip init files
+;; --script: Batch mode
+```
+
+### Load Init File
+
+```bash
+#!/bin/sh
+":"; exec emacs --script "$0" "$@" # -*-emacs-lisp-*-
+;; Loads ~/.emacs.d/init.el
+```
+
+## Command-Line Arguments
+
+### Access Arguments
+
+```elisp
+#!/usr/bin/emacs --script
+
+;; Script name
+(message "Script: %s" load-file-name)
+
+;; All arguments
+(message "Args: %S" command-line-args-left)
+
+;; Process arguments
+(let ((input-file (pop command-line-args-left))
+ (output-file (pop command-line-args-left)))
+ (unless (and input-file output-file)
+ (error "Usage: %s INPUT OUTPUT" load-file-name))
+
+ (message "Input: %s" input-file)
+ (message "Output: %s" output-file))
+```
+
+### Parse Options
+
+```elisp
+#!/usr/bin/emacs --script
+
+(defun parse-args (args)
+ "Parse command-line ARGS."
+ (let ((verbose nil)
+ (output nil)
+ (files nil))
+
+ (while args
+ (let ((arg (pop args)))
+ (cond
+ ((string= arg "--verbose")
+ (setq verbose t))
+
+ ((string= arg "--output")
+ (setq output (pop args)))
+
+ ((string-prefix-p "--" arg)
+ (error "Unknown option: %s" arg))
+
+ (t
+ (push arg files)))))
+
+ (list :verbose verbose
+ :output output
+ :files (nreverse files))))
+
+(let ((options (parse-args command-line-args-left)))
+ (message "Options: %S" options))
+```
+
+## Common Script Patterns
+
+### File Processing
+
+```elisp
+#!/usr/bin/emacs --script
+;;; convert-encoding.el --- Convert file encoding
+
+(defun convert-file-encoding (file from to)
+ "Convert FILE from FROM encoding to TO encoding."
+ (let ((content (with-temp-buffer
+ (let ((coding-system-for-read from))
+ (insert-file-contents file)
+ (buffer-string)))))
+ (with-temp-buffer
+ (insert content)
+ (let ((coding-system-for-write to))
+ (write-region (point-min) (point-max) file)))))
+
+(dolist (file command-line-args-left)
+ (message "Converting %s..." file)
+ (convert-file-encoding file 'utf-8 'iso-8859-1)
+ (message "Done"))
+```
+
+### Directory Processing
+
+```elisp
+#!/usr/bin/emacs --script
+;;; list-el-files.el --- List all .el files
+
+(require 'find-lisp)
+
+(defun list-el-files (directory)
+ "List all .el files in DIRECTORY recursively."
+ (let ((files (find-lisp-find-files directory "\\.el$")))
+ (dolist (file files)
+ (princ file)
+ (terpri))))
+
+(let ((dir (or (car command-line-args-left) ".")))
+ (list-el-files dir))
+```
+
+### Text Transformation
+
+```elisp
+#!/usr/bin/emacs --script
+;;; markdown-to-org.el --- Convert Markdown to Org
+
+(defun markdown-to-org (md-file org-file)
+ "Convert MD-FILE to ORG-FILE."
+ (with-temp-buffer
+ (insert-file-contents md-file)
+
+ ;; Headers
+ (goto-char (point-min))
+ (while (re-search-forward "^\\(#+\\) \\(.*\\)$" nil t)
+ (let ((level (length (match-string 1)))
+ (title (match-string 2)))
+ (replace-match (format "%s %s" (make-string level ?*) title))))
+
+ ;; Bold
+ (goto-char (point-min))
+ (while (re-search-forward "\\*\\*\\([^*]+\\)\\*\\*" nil t)
+ (replace-match "*\\1*"))
+
+ ;; Write output
+ (write-region (point-min) (point-max) org-file)))
+
+(let ((input (pop command-line-args-left))
+ (output (pop command-line-args-left)))
+ (markdown-to-org input output)
+ (message "Converted %s to %s" input output))
+```
+
+## Exit Codes
+
+### Success/Failure
+
+```elisp
+#!/usr/bin/emacs --script
+
+(condition-case err
+ (progn
+ ;; Script logic
+ (when (some-error-condition)
+ (error "Something went wrong"))
+
+ ;; Success
+ (kill-emacs 0))
+
+ (error
+ (message "Error: %s" (error-message-string err))
+ (kill-emacs 1)))
+```
+
+### Exit with Code
+
+```elisp
+(kill-emacs 0) ; Success
+(kill-emacs 1) ; General error
+(kill-emacs 2) ; Misuse of command
+```
+
+## Output
+
+### Standard Output
+
+```elisp
+;; Print to stdout
+(princ "Hello, World!")
+(terpri) ; Newline
+
+;; Or use message (goes to stderr in batch mode)
+(message "Processing...")
+
+;; Format output
+(princ (format "Processed %d files\n" count))
+```
+
+### Standard Error
+
+```elisp
+;; In batch mode, message goes to stderr
+(message "Warning: %s" warning-text)
+
+;; Explicit stderr
+(with-current-buffer (get-buffer-create "*stderr*")
+ (insert "Error message\n"))
+```
+
+## Practical Examples
+
+### Batch Byte Compilation
+
+```elisp
+#!/usr/bin/emacs --script
+;;; batch-compile.el --- Byte compile all .el files
+
+(require 'bytecomp)
+
+(defun batch-byte-compile-directory (directory)
+ "Byte compile all .el files in DIRECTORY."
+ (let ((files (directory-files directory t "\\.el$")))
+ (dolist (file files)
+ (unless (string-match-p "-test\\.el$" file)
+ (message "Compiling %s..." file)
+ (byte-compile-file file)))))
+
+(let ((dir (or (car command-line-args-left) ".")))
+ (batch-byte-compile-directory dir))
+```
+
+### Generate Autoloads
+
+```elisp
+#!/usr/bin/emacs --script
+;;; generate-autoloads.el --- Generate autoloads file
+
+(require 'autoload)
+
+(let ((dir (or (car command-line-args-left) "."))
+ (output "my-package-autoloads.el"))
+
+ (with-current-buffer (find-file-noselect output)
+ (erase-buffer)
+ (insert ";;; Autoloads\n")
+ (save-buffer))
+
+ (update-directory-autoloads dir)
+ (message "Generated %s" output))
+```
+
+### Run Tests
+
+```elisp
+#!/usr/bin/emacs --script
+;;; run-tests.el --- Run ERT tests
+
+(require 'ert)
+
+;; Load package
+(add-to-list 'load-path ".")
+(load "my-package.el")
+(load "my-package-test.el")
+
+;; Run tests
+(ert-run-tests-batch-and-exit t)
+```
+
+### Extract Documentation
+
+```elisp
+#!/usr/bin/emacs --script
+;;; extract-docs.el --- Extract function documentation
+
+(defun extract-function-docs (file)
+ "Extract function documentation from FILE."
+ (with-temp-buffer
+ (insert-file-contents file)
+ (goto-char (point-min))
+
+ (while (re-search-forward "^(defun \\([^ ]+\\)" nil t)
+ (let ((func-name (match-string 1)))
+ (forward-sexp)
+ (forward-line)
+ (when (looking-at "[ \t]*\"\\([^\"]+\\)\"")
+ (princ (format "* %s\n %s\n\n" func-name (match-string 1))))))))
+
+(dolist (file command-line-args-left)
+ (extract-function-docs file))
+```
+
+## Debugging Scripts
+
+### Enable Debug
+
+```elisp
+#!/usr/bin/emacs --script
+
+(setq debug-on-error t)
+
+;; Your code
+```
+
+### Print Variables
+
+```elisp
+(message "Variable value: %S" my-var)
+(prin1 my-var)
+```
+
+### Backtrace
+
+```elisp
+(condition-case err
+ (risky-operation)
+ (error
+ (message "Error: %s" (error-message-string err))
+ (message "Backtrace: %S" (backtrace-to-string))
+ (kill-emacs 1)))
+```
+
+## Advanced Techniques
+
+### Load Dependencies
+
+```elisp
+#!/usr/bin/emacs --script
+
+;; Add package archives
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
+(package-initialize)
+
+;; Ensure package is installed
+(unless (package-installed-p 'dash)
+ (package-refresh-contents)
+ (package-install 'dash))
+
+(require 'dash)
+
+;; Use dash functions
+(-map (lambda (x) (* x 2)) '(1 2 3))
+```
+
+### Parallel Processing
+
+```elisp
+#!/usr/bin/emacs --script
+
+(defun process-file-async (file callback)
+ "Process FILE asynchronously, call CALLBACK when done."
+ (make-process
+ :name (format "process-%s" file)
+ :buffer nil
+ :command (list "emacs" "--batch"
+ "--eval" (format "(progn (load \"%s\") (process-file \"%s\"))"
+ load-file-name file))
+ :sentinel (lambda (proc event)
+ (when (string-match-p "finished" event)
+ (funcall callback file)))))
+
+;; Process files in parallel
+(let ((files command-line-args-left)
+ (count 0))
+ (dolist (file files)
+ (process-file-async file
+ (lambda (f)
+ (setq count (1+ count))
+ (when (= count (length files))
+ (kill-emacs 0)))))
+
+ ;; Wait for completion
+ (while t (sleep-for 0.1)))
+```
+
+## Best Practices
+
+1. **Use `--script`**: Faster than `--batch`
+2. **Handle errors**: Use `condition-case`
+3. **Check arguments**: Validate input
+4. **Exit codes**: Return appropriate codes
+5. **Progress messages**: Use `message` for feedback
+6. **Load minimal**: Only load needed libraries
+7. **Test scripts**: Like any other code
+8. **Document**: Add usage at top of file
+9. **Make executable**: `chmod +x`
+10. **Clean output**: Separate status from data
+
+## Resources
+
+- [Batch Mode Documentation](https://www.gnu.org/software/emacs/manual/html_node/elisp/Batch-Mode.html)
+- [Command-Line Arguments](https://www.gnu.org/software/emacs/manual/html_node/elisp/Command_002dLine-Arguments.html)
+- [Scripting Emacs](https://www.masteringemacs.org/article/scripting-emacs-batch-mode)
dots/.config/claude/skills/EmacsLisp/workflows/Test.md
@@ -0,0 +1,455 @@
+# Test Workflow
+
+Write and run tests for Emacs Lisp packages using ERT (Emacs Lisp Regression Testing).
+
+## ERT (Built-in Testing Framework)
+
+ERT is the standard testing framework for Emacs Lisp.
+
+### Basic Test Structure
+
+```elisp
+;;; my-package-test.el --- Tests for my-package -*- lexical-binding: t -*-
+
+(require 'ert)
+(require 'my-package)
+
+(ert-deftest my-package-test-basic ()
+ "Test basic functionality."
+ (should (= 2 (+ 1 1)))
+ (should (equal "hello" "hello"))
+ (should (functionp 'my-package-enable)))
+
+(ert-deftest my-package-test-error ()
+ "Test that errors are raised."
+ (should-error (my-package-divide-by-zero))
+ (should-error (my-package-invalid-input "") :type 'wrong-type-argument))
+
+(ert-deftest my-package-test-buffer ()
+ "Test buffer operations."
+ (with-temp-buffer
+ (insert "test content")
+ (goto-char (point-min))
+ (should (looking-at "test"))
+ (should (= (point-max) 13))))
+
+(provide 'my-package-test)
+;;; my-package-test.el ends here
+```
+
+## ERT Assertions
+
+### should
+
+```elisp
+(ert-deftest test-should ()
+ "Test should assertions."
+ ;; Basic equality
+ (should (= 1 1))
+ (should (equal "a" "a"))
+ (should (string= "hello" "hello"))
+
+ ;; Boolean tests
+ (should t)
+ (should (listp '(1 2 3)))
+ (should (functionp 'car))
+
+ ;; Negation
+ (should-not nil)
+ (should-not (= 1 2)))
+```
+
+### should-error
+
+```elisp
+(ert-deftest test-errors ()
+ "Test error handling."
+ ;; Any error
+ (should-error (error "Something went wrong"))
+
+ ;; Specific error type
+ (should-error (/ 1 0) :type 'arith-error)
+ (should-error (car 'not-a-list) :type 'wrong-type-argument))
+```
+
+### Custom Assertions
+
+```elisp
+(defun should-contain (list element)
+ "Assert that LIST contains ELEMENT."
+ (should (member element list)))
+
+(ert-deftest test-custom-assertion ()
+ (should-contain '(1 2 3) 2))
+```
+
+## Test Organization
+
+### Test File Location
+
+```
+my-package/
+βββ my-package.el
+βββ my-package-core.el
+βββ test/
+ βββ my-package-test.el
+ βββ my-package-core-test.el
+ βββ test-helper.el
+```
+
+### Test Helper
+
+**test/test-helper.el**:
+
+```elisp
+;;; test-helper.el --- Test helpers -*- lexical-binding: t -*-
+
+;; Add parent directory to load path
+(add-to-list 'load-path (file-name-directory (directory-file-name (file-name-directory load-file-name))))
+
+(require 'my-package)
+
+;; Helper functions
+(defun test-helper-create-temp-file (content)
+ "Create temporary file with CONTENT."
+ (let ((file (make-temp-file "my-package-test-")))
+ (with-temp-file file
+ (insert content))
+ file))
+
+(provide 'test-helper)
+;;; test-helper.el ends here
+```
+
+## Running Tests
+
+### Interactive (in Emacs)
+
+```elisp
+;; Run all tests
+M-x ert RET t RET
+
+;; Run specific test
+M-x ert RET my-package-test-basic RET
+
+;; Run tests matching pattern
+M-x ert RET "my-package.*" RET
+
+;; Rerun failed tests
+M-x ert-results-rerun-test-at-point
+```
+
+### Batch Mode
+
+```bash
+# Run all tests
+emacs -batch -l my-package.el -l my-package-test.el -f ert-run-tests-batch-and-exit
+
+# With better output
+emacs -batch -l ert -l my-package.el -l my-package-test.el \
+ --eval "(ert-run-tests-batch-and-exit)"
+```
+
+### With Eask
+
+```bash
+# Run all tests
+eask test ert
+
+# Run specific test file
+eask test ert my-package-test.el
+
+# With coverage (if using undercover)
+eask test ert --coverage
+```
+
+## Advanced Testing
+
+### Mocking
+
+```elisp
+(ert-deftest test-with-mocking ()
+ "Test with function mocking."
+ (cl-letf (((symbol-function 'current-time)
+ (lambda () '(0 0 0))))
+ (should (equal (current-time) '(0 0 0)))))
+
+(ert-deftest test-mock-user-input ()
+ "Mock user input."
+ (cl-letf (((symbol-function 'read-string)
+ (lambda (prompt) "mocked input")))
+ (should (string= (read-string "Enter: ") "mocked input"))))
+```
+
+### Fixtures
+
+```elisp
+(defvar my-package-test-fixture nil
+ "Test fixture data.")
+
+(defun my-package-test-setup ()
+ "Set up test fixture."
+ (setq my-package-test-fixture
+ (with-temp-buffer
+ (insert "fixture content")
+ (buffer-string))))
+
+(defun my-package-test-teardown ()
+ "Tear down test fixture."
+ (setq my-package-test-fixture nil))
+
+(ert-deftest test-with-fixture ()
+ "Test using fixture."
+ (unwind-protect
+ (progn
+ (my-package-test-setup)
+ (should (string= my-package-test-fixture "fixture content")))
+ (my-package-test-teardown)))
+```
+
+### Parameterized Tests
+
+```elisp
+(defun make-addition-test (a b expected)
+ "Create test for addition of A and B expecting EXPECTED."
+ (lambda ()
+ (should (= (+ a b) expected))))
+
+(ert-deftest test-addition-1 ()
+ (funcall (make-addition-test 1 1 2)))
+
+(ert-deftest test-addition-2 ()
+ (funcall (make-addition-test 2 3 5)))
+
+;; Or use a macro
+(defmacro def-addition-test (name a b expected)
+ "Define addition test NAME for A + B = EXPECTED."
+ `(ert-deftest ,name ()
+ ,(format "Test that %s + %s = %s" a b expected)
+ (should (= (+ ,a ,b) ,expected))))
+
+(def-addition-test test-add-positive 2 3 5)
+(def-addition-test test-add-negative -1 1 0)
+```
+
+### Testing Async Code
+
+```elisp
+(ert-deftest test-async-operation ()
+ "Test asynchronous operation."
+ (let ((done nil)
+ (result nil))
+ (my-package-async-operation
+ (lambda (res)
+ (setq result res
+ done t)))
+
+ ;; Wait for callback
+ (with-timeout (5 (error "Timeout"))
+ (while (not done)
+ (sleep-for 0.1)))
+
+ (should (equal result expected-value))))
+```
+
+## Buttercup (Alternative BDD Framework)
+
+### Installation
+
+```elisp
+;; In Eask
+(development
+ (depends-on "buttercup"))
+```
+
+### Basic Test
+
+```elisp
+;;; my-package-test.el --- Tests using Buttercup -*- lexical-binding: t -*-
+
+(require 'buttercup)
+(require 'my-package)
+
+(describe "my-package"
+ (describe "basic functionality"
+ (it "should add numbers correctly"
+ (expect (+ 2 3) :to-equal 5))
+
+ (it "should handle strings"
+ (expect (concat "hello" " " "world")
+ :to-equal "hello world")))
+
+ (describe "error handling"
+ (it "should throw error on invalid input"
+ (expect (my-package-invalid-operation)
+ :to-throw 'error))))
+
+;;; my-package-test.el ends here
+```
+
+### Run Buttercup
+
+```bash
+# With Eask
+eask exec buttercup -L .
+
+# Direct
+buttercup -L . -L test
+```
+
+## Coverage
+
+### Using undercover
+
+```elisp
+;; In Eask
+(development
+ (depends-on "undercover"))
+
+;; In test file
+(when (require 'undercover nil t)
+ (undercover "*.el"
+ (:exclude "my-package-test.el")))
+```
+
+### Run with Coverage
+
+```bash
+# Generate coverage report
+eask test ert
+
+# View coverage in Coveralls (CI integration)
+```
+
+## CI/CD Testing
+
+### GitHub Actions
+
+```yaml
+name: Tests
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+ emacs-version: ['29.1', '29.2', 'snapshot']
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: jcs090218/setup-emacs@master
+ with:
+ version: ${{ matrix.emacs-version }}
+
+ - uses: emacs-eask/setup-eask@master
+
+ - name: Install dependencies
+ run: eask install-deps
+
+ - name: Run tests
+ run: eask test ert
+
+ - name: Upload coverage
+ if: matrix.os == 'ubuntu-latest' && matrix.emacs-version == '29.2'
+ uses: codecov/codecov-action@v3
+```
+
+## Best Practices
+
+1. **Test public API**: Focus on public functions
+2. **Use descriptive names**: `test-feature-behavior` not `test1`
+3. **One assertion per concept**: Multiple related assertions OK
+4. **Clean up**: Use `unwind-protect` for cleanup
+5. **Test edge cases**: Empty lists, nil, extremes
+6. **Mock external dependencies**: File system, network, time
+7. **Fast tests**: Keep tests under 1 second each
+8. **Independent tests**: Each test should work alone
+9. **Readable failures**: Clear error messages
+10. **Test errors**: Verify error handling
+
+## Common Patterns
+
+### Testing Mode Activation
+
+```elisp
+(ert-deftest test-mode-activation ()
+ "Test that mode activates correctly."
+ (with-temp-buffer
+ (my-package-mode 1)
+ (should my-package-mode)
+ (should (memq 'my-package--hook some-hook))
+ (my-package-mode -1)
+ (should-not my-package-mode)))
+```
+
+### Testing File Operations
+
+```elisp
+(ert-deftest test-file-processing ()
+ "Test file processing."
+ (let ((temp-file (make-temp-file "my-package-test-")))
+ (unwind-protect
+ (progn
+ (with-temp-file temp-file
+ (insert "test content"))
+ (should (my-package-process-file temp-file))
+ (should (file-exists-p temp-file)))
+ (when (file-exists-p temp-file)
+ (delete-file temp-file)))))
+```
+
+### Testing Hooks
+
+```elisp
+(ert-deftest test-hooks ()
+ "Test hook execution."
+ (let ((called nil))
+ (add-hook 'my-package-mode-hook
+ (lambda () (setq called t)))
+ (my-package-mode 1)
+ (should called)))
+```
+
+## Debugging Tests
+
+### Run Single Test
+
+```elisp
+M-x eval-defun ; On test definition
+M-x ert RET test-name RET
+```
+
+### Debug Failed Test
+
+```elisp
+;; Enable debugger on error
+M-x toggle-debug-on-error
+
+;; Or in test
+(ert-deftest test-with-debug ()
+ (let ((debug-on-error t))
+ ;; Test code
+ ))
+```
+
+### Print Debug Info
+
+```elisp
+(ert-deftest test-with-output ()
+ "Test with debug output."
+ (message "Starting test...")
+ (let ((result (my-function)))
+ (message "Result: %S" result)
+ (should (= result expected))))
+```
+
+## Resources
+
+- [ERT Manual](https://www.gnu.org/software/emacs/manual/html_node/ert/)
+- [Buttercup](https://github.com/jorgenschaefer/emacs-buttercup)
+- [Undercover](https://github.com/undercover-el/undercover.el)
+- [Testing Best Practices](https://github.com/flycheck/flycheck/blob/master/doc/contributor/contributing.rst#testing)
dots/.config/claude/skills/EmacsLisp/SKILL.md
@@ -0,0 +1,634 @@
+---
+name: EmacsLisp
+description: Emacs Lisp development with modern tooling and best practices. USE WHEN writing Emacs configuration, developing packages, testing, linting, publishing to MELPA/ELPA, or working with Emacs Lisp code.
+---
+
+# Emacs Lisp Development
+
+Expert guidance on Emacs Lisp programming following modern best practices (2025), from configuration and scripting to package development and publishing.
+
+## Purpose
+
+Guide Emacs Lisp development using modern tooling and conventions:
+- **Configuration**: use-package, straight.el, package.el best practices
+- **Package development**: Structure, conventions, and tooling
+- **Testing**: ERT (Emacs Lisp Regression Testing)
+- **Code quality**: package-lint, checkdoc, byte-compilation
+- **Publishing**: MELPA, GNU ELPA, NonGNU ELPA
+- **Modern tools**: Eask, native compilation, package-vc
+
+### Context Detection
+
+**This skill activates when:**
+- Working with `.el` files
+- Directory contains `Eask`, `Cask`, or package headers
+- User mentions Emacs configuration, packages, or MELPA
+- Commands like `emacs`, `eask`, `package-lint` are mentioned
+- Working in `.emacs.d/` or similar Emacs directories
+
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **EmacsLisp** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Configure** | "emacs configuration", "use-package", "init.el" | `workflows/Configure.md` |
+| **Package** | "create emacs package", "package structure", "elisp package" | `workflows/Package.md` |
+| **Test** | "emacs tests", "ert", "test elisp", "buttercup" | `workflows/Test.md` |
+| **Lint** | "lint elisp", "package-lint", "checkdoc", "byte compile" | `workflows/Lint.md` |
+| **Publish** | "publish to melpa", "elpa", "submit package" | `workflows/Publish.md` |
+| **Script** | "elisp script", "batch mode", "standalone elisp" | `workflows/Script.md` |
+| **Debug** | "debug elisp", "edebug", "elisp debugger" | `workflows/Debug.md` |
+| **Document** | "elisp documentation", "docstrings", "info manual" | `workflows/Document.md` |
+
+## Core Principles
+
+1. **Follow conventions**: Package naming, headers, docstrings
+2. **Use modern Emacs**: Target Emacs 29+ for new packages
+3. **Write tests**: Use ERT for all packages
+4. **Lint before publishing**: package-lint, checkdoc, byte-compile
+5. **Document thoroughly**: Every function, variable, and customization
+6. **Use lexical binding**: Always use `;;; -*- lexical-binding: t -*-`
+7. **Native compilation**: Support native-comp for performance
+
+## Modern Emacs (2025)
+
+### Emacs 29+ Features
+
+- **use-package**: Built-in package configuration
+- **package-vc**: Install packages directly from version control
+- **Native compilation**: Faster Emacs Lisp execution
+- **eglot**: Built-in LSP client
+- **tree-sitter**: Fast syntax parsing
+
+### Recommended Tooling
+
+| Tool | Purpose | Status |
+|------|---------|--------|
+| **Eask** | Package development, testing, linting | Modern (2022+) |
+| **package-lint** | Lint packages for MELPA | Essential |
+| **checkdoc** | Check docstrings | Built-in |
+| **ERT** | Testing framework | Built-in |
+| **buttercup** | BDD testing (alternative) | Optional |
+| **use-package** | Configuration management | Built-in (29+) |
+
+## Package Structure
+
+### Standard Package
+
+```
+my-package/
+βββ my-package.el # Main package file
+βββ my-package-test.el # Tests (ERT)
+βββ Eask # Package development tool
+βββ README.md # Description and usage
+βββ CHANGELOG.md # Version history
+βββ .github/
+ βββ workflows/
+ βββ test.yml # CI testing
+```
+
+### Multi-file Package
+
+```
+my-package/
+βββ my-package.el # Main entry point with autoloads
+βββ my-package-core.el # Core functionality
+βββ my-package-ui.el # UI components
+βββ my-package-utils.el # Utilities
+βββ test/
+β βββ my-package-test.el
+β βββ my-package-core-test.el
+βββ Eask
+βββ README.md
+```
+
+## Package Headers
+
+Every Emacs Lisp package must start with standard headers:
+
+```elisp
+;;; my-package.el --- Brief description -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Your Name
+
+;; Author: Your Name <your.email@example.com>
+;; Version: 0.1.0
+;; Package-Requires: ((emacs "29.1"))
+;; Keywords: convenience, tools
+;; URL: https://github.com/yourusername/my-package
+
+;; This file is not part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Longer description of what this package does.
+;;
+;; Usage:
+;;
+;; (require 'my-package)
+;; (my-package-enable)
+
+;;; Code:
+
+(defgroup my-package nil
+ "Customization group for my-package."
+ :group 'tools
+ :prefix "my-package-")
+
+;; Package code here...
+
+(provide 'my-package)
+;;; my-package.el ends here
+```
+
+## Coding Conventions
+
+### Naming
+
+```elisp
+;; Package prefix for all symbols
+(defun my-package-do-something () ; Function
+ ...)
+
+(defvar my-package-mode-map ; Variable
+ (make-sparse-keymap))
+
+(defcustom my-package-enable-feature nil ; Customizable
+ "Whether to enable feature."
+ :type 'boolean
+ :group 'my-package)
+
+;; Private/internal (double dash)
+(defun my-package--internal-helper ()
+ "Internal helper function."
+ ...)
+```
+
+### Docstrings
+
+```elisp
+(defun my-package-process-file (file &optional verbose)
+ "Process FILE and return the result.
+
+If VERBOSE is non-nil, print progress messages.
+
+FILE should be a path to a readable file. Returns a list
+of processed items, or nil if FILE cannot be processed.
+
+Example usage:
+
+ (my-package-process-file \"/path/to/file.txt\" t)
+
+See also `my-package-process-directory'."
+ ...)
+
+(defcustom my-package-timeout 30
+ "Timeout in seconds for operations.
+
+This value controls how long to wait before giving up on
+long-running operations. Set to 0 to disable timeout."
+ :type 'integer
+ :group 'my-package)
+```
+
+### Lexical Binding
+
+Always use lexical binding (modern Emacs standard):
+
+```elisp
+;;; my-package.el --- Description -*- lexical-binding: t -*-
+```
+
+Benefits:
+- Better performance
+- Proper closures
+- Catches more errors
+
+## Configuration Best Practices
+
+### use-package (Built-in since Emacs 29)
+
+```elisp
+;; In init.el or early-init.el
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
+(package-initialize)
+
+;; Configure packages with use-package
+(use-package magit
+ :ensure t
+ :bind ("C-x g" . magit-status)
+ :config
+ (setq magit-display-buffer-function
+ #'magit-display-buffer-same-window-except-diff-v1))
+
+(use-package org
+ :ensure t
+ :defer t
+ :custom
+ (org-directory "~/org")
+ (org-agenda-files '("~/org/agenda.org"))
+ :config
+ (org-babel-do-load-languages
+ 'org-babel-load-languages
+ '((emacs-lisp . t)
+ (python . t))))
+```
+
+### straight.el (Alternative package manager)
+
+```elisp
+;; Bootstrap straight.el
+(defvar bootstrap-version)
+(let ((bootstrap-file
+ (expand-file-name "straight/repos/straight.el/bootstrap.el"
+ user-emacs-directory))
+ (bootstrap-version 6))
+ (unless (file-exists-p bootstrap-file)
+ (with-current-buffer
+ (url-retrieve-synchronously
+ "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
+ 'silent 'inhibit-cookies)
+ (goto-char (point-max))
+ (eval-print-last-sexp)))
+ (load bootstrap-file nil 'nomessage))
+
+;; Use packages
+(straight-use-package 'use-package)
+(use-package magit
+ :straight t)
+```
+
+## Testing with ERT
+
+### Basic Test
+
+```elisp
+;;; my-package-test.el --- Tests for my-package -*- lexical-binding: t -*-
+
+(require 'ert)
+(require 'my-package)
+
+(ert-deftest my-package-test-addition ()
+ "Test that addition works correctly."
+ (should (= (my-package-add 2 3) 5))
+ (should (= (my-package-add -1 1) 0))
+ (should (= (my-package-add 0 0) 0)))
+
+(ert-deftest my-package-test-error ()
+ "Test that errors are raised correctly."
+ (should-error (my-package-divide 10 0)))
+
+(ert-deftest my-package-test-buffer ()
+ "Test buffer operations."
+ (with-temp-buffer
+ (insert "test content")
+ (should (= (point-max) 13))
+ (goto-char (point-min))
+ (should (looking-at "test"))))
+
+(provide 'my-package-test)
+;;; my-package-test.el ends here
+```
+
+### Run Tests
+
+```bash
+# Using Emacs batch mode
+emacs -batch -l my-package.el -l my-package-test.el -f ert-run-tests-batch-and-exit
+
+# Using Eask
+eask test ert my-package-test.el
+
+# In Emacs interactively
+M-x ert RET t RET
+```
+
+## Eask (Modern Development Tool)
+
+### Eask File
+
+```elisp
+;; Eask
+(package "my-package"
+ "0.1.0"
+ "Brief description of my package")
+
+(website-url "https://github.com/yourusername/my-package")
+(keywords "convenience" "tools")
+
+(package-file "my-package.el")
+
+(script "test" "echo \"Run tests..\" && eask ert-runner")
+(script "lint" "echo \"Linting..\" && eask lint package")
+
+(source "gnu")
+(source "melpa")
+
+(depends-on "emacs" "29.1")
+
+(development
+ (depends-on "ert-runner")
+ (depends-on "package-lint"))
+```
+
+### Eask Commands
+
+```bash
+# Install dependencies
+eask install-deps
+
+# Run tests
+eask test
+
+# Lint package
+eask lint package
+eask lint checkdoc
+eask lint elisp-lint
+
+# Byte compile
+eask compile
+
+# Package for distribution
+eask package
+
+# Clean build artifacts
+eask clean all
+```
+
+## Publishing to MELPA
+
+### Requirements
+
+1. **Package structure**: Follow conventions
+2. **Tests**: Include tests
+3. **Documentation**: Complete docstrings
+4. **License**: GPL-compatible license
+5. **Git repository**: Public Git repo (GitHub, GitLab, etc.)
+
+### MELPA Recipe
+
+Create a recipe in MELPA repository:
+
+```elisp
+;; In melpa/recipes/my-package
+(my-package :fetcher github
+ :repo "yourusername/my-package"
+ :files ("*.el"))
+```
+
+### Submission Process
+
+1. **Prepare package**:
+ ```bash
+ eask lint package
+ eask lint checkdoc
+ eask compile
+ eask test
+ ```
+
+2. **Fork MELPA**: https://github.com/melpa/melpa
+
+3. **Add recipe**: Create `recipes/my-package`
+
+4. **Test locally**:
+ ```bash
+ make recipes/my-package
+ make sandbox INSTALL=my-package
+ ```
+
+5. **Submit PR**: Create pull request to MELPA
+
+6. **Wait for review**: MELPA maintainers will review
+
+## Publishing to GNU ELPA
+
+### Requirements
+
+- **Copyright assignment**: Assign copyright to FSF (for packages >300 lines)
+- **License**: GPL-compatible
+- **No external dependencies**: Prefer built-in Emacs features
+
+### Submission
+
+1. Email `emacs-devel@gnu.org` with package proposal
+2. Provide Git repository URL
+3. Complete copyright assignment if needed
+4. Maintainers will add to GNU ELPA
+
+## Code Quality Tools
+
+### package-lint
+
+```bash
+# Install
+M-x package-install RET package-lint RET
+
+# Run
+M-x package-lint-current-buffer
+
+# Or with Eask
+eask lint package
+```
+
+### checkdoc
+
+```bash
+# Interactive
+M-x checkdoc
+
+# Batch mode
+emacs -batch -l checkdoc -f checkdoc-file my-package.el
+```
+
+### Byte Compilation
+
+```bash
+# Interactive
+M-x byte-compile-file
+
+# Batch
+emacs -batch -f batch-byte-compile my-package.el
+
+# Eask
+eask compile
+```
+
+## Common Patterns
+
+### Minor Mode
+
+```elisp
+(defvar my-package-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-c m") #'my-package-command)
+ map)
+ "Keymap for `my-package-mode'.")
+
+;;;###autoload
+(define-minor-mode my-package-mode
+ "Toggle My Package mode.
+
+When enabled, provides enhanced features for working with files."
+ :lighter " MyPkg"
+ :keymap my-package-mode-map
+ :group 'my-package
+ (if my-package-mode
+ (my-package--enable)
+ (my-package--disable)))
+
+(defun my-package--enable ()
+ "Enable My Package mode."
+ (add-hook 'before-save-hook #'my-package--before-save nil t))
+
+(defun my-package--disable ()
+ "Disable My Package mode."
+ (remove-hook 'before-save-hook #'my-package--before-save t))
+```
+
+### Autoloads
+
+```elisp
+;;;###autoload
+(defun my-package-enable ()
+ "Enable my-package globally."
+ (interactive)
+ (my-package-mode 1))
+```
+
+### Customization
+
+```elisp
+(defgroup my-package nil
+ "Customization group for my-package."
+ :group 'tools
+ :prefix "my-package-")
+
+(defcustom my-package-auto-save t
+ "Whether to automatically save files."
+ :type 'boolean
+ :safe #'booleanp
+ :group 'my-package)
+
+(defcustom my-package-file-extensions '("txt" "md")
+ "List of file extensions to process."
+ :type '(repeat string)
+ :group 'my-package)
+```
+
+## Performance
+
+### Lazy Loading
+
+```elisp
+;; Defer loading until needed
+(use-package my-package
+ :defer t
+ :commands (my-package-enable my-package-do-something))
+
+;; Load on file type
+(use-package my-package
+ :mode "\\.mypkg\\'")
+
+;; Load on hook
+(use-package my-package
+ :hook (prog-mode . my-package-mode))
+```
+
+### Byte Compilation
+
+Always byte-compile packages for distribution:
+- Faster execution
+- Catches some errors
+- Smaller file size
+
+### Native Compilation
+
+Support native compilation (Emacs 28+):
+- Automatically compiles to native code
+- Significantly faster execution
+- No code changes needed
+
+## Best Practices
+
+1. **Use lexical binding**: `;;; -*- lexical-binding: t -*-`
+2. **Follow naming conventions**: Use package prefix
+3. **Write complete docstrings**: Every public function/variable
+4. **Include tests**: Use ERT for all functionality
+5. **Lint before publishing**: package-lint, checkdoc
+6. **Use autoloads**: Mark entry points with `;;;###autoload`
+7. **Avoid global state**: Use buffer-local variables
+8. **Handle errors**: Use `condition-case` appropriately
+9. **Check Emacs version**: Use `(when (version< emacs-version "29.1") ...)`
+10. **Keep dependencies minimal**: Prefer built-in features
+
+## Resources
+
+### Official Documentation
+
+- [Emacs Lisp Manual](https://www.gnu.org/software/emacs/manual/html_node/elisp/)
+- [Emacs Lisp Intro](https://www.gnu.org/software/emacs/manual/html_node/eintr/)
+- [MELPA Contributing](https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org)
+
+### Tools
+
+- [Eask](https://emacs-eask.github.io/) - Modern package development
+- [package-lint](https://github.com/purcell/package-lint) - Lint for packages
+- [elisp-lint](https://github.com/gonewest818/elisp-lint) - Comprehensive linting
+- [buttercup](https://github.com/jorgenschaefer/emacs-buttercup) - BDD testing
+
+### Style Guides
+
+- [Emacs Lisp Style Guide](https://github.com/bbatsov/emacs-lisp-style-guide)
+- [Naming Conventions](https://www.gnu.org/software/emacs/manual/html_node/elisp/Coding-Conventions.html)
+
+## Examples
+
+**Example 1: Create a new package**
+```
+User: "Create an Emacs package for managing bookmarks"
+β Invokes Package workflow
+β Creates package structure with Eask
+β Sets up tests and CI
+β Generates package headers and boilerplate
+```
+
+**Example 2: Publish to MELPA**
+```
+User: "How do I publish my package to MELPA?"
+β Invokes Publish workflow
+β Checks package quality with linters
+β Creates MELPA recipe
+β Guides through PR submission
+```
+
+**Example 3: Configure Emacs**
+```
+User: "Set up my Emacs with use-package"
+β Invokes Configure workflow
+β Shows modern use-package patterns
+β Demonstrates package installation
+β Explains performance optimization
+```
+
+---
+
+**Philosophy**: Modern Emacs Lisp development emphasizes testing, documentation, and code quality. Use modern tooling (Eask, package-lint) and follow conventions to create packages that integrate seamlessly with the Emacs ecosystem.