Skip to content

Latest commit

 

History

History
90 lines (69 loc) · 3.78 KB

File metadata and controls

90 lines (69 loc) · 3.78 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Critical Warning: Literate Configuration

ALL edits go in config.org, NEVER in config.el.

config.el is auto-generated by tangling config.org via Doom's :config literate module. Direct edits will be overwritten on doom sync.

Commands

doom sync      # Run after ANY config changes (tangles, installs packages, rebuilds)
doom upgrade   # Update Doom and all packages
doom doctor    # Diagnose configuration issues
doom env       # Regenerate environment snapshot

File Purposes

File Edit? Purpose
config.org YES Literate source of truth with org-mode + embedded elisp
config.el NO Auto-generated, never edit
init.el YES Enable/disable Doom modules via doom! macro
packages.el YES Declare packages via package! macro (no config here)
elfeed-config.el YES Standalone RSS/elfeed scoring config
remarkable-config.el YES Standalone reMarkable tablet integration (load!-ed from config.org)

Doom Conventions

Use Doom macros where still applicable:

  • map! not define-key — EXCEPTION: define-key is fine (and idiomatic) when building a standalone sparse keymap inside a defvar initializer (e.g. bmg/ai-command-map, remarkable-command-map); map! cannot produce a keymap value there. Never re-label an existing Doom :prefix with a which-key label — it silently wipes every binding under that prefix (Doom commit 635bc939d); use a bare :prefix "n" or which-key-add-keymap-based-replacements.

Use standard Emacs equivalents (Doom versions are deprecated):

  • setopt for defcustom variables (validates types); use setq for non-defcustom variables (Doom + prefixed vars, defvar) and complex template structures that fail setopt type validation (e.g., capture templates, agenda commands)
  • with-eval-after-load not after!
  • use-package not use-package!

Wrap all package configuration in with-eval-after-load blocks:

(with-eval-after-load 'org
  (setopt org-directory "~/Documents/org/"))

Code Style

  • Custom functions use bmg/ prefix — EXCEPTION: the reMarkable integration uses a remarkable- prefix as an embedded pseudo-package (it has its own defgroup); keep that prefix consistent within the section
  • Sections delimited with ;;; BEGIN_SectionName / ;;; END_SectionName markers
  • All elisp files need ;;; filename.el -*- lexical-binding: t; -*- header
  • Config.org uses #+BEGIN_SRC emacs-lisp blocks for code

Key Architecture Notes

  • No Evil mode - Uses standard Emacs keybindings
  • Corfu + Vertico for completion (not Company/Ivy)
  • LSP + tree-sitter for all supported languages
  • Format on save enabled via (format +lsp +onsave), but gated to projects that declare a formatter (treefmt.nix, .clang-format, rustfmt.toml, ...) — see the FormatOnSave section in config.org. +lsp formatting is always whole-buffer, so ungated it rewrites entire files in foreign repos. Override per project with bmg/format-on-save in .dir-locals.el. Note .editorconfig is intentionally not an opt-in marker.
  • Org-roam for Zettelkasten at ~/Documents/org/roam/
  • GitHub Copilot for inline completions via copilot.el
  • API keys stored in ~/.authinfo.gpg

LSP Servers

  • Nix: nixd with flake expressions pointing to ~/.dotfiles
  • C/C++: clangd with background indexing and clang-tidy
  • Others: Standard LSP servers

Testing Changes

  1. Edit config.org
  2. Run doom sync
  3. Restart Emacs or M-x doom/reload
  4. Verify with doom doctor

See .github/copilot-instructions.md for comprehensive details on modules, keybindings, and org-mode configuration.