Compare commits
31
Commits
788b862e5b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c406c0f051 | ||
|
|
46a54a167f | ||
|
|
5d31ed089d | ||
|
|
a14cf7865e | ||
|
|
2b5423a925 | ||
|
|
7bfdf5c028 | ||
|
|
95b50b3a10 | ||
|
|
a06f2f5b18 | ||
|
|
7d6e9f500b | ||
|
|
b5bb42cca6 | ||
|
|
7d0b244e22 | ||
|
|
72726d6108 | ||
|
|
53fb673dae | ||
|
|
20a2f69501 | ||
|
|
ec119361e5 | ||
|
|
94c9caa171 | ||
|
|
72e1ab8c7e | ||
|
|
f99f7a9751 | ||
|
|
49b64da74d | ||
|
|
0c061e37ab | ||
|
|
4be0e63fac | ||
|
|
cb6d55b456 | ||
|
|
c021bc8452 | ||
|
|
298a9913b5 | ||
|
|
62dd22b544 | ||
|
|
5000e00fb6 | ||
|
|
5d369dd3b5 | ||
|
|
fafe8f4ab5 | ||
|
|
c23a1ba64a | ||
|
|
e1b3fe7244 | ||
|
|
48f26adf81 |
+21
@@ -0,0 +1,21 @@
|
|||||||
|
# Emacs temporary files
|
||||||
|
*~
|
||||||
|
\#*\#
|
||||||
|
.#*
|
||||||
|
*.elc
|
||||||
|
|
||||||
|
# Doom/Package generated
|
||||||
|
auto-save-list/
|
||||||
|
tramp/
|
||||||
|
keyfreq.html
|
||||||
|
|
||||||
|
# AI Assistant folders
|
||||||
|
.claude/
|
||||||
|
.opencode/
|
||||||
|
|
||||||
|
# MacOS (just in case)
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
# AGENTS.md — Doom Emacs Configuration
|
||||||
|
|
||||||
|
This is a Doom Emacs 3 personal configuration at `~/.config/doom/`.
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
doom/
|
||||||
|
├── init.el # Module declarations (doom! macro)
|
||||||
|
├── config.el # Main config, loads modular files via load!
|
||||||
|
├── packages.el # Package declarations (package! macro)
|
||||||
|
├── core.el # Core settings and super-save
|
||||||
|
├── custom.el # Emacs custom variables (auto-generated)
|
||||||
|
├── security.el # Security settings
|
||||||
|
├── org.el # Org-mode configuration
|
||||||
|
├── metrics.el # Usage tracking (keyfreq)
|
||||||
|
├── theme.el # Theme configuration
|
||||||
|
├── inbox.el # Quick capture inbox
|
||||||
|
├── ai/
|
||||||
|
│ ├── agents.el # Claude Code & Gemini CLI configuration
|
||||||
|
│ └── gptel.el # GPTel (ChatGPT) configuration
|
||||||
|
├── development/
|
||||||
|
│ ├── lsp.el # LSP/LSP-UI configuration
|
||||||
|
│ ├── cpp.el # C++ development settings
|
||||||
|
│ ├── nix.el # Nix development settings
|
||||||
|
│ └── misc.el # Miscellaneous dev settings
|
||||||
|
├── docs/
|
||||||
|
│ └── doom-macros-reference.md # Doom macro documentation
|
||||||
|
└── snippets/ # Yasnippet snippets
|
||||||
|
```
|
||||||
|
|
||||||
|
## Doom Commands
|
||||||
|
|
||||||
|
### Essential Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sync config (run after ANY change to init.el, packages.el, or package configs)
|
||||||
|
doom sync
|
||||||
|
|
||||||
|
# Rebuild all packages
|
||||||
|
doom build
|
||||||
|
|
||||||
|
# Diagnose issues
|
||||||
|
doom doctor
|
||||||
|
|
||||||
|
# Update all packages
|
||||||
|
doom sync -u
|
||||||
|
|
||||||
|
# Show verbose output
|
||||||
|
doom -v sync
|
||||||
|
|
||||||
|
# Run in batch mode (for CI/testing)
|
||||||
|
emacs --batch -l ~/.config/doom/config.el --eval "(message \"test\")"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Package Management
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Force sync without prompts
|
||||||
|
doom sync -!
|
||||||
|
|
||||||
|
# Clean up orphaned packages
|
||||||
|
doom sync --gc
|
||||||
|
|
||||||
|
# Install packages only (no rebuild)
|
||||||
|
doom install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing Individual Config Files
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Load a specific config file and check for errors
|
||||||
|
emacs --batch -l ~/.config/emacs/bin/doom -l config.el -l ai/agents.el --eval "(message \"Loaded successfully\")"
|
||||||
|
|
||||||
|
# Check Elisp syntax
|
||||||
|
emacs --batch --eval "(setq lexical-binding t)" -l ai/agents.el --eval "(message \"Syntax OK\")"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style Guidelines (Emacs Lisp)
|
||||||
|
|
||||||
|
### File Headers
|
||||||
|
|
||||||
|
Every `.el` file should start with a standard header:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;;; filename.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Description of what this file does
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lexical Binding
|
||||||
|
|
||||||
|
Always use `lexical-binding: t` (note the dash, not underscore in the file-local variable).
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;;; init.el -*- lexical-binding: t; -*-
|
||||||
|
```
|
||||||
|
|
||||||
|
### Naming Conventions
|
||||||
|
|
||||||
|
| Element | Convention | Example |
|
||||||
|
|---------|------------|---------|
|
||||||
|
| Private functions | `+prefix--name` | `+org--restart-mode-h` |
|
||||||
|
| Hook functions | `+module-hook-function-h` | `+org-exclude-agenda-buffers-from-workspace-h` |
|
||||||
|
| Variables | `+module-variable-name` | `+org--restart-mode-h` |
|
||||||
|
| Package hooks | `-module-hook-function-h` | `-org-exclude-agenda-buffers-from-workspace-h` |
|
||||||
|
| Doom modules | `:module` | `:lang`, `:completion` |
|
||||||
|
| Module flags | `+flag` | `+orderless`, `+lsp` |
|
||||||
|
| Constants | `SCREAMING-SNAKE` | `MAX-HEIGHT` |
|
||||||
|
|
||||||
|
### Keybinding Syntax (map!)
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Basic keybindings
|
||||||
|
(map! :n "C-s" #'consult-line)
|
||||||
|
|
||||||
|
;; With lambda
|
||||||
|
(map! :n "M-s" (lambda () (interactive) (consult-line (thing-at-point 'symbol))))
|
||||||
|
|
||||||
|
;; Leader key with prefix
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("C" . "claude-code")
|
||||||
|
:desc "Start Claude" "c" #'claude-code
|
||||||
|
:desc "Kill Claude" "k" #'claude-code-kill))
|
||||||
|
|
||||||
|
;; State modifiers: :n (normal), :v (visual), :i (insert), :e (emacs)
|
||||||
|
(map! :nv "C-j" #'something)
|
||||||
|
```
|
||||||
|
|
||||||
|
### use-package! vs use-package
|
||||||
|
|
||||||
|
- Use `use-package!` in Doom configs (macro version)
|
||||||
|
- Use `use-package` when referring to the built-in package.el macro
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Doom configuration
|
||||||
|
(use-package! org-roam
|
||||||
|
:after org
|
||||||
|
:custom
|
||||||
|
(org-roam-directory "~/org/roam")
|
||||||
|
:config
|
||||||
|
(org-roam-db-autosync-mode))
|
||||||
|
|
||||||
|
;; Standard Emacs (when needed)
|
||||||
|
(use-package org
|
||||||
|
:init
|
||||||
|
(setq org-todo-keywords '("TODO" "DONE"))
|
||||||
|
:config
|
||||||
|
(org-mode 1))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hook Registration
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Anonymous function with defun inside
|
||||||
|
(add-hook! 'org-agenda-finalize-hook
|
||||||
|
(defun +org-exclude-agenda-buffers-from-workspace-h ()
|
||||||
|
"Don't associate temporary agenda buffers with current workspace."
|
||||||
|
(when org-agenda-new-buffers
|
||||||
|
(persp-remove-buffer org-agenda-new-buffers
|
||||||
|
(get-current-persp)
|
||||||
|
nil))))
|
||||||
|
|
||||||
|
;; :local makes hook buffer-local
|
||||||
|
(add-hook! :local 'some-mode-hook
|
||||||
|
(defun my-local-hook ()
|
||||||
|
(do-something)))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Loading
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; After package loads (preferred in Doom)
|
||||||
|
(after! lsp-ui
|
||||||
|
(setq lsp-ui-doc-enable t))
|
||||||
|
|
||||||
|
;; With feature check
|
||||||
|
(when (featurep! :system 'macos)
|
||||||
|
(setq mac-command-modifier 'meta))
|
||||||
|
|
||||||
|
;; After multiple packages
|
||||||
|
(after! (org org-roam)
|
||||||
|
(require 'org-roam-protocol))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Defcustom vs Defvar
|
||||||
|
|
||||||
|
- Use `defcustom` for user-configurable settings that belong in `custom.el`
|
||||||
|
- Use `defvar` or `setq` for internal variables
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; In packages.el (for user customization)
|
||||||
|
(setq org-directory "~/org/")
|
||||||
|
|
||||||
|
;; Not a defcustom unless it belongs in custom.el
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Use quiet! to suppress output
|
||||||
|
(quiet! (org-mode-restart))
|
||||||
|
|
||||||
|
;; Use fn! or #' for function references
|
||||||
|
(advice-add #'org-capture :around
|
||||||
|
(lambda (fun &rest args)
|
||||||
|
(letf! ((#'+org--restart-mode-h #'ignore))
|
||||||
|
(apply fun args))))
|
||||||
|
|
||||||
|
;; Use ignore when function should do nothing
|
||||||
|
(defalias '+org--restart-mode-h #'ignore)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Package Recipes (packages.el)
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Simple package from Melpa
|
||||||
|
(package! super-save)
|
||||||
|
|
||||||
|
;; GitHub recipe with custom files
|
||||||
|
(package! copilot
|
||||||
|
:recipe (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")))
|
||||||
|
|
||||||
|
;; GitHub with exclusion patterns
|
||||||
|
(package! eat
|
||||||
|
:recipe (:host codeberg
|
||||||
|
:repo "akib/emacs-eat"
|
||||||
|
:files ("*.el" ("term" "term/*.el") "*.texi"
|
||||||
|
"*.ti" ("terminfo/e" "terminfo/e/*")
|
||||||
|
(:exclude ".dir-locals.el" "*-tests.el"))))
|
||||||
|
|
||||||
|
;; Disable a package
|
||||||
|
(package! some-package :disable t)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Restart/Reload Functions
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(defun +org--restart-mode-h ()
|
||||||
|
"Restart org-mode on buffer switch."
|
||||||
|
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h 'local)
|
||||||
|
(cl-delete (current-buffer) org-agenda-new-buffers :test 'eq)
|
||||||
|
(quiet! (org-mode-restart))
|
||||||
|
(run-hooks 'find-file-hook))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advice Around Functions
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(advice-add #'org-capture :around
|
||||||
|
(lambda (fun &rest args)
|
||||||
|
(letf! ((#'+org--restart-mode-h #'ignore))
|
||||||
|
(apply fun args))))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Buffer Display Configuration
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(add-to-list 'display-buffer-alist
|
||||||
|
'("^\\*claude"
|
||||||
|
(display-buffer-in-side-window)
|
||||||
|
(side . right)
|
||||||
|
(window-width . 90)))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
;; Unset for subprocess access
|
||||||
|
(setenv "CLAUDECODE" nil)
|
||||||
|
|
||||||
|
;; Set with path
|
||||||
|
(setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH")))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Doom Module System
|
||||||
|
|
||||||
|
The `init.el` uses the `doom!` macro to declare enabled modules:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(doom! :category
|
||||||
|
(module +flag)
|
||||||
|
:another-category)
|
||||||
|
```
|
||||||
|
|
||||||
|
Modules referenced in this config:
|
||||||
|
- `:completion` — Vertico, Corfu
|
||||||
|
- `:ui` — Doom dashboard, treemacs, workspaces
|
||||||
|
- `:editor` — Evil, format+, multiple-cursors
|
||||||
|
- `:emacs` — Dired, ibuffer, undo
|
||||||
|
- `:term` — Eshell, vterm
|
||||||
|
- `:checkers` — Syntax, spell
|
||||||
|
- `:tools` — LSP, magit, direnv, docker
|
||||||
|
- `:lang` — Python, Go, Rust, Org, JavaScript, etc.
|
||||||
|
- `:config` — Default bindings, smartparens
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
1. Run `doom sync` after ANY change to `init.el`, `packages.el`, or `config.el`
|
||||||
|
2. Use `doom build` to rebuild if byte-compilation errors occur
|
||||||
|
3. This config uses straight.el for package management (via Doom)
|
||||||
|
4. Custom variables are auto-generated to `custom.el` — don't edit manually
|
||||||
|
5. The `load!` macro loads relative to `doom-private-dir` (this config directory)
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
;;; ai.el -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
(setq gptel-model 'google/gemini-2.5-flash ;; Default model
|
|
||||||
gptel-backend
|
|
||||||
(gptel-make-openai "OpenRouter" ;Any name you want
|
|
||||||
:host "openrouter.ai"
|
|
||||||
:endpoint "/api/v1/chat/completions"
|
|
||||||
:stream t
|
|
||||||
:key "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" ;can be a function that returns the key
|
|
||||||
:models '(google/gemini-2.5-flash
|
|
||||||
google/gemini-2.5-pro
|
|
||||||
anthropic/claude-sonnet-4
|
|
||||||
anthropic/claude-sonnet-4.5
|
|
||||||
)))
|
|
||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
;;; ai/agents.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; Claude Code Configuration
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
(use-package! claude-code
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
;; Unset CLAUDECODE to allow running Claude Code inside Emacs sub-processes
|
||||||
|
(setenv "CLAUDECODE" nil)
|
||||||
|
(setq claude-code-program "ccr"
|
||||||
|
claude-code-program-switches '("code" "--dangerously-skip-permissions"))
|
||||||
|
|
||||||
|
;; Use Eat backend
|
||||||
|
(setq claude-code-terminal-backend 'eat
|
||||||
|
;; Emacs-style editing in Claude buffer: RET inserts newline, S-RET sends
|
||||||
|
claude-code-newline-keybinding-style 'shift-return-to-send)
|
||||||
|
|
||||||
|
;; Enable global mode
|
||||||
|
(claude-code-mode 1)
|
||||||
|
|
||||||
|
;; Emacs-style prefix key (works without Doom/Evil leader keys)
|
||||||
|
(global-set-key (kbd "C-c c") claude-code-command-map)
|
||||||
|
|
||||||
|
;; Set Doom leader keybindings
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("C" . "claude-code")
|
||||||
|
:desc "Start Claude" "c" #'claude-code
|
||||||
|
:desc "Start in directory" "d" #'claude-code-start-in-directory
|
||||||
|
:desc "Continue conversation" "C" #'claude-code-continue
|
||||||
|
:desc "Resume session" "R" #'claude-code-resume
|
||||||
|
:desc "New instance" "i" #'claude-code-new-instance
|
||||||
|
:desc "Kill Claude" "k" #'claude-code-kill
|
||||||
|
:desc "Kill all instances" "K" #'claude-code-kill-all
|
||||||
|
:desc "Send command" "s" #'claude-code-send-command
|
||||||
|
:desc "Send command with context" "x" #'claude-code-send-command-with-context
|
||||||
|
:desc "Send region/buffer" "r" #'claude-code-send-region
|
||||||
|
:desc "Send buffer file" "o" #'claude-code-send-buffer-file
|
||||||
|
:desc "Fix error at point" "e" #'claude-code-fix-error-at-point
|
||||||
|
:desc "Toggle window" "t" #'claude-code-toggle
|
||||||
|
:desc "Switch to buffer" "b" #'claude-code-switch-to-buffer
|
||||||
|
:desc "Select buffer" "B" #'claude-code-select-buffer
|
||||||
|
:desc "Toggle read-only" "z" #'claude-code-toggle-read-only-mode
|
||||||
|
:desc "Cycle mode" "M" #'claude-code-cycle-mode
|
||||||
|
:desc "Transient menu" "m" #'claude-code-transient
|
||||||
|
:desc "Slash commands" "/" #'claude-code-slash-commands
|
||||||
|
:desc "Fork conversation" "f" #'claude-code-fork
|
||||||
|
:desc "Send return" "y" #'claude-code-send-return
|
||||||
|
:desc "Send escape" "n" #'claude-code-send-escape
|
||||||
|
:desc "Send 1" "1" #'claude-code-send-1
|
||||||
|
:desc "Send 2" "2" #'claude-code-send-2
|
||||||
|
:desc "Send 3" "3" #'claude-code-send-3))
|
||||||
|
|
||||||
|
;; Optional: Configure window display (side window on right)
|
||||||
|
(add-to-list 'display-buffer-alist
|
||||||
|
'("^\\*claude"
|
||||||
|
(display-buffer-in-side-window)
|
||||||
|
(side . right)
|
||||||
|
(window-width . 90)))
|
||||||
|
|
||||||
|
;; Optional: Enable auto-revert for files modified by Claude
|
||||||
|
(global-auto-revert-mode 1)
|
||||||
|
|
||||||
|
;; Optional: Increase vterm scrollback for long conversations
|
||||||
|
(add-hook 'claude-code-start-hook
|
||||||
|
(lambda ()
|
||||||
|
(when (eq claude-code-terminal-backend 'vterm)
|
||||||
|
(setq-local vterm-max-scrollback 100000)))))
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; Gemini CLI Configuration
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
(use-package! gemini-cli
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
;; Set the Gemini executable
|
||||||
|
(setq gemini-cli-program "gemini"
|
||||||
|
gemini-cli-program-switches nil)
|
||||||
|
|
||||||
|
;; Use Eat backend
|
||||||
|
(setq gemini-cli-terminal-backend 'eat
|
||||||
|
;; Emacs-style editing in Gemini buffer: RET inserts newline, S-RET sends
|
||||||
|
gemini-cli-newline-keybinding-style 'shift-return-to-send)
|
||||||
|
|
||||||
|
;; Enable global mode
|
||||||
|
(gemini-cli-mode 1)
|
||||||
|
|
||||||
|
;; Emacs-style prefix key
|
||||||
|
(global-set-key (kbd "C-c g") gemini-cli-command-map)
|
||||||
|
|
||||||
|
;; Set Doom leader keybindings under SPC G
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("G" . "gemini-cli")
|
||||||
|
:desc "Start Gemini" "c" #'gemini-cli
|
||||||
|
:desc "Start in directory" "d" #'gemini-cli-start-in-directory
|
||||||
|
:desc "Continue conversation" "C" #'gemini-cli-continue
|
||||||
|
:desc "Resume session" "R" #'gemini-cli-resume
|
||||||
|
:desc "New instance" "i" #'gemini-cli-new-instance
|
||||||
|
:desc "Kill Gemini" "k" #'gemini-cli-kill
|
||||||
|
:desc "Kill all instances" "K" #'gemini-cli-kill-all
|
||||||
|
:desc "Send command" "s" #'gemini-cli-send-command
|
||||||
|
:desc "Send command with context" "x" #'gemini-cli-send-command-with-context
|
||||||
|
:desc "Send region/buffer" "r" #'gemini-cli-send-region
|
||||||
|
:desc "Send buffer file" "o" #'gemini-cli-send-buffer-file
|
||||||
|
:desc "Fix error at point" "e" #'gemini-cli-fix-error-at-point
|
||||||
|
:desc "Toggle window" "t" #'gemini-cli-toggle
|
||||||
|
:desc "Switch to buffer" "b" #'gemini-cli-switch-to-buffer
|
||||||
|
:desc "Select buffer" "B" #'gemini-cli-select-buffer
|
||||||
|
:desc "Toggle read-only" "z" #'gemini-cli-toggle-read-only-mode
|
||||||
|
:desc "Cycle mode" "M" #'gemini-cli-cycle-mode
|
||||||
|
:desc "Transient menu" "m" #'gemini-cli-transient
|
||||||
|
:desc "Slash commands" "/" #'gemini-cli-slash-commands
|
||||||
|
:desc "Fork conversation" "f" #'gemini-cli-fork
|
||||||
|
:desc "Send return" "y" #'gemini-cli-send-return
|
||||||
|
:desc "Send escape" "n" #'gemini-cli-send-escape
|
||||||
|
:desc "Send 1" "1" #'gemini-cli-send-1
|
||||||
|
:desc "Send 2" "2" #'gemini-cli-send-2
|
||||||
|
:desc "Send 3" "3" #'gemini-cli-send-3))
|
||||||
|
|
||||||
|
;; Optional: Configure window display (side window on right)
|
||||||
|
(add-to-list 'display-buffer-alist
|
||||||
|
'("^\\*gemini"
|
||||||
|
(display-buffer-in-side-window)
|
||||||
|
(side . right)
|
||||||
|
(window-width . 90)))
|
||||||
|
|
||||||
|
;; Optional: Increase vterm scrollback for long conversations
|
||||||
|
(add-hook 'gemini-cli-start-hook
|
||||||
|
(lambda ()
|
||||||
|
(when (eq gemini-cli-terminal-backend 'vterm)
|
||||||
|
(setq-local vterm-max-scrollback 100000)))))
|
||||||
+205
@@ -0,0 +1,205 @@
|
|||||||
|
;;; ai/gptel.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; gptel Configuration
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
;; Core gptel setup
|
||||||
|
(use-package! gptel
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
;; Default backend: OpenRouter
|
||||||
|
(setq gptel-model 'google/gemini-3-flash-preview
|
||||||
|
gptel-backend
|
||||||
|
(gptel-make-openai "OpenRouter"
|
||||||
|
:host "openrouter.ai"
|
||||||
|
:endpoint "/api/v1/chat/completions"
|
||||||
|
:stream t
|
||||||
|
:key "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"
|
||||||
|
:models '(google/gemini-3-flash-preview
|
||||||
|
x-ai/grok-4.1-fast
|
||||||
|
x-ai/grok-code-fast-1
|
||||||
|
google/gemini-3-pro-preview
|
||||||
|
anthropic/claude-sonnet-4.5)))
|
||||||
|
|
||||||
|
;; Use org-mode by default for better note-taking
|
||||||
|
(setq gptel-default-mode 'org-mode)
|
||||||
|
|
||||||
|
;; Move cursor to end of response automatically
|
||||||
|
(add-hook 'gptel-post-response-functions 'gptel-end-of-response)
|
||||||
|
|
||||||
|
;; Keybindings - using SPC A for AI (uppercase to avoid conflicts)
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("A" . "AI/gptel")
|
||||||
|
:desc "gptel chat" "g" #'gptel
|
||||||
|
:desc "gptel send" "s" #'gptel-send
|
||||||
|
:desc "gptel menu" "m" #'gptel-menu
|
||||||
|
:desc "gptel rewrite" "r" #'gptel-rewrite
|
||||||
|
:desc "Add context" "c" #'gptel-add
|
||||||
|
:desc "Add file to context" "f" #'gptel-add-file))
|
||||||
|
|
||||||
|
;; Additional keybindings in gptel buffer
|
||||||
|
(map! :map gptel-mode-map
|
||||||
|
"C-c RET" #'gptel-send
|
||||||
|
"C-c C-k" #'gptel-abort
|
||||||
|
"C-c C-c" #'gptel-menu))
|
||||||
|
|
||||||
|
;; gptel presets for different tasks
|
||||||
|
(after! gptel
|
||||||
|
;; Coding assistant preset
|
||||||
|
(gptel-make-preset 'coder
|
||||||
|
:description "Expert coding assistant"
|
||||||
|
:backend "OpenRouter"
|
||||||
|
:model 'anthropic/claude-sonnet-4.5
|
||||||
|
:system "You are an expert coding assistant. Provide high-quality code solutions, refactorings, and explanations. Be concise but thorough. Include error handling and follow best practices.")
|
||||||
|
|
||||||
|
;; Code explainer preset
|
||||||
|
(gptel-make-preset 'explain
|
||||||
|
:description "Explain code to beginners"
|
||||||
|
:system "Explain this code to a novice programmer. Use simple language and break down complex concepts.")
|
||||||
|
|
||||||
|
;; Refactoring preset
|
||||||
|
(gptel-make-preset 'refactor
|
||||||
|
:description "Code refactoring expert"
|
||||||
|
:model 'anthropic/claude-sonnet-4.5
|
||||||
|
:system "You are a code refactoring expert. Improve code quality, readability, and performance while maintaining functionality. Explain your changes.")
|
||||||
|
|
||||||
|
;; Quick answers preset
|
||||||
|
(gptel-make-preset 'quick
|
||||||
|
:description "Quick, concise answers"
|
||||||
|
:model 'google/gemini-3-flash-preview
|
||||||
|
:system "Provide quick, concise answers. Be direct and to the point.")
|
||||||
|
|
||||||
|
;; Documentation writer preset
|
||||||
|
(gptel-make-preset 'docs
|
||||||
|
:description "Documentation writer"
|
||||||
|
:system "Write clear, comprehensive documentation. Include examples and explain edge cases."))
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; gptel-quick - Quick lookups and explanations
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
(use-package! gptel-quick
|
||||||
|
:after gptel
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
;; Include context from gptel-add if available
|
||||||
|
(setq gptel-quick-use-context t)
|
||||||
|
|
||||||
|
(map! :leader
|
||||||
|
(:prefix "A"
|
||||||
|
:desc "Quick lookup" "q" #'gptel-quick)))
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; gptel-extensions - Extra utility functions
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
(use-package! gptel-extensions
|
||||||
|
:after gptel
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(map! :leader
|
||||||
|
(:prefix "A"
|
||||||
|
:desc "Load buffer into session" "l" #'gptel-extensions-load-buffer
|
||||||
|
:desc "Send whole buffer" "b" #'gptel-extensions-send-whole-buffer
|
||||||
|
:desc "Refactor region" "R" #'gptel-extensions-refactor)))
|
||||||
|
|
||||||
|
;;; ============================================================================
|
||||||
|
;;; gptel-autocomplete - Inline code completion
|
||||||
|
;;; ============================================================================
|
||||||
|
|
||||||
|
(use-package! gptel-autocomplete
|
||||||
|
:after gptel
|
||||||
|
:defer t
|
||||||
|
:commands (gptel-complete gptel-accept-completion)
|
||||||
|
:config
|
||||||
|
;; Configure context size
|
||||||
|
(setq gptel-autocomplete-before-context-lines 100
|
||||||
|
gptel-autocomplete-after-context-lines 20
|
||||||
|
gptel-autocomplete-temperature 0.1)
|
||||||
|
|
||||||
|
;; Keybindings for autocomplete
|
||||||
|
(map! :leader
|
||||||
|
(:prefix "A"
|
||||||
|
:desc "Complete at point" "C" #'gptel-complete
|
||||||
|
:desc "Accept completion" "a" #'gptel-accept-completion))
|
||||||
|
|
||||||
|
;; Also add convenient keybindings in prog-mode
|
||||||
|
(map! :map prog-mode-map
|
||||||
|
"M-TAB" #'gptel-complete
|
||||||
|
"C-c TAB" #'gptel-complete
|
||||||
|
"C-c C-a" #'gptel-accept-completion))
|
||||||
|
|
||||||
|
(defun my/gptel-quick-explain-region ()
|
||||||
|
"Quickly explain selected code region in the gptel buffer."
|
||||||
|
(interactive)
|
||||||
|
(when (use-region-p)
|
||||||
|
(let* ((code (buffer-substring-no-properties (region-beginning) (region-end)))
|
||||||
|
(buf (get-buffer-create "*gptel*")))
|
||||||
|
;; Prepare the buffer and insert the query immediately
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-max))
|
||||||
|
(unless (derived-mode-p 'gptel-mode)
|
||||||
|
(funcall gptel-default-mode)
|
||||||
|
(gptel-mode 1))
|
||||||
|
(insert "\n\n--- Code to Explain ---\n\n" code "\n\n### Explanation Request Sent...\n"))
|
||||||
|
(display-buffer buf)
|
||||||
|
;; Send the request
|
||||||
|
(gptel-request
|
||||||
|
(format "Explain this code concisely in 2-3 sentences:\n\n%s" code)
|
||||||
|
:system "You are an expert programmer explaining code."
|
||||||
|
:callback (lambda (response info)
|
||||||
|
(with-current-buffer (get-buffer "*gptel*")
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "\n### Code Explanation\n\n" response "\n\n"))
|
||||||
|
(message "Explanation received in *gptel* buffer."))))))
|
||||||
|
|
||||||
|
(defun my/gptel-proofread-region ()
|
||||||
|
"Proofread and improve selected text."
|
||||||
|
(interactive)
|
||||||
|
(when (use-region-p)
|
||||||
|
(gptel-rewrite-region (region-beginning) (region-end)
|
||||||
|
"Fix spelling, grammar, and improve clarity. Keep the same tone and style.")))
|
||||||
|
|
||||||
|
(defun my--get-region-as-path-tag (path-fn)
|
||||||
|
"Helper to get path tag using PATH-FN to determine the file path."
|
||||||
|
(let* ((filename (funcall path-fn))
|
||||||
|
(start-line (line-number-at-pos (if (use-region-p) (region-beginning) (point))))
|
||||||
|
(tag (if (use-region-p)
|
||||||
|
(let* ((end-pos (1- (region-end)))
|
||||||
|
(end-line (line-number-at-pos (max (region-beginning) end-pos))))
|
||||||
|
(format "@%s:%d-%d" filename start-line end-line))
|
||||||
|
(format "@%s:%d" filename start-line))))
|
||||||
|
tag))
|
||||||
|
|
||||||
|
(defun my/copy-region-as-path-tag ()
|
||||||
|
"Copy the current region as a relative path tag: @path/to/file.ext:start-end"
|
||||||
|
(interactive)
|
||||||
|
(let ((tag (my--get-region-as-path-tag
|
||||||
|
(lambda () (file-relative-name (buffer-file-name) (doom-project-root))))))
|
||||||
|
(kill-new tag)
|
||||||
|
(message "Copied: %s" tag)))
|
||||||
|
|
||||||
|
(defun my/copy-region-as-path-tag-absolute ()
|
||||||
|
"Copy the current region as an absolute path tag: @/abs/path/to/file.ext:start-end"
|
||||||
|
(interactive)
|
||||||
|
(let ((tag (my--get-region-as-path-tag #'buffer-file-name)))
|
||||||
|
(kill-new tag)
|
||||||
|
(message "Copied: %s" tag)))
|
||||||
|
|
||||||
|
;; Add keybindings for helper functions
|
||||||
|
(defvar my-ai-helper-map (make-sparse-keymap)
|
||||||
|
"Keymap for my AI helper functions.")
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-c a") my-ai-helper-map)
|
||||||
|
(define-key my-ai-helper-map (kbd "e") #'my/gptel-quick-explain-region)
|
||||||
|
(define-key my-ai-helper-map (kbd "p") #'my/gptel-proofread-region)
|
||||||
|
(define-key my-ai-helper-map (kbd "t") #'my/copy-region-as-path-tag)
|
||||||
|
(define-key my-ai-helper-map (kbd "T") #'my/copy-region-as-path-tag-absolute)
|
||||||
|
|
||||||
|
(map! :leader
|
||||||
|
(:prefix "A"
|
||||||
|
:desc "Quick explain" "e" #'my/gptel-quick-explain-region
|
||||||
|
:desc "Proofread text" "p" #'my/gptel-proofread-region
|
||||||
|
:desc "Copy path tag (relative)" "t" #'my/copy-region-as-path-tag
|
||||||
|
:desc "Copy path tag (absolute)" "T" #'my/copy-region-as-path-tag-absolute))
|
||||||
@@ -3,6 +3,21 @@
|
|||||||
;; Load modular configuration files
|
;; Load modular configuration files
|
||||||
(load! "security")
|
(load! "security")
|
||||||
(load! "core")
|
(load! "core")
|
||||||
(load! "development")
|
(load! "development/lsp")
|
||||||
|
(load! "development/cpp")
|
||||||
|
(load! "development/nix")
|
||||||
|
(load! "development/misc")
|
||||||
(load! "org")
|
(load! "org")
|
||||||
(load! "ai")
|
(load! "ai/gptel")
|
||||||
|
(load! "ai/agents")
|
||||||
|
(load! "inbox")
|
||||||
|
(load! "metrics")
|
||||||
|
(load! "theme")
|
||||||
|
|
||||||
|
;; Performance tweaks
|
||||||
|
(setq gc-cons-threshold 100000000 ; Increase GC threshold to 100MB
|
||||||
|
gc-cons-percentage 0.6)
|
||||||
|
(run-with-idle-timer 5 t #'garbage-collect)
|
||||||
|
|
||||||
|
;; Keybinding to open inbox.el
|
||||||
|
(map! "C-c i" #'(lambda () (interactive) (find-file (expand-file-name "inbox.el" doom-user-dir))))
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
(setq super-save-auto-save-when-idle t)
|
(setq super-save-auto-save-when-idle t)
|
||||||
(setq super-save-idle-duration 1))
|
(setq super-save-idle-duration 1))
|
||||||
|
|
||||||
|
;; Which-key: show keybindings faster
|
||||||
|
(setq which-key-idle-delay 0.01
|
||||||
|
which-key-min-display-time 0.1)
|
||||||
|
|
||||||
;; Search bindings for consult-line
|
;; Search bindings for consult-line
|
||||||
(map!
|
(map!
|
||||||
@@ -19,4 +22,4 @@
|
|||||||
:n "M-s" (lambda () (interactive) (consult-line (thing-at-point 'symbol)))
|
:n "M-s" (lambda () (interactive) (consult-line (thing-at-point 'symbol)))
|
||||||
:n "C-S-s" #'consult-line-multi)
|
:n "C-S-s" #'consult-line-multi)
|
||||||
|
|
||||||
(setq-default show-trailing-whitespace t)
|
(setq-default show-trailing-whitespace nil)
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
;;; -*- lexical-binding: t -*-
|
||||||
|
(custom-set-variables
|
||||||
|
;; custom-set-variables was added by Custom.
|
||||||
|
;; If you edit it by hand, you could mess it up, so be careful.
|
||||||
|
;; Your init file should contain only one such instance.
|
||||||
|
;; If there is more than one, they won't work right.
|
||||||
|
'(custom-safe-themes
|
||||||
|
'("0325a6b5eea7e5febae709dab35ec8648908af12cf2d2b569bedc8da0a3a81c1"
|
||||||
|
"8a379e7ac3a57e64de672dd744d4730b3bdb88ae328e8106f95cd81cbd44e0b6" default)))
|
||||||
|
(custom-set-faces
|
||||||
|
;; custom-set-faces was added by Custom.
|
||||||
|
;; If you edit it by hand, you could mess it up, so be careful.
|
||||||
|
;; Your init file should contain only one such instance.
|
||||||
|
;; If there is more than one, they won't work right.
|
||||||
|
)
|
||||||
-134
@@ -1,134 +0,0 @@
|
|||||||
;;; development.el -*- lexical-binding: t; -*-
|
|
||||||
|
|
||||||
(after! lsp-ui
|
|
||||||
(setq lsp-ui-doc-include-signature t ;; Show method signatures in docs
|
|
||||||
lsp-ui-sideline-show-symbol t ;; Show symbols in the sideline
|
|
||||||
lsp-ui-doc-show-with-cursor t ;; Show docs when cursor is on symbol
|
|
||||||
lsp-ui-doc-max-height 30 ;; Increase doc height to show more info
|
|
||||||
lsp-ui-sideline-show-hover t ;; Show hover information in sideline
|
|
||||||
lsp-ui-doc-enable t ;; Enable documentation
|
|
||||||
lsp-signature-auto-activate t ;; Show signature help automatically
|
|
||||||
lsp-signature-render-documentation t)) ;; Include docs in signature help
|
|
||||||
|
|
||||||
(after! eldoc
|
|
||||||
(setq eldoc-echo-area-use-multiline-p t
|
|
||||||
eldoc-echo-area-prefer-doc-buffer t))
|
|
||||||
|
|
||||||
(use-package! corfu-popupinfo
|
|
||||||
:after corfu
|
|
||||||
:hook (corfu-mode . corfu-popupinfo-mode)
|
|
||||||
:custom
|
|
||||||
(corfu-popupinfo-delay '(0.25 . 0.1)) ; Faster popup display
|
|
||||||
(corfu-popupinfo-hide nil) ; Don't hide automatically
|
|
||||||
)
|
|
||||||
|
|
||||||
;; Configure Corfu for richer display
|
|
||||||
(after! corfu
|
|
||||||
(setq corfu-auto t ; Enable auto completion
|
|
||||||
corfu-auto-prefix 2 ; Complete after 2 characters
|
|
||||||
corfu-preview-current t ; Preview current candidate
|
|
||||||
corfu-show-documentation t ; Show documentation in popup
|
|
||||||
corfu-doc-max-height 20 ; Max height for doc popup
|
|
||||||
corfu-doc-delay 0.2 ; Faster doc popup
|
|
||||||
corfu-quit-no-match t) ; Quit if no match
|
|
||||||
|
|
||||||
;; Show more detailed annotations
|
|
||||||
(setq corfu-show-annotations t
|
|
||||||
corfu-annotate-max-width 50))
|
|
||||||
|
|
||||||
;; If using LSP, configure to show more details
|
|
||||||
(after! lsp-mode
|
|
||||||
(setq lsp-completion-show-detail t ; Show method signatures
|
|
||||||
lsp-completion-show-kind t ; Show completion item kind
|
|
||||||
lsp-completion-show-label-description t ; Show more details in label
|
|
||||||
))
|
|
||||||
|
|
||||||
(after! lsp-haskell
|
|
||||||
(setq lsp-haskell-plugin-fourmolu-config-path "fourmolu -o -XImportQualifiedPost -o -XOverloadedStrings -o -XTypeApplications -o -XScopedTypeVariables -o -XGADTs -o -XDataKinds -o -XTypeFamilies -o -XFlexibleContexts -o -XFlexibleInstances -o -XMultiParamTypeClasses -o -XRankNTypes -o -XExistentialQuantification")
|
|
||||||
)
|
|
||||||
|
|
||||||
(use-package! bnf-mode
|
|
||||||
:mode "\\.bnf\\'"
|
|
||||||
:config
|
|
||||||
;; Optional: Add any custom configuration here
|
|
||||||
(setq bnf-mode-hook
|
|
||||||
(lambda ()
|
|
||||||
;; Enable line numbers
|
|
||||||
(display-line-numbers-mode)
|
|
||||||
;; Enable auto-pairing of angle brackets
|
|
||||||
(modify-syntax-entry ?< "(>" bnf-mode-syntax-table)
|
|
||||||
(modify-syntax-entry ?> ")<" bnf-mode-syntax-table))))
|
|
||||||
|
|
||||||
(use-package! ebnf-mode
|
|
||||||
:mode "\\.ebnf\\'"
|
|
||||||
:config
|
|
||||||
;; Optional customizations:
|
|
||||||
(setq ebnf-mode-indent-offset 4) ; Default is 8 spaces
|
|
||||||
(setq ebnf-mode-indent-by-production t) ; Align with the '=' in productions
|
|
||||||
(setq ebnf-mode-comment-char ?\;) ; Use ; for comments
|
|
||||||
(setq ebnf-mode-eop-char ?\.)) ; Use . for end of production
|
|
||||||
|
|
||||||
(use-package! nix-mode
|
|
||||||
:mode "\\.nix\\'"
|
|
||||||
:config
|
|
||||||
;; Function to check if we're in a nixpkgs repository
|
|
||||||
(defun in-nixpkgs-repo-p ()
|
|
||||||
(when-let ((root (or (locate-dominating-file default-directory ".git")
|
|
||||||
(vc-root-dir))))
|
|
||||||
(or (string-match-p "/nixpkgs/?$" root)
|
|
||||||
(file-exists-p (expand-file-name "pkgs/top-level/all-packages.nix" root))
|
|
||||||
(file-exists-p (expand-file-name ".nixpkgs-version.json" root)))))
|
|
||||||
|
|
||||||
;; Set up format-all-mode to use our custom formatter selection
|
|
||||||
(set-formatter! 'nixfmt
|
|
||||||
'("nixfmt")
|
|
||||||
:modes '(nix-mode))
|
|
||||||
|
|
||||||
(set-formatter! 'alejandra
|
|
||||||
'("alejandra" "--quiet")
|
|
||||||
:modes '(nix-mode))
|
|
||||||
|
|
||||||
;; Add hooks to handle all formatting scenarios
|
|
||||||
(add-hook! 'nix-mode-hook
|
|
||||||
;; Disable LSP formatting
|
|
||||||
(setq-local +format-with-lsp nil)
|
|
||||||
|
|
||||||
;; Set formatter for format-all-mode (+format/buffer)
|
|
||||||
(setq-local +format-with
|
|
||||||
(if (in-nixpkgs-repo-p)
|
|
||||||
'nixfmt
|
|
||||||
'alejandra))
|
|
||||||
|
|
||||||
;; Handle format-on-save
|
|
||||||
(when (bound-and-true-p format-all-mode)
|
|
||||||
(format-all-mode -1))
|
|
||||||
(add-hook! 'before-save-hook :local
|
|
||||||
(when (eq major-mode 'nix-mode)
|
|
||||||
(if (in-nixpkgs-repo-p)
|
|
||||||
(format-all-buffer 'nixfmt)
|
|
||||||
(format-all-buffer 'alejandra))))
|
|
||||||
|
|
||||||
;; Override lsp-format-buffer
|
|
||||||
(advice-add 'lsp-format-buffer :around
|
|
||||||
(lambda (orig-fun &rest args)
|
|
||||||
(if (eq major-mode 'nix-mode)
|
|
||||||
(if (in-nixpkgs-repo-p)
|
|
||||||
(format-all-buffer 'nixfmt)
|
|
||||||
(format-all-buffer 'alejandra))
|
|
||||||
(apply orig-fun args))))))
|
|
||||||
|
|
||||||
;; Enable format-on-save globally if desired
|
|
||||||
(setq +format-on-save-enabled-modes '(nix-mode))
|
|
||||||
|
|
||||||
(use-package! llvm-ts-mode
|
|
||||||
:mode "\\.ll\\'" ; LLVM IR files
|
|
||||||
:mode "\\.td\\'" ; TableGen files
|
|
||||||
:hook (llvm-ts-mode . tree-sitter-mode))
|
|
||||||
|
|
||||||
(after! tree-sitter
|
|
||||||
(add-to-list 'tree-sitter-major-mode-language-alist '(llvm-ts-mode . llvm)))
|
|
||||||
|
|
||||||
(after! lsp-clangd
|
|
||||||
(setq lsp-clients-clangd-executable "clangd")
|
|
||||||
(setq lsp-clients--clangd-default-executable "clangd")
|
|
||||||
(setq lsp-clangd-binary-path "clangd"))
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
;;; development/cpp.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; 4. Optional: Fine-tuning Clangd
|
||||||
|
;; These arguments are passed directly to the clangd binary.
|
||||||
|
(setq lsp-clients-clangd-args
|
||||||
|
'("-j=4"
|
||||||
|
"--background-index"
|
||||||
|
"--clang-tidy"
|
||||||
|
"--completion-style=detailed"
|
||||||
|
"--header-insertion=never"
|
||||||
|
"--header-insertion-decorators=0"))
|
||||||
|
|
||||||
|
(after! lsp-clangd
|
||||||
|
(set-lsp-priority! 'clangd 2)) ; Ensure clangd is preferred over ccls
|
||||||
|
|
||||||
|
;; Formatting for c++
|
||||||
|
;; This tells Doom to use the LSP server (clangd) for formatting instead of
|
||||||
|
;; a separate clang-format call via apheleia.
|
||||||
|
(setq-hook! '(c-mode-hook c++-mode-hook) +format-with-lsp t)
|
||||||
|
|
||||||
|
;; Formatting as I type
|
||||||
|
;; This enables real-time formatting as you type trigger characters like ; or }
|
||||||
|
(after! lsp-mode
|
||||||
|
(setq lsp-enable-on-type-formatting t))
|
||||||
|
|
||||||
|
;; Ensure cc-mode settings align with clangd/clang-format
|
||||||
|
;; While clangd handles most things, basic Emacs indentation settings are
|
||||||
|
;; still useful as a fallback or for initial indentation.
|
||||||
|
(after! cc-mode
|
||||||
|
(setq-default c-basic-offset 2)
|
||||||
|
(c-add-style "doom-cpp"
|
||||||
|
'("llvm"
|
||||||
|
(c-basic-offset . 2)
|
||||||
|
(c-offsets-alist . ((innamespace . 0)
|
||||||
|
(access-label . -)
|
||||||
|
(arglist-intro . +)
|
||||||
|
(arglist-cont-nonempty . +)))))
|
||||||
|
(add-hook! '(c-mode-hook c++-mode-hook)
|
||||||
|
(c-set-style "doom-cpp")))
|
||||||
|
|
||||||
|
;; Add C++ documentation support
|
||||||
|
(set-docsets! 'c++-mode "C++")
|
||||||
|
(set-docsets! 'c-mode "C")
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
;;; development/lsp.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(after! lsp-ui
|
||||||
|
(setq lsp-ui-doc-include-signature t ;; Show method signatures in docs
|
||||||
|
lsp-ui-sideline-show-symbol t ;; Show symbols in the sideline
|
||||||
|
lsp-ui-doc-show-with-cursor t ;; Show docs when cursor is on symbol
|
||||||
|
lsp-ui-doc-max-height 30 ;; Increase doc height to show more info
|
||||||
|
lsp-ui-sideline-show-hover t ;; Show hover information in sideline
|
||||||
|
lsp-ui-doc-enable t ;; Enable documentation
|
||||||
|
lsp-signature-auto-activate t ;; Show signature help automatically
|
||||||
|
lsp-signature-render-documentation t)) ;; Include docs in signature help
|
||||||
|
|
||||||
|
(after! eldoc
|
||||||
|
(setq eldoc-echo-area-use-multiline-p t
|
||||||
|
eldoc-echo-area-prefer-doc-buffer t))
|
||||||
|
|
||||||
|
(use-package! corfu-popupinfo
|
||||||
|
:after corfu
|
||||||
|
:hook (corfu-mode . corfu-popupinfo-mode)
|
||||||
|
:custom
|
||||||
|
(corfu-popupinfo-delay '(0.25 . 0.1)) ; Faster popup display
|
||||||
|
(corfu-popupinfo-hide nil) ; Don't hide automatically
|
||||||
|
)
|
||||||
|
|
||||||
|
;; Configure Corfu for richer display
|
||||||
|
(after! corfu
|
||||||
|
(setq corfu-auto t ; Enable auto completion
|
||||||
|
corfu-auto-prefix 2 ; Complete after 2 characters
|
||||||
|
corfu-preview-current t ; Preview current candidate
|
||||||
|
corfu-show-documentation t ; Show documentation in popup
|
||||||
|
corfu-doc-max-height 20 ; Max height for doc popup
|
||||||
|
corfu-doc-delay 0.2 ; Faster doc popup
|
||||||
|
corfu-quit-no-match t) ; Quit if no match
|
||||||
|
|
||||||
|
;; Show more detailed annotations
|
||||||
|
(setq corfu-show-annotations t
|
||||||
|
corfu-annotate-max-width 50)
|
||||||
|
)
|
||||||
|
|
||||||
|
(after! lsp-mode
|
||||||
|
(setq lsp-completion-show-detail t ; Show method signatures
|
||||||
|
lsp-completion-show-kind t ; Show completion item kind
|
||||||
|
lsp-completion-show-label-description t ; Show more details in label
|
||||||
|
))
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
;;; development/misc.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package! bnf-mode
|
||||||
|
:mode "\\.bnf\\'"
|
||||||
|
:config
|
||||||
|
;; Optional: Add any custom configuration here
|
||||||
|
(setq bnf-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
;; Enable line numbers
|
||||||
|
(display-line-numbers-mode)
|
||||||
|
;; Enable auto-pairing of angle brackets
|
||||||
|
(modify-syntax-entry ?< "(>" bnf-mode-syntax-table)
|
||||||
|
(modify-syntax-entry ?> ")<" bnf-mode-syntax-table))))
|
||||||
|
|
||||||
|
(use-package! ebnf-mode
|
||||||
|
:mode "\\.ebnf\\'"
|
||||||
|
:config
|
||||||
|
;; Optional customizations:
|
||||||
|
(setq ebnf-mode-indent-offset 4) ; Default is 8 spaces
|
||||||
|
(setq ebnf-mode-indent-by-production t) ; Align with the '=' in productions
|
||||||
|
(setq ebnf-mode-comment-char ?\;) ; Use ; for comments
|
||||||
|
(setq ebnf-mode-eop-char ?\.)) ; Use . for end of production
|
||||||
|
|
||||||
|
;; Devicetree mode (ZMK keymap, .dts, .dtsi)
|
||||||
|
(use-package! dts-mode
|
||||||
|
:mode ("\\.keymap\\'" "\\.dts\\'" "\\.dtsi\\'"))
|
||||||
|
|
||||||
|
;; Justfile mode (psibi/justl.el)
|
||||||
|
(use-package! justl
|
||||||
|
:config
|
||||||
|
(map! :n "e" 'justl-exec-recipe))
|
||||||
|
|
||||||
|
;; align-repeat: repeatedly align region by a given regexp/character
|
||||||
|
;; From EmacsWiki: https://www.emacswiki.org/emacs/AlignCommands
|
||||||
|
(defun align-repeat (start end regexp)
|
||||||
|
"Repeat alignment with respect to the given regular expression."
|
||||||
|
(interactive "r\nsAlign regexp: ")
|
||||||
|
(align-regexp start end
|
||||||
|
(concat "\\(\\s-*\\)" regexp) 1 1 t))
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
;;; development/nix.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package! nix-mode
|
||||||
|
:mode "\\.nix\\'"
|
||||||
|
:hook (nix-mode . lsp-deferred)
|
||||||
|
:config
|
||||||
|
;; Configure nil LSP server
|
||||||
|
(after! lsp-mode
|
||||||
|
(add-to-list 'lsp-language-id-configuration '(nix-mode . "nix"))
|
||||||
|
(lsp-register-client
|
||||||
|
(make-lsp-client :new-connection (lsp-stdio-connection "nil")
|
||||||
|
:major-modes '(nix-mode)
|
||||||
|
:server-id 'nil-ls
|
||||||
|
:priority 0)))
|
||||||
|
|
||||||
|
;; Function to check if we're in a nixpkgs repository
|
||||||
|
(defun in-nixpkgs-repo-p ()
|
||||||
|
(when-let ((root (or (locate-dominating-file default-directory ".git")
|
||||||
|
(vc-root-dir))))
|
||||||
|
(or (string-match-p "/nixpkgs/?$" root)
|
||||||
|
(file-exists-p (expand-file-name "pkgs/top-level/all-packages.nix" root))
|
||||||
|
(file-exists-p (expand-file-name ".nixpkgs-version.json" root)))))
|
||||||
|
|
||||||
|
;; Set up format-all-mode to use our custom formatter selection
|
||||||
|
(set-formatter! 'nixfmt
|
||||||
|
'("nixfmt")
|
||||||
|
:modes '(nix-mode))
|
||||||
|
|
||||||
|
(set-formatter! 'alejandra
|
||||||
|
'("alejandra" "--quiet")
|
||||||
|
:modes '(nix-mode))
|
||||||
|
|
||||||
|
;; Add hooks to handle all formatting scenarios
|
||||||
|
(add-hook! 'nix-mode-hook
|
||||||
|
;; Disable LSP formatting
|
||||||
|
(setq-local +format-with-lsp nil)
|
||||||
|
|
||||||
|
;; Set formatter for format-all-mode (+format/buffer)
|
||||||
|
(setq-local +format-with
|
||||||
|
(if (in-nixpkgs-repo-p)
|
||||||
|
'nixfmt
|
||||||
|
'alejandra))
|
||||||
|
|
||||||
|
;; Handle format-on-save
|
||||||
|
(when (bound-and-true-p format-all-mode)
|
||||||
|
(format-all-mode -1))
|
||||||
|
(add-hook! 'before-save-hook :local
|
||||||
|
(when (eq major-mode 'nix-mode)
|
||||||
|
(if (in-nixpkgs-repo-p)
|
||||||
|
(format-all-buffer 'nixfmt)
|
||||||
|
(format-all-buffer 'alejandra))))
|
||||||
|
|
||||||
|
;; Override lsp-format-buffer
|
||||||
|
(advice-add 'lsp-format-buffer :around
|
||||||
|
(lambda (orig-fun &rest args)
|
||||||
|
(if (eq major-mode 'nix-mode)
|
||||||
|
(let ((fmt (if (in-nixpkgs-repo-p)
|
||||||
|
(executable-find "nixfmt")
|
||||||
|
(executable-find "alejandra"))))
|
||||||
|
(when fmt
|
||||||
|
(format-all-buffer (intern (file-name-nondirectory fmt)))))
|
||||||
|
(apply orig-fun args))))))
|
||||||
|
|
||||||
|
;; Enable format-on-save globally if desired
|
||||||
|
(setq +format-on-save-enabled-modes '(nix-mode))
|
||||||
|
|
||||||
|
(use-package! llvm-ts-mode
|
||||||
|
:mode "\\.ll\\'" ; LLVM IR files
|
||||||
|
:mode "\\.td\\'" ; TableGen files
|
||||||
|
:hook (llvm-ts-mode . tree-sitter-mode))
|
||||||
|
|
||||||
|
(after! tree-sitter
|
||||||
|
(add-to-list 'tree-sitter-major-mode-language-alist '(llvm-ts-mode . llvm)))
|
||||||
@@ -0,0 +1,283 @@
|
|||||||
|
# Doom Emacs Macros and Keywords Reference
|
||||||
|
|
||||||
|
This document describes the macros and their keywords used in Doom Emacs 3 configuration.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [`doom!` - Module Declaration](#doom---module-declaration)
|
||||||
|
- [`package!` - Package Declaration](#package---package-declaration)
|
||||||
|
- [`use-package!` / `use-package` - Package Configuration](#use-package--use-package---package-configuration)
|
||||||
|
- [`add-hook!` - Hook Registration](#add-hook---hook-registration)
|
||||||
|
- [`setq-hook!` - Set Variables in Hooks](#setq-hook---set-variables-in-hooks)
|
||||||
|
- [`map!` - Keybinding](#map---keybinding)
|
||||||
|
- [`after!` - Run Code After Package](#after---run-code-after-package)
|
||||||
|
- [`load!` - Load Sub-config Files](#load---load-sub-config-files)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `doom!` - Module Declaration
|
||||||
|
|
||||||
|
Declares enabled modules and their flags in `init.el`.
|
||||||
|
|
||||||
|
**Location:** `init.el`
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(doom! :module
|
||||||
|
(module +flag1 +flag2)
|
||||||
|
:another-module)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Keywords:** Module names and optional flags (prefixed with `+`).
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(doom! :completion
|
||||||
|
(company +orderless)
|
||||||
|
:lang
|
||||||
|
(org +brain +crypt)
|
||||||
|
:tools
|
||||||
|
lsp)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `package!` - Package Declaration
|
||||||
|
|
||||||
|
Declares packages to install in `packages.el`.
|
||||||
|
|
||||||
|
**Location:** `packages.el`
|
||||||
|
|
||||||
|
| Keyword | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `:recipe` | MELPA-style straight recipe with `:host`, `:repo`, `:branch`, `:files`, etc. |
|
||||||
|
| `:disable` | Disable the package (`t` to disable) |
|
||||||
|
| `:built-in` | Mark as built-in (`'prefer`) |
|
||||||
|
| `:pin` | Pin to a specific commit hash |
|
||||||
|
| `:local-repo` | Local repository path |
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(package! super-save)
|
||||||
|
|
||||||
|
(package! copilot
|
||||||
|
:recipe (:host github :repo "copilot-emacs/copilot.el" :files ("*.el")))
|
||||||
|
|
||||||
|
(package! org-re-reveal :disable t)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `use-package!` / `use-package` - Package Configuration
|
||||||
|
|
||||||
|
Configures packages with a declarative DSL.
|
||||||
|
|
||||||
|
**Location:** `config.el` or modular config files
|
||||||
|
|
||||||
|
| Keyword | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `:init` | Code to run immediately (before package loads) |
|
||||||
|
| `:config` | Code to run after package loads |
|
||||||
|
| `:defer` | Defer loading (boolean or integer seconds) |
|
||||||
|
| `:after` | Load after another package or packages |
|
||||||
|
| `:hook` | Hook into specific hooks |
|
||||||
|
| `:bind` | Define key bindings |
|
||||||
|
| `:commands` | Autoload commands |
|
||||||
|
| `:custom` | Set customization variables |
|
||||||
|
| `:custom-face` | Customize faces |
|
||||||
|
| `:pre-init` | Run before package's own `:init` |
|
||||||
|
| `:pre-config` | Run before package's own `:config` |
|
||||||
|
| `:post-init` | Run after package's own `:init` |
|
||||||
|
| `:post-config` | Run after package's own `:config` |
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(use-package! org-roam
|
||||||
|
:after org
|
||||||
|
:custom
|
||||||
|
(org-roam-directory "~/org/roam")
|
||||||
|
(org-roam-completion-everywhere t)
|
||||||
|
:config
|
||||||
|
(org-roam-db-autosync-mode)
|
||||||
|
:bind (("C-c n l" . org-roam-buffer-toggle)
|
||||||
|
("C-c n f" . org-roam-node-find)))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Hook Syntax
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(use-package! some-package
|
||||||
|
:hook ((prog-mode . some-package-mode)
|
||||||
|
(org-mode . some-package-mode)))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bind Syntax with Maps
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(use-package! anki-editor
|
||||||
|
:after org
|
||||||
|
:bind (:map org-mode-map
|
||||||
|
("C-c a" . anki-editor-push-notes)))
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `add-hook!` - Hook Registration
|
||||||
|
|
||||||
|
Add hooks with inline function definitions.
|
||||||
|
|
||||||
|
**Location:** Any config file
|
||||||
|
|
||||||
|
| Keyword | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| `:local` | Make the hook local to current buffer |
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(add-hook! HOOK-SPEC
|
||||||
|
(defun my-hook-function ()
|
||||||
|
"Description."
|
||||||
|
(do-something)))
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(add-hook! 'org-agenda-finalize-hook
|
||||||
|
(defun +org-exclude-agenda-buffers-from-workspace-h ()
|
||||||
|
"Don't associate temporary agenda buffers with current workspace."
|
||||||
|
(when (and org-agenda-new-buffers
|
||||||
|
(bound-and-true-p persp-mode)
|
||||||
|
(not org-agenda-sticky))
|
||||||
|
(let (persp-autokill-buffer-on-remove)
|
||||||
|
(persp-remove-buffer org-agenda-new-buffers
|
||||||
|
(get-current-persp)
|
||||||
|
nil)))))
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `setq-hook!` - Set Variables in Hooks
|
||||||
|
|
||||||
|
Set variables specifically for particular mode hooks.
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(setq-hook! MODE-SPEC VARS...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(setq-hook! 'python-mode-hook
|
||||||
|
python-indent-offset 4
|
||||||
|
python-shell-interpreter "bpython")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `map!` - Keybinding
|
||||||
|
|
||||||
|
Define key bindings with a declarative syntax.
|
||||||
|
|
||||||
|
**Location:** Any config file
|
||||||
|
|
||||||
|
| Keyword | State/Scope |
|
||||||
|
|---------|-------------|
|
||||||
|
| `:leader` | Normal state leader key (SPC) |
|
||||||
|
| `:n` | Normal state |
|
||||||
|
| `:v` | Visual state |
|
||||||
|
| `:i` | Insert state |
|
||||||
|
| `:e` | Emacs state |
|
||||||
|
| `:o` | Operator-pending state |
|
||||||
|
| `:ic` | Insert+normal (after ESC) |
|
||||||
|
| `:nv` | Normal+visual combined |
|
||||||
|
| `:after` | Delay until package loads |
|
||||||
|
| `:map` | Specific keymap |
|
||||||
|
| `:prefix` | Key sequence prefix |
|
||||||
|
| `:desc` | Description for which-key display |
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(map! KEYCOMBO COMMAND
|
||||||
|
KEYCOMBO COMMAND
|
||||||
|
...)
|
||||||
|
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("KEY" . "DESC")
|
||||||
|
KEYCOMBO COMMAND
|
||||||
|
...))
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(map! :n "C-s" #'consult-line
|
||||||
|
:n "M-s" (lambda () (interactive) (consult-line (thing-at-point 'symbol))))
|
||||||
|
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("C" . "claude-code")
|
||||||
|
:desc "Start Claude" "c" #'claude-code
|
||||||
|
:desc "Kill Claude" "k" #'claude-code-kill))
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `after!` - Run Code After Package
|
||||||
|
|
||||||
|
Run code after a package loads (shorthand for `with-eval-after-load`).
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(after! PACKAGE
|
||||||
|
BODY...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
(after! org
|
||||||
|
(require 'org-re-reveal)
|
||||||
|
(setq org-re-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js"))
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `load!` - Load Sub-config Files
|
||||||
|
|
||||||
|
Load additional configuration files from `config.el`.
|
||||||
|
|
||||||
|
**Location:** `config.el`
|
||||||
|
|
||||||
|
**Syntax:**
|
||||||
|
```elisp
|
||||||
|
(load! "path/to/file") ; Without .el extension
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```elisp
|
||||||
|
;; In config.el
|
||||||
|
(load! "security")
|
||||||
|
(load! "core")
|
||||||
|
(load! "org")
|
||||||
|
(load! "ai/gptel")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary Table
|
||||||
|
|
||||||
|
| Macro | Purpose | Location |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| `doom!` | Declare enabled modules | `init.el` |
|
||||||
|
| `package!` | Declare packages to install | `packages.el` |
|
||||||
|
| `use-package!` | Configure packages | `config.el` or modular configs |
|
||||||
|
| `add-hook!` | Register hooks | Any config file |
|
||||||
|
| `setq-hook!` | Set vars for mode hooks | Any config file |
|
||||||
|
| `map!` | Define keybindings | Any config file |
|
||||||
|
| `after!` | Run code after package loads | Any config file |
|
||||||
|
| `load!` | Load sub-config files | `config.el` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Doom Emacs Documentation](https://docs.doomemacs.org)
|
||||||
|
- [Doom Modules Index](https://github.com/doomemacs/doomemacs/blob/master/docs/modules.org)
|
||||||
|
- [Getting Started Guide](https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
;;; inbox.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Use this file for new packages and configuration snippets
|
||||||
|
;; before sorting them into their proper places.
|
||||||
|
|
||||||
|
(defun df/copy-file-line-ref ()
|
||||||
|
"Copy absolute file path with line reference as @/path#Lline or @/path#Lstart-end."
|
||||||
|
(interactive)
|
||||||
|
(let* ((file (or (buffer-file-name) (buffer-name)))
|
||||||
|
(abs-file (if (file-name-absolute-p file) file (expand-file-name file)))
|
||||||
|
(ref
|
||||||
|
(if (use-region-p)
|
||||||
|
(let* ((start (region-beginning))
|
||||||
|
(end (region-end))
|
||||||
|
(start-line (line-number-at-pos start))
|
||||||
|
(end-line (line-number-at-pos (max start (1- end)))))
|
||||||
|
(format "@%s#L%d-%d" abs-file start-line end-line))
|
||||||
|
(format "@%s#L%d" abs-file (line-number-at-pos (point))))))
|
||||||
|
(kill-new ref)
|
||||||
|
(when (fboundp 'gui-set-selection)
|
||||||
|
(gui-set-selection 'CLIPBOARD ref))
|
||||||
|
(message "%s" ref)))
|
||||||
|
|
||||||
|
(global-set-key (kbd "M-S w") #'df/copy-file-line-ref)
|
||||||
|
|
||||||
|
(defun load-current-file ()
|
||||||
|
(interactive)
|
||||||
|
(load (buffer-file-name)))
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-c l") #'load-current-file)
|
||||||
|
|
||||||
|
(use-package! command-log-mode
|
||||||
|
:config
|
||||||
|
(map! "C-c L" #'(lambda () (interactive)
|
||||||
|
(command-log-mode (if command-log-mode -1 +1))
|
||||||
|
(when command-log-mode
|
||||||
|
(switch-to-buffer "*Command Log*")))))
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
;;unicode ; extended unicode support for various languages
|
;;unicode ; extended unicode support for various languages
|
||||||
(vc-gutter +pretty) ; vcs diff in the fringe
|
(vc-gutter +pretty) ; vcs diff in the fringe
|
||||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||||
|
(which-key +popup) ; key binding popups
|
||||||
window-select ; visually switch windows
|
window-select ; visually switch windows
|
||||||
workspaces ; tab emulation, persistence & separate workspaces
|
workspaces ; tab emulation, persistence & separate workspaces
|
||||||
zen ; distraction-free coding or writing
|
zen ; distraction-free coding or writing
|
||||||
@@ -78,7 +79,7 @@
|
|||||||
eshell ; the elisp shell that works everywhere
|
eshell ; the elisp shell that works everywhere
|
||||||
;;shell ; simple shell REPL for Emacs
|
;;shell ; simple shell REPL for Emacs
|
||||||
;;term ; basic terminal emulator for Emacs
|
;;term ; basic terminal emulator for Emacs
|
||||||
;;vterm ; the best terminal emulation in Emacs
|
vterm ; the best terminal emulation in Emacs
|
||||||
|
|
||||||
:checkers
|
:checkers
|
||||||
syntax ; tasing you for every semicolon you forget
|
syntax ; tasing you for every semicolon you forget
|
||||||
@@ -114,7 +115,7 @@
|
|||||||
:lang
|
:lang
|
||||||
;;agda ; types of types of types of types...
|
;;agda ; types of types of types of types...
|
||||||
;;beancount ; mind the GAAP
|
;;beancount ; mind the GAAP
|
||||||
(cc +lsp) ; C > C++ == 1
|
(cc +lsp +tree-sitter) ; C > C++ == 1
|
||||||
;;clojure ; java with a lisp
|
;;clojure ; java with a lisp
|
||||||
;;common-lisp ; if you've seen one lisp, you've seen them all
|
;;common-lisp ; if you've seen one lisp, you've seen them all
|
||||||
;;coq ; proofs-as-programs
|
;;coq ; proofs-as-programs
|
||||||
@@ -150,7 +151,7 @@
|
|||||||
;;lua ; one-based indices? one-based indices
|
;;lua ; one-based indices? one-based indices
|
||||||
markdown ; writing docs for people to ignore
|
markdown ; writing docs for people to ignore
|
||||||
;;nim ; python + lisp at the speed of c
|
;;nim ; python + lisp at the speed of c
|
||||||
nix ; I hereby declare "nix geht mehr!"
|
(nix +lsp) ; I hereby declare "nix geht mehr!"
|
||||||
;;ocaml ; an objective camel
|
;;ocaml ; an objective camel
|
||||||
(org +brain
|
(org +brain
|
||||||
+contacts
|
+contacts
|
||||||
@@ -159,7 +160,6 @@
|
|||||||
+gnuplot
|
+gnuplot
|
||||||
+hugo
|
+hugo
|
||||||
+journal
|
+journal
|
||||||
+jupyter
|
|
||||||
+link
|
+link
|
||||||
+noter
|
+noter
|
||||||
+pandoc
|
+pandoc
|
||||||
|
|||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
;;; metrics.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;; Keyfreq - Track command usage statistics
|
||||||
|
(use-package! keyfreq
|
||||||
|
:config
|
||||||
|
(keyfreq-mode 1)
|
||||||
|
(keyfreq-autosave-mode 1)
|
||||||
|
(setq keyfreq-file (concat doom-cache-dir "keyfreq")
|
||||||
|
keyfreq-file-lock (concat doom-cache-dir "keyfreq.lock"))
|
||||||
|
|
||||||
|
;; Optional: Exclude commands you don't want to track (uncomment to use)
|
||||||
|
;; (setq keyfreq-excluded-commands
|
||||||
|
;; '(self-insert-command
|
||||||
|
;; forward-char
|
||||||
|
;; backward-char
|
||||||
|
;; previous-line
|
||||||
|
;; next-line))
|
||||||
|
)
|
||||||
|
|
||||||
|
;;; Command Log Mode - visual log of keystrokes and commands
|
||||||
|
(use-package! command-log-mode
|
||||||
|
:config
|
||||||
|
;; Global mode to track everywhere
|
||||||
|
;; (global-command-log-mode 1) ; Uncomment if you want it always on (can be noisy)
|
||||||
|
|
||||||
|
(map! :leader
|
||||||
|
(:prefix ("t" . "toggle")
|
||||||
|
:desc "Toggle command log" "L" #'clm/toggle-command-log-buffer))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,33 +1,10 @@
|
|||||||
;;; org.el -*- lexical-binding: t; -*-
|
;;; org.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
(defun +org--restart-mode-h ()
|
(defun +org--restart-mode-h ()
|
||||||
"Restart `org-mode', but only once."
|
"Restart org-mode on buffer switch."
|
||||||
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h
|
|
||||||
'local)
|
|
||||||
(delq! (current-buffer) org-agenda-new-buffers)
|
|
||||||
(let ((file buffer-file-name)
|
|
||||||
(old-buffer (current-buffer))
|
|
||||||
(inhibit-redisplay t)
|
|
||||||
new-buffer)
|
|
||||||
(kill-buffer)
|
|
||||||
(setq new-buffer (find-file file))
|
|
||||||
(unless (buffer-live-p old-buffer)
|
|
||||||
(make-indirect-buffer new-buffer old-buffer 'clone))))
|
|
||||||
|
|
||||||
(defun +org--restart-mode-h ()
|
|
||||||
"Restart `org-mode', but only once."
|
|
||||||
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h
|
|
||||||
'local)
|
|
||||||
(delq! (current-buffer) org-agenda-new-buffers)
|
|
||||||
(let ((file buffer-file-name)
|
|
||||||
(inhibit-redisplay t))
|
|
||||||
(kill-buffer)
|
|
||||||
(find-file file)))
|
|
||||||
(defun +org--restart-mode-h ()
|
|
||||||
"Restart `org-mode', but only once."
|
|
||||||
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h 'local)
|
(remove-hook 'doom-switch-buffer-hook #'+org--restart-mode-h 'local)
|
||||||
|
(cl-delete (current-buffer) org-agenda-new-buffers :test 'eq)
|
||||||
(quiet! (org-mode-restart))
|
(quiet! (org-mode-restart))
|
||||||
(delq! (current-buffer) org-agenda-new-buffers)
|
|
||||||
(run-hooks 'find-file-hook))
|
(run-hooks 'find-file-hook))
|
||||||
|
|
||||||
(add-hook! 'org-agenda-finalize-hook
|
(add-hook! 'org-agenda-finalize-hook
|
||||||
@@ -52,15 +29,32 @@
|
|||||||
(letf! ((#'+org--restart-mode-h #'ignore))
|
(letf! ((#'+org--restart-mode-h #'ignore))
|
||||||
(apply fun args))))
|
(apply fun args))))
|
||||||
|
|
||||||
;;(use-package! org-roam
|
(use-package! org-roam
|
||||||
;; :after org
|
:after org
|
||||||
;; :config
|
:custom
|
||||||
;; :init
|
(org-roam-directory "~/org/roam")
|
||||||
;; (setq org-roam-directory "~/org/roam") ; No file-truename needed in Doom
|
(org-roam-completion-everywhere t)
|
||||||
;; :config
|
(org-roam-capture-templates
|
||||||
;; (advice-remove 'org-roam-db-query '+org-roam-try-init-db-a)
|
'(("d" "default" plain
|
||||||
;; (org-roam-db-autosync-mode)
|
"%?"
|
||||||
;; (setq org-roam-completion-everywhere t))
|
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
|
||||||
|
"#+title: ${title}\n")
|
||||||
|
:unnarrowed t)
|
||||||
|
("r" "reference" plain
|
||||||
|
"%?"
|
||||||
|
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
|
||||||
|
"#+title: ${title}\n#+filetags: :reference:\n")
|
||||||
|
:unnarrowed t)
|
||||||
|
("p" "project" plain
|
||||||
|
"\n* Goals\n\n%?\n\n* Tasks\n\n* Notes\n\n"
|
||||||
|
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
|
||||||
|
"#+title: ${title}\n#+filetags: :project:\n")
|
||||||
|
:unnarrowed t)))
|
||||||
|
:config
|
||||||
|
(org-roam-db-autosync-mode)
|
||||||
|
:bind (("C-c n l" . org-roam-buffer-toggle)
|
||||||
|
("C-c n f" . org-roam-node-find)
|
||||||
|
("C-c n r" . org-roam-node-random)))
|
||||||
|
|
||||||
; (use-package! org-roam
|
; (use-package! org-roam
|
||||||
; :custom
|
; :custom
|
||||||
@@ -127,10 +121,12 @@
|
|||||||
|
|
||||||
(defun my/org-download-image-dir-setup ()
|
(defun my/org-download-image-dir-setup ()
|
||||||
"Create and set org-download-image-dir relative to current org file."
|
"Create and set org-download-image-dir relative to current org file."
|
||||||
(let* ((current-file-dir (file-name-directory (buffer-file-name)))
|
(let ((filename (buffer-file-name)))
|
||||||
|
(when filename
|
||||||
|
(let* ((current-file-dir (file-name-directory filename))
|
||||||
(image-dir (expand-file-name "images" current-file-dir)))
|
(image-dir (expand-file-name "images" current-file-dir)))
|
||||||
(make-directory image-dir t)
|
(make-directory image-dir t)
|
||||||
(setq-local org-download-image-dir image-dir)))
|
(setq-local org-download-image-dir image-dir)))))
|
||||||
|
|
||||||
(add-hook 'org-mode-hook #'my/org-download-image-dir-setup)
|
(add-hook 'org-mode-hook #'my/org-download-image-dir-setup)
|
||||||
(setq org-download-link-format "[[file:%s]]\n")
|
(setq org-download-link-format "[[file:%s]]\n")
|
||||||
|
|||||||
+54
-1
@@ -1,10 +1,21 @@
|
|||||||
;; -*- no-byte-compile: t; -*-
|
|
||||||
;;; $DOOMDIR/packages.el
|
;;; $DOOMDIR/packages.el
|
||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
|
||||||
(package! super-save)
|
(package! super-save)
|
||||||
|
|
||||||
|
;; gptel and extensions
|
||||||
(package! gptel)
|
(package! gptel)
|
||||||
|
|
||||||
|
;; gptel extensions
|
||||||
|
(package! gptel-quick
|
||||||
|
:recipe (:host github :repo "karthink/gptel-quick"))
|
||||||
|
|
||||||
|
(package! gptel-extensions
|
||||||
|
:recipe (:host github :repo "kamushadenes/gptel-extensions.el"))
|
||||||
|
|
||||||
|
(package! gptel-autocomplete
|
||||||
|
:recipe (:host github :repo "JDNdeveloper/gptel-autocomplete"))
|
||||||
|
|
||||||
(package! org-re-reveal)
|
(package! org-re-reveal)
|
||||||
|
|
||||||
(package! copilot
|
(package! copilot
|
||||||
@@ -29,3 +40,45 @@
|
|||||||
(package! tree-sitter-langs)
|
(package! tree-sitter-langs)
|
||||||
|
|
||||||
(package! ob-mermaid)
|
(package! ob-mermaid)
|
||||||
|
|
||||||
|
;; Claude Code integration
|
||||||
|
(package! inheritenv
|
||||||
|
:recipe (:host github :repo "purcell/inheritenv"))
|
||||||
|
|
||||||
|
(package! consult)
|
||||||
|
|
||||||
|
(package! popup)
|
||||||
|
|
||||||
|
(package! claude-code
|
||||||
|
:recipe (:host github :repo "stevemolitor/claude-code.el" :branch "main" :depth 1
|
||||||
|
:files ("*.el" (:exclude "images/*"))))
|
||||||
|
|
||||||
|
(package! gemini-cli
|
||||||
|
:recipe (:host github :repo "linchen2chris/gemini-cli.el" :branch "main"
|
||||||
|
:files ("*.el" (:exclude "demo.gif"))))
|
||||||
|
|
||||||
|
(package! claudemacs
|
||||||
|
:recipe (:host github :repo "cpoile/claudemacs"))
|
||||||
|
|
||||||
|
;; Terminal emulator
|
||||||
|
(package! eat
|
||||||
|
:recipe (: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"))))
|
||||||
|
|
||||||
|
;; Justfile mode
|
||||||
|
(package! justl :recipe (:host github :repo "psibi/justl.el"))
|
||||||
|
|
||||||
|
;; Usage metrics and key tracking
|
||||||
|
(package! keyfreq)
|
||||||
|
(package! command-log-mode)
|
||||||
|
|
||||||
|
;; Theme
|
||||||
|
(package! base16-theme)
|
||||||
|
(package! ewal)
|
||||||
|
(package! ewal-doom-themes
|
||||||
|
:recipe (:host github :repo "cyruseuros/ewal" :files ("doom-themes/*.el")))
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# -*- mode: snippet -*-
|
||||||
|
# name: Anki Basic (Subheadings)
|
||||||
|
# key: <a
|
||||||
|
# --
|
||||||
|
* ${1:Title} :study_card:
|
||||||
|
:PROPERTIES:
|
||||||
|
:ANKI_NOTE_TYPE: Basic
|
||||||
|
:END:
|
||||||
|
|
||||||
|
** Front
|
||||||
|
$2
|
||||||
|
|
||||||
|
** Back
|
||||||
|
$3
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
;;; theme.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Default Doom Theme
|
||||||
|
(setq doom-theme 'doom-one)
|
||||||
|
|
||||||
|
;; --- Ewal Configuration ---
|
||||||
|
(use-package! ewal
|
||||||
|
:disabled t
|
||||||
|
:init
|
||||||
|
(setq ewal-json-file "~/.cache/wal/colors.json"
|
||||||
|
ewal-use-built-in-always-p nil
|
||||||
|
ewal-use-built-in-on-failure-p t
|
||||||
|
ewal-built-in-palette "sexy-material"))
|
||||||
|
|
||||||
|
(use-package! ewal-doom-themes
|
||||||
|
:disabled t
|
||||||
|
:config
|
||||||
|
(load-theme 'ewal-doom-one t)
|
||||||
|
(enable-theme 'ewal-doom-one)
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user