Claude Code provides a CLI interface to Claude that maintains full project context and can execute commands directly. The claude-code.el package integrates this into Emacs, giving you access to Claude's capabilities without leaving your editor.

Key Integration Points

Project Scope Management

Claude Code operates on entire directory trees rather than individual files. When you start a session from your project root, Claude has read access to all files in that directory and can understand relationships between components, build configurations, and test files.

Terminal Backend

The integration uses a terminal emulator (eat or vterm) to run Claude Code's CLI. This means Claude can execute shell commands, run tests, install dependencies, and interact with git - not just generate code suggestions.

Context Preservation

Sessions persist across Emacs restarts. You can resume conversations, and Claude maintains awareness of previous changes made to your codebase during that session.

Error Location Awareness

The claude-code-fix-error-at-point function sends Claude both the error message and surrounding code context, including file paths and line numbers. Claude can then make targeted fixes with full understanding of the error's location.

Installation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  ;; Terminal backend for Claude's command execution
  (use-package eat
    :straight (:type git
                     :host codeberg
                     :repo "akib/emacs-eat"
                     :files ("*.el" ("term" "term/*.el") "*.texi"
                             "*.ti" ("terminfo/e" "terminfo/e/*")
                             ("terminfo/65" "terminfo/65/*") 
                             ("integration" "integration/*")
                             (:exclude ".dir-locals.el" "*-tests.el")))
    :config
    ;; Make URLs clickable in eat buffers
    (add-hook 'eat-mode-hook #'goto-address-mode))

  ;; Force dark theme colors globally for eat terminal
  ;; This sets the color palette before any eat buffer is created
  (with-eval-after-load 'eat
    (setq eat-term-color-0  "#808080"   ; black -> gray (visible on dark bg)
          eat-term-color-1  "#ff6b6b"   ; red
          eat-term-color-2  "#69ff94"   ; green
          eat-term-color-3  "#ffff6b"   ; yellow
          eat-term-color-4  "#6bb5ff"   ; blue
          eat-term-color-5  "#ff6bff"   ; magenta
          eat-term-color-6  "#6bffff"   ; cyan
          eat-term-color-7  "#e0e0e0"   ; white
          eat-term-color-8  "#a0a0a0"   ; bright black
          eat-term-color-9  "#ff8a8a"   ; bright red
          eat-term-color-10 "#8affb0"   ; bright green
          eat-term-color-11 "#ffff8a"   ; bright yellow
          eat-term-color-12 "#8ac5ff"   ; bright blue
          eat-term-color-13 "#ff8aff"   ; bright magenta
          eat-term-color-14 "#8affff"   ; bright cyan
          eat-term-color-15 "#ffffff")) ; bright white

  ;; Force dark background in eat buffers
  (defun my/eat-force-dark-background ()
    "Force dark background for eat buffers."
    (setq-local buffer-face-mode-face '(:background "#1e1e1e" :foreground "#e0e0e0"))
    (buffer-face-mode 1))

  (add-hook 'eat-mode-hook #'my/eat-force-dark-background)

  ;; Notify process of window size changes
  (add-hook 'eat-mode-hook
            (lambda ()
              (add-hook 'window-size-change-functions
                        (lambda (_frame)
                          (when (and (eq major-mode 'eat-mode)
                                     eat-terminal)
                            (eat-term-resize eat-terminal
                                             (window-max-chars-per-line)
                                             (window-text-height))))
                        nil t)))

  ;; Optional: IDE features like go-to-definition
  (use-package monet
    :straight (:type git :host github :repo "stevemolitor/monet"))

  ;; Main Claude Code package
  (use-package claude-code
    :straight (:type git :host github :repo "stevemolitor/claude-code.el")
    :bind-keymap ("C-c c" . claude-code-command-map)
    :config
    ;; Enable IDE integration
    (add-hook 'claude-code-process-environment-functions #'monet-start-server-function)
    (monet-mode 1))

Usage

Starting Sessions

  • C-c c c (claude-code): Start from current buffer's directory
  • C-c c d (claude-code-start-in-directory): Select specific directory scope

Sending Context

  • C-c c e (claude-code-fix-error-at-point): Send error at cursor with surrounding context
  • C-c c r (claude-code-send-region): Send selected region or current buffer
  • C-c c o (claude-code-send-buffer-file): Send entire current file
  • C-c c s (claude-code-send-command): Send arbitrary text command

Session Management

  • C-c c C (claude-code-continue): Resume last session
  • C-c c R (claude-code-resume): Select from all previous sessions
  • C-c c k (claude-code-kill): Terminate current session

Working Patterns

Directory Scope Selection

The choice of starting directory determines Claude's file access scope. Starting from a project root gives access to build files, documentation, and full source tree. Starting from a subdirectory limits scope to that subtree, which can be useful for large monorepos or when working with sensitive files.

Multi-File Operations

Claude can modify multiple files in a single response when it has appropriate context. For example, renaming a function will update its definition, all call sites, tests, and documentation if they're within the accessible directory tree.

Terminal Integration

Commands execute in a persistent shell session. This means environment variables, directory changes, and installed packages persist throughout the session. Claude can run test suites, install dependencies, and create git commits as part of its responses.

Error Context

claude-code-fix-error-at-point sends the error message, cursor position, and surrounding code context. This often provides sufficient information for Claude to identify the root cause and implement fixes across related files.

Session Continuity

Conversations persist across Emacs sessions. Claude maintains context about previous modifications and can refer to earlier parts of the conversation when making new changes.

Command Reference

Key BindingFunctionDescription
C-c c cclaude-codeStart session from current directory
C-c c dclaude-code-start-in-directoryStart session with directory selection
C-c c eclaude-code-fix-error-at-pointSend error context to Claude
C-c c rclaude-code-send-regionSend region or buffer content
C-c c oclaude-code-send-buffer-fileSend current file
C-c c sclaude-code-send-commandSend text command
C-c c Cclaude-code-continueResume last session
C-c c Rclaude-code-resumeSelect previous session
C-c c kclaude-code-killTerminate current session
C-c c mclaude-code-transientOpen command menu
C-c c bclaude-code-switch-to-bufferSwitch to Claude buffer
C-c c zclaude-code-toggle-read-only-modeToggle text selection mode

Configuration Notes

The package requires a terminal emulator backend (eat or vterm) and assumes Claude Code CLI is available in your PATH. The optional Monet integration provides IDE features like go-to-definition within Claude sessions.

Directory selection affects performance and response relevance. Large codebases benefit from scoping to specific subtrees. The persistent shell session means Claude can maintain state across multiple commands within a session.

References