diff options
| author | Luke Hoersten <[email protected]> | 2026-04-26 20:29:54 -0500 |
|---|---|---|
| committer | Luke Hoersten <[email protected]> | 2026-04-26 20:29:54 -0500 |
| commit | f3ecec24a273a2ecdbb98b68c894ab2b722dd906 (patch) | |
| tree | f4c0bfaaab2497e4d018d9e655f90c02d89cf17c | |
| parent | 773a6403db60cfabcbcd42694ef6219ece1948e0 (diff) | |
Fix package-lint errors, add transient buffer support, XDG path detectionmain
| -rw-r--r-- | README.md | 26 | ||||
| -rw-r--r-- | claude-code-context.el | 73 | ||||
| -rw-r--r-- | claude-code-hook-example.json | 2 | ||||
| -rw-r--r-- | recipe | 2 |
4 files changed, 60 insertions, 43 deletions
@@ -54,6 +54,18 @@ Add to your `init.el`: ### Claude Code Hook Setup +#### Option A: Automatic via `/update-config` skill + +If you use [Claude Code](https://claude.ai/code), you can set up the hook automatically. Type this in Claude Code: + +``` +/update-config Add a UserPromptSubmit hook that reads ~/.config/emacs/claude-code-context.json and injects it into the prompt +``` + +Claude Code's `update-config` skill will read your existing `~/.claude/settings.json`, merge in the hook safely, and validate the result. + +#### Option B: Manual + Add this hook configuration to your `~/.claude/settings.json`: ```json @@ -64,7 +76,7 @@ Add this hook configuration to your `~/.claude/settings.json`: "hooks": [ { "type": "command", - "command": "CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" + "command": "CONTEXT_FILE=\"${XDG_CONFIG_HOME:-$HOME/.config}/emacs/claude-code-context.json\"; [ -f \"$CONTEXT_FILE\" ] || CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" } ] } @@ -85,10 +97,10 @@ When `claude-code-context-mode` is enabled, your current buffer context is autom | Keybinding | Command | Description | |-------------|---------------------------------|------------------------------------------------| -| `C-c C-l u` | `claude-code-update-context` | Manually update context | -| `C-c C-l d` | `claude-code-add-diagnostics` | Add flymake diagnostics to context | -| `C-c C-l c` | `claude-code-clear-context` | Clear the context file | -| `C-c C-l m` | `claude-code-context-mode` | Toggle automatic context mode | +| `C-c C-l u` | `claude-code-context-update-context` | Manually update context | +| `C-c C-l d` | `claude-code-context-add-diagnostics` | Add flymake diagnostics to context | +| `C-c C-l c` | `claude-code-context-clear-context` | Clear the context file | +| `C-c C-l m` | `claude-code-context-mode` | Toggle automatic context mode | ### Workflow Example @@ -103,7 +115,7 @@ When `claude-code-context-mode` is enabled, your current buffer context is autom The context file is JSON format for easy parsing and includes: -- **file**: Full path to the current buffer's file +- **buffer**: Full path to the current buffer's file, or buffer name for non-file buffers (e.g. `*Messages*`). Selections work in all buffers — select the relevant text to include it in context. - **line**: Current line number - **column**: Current column number - **modified**: Boolean indicating if the buffer has unsaved changes @@ -114,7 +126,7 @@ Example context: ```json { - "file": "/Users/username/project/src/main.py", + "buffer": "/Users/username/project/src/main.py", "line": 42, "column": 8, "modified": true, diff --git a/claude-code-context.el b/claude-code-context.el index f98ee33..73923cd 100644 --- a/claude-code-context.el +++ b/claude-code-context.el @@ -1,9 +1,10 @@ -;;; claude-code-context.el --- Share Emacs context with Claude Code -*- lexical-binding: t; -*- +;;; claude-code-context.el --- Share buffer context with Claude Code -*- lexical-binding: t; -*- ;; Copyright (C) 2025 Luke Hoersten ;; Author: Luke Hoersten <[email protected]> -;; URL: https://github.com/lhoersten/claude-code-context +;; Maintainer: Luke Hoersten <[email protected]> +;; URL: https://github.com/lukehoersten/claude-code-context ;; Version: 0.1.0 ;; Package-Requires: ((emacs "27.1")) ;; Keywords: tools, ai, convenience @@ -25,7 +26,7 @@ ;;; Commentary: -;; This package automatically shares your current Emacs buffer context +;; This package automatically shares your current buffer context ;; (file, line, column, selection, and diagnostics) with Claude Code ;; via a context file that Claude Code hooks can read. ;; @@ -42,7 +43,7 @@ ;; "hooks": [ ;; { ;; "type": "command", -;; "command": "CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" +;; "command": "CONTEXT_FILE=\"${XDG_CONFIG_HOME:-$HOME/.config}/emacs/claude-code-context.json\"; [ -f \"$CONTEXT_FILE\" ] || CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" ;; } ;; ] ;; } @@ -59,7 +60,7 @@ ;;; Code: (defgroup claude-code-context nil - "Share Emacs context with Claude Code." + "Share buffer context with Claude Code." :group 'tools :prefix "claude-code-context-") @@ -77,22 +78,22 @@ (defvar claude-code-context-timer nil "Timer for updating Claude Code context.") -(defun claude-code--get-current-context () +(defun claude-code-context--get-current-context () "Get current buffer context as an alist." - (when (buffer-file-name) - (let* ((file (buffer-file-name)) + (unless (minibufferp) + (let* ((file (or (buffer-file-name) (buffer-name))) (line (line-number-at-pos)) (col (current-column)) - (modified (buffer-modified-p)) + (modified (and (buffer-file-name) (buffer-modified-p))) (selection (when (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end))))) - `((file . ,file) + `((buffer . ,file) (line . ,line) (column . ,col) (modified . ,(if modified t :json-false)) ,@(when selection `((selection . ,selection))))))) -(defun claude-code--get-flymake-diagnostics () +(defun claude-code-context--get-flymake-diagnostics () "Get flymake diagnostics for current buffer as a list." (when (and (bound-and-true-p flymake-mode) (buffer-file-name)) @@ -106,20 +107,20 @@ (text . ,(flymake-diagnostic-text diag)))) diags))))) -(defun claude-code-update-context () +(defun claude-code-context-update-context () "Update Claude Code context file with current buffer state." (interactive) - (let ((context (claude-code--get-current-context))) + (let ((context (claude-code-context--get-current-context))) (when context (with-temp-file claude-code-context-file (insert (json-encode context))) (message "Claude Code context updated")))) -(defun claude-code-add-diagnostics () +(defun claude-code-context-add-diagnostics () "Add flymake diagnostics to Claude Code context file." (interactive) - (let ((context (claude-code--get-current-context)) - (diags (claude-code--get-flymake-diagnostics))) + (let ((context (claude-code-context--get-current-context)) + (diags (claude-code-context--get-flymake-diagnostics))) (when context (when diags (setq context (append context `((diagnostics . ,diags))))) @@ -127,25 +128,25 @@ (insert (json-encode context))) (message "Claude Code context updated with diagnostics")))) -(defun claude-code-clear-context () +(defun claude-code-context-clear-context () "Clear the Claude Code context file." (interactive) (when (file-exists-p claude-code-context-file) (delete-file claude-code-context-file) (message "Claude Code context cleared"))) -(defun claude-code--update-context-timer () +(defun claude-code-context--update-context-timer () "Timer function to update context periodically." - (when (and (buffer-file-name) - (not (minibufferp))) - (claude-code-update-context))) + (with-current-buffer (window-buffer (selected-window)) + (unless (minibufferp) + (claude-code-context-update-context)))) (defun claude-code-context-mode-enable () "Enable automatic context updates." (unless claude-code-context-timer (setq claude-code-context-timer (run-with-idle-timer claude-code-context-update-interval t - #'claude-code--update-context-timer)) + #'claude-code-context--update-context-timer)) (message "Claude Code context mode enabled"))) (defun claude-code-context-mode-disable () @@ -155,27 +156,31 @@ (setq claude-code-context-timer nil) (message "Claude Code context mode disabled"))) +(defvar claude-code-context-command-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "u") #'claude-code-context-update-context) + (define-key map (kbd "d") #'claude-code-context-add-diagnostics) + (define-key map (kbd "c") #'claude-code-context-clear-context) + (define-key map (kbd "m") #'claude-code-context-mode) + map) + "Keymap for claude-code-context commands.") + +(defvar claude-code-context-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-l") claude-code-context-command-map) + map) + "Keymap for `claude-code-context-mode'.") + ;;;###autoload (define-minor-mode claude-code-context-mode "Minor mode for automatic Claude Code context updates." :global t :lighter " CC" + :keymap claude-code-context-mode-map :group 'claude-code-context (if claude-code-context-mode (claude-code-context-mode-enable) (claude-code-context-mode-disable))) -;; Keybindings -(defvar claude-code-context-command-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "u") #'claude-code-update-context) - (define-key map (kbd "d") #'claude-code-add-diagnostics) - (define-key map (kbd "c") #'claude-code-clear-context) - (define-key map (kbd "m") #'claude-code-context-mode) - map) - "Keymap for claude-code-context commands.") - -(global-set-key (kbd "C-c C-l") claude-code-context-command-map) - (provide 'claude-code-context) ;;; claude-code-context.el ends here diff --git a/claude-code-hook-example.json b/claude-code-hook-example.json index 8cc880f..2547e5a 100644 --- a/claude-code-hook-example.json +++ b/claude-code-hook-example.json @@ -7,7 +7,7 @@ "hooks": [ { "type": "command", - "command": "CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" + "command": "CONTEXT_FILE=\"${XDG_CONFIG_HOME:-$HOME/.config}/emacs/claude-code-context.json\"; [ -f \"$CONTEXT_FILE\" ] || CONTEXT_FILE=\"$HOME/.emacs.d/claude-code-context.json\"; if [ -f \"$CONTEXT_FILE\" ]; then echo \"\\n---\\n## Emacs Context\\n\"; cat \"$CONTEXT_FILE\"; echo \"\\n---\"; fi" } ] } @@ -1,4 +1,4 @@ (claude-code-context - :repo "lhoersten/claude-code-context" + :repo "lukehoersten/claude-code-context" :fetcher github :files ("claude-code-context.el")) |
