diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9af99d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/config.el diff --git a/config.org b/config.org new file mode 100644 index 0000000..e92d7f1 --- /dev/null +++ b/config.org @@ -0,0 +1,1111 @@ +#+AUTHOR: Tom Berg +#+OPTIONS: num:nil + +* Lexical Binding +#+BEGIN_SRC emacs-lisp + ;;; ... -*- lexical-binding: t -*- +#+END_SRC + +* Package +#+BEGIN_SRC emacs-lisp + ;; Initialize package sources + (require 'package) + + (setq package-archives '(("melpa" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("elpa" . "https://elpa.gnu.org/packages/"))) + + (unless package-archive-contents + (package-refresh-contents)) + + ;; Bootstrap use-package + (unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + (require 'use-package) + (setq use-package-always-ensure t) +#+END_SRC + +* UI +** Clean up +#+BEGIN_SRC emacs-lisp + (setq inhibit-startup-message t) + + (scroll-bar-mode -1) ; Disable visible scrollbar + (tool-bar-mode -1) ; Disable the toolbar + (tooltip-mode -1) ; Disable tooltips + (set-fringe-mode 10) ; Give some breathing room + + (menu-bar-mode -1) ; Disable the menu bar + + ;; Better defaults + (setq ring-bell-function 'ignore) ; No bell sound + (setq use-dialog-box nil) + (setq truncate-lines nil) + (setq truncate-partial-width-windows nil) +#+END_SRC + +** Fonts +#+BEGIN_SRC emacs-lisp + ;; Set fonts with better distinction for dysgraphia + (set-face-attribute 'default nil :font "MesloLGS NF" :height 140) + + ;; Variable pitch font for Org prose + (set-face-attribute 'variable-pitch nil + :font "Inter" ; or "Georgia", "Source Sans Pro" + :height 150) + + ;; Fixed pitch font + (set-face-attribute 'fixed-pitch nil + :font "MesloLGS NF" + :height 140) + +#+END_SRC + +** Theme +#+BEGIN_SRC emacs-lisp + (use-package doom-themes + :config + ;; Best dark themes for focus: + ;; doom-one, doom-dracula, doom-tokyo-night, doom-palenight + (load-theme 'doom-tokyo-night t) + + ;; Enable flashing mode-line on errors + (doom-themes-visual-bell-config) + + ;; Corrects org-mode's native fontification + (doom-themes-org-config)) + + ;; All-the-icons for visual indicators + ;;(use-package all-the-icons + ;; :if (display-graphic-p)) + (use-package nerd-icons + :ensure t) + #+END_SRC + +** Modeline +#+BEGIN_SRC emacs-lisp + (use-package doom-modeline + :init (doom-modeline-mode 1) + :config + (setq doom-modeline-height 35) + (setq doom-modeline-bar-width 6) + (setq doom-modeline-lsp t) + (setq doom-modeline-github nil) + (setq doom-modeline-mu4e nil) + (setq doom-modeline-irc nil) + (setq doom-modeline-buffer-file-name-style 'truncate-except-project) + (setq doom-modeline-major-mode-icon t)) +#+END_SRC + +** Dashboard +#+BEGIN_SRC emacs-lisp + (use-package dashboard + :config + (dashboard-setup-startup-hook) + (setq dashboard-banner-logo-title "Command Center") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t) + (setq dashboard-items '((recents . 5) + (agenda . 5) + (bookmarks . 5))) + (setq dashboard-set-heading-icons t) + (setq dashboard-set-file-icons t) + (setq dashboard-week-agenda t) + (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))) +#+END_SRC + +** Help +#+BEGIN_SRC emacs-lisp + (use-package which-key + :init (which-key-mode) + :diminish which-key-mode + :config + (setq which-key-idle-delay 0.5)) ; Quick popup fmory + + (use-package helpful + :ensure t + :bind + (("C-h f" . helpful-callable) + ("C-h v" . helpful-variable) + ("C-h k" . helpful-key) + ("C-h x" . helpful-command) + ("C-h ." . helpful-at-point))) +#+END_SRC + +** Visual Enhancements +#+BEGIN_SRC emacs-lisp + ;; Highlight current line - Helps with focus + (global-hl-line-mode 1) + + ;; Smooth scrolling + (setq scroll-conservatively 101) + (setq scroll-margin 5) + (setq mouse-wheel-scroll-amount '(1)) + (setq mouse-wheel-progressive-speed nil) + + ;; Remember cursor position + (save-place-mode 1) + + ;; Matching parentheses + (show-paren-mode 1) + (setq show-paren-delay 0) + + ;; Electric pair mode - Auto close brackets + (electric-pair-mode 1) +#+END_SRC + +** Auto-save and Backup +#+BEGIN_SRC emacs-lisp + ;; aggressive auto-save + (setq backup-directory-alist '(("." . "~/.emacs.d/backups"))) + (setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-saves/" t))) + (setq auto-save-default t) + (setq auto-save-timeout 20) + (setq auto-save-interval 200) + + ;; Recent files + (recentf-mode 1) + (setq recentf-max-menu-items 25) + (setq recentf-max-saved-items 25) +#+END_SRC + +* Evil Mode +#+BEGIN_SRC emacs-lisp + (use-package evil + :ensure t + :init + (setq evil-want-integration t) + (setq evil-want-keybinding nil) + (setq evil-want-C-u-scroll t) + (setq evil-want-C-i-jump nil) + :config + (evil-mode 1) + + (define-key evil-normal-state-map (kbd "n") 'evil-backward-char) + (define-key evil-normal-state-map (kbd "e") 'evil-next-line) + (define-key evil-normal-state-map (kbd "i") 'evil-previous-line) + (define-key evil-normal-state-map (kbd "o") 'evil-forward-char) + + (define-key evil-visual-state-map (kbd "n") 'evil-backward-char) + (define-key evil-visual-state-map (kbd "e") 'evil-next-line) + (define-key evil-visual-state-map (kbd "i") 'evil-previous-line) + (define-key evil-visual-state-map (kbd "o") 'evil-forward-char) + + (define-key evil-visual-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-visual-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-visual-state-map (kbd "l") 'evil-forward-word-end) + + (define-key evil-motion-state-map (kbd "n") 'evil-backward-char) + (define-key evil-motion-state-map (kbd "e") 'evil-next-line) + (define-key evil-motion-state-map (kbd "i") 'evil-previous-line) + (define-key evil-motion-state-map (kbd "o") 'evil-forward-char) + + (define-key evil-motion-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-motion-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-motion-state-map (kbd "l") 'evil-forward-word-end) + + (define-key evil-normal-state-map (kbd "m") 'evil-insert) + (define-key evil-normal-state-map (kbd "M") 'evil-insert-line) + (define-key evil-normal-state-map (kbd "j") 'evil-open-below) + (define-key evil-normal-state-map (kbd "J") 'evil-open-above) + (define-key evil-normal-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-normal-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-normal-state-map (kbd "l") 'evil-forward-word-end) + ;;(define-key evil-normal-state-map (kbd "") 'evil-end-of-line) + (define-key evil-normal-state-map (kbd "k") 'evil-set-marker) + + (define-key evil-normal-state-map (kbd "C-w n") 'evil-window-left) + (define-key evil-normal-state-map (kbd "C-w e") 'evil-window-down) + (define-key evil-normal-state-map (kbd "C-w i") 'evil-window-up) + (define-key evil-normal-state-map (kbd "C-w o") 'evil-window-right)) + + (use-package evil-collection + :after evil + :ensure t + :config + (evil-collection-init)) + + ;; Use hook to ensure our bindings always take precedence + (add-hook 'evil-collection-setup-hook + (lambda (_mode keymaps) + (define-key evil-normal-state-map (kbd "n") 'evil-backward-char) + (define-key evil-normal-state-map (kbd "e") 'evil-next-line) + (define-key evil-normal-state-map (kbd "i") 'evil-previous-line) + (define-key evil-normal-state-map (kbd "o") 'evil-forward-char) + (define-key evil-normal-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-normal-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-normal-state-map (kbd "l") 'evil-forward-word-end) + + (define-key evil-visual-state-map (kbd "n") 'evil-backward-char) + (define-key evil-visual-state-map (kbd "e") 'evil-next-line) + (define-key evil-visual-state-map (kbd "i") 'evil-previous-line) + (define-key evil-visual-state-map (kbd "o") 'evil-forward-char) + (define-key evil-visual-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-visual-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-visual-state-map (kbd "l") 'evil-forward-word-end) + + (define-key evil-motion-state-map (kbd "n") 'evil-backward-char) + (define-key evil-motion-state-map (kbd "e") 'evil-next-line) + (define-key evil-motion-state-map (kbd "i") 'evil-previous-line) + (define-key evil-motion-state-map (kbd "o") 'evil-forward-char) + (define-key evil-motion-state-map (kbd "h") 'evil-ex-search-next) + (define-key evil-motion-state-map (kbd "H") 'evil-ex-search-previous) + (define-key evil-motion-state-map (kbd "l") 'evil-forward-word-end))) + + (use-package evil-org + :after (evil org) + :hook (org-mode . evil-org-mode) + :config + (evil-org-set-key-theme '(navigation insert textobjects additional calendar)) + + ;; Use hook to ensure our org bindings work + (add-hook 'org-mode-hook + (lambda () + (evil-define-key 'normal evil-org-mode-map + (kbd "n") 'evil-backward-char + (kbd "e") 'evil-next-line + (kbd "i") 'evil-previous-line + (kbd "o") 'evil-forward-char + (kbd "h") 'evil-ex-search-next + (kbd "H") 'evil-ex-search-previous + (kbd "l") 'evil-forward-word-end + (kbd "m") 'evil-insert + (kbd "M") 'evil-insert-line + (kbd "j") 'evil-open-below + (kbd "J") 'evil-open-above) + + (evil-define-key 'visual evil-org-mode-map + (kbd "n") 'evil-backward-char + (kbd "e") 'evil-next-line + (kbd "i") 'evil-previous-line + (kbd "o") 'evil-forward-char + (kbd "h") 'evil-ex-search-next + (kbd "H") 'evil-ex-search-previous + (kbd "l") 'evil-forward-word-end)))) +#+END_SRC + +* Programming +** UI +#+BEGIN_SRC emacs-lisp + (column-number-mode) + (add-hook 'prog-mode-hook 'display-line-numbers-mode) + (use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) +#+END_SRC + +** Magit +#+BEGIN_SRC emacs-lisp + (use-package magit + :commands (magit-status magit-get-current-branch) + :custom + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) +#+END_SRC + +** Git Visual Indicators +#+BEGIN_SRC emacs-lisp + ;; Show git changes in the editor fringe + (use-package diff-hl + :ensure t + :hook ((prog-mode . diff-hl-mode) + (org-mode . diff-hl-mode) + (dired-mode . diff-hl-dired-mode)) + :config + ;; Highlight changes on the fly + (diff-hl-flydiff-mode) + ;; Update diff-hl after magit operations + (add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh) + (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh) + ;; Better colors for visibility + (custom-set-faces + '(diff-hl-change ((t (:background "#3c3836" :foreground "#fabd2f")))) + '(diff-hl-insert ((t (:background "#3c3836" :foreground "#b8bb26")))) + '(diff-hl-delete ((t (:background "#3c3836" :foreground "#fb4934")))))) +#+END_SRC + +** Format +#+BEGIN_SRC emacs-lisp + (use-package format-all + :commands format-all-mode + :hook (prog-mode . format-all-mode) + :config + (setq-default format-all-formatters + '(("C" (astyle "--mode=c")) + ("Shell" (shfmt "-i" "4" "-ci"))))) +#+END_SRC + +** treesit +#+BEGIN_SRC emacs-lisp + (use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (delete 'rust treesit-auto-langs) + (global-treesit-auto-mode)) +#+END_SRC + +** direnv +#+BEGIN_SRC emacs-lisp + (use-package direnv + :config + (direnv-mode)) +#+END_SRC + +** Rust +#+BEGIN_SRC emacs-lisp + (use-package rust-mode + :init + (setq rust-mode-treesitter-derive t) + :config + (add-hook 'rust-mode-hook 'eglot-ensure) + (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))) +#+END_SRC + +** Haskell +#+BEGIN_SRC emacs-lisp + (use-package haskell-mode + :config + (add-to-list 'auto-mode-alist '("\\.hs\\'" . haskell-mode)) + (add-hook 'haskell-mode-hook 'eglot-ensure)) +#+END_SRC + +** Nix +#+BEGIN_SRC emacs-lisp + (add-to-list 'auto-mode-alist '("\\.nix\\'" . nix-ts-mode)) +#+END_SRC + +* Claude Code IDE Integration +** Terminal Backend +#+BEGIN_SRC emacs-lisp + ;; Choose your preferred terminal backend (eat is lighter and faster) + (use-package eat + :ensure t + :vc (:url "https://codeberg.org/akib/emacs-eat" :rev :newest) + :config + ;; Enhanced eat terminal integration with evil mode + (with-eval-after-load 'evil + (define-key eat-mode-map (kbd "C-y") 'eat-yank) + (add-hook 'eat-mode-hook + (lambda () + (when (bound-and-true-p evil-mode) + (define-key evil-normal-state-local-map (kbd "p") 'eat-yank) + (define-key evil-normal-state-local-map (kbd "P") 'eat-yank)))))) + ;; Alternative: vterm (more features but heavier) + ;; (use-package vterm + ;; :ensure t) +#+END_SRC + +** Claude Code IDE +#+BEGIN_SRC emacs-lisp + ;; Modern Claude Code integration with Model Context Protocol (MCP) + (use-package claude-code-ide + :ensure t + :vc (:url "https://github.com/manzaltu/claude-code-ide.el" :rev :newest) + :bind ("C-c a" . claude-code-ide-menu) + :config + ;; Enable Emacs MCP tools for Claude to access LSP, tree-sitter, etc. + (claude-code-ide-emacs-tools-setup) + + ;; Window placement - opens on the right side + (setq claude-code-ide-window-side 'right + claude-code-ide-window-width 100 + claude-code-ide-focus-on-open t) + + ;; Terminal backend configuration + (setq claude-code-ide-terminal-backend 'eat) + + ;; Enable better diff viewing with ediff + (setq claude-code-ide-use-ide-diff t + claude-code-ide-focus-claude-after-ediff nil + claude-code-ide-show-claude-window-in-ediff t) + + ;; Better diff colors and settings + (with-eval-after-load 'ediff + ;; Split windows horizontally for better diff viewing + (setq ediff-split-window-function 'split-window-horizontally) + (setq ediff-window-setup-function 'ediff-setup-windows-plain) + + ;; Better diff highlighting + (custom-set-faces + '(ediff-current-diff-A ((t (:background "#2d1b1b" :foreground "#fb4934")))) + '(ediff-current-diff-B ((t (:background "#1b2d1b" :foreground "#b8bb26")))) + '(ediff-fine-diff-A ((t (:background "#4d2d2d" :foreground "#ff6b6b")))) + '(ediff-fine-diff-B ((t (:background "#2d4d2d" :foreground "#4ecdc4")))) + '(ediff-even-diff-A ((t (:background "#1c1c1c")))) + '(ediff-even-diff-B ((t (:background "#1c1c1c")))) + '(ediff-odd-diff-A ((t (:background "#262626")))) + '(ediff-odd-diff-B ((t (:background "#262626")))))) + + ;; Auto-focus settings + (setq claude-code-ide-focus-on-open t)) +#+END_SRC + +** Alternative Diff Viewer +#+BEGIN_SRC emacs-lisp + ;; Alternative: vdiff for even better diff viewing + (use-package vdiff + :ensure t + :commands (vdiff-buffers vdiff-files) + :config + ;; Better diff colors for Tokyo Night theme + (custom-set-faces + '(vdiff-addition-face ((t (:background "#1b2d1b" :foreground "#b8bb26")))) + '(vdiff-change-face ((t (:background "#2d1b1b" :foreground "#fabd2f")))) + '(vdiff-closed-fold-face ((t (:background "#3c3836")))) + '(vdiff-open-fold-face ((t (:background "#504945")))) + '(vdiff-subtraction-face ((t (:background "#2d1b1b" :foreground "#fb4934"))))) + + ;; Keybindings for vdiff + (define-key vdiff-mode-map (kbd "C-c v n") 'vdiff-next-hunk) + (define-key vdiff-mode-map (kbd "C-c v p") 'vdiff-previous-hunk) + (define-key vdiff-mode-map (kbd "C-c v q") 'vdiff-quit)) +#+END_SRC + +** MCP Server Setup +#+BEGIN_SRC emacs-lisp + ;; Helper function to set up MCP server for Claude Code + (defun setup-claude-code-mcp () + "Set up MCP server for Claude Code IDE integration." + (interactive) + (let ((setup-commands + '("npm install -g claude-code-mcp-server" + "claude mcp add-json emacs '{\"type\": \"stdio\", \"command\": \"claude-code-mcp\"}'"))) + (message "Run these commands in your terminal to set up MCP:") + (dolist (cmd setup-commands) + (message " %s" cmd)) + (with-temp-buffer + (insert "# Claude Code MCP Setup Commands\n\n") + (dolist (cmd setup-commands) + (insert (format "%s\n" cmd))) + (insert "\n# After running these commands, restart Emacs and try C-c a") + (switch-to-buffer-other-window (current-buffer)) + (markdown-mode)))) +#+END_SRC + +** Font Configuration for Claude Code +#+BEGIN_SRC emacs-lisp + ;; Ensure Claude Code's unicode characters display properly + (defun setup-claude-code-fonts () + "Configure font fallbacks for Claude Code's unicode characters." + (when (display-graphic-p) + ;; Disable default font for symbols to use our fallbacks + (setq use-default-font-for-symbols nil) + + ;; Add fallback fonts for unicode characters Claude Code uses + (set-fontset-font t 'symbol "DejaVu Sans" nil 'prepend) + (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend) + (set-fontset-font t 'unicode "Symbola" nil 'prepend) + + ;; Keep your main font as primary + (set-fontset-font t 'symbol "MesloLGS NF" nil 'prepend))) + + ;; Apply font setup after Emacs starts + (add-hook 'emacs-startup-hook #'setup-claude-code-fonts) +#+END_SRC + +** Project and Directory Setup +#+BEGIN_SRC emacs-lisp + ;; Automatically create Claude Code directories and config files + (defun setup-claude-code-directories () + "Create necessary Claude Code directories and example files." + (let ((claude-dirs '("~/.claude" + "~/.claude/commands" + "~/.claude/local")) + (example-prompt "~/.claude-code.prompt.md") + (example-command "~/.claude/commands/understand-guidelines.md")) + + ;; Create directories + (dolist (dir claude-dirs) + (unless (file-exists-p dir) + (make-directory dir t))) + + ;; Create example project prompt + (unless (file-exists-p example-prompt) + (with-temp-buffer + (insert "# Project Context\n\n") + (insert "This is an Emacs configuration focused on productivity and brain-friendly workflows.\n\n") + (insert "## Key Features\n") + (insert "- Evil mode for Vim-like editing\n") + (insert "- Org-roam for knowledge management\n") + (insert "- Doom themes and modeline\n") + (insert "- Focus modes for editing\n\n") + (insert "Please maintain consistency with existing patterns and conventions.\n") + (write-file example-prompt))) + + ;; Create example command + (unless (file-exists-p example-command) + (with-temp-buffer + (insert "# Understand Guidelines\n\n") + (insert "Please review the project context and understand the coding style.\n") + (insert "Focus on:\n") + (insert "- Emacs Lisp best practices\n") + (insert "- use-package configuration patterns\n") + (insert "- Evil mode compatibility\n") + (insert "- User experience for friendly workflows\n") + (write-file example-command))))) + + ;; Set up directories when claude-code-ide loads + (with-eval-after-load 'claude-code-ide + (setup-claude-code-directories)) +#+END_SRC + +** Evil Mode Integration +#+BEGIN_SRC emacs-lisp + ;; Evil keybindings for Claude Code IDE + (with-eval-after-load 'claude-code-ide + ;; Add Evil-friendly keybindings using leader key + (with-eval-after-load 'evil + (define-key evil-normal-state-map (kbd "SPC a c") 'claude-code-ide) + (define-key evil-normal-state-map (kbd "SPC a m") 'claude-code-ide-menu) + (define-key evil-normal-state-map (kbd "SPC a r") 'claude-code-ide-resume)) + + ;; Configure Claude Code buffers for Evil + (add-hook 'claude-code-ide-mode-hook + (lambda () + (when (bound-and-true-p evil-mode) + (define-key evil-normal-state-local-map (kbd "q") 'quit-window) + (define-key evil-normal-state-local-map (kbd "r") 'revert-buffer))))) +#+END_SRC + +** Custom Tools for Claude Code +#+BEGIN_SRC emacs-lisp + ;; Example of exposing custom Emacs functions to Claude via MCP + (with-eval-after-load 'claude-code-ide + ;; Example: Expose org-roam functions to Claude + (with-eval-after-load 'org-roam + (claude-code-ide-make-tool + :function #'org-roam-node-find + :name "find_roam_node" + :description "Find and open an org-roam node" + :args '((:name "query" + :type string + :description "Search query for the node" + :optional t))) + + (claude-code-ide-make-tool + :function #'org-roam-capture + :name "create_roam_note" + :description "Create a new org-roam note" + :args '((:name "title" + :type string + :description "Title for the new note" + :optional t))))) +#+END_SRC +* Org +** Agenda Configuration +#+BEGIN_SRC emacs-lisp + ;; Simple agenda setup for habits + (setq org-agenda-custom-commands + '(("h" "Habits" agenda "" + ((org-agenda-show-log t) + (org-agenda-ndays 7) + (org-agenda-log-mode-items '(closed clock state)) + (org-agenda-skip-function '(org-agenda-skip-entry-if 'notregexp ":habit:")))) + ("d" "Daily agenda and habits" + ((agenda "" ((org-agenda-ndays 1) + (org-agenda-overriding-header "Today's Schedule"))) + (tags-todo "+habit" ((org-agenda-overriding-header "Daily Habits"))))) + ("w" "Weekly Review" + ((agenda "" ((org-agenda-ndays 7) + (org-agenda-overriding-header "This Week"))) + (todo "TODO" ((org-agenda-overriding-header "All TODOs"))))))) + + ;; Better agenda display + (setq org-agenda-prefix-format + '((agenda . " %i %-12:c%?-12t% s") + (todo . " %i %-12:c") + (tags . " %i %-12:c") + (search . " %i %-12:c"))) +#+END_SRC + +** Setup +#+BEGIN_SRC emacs-lisp + (defun dw/org-mode-setup () + (org-indent-mode) + (variable-pitch-mode 1) + (auto-fill-mode 0) + (visual-line-mode 1) + (setq evil-auto-indent nil) + (setq auto-save-timeout 10)) + + (use-package org + :hook (org-mode . dw/org-mode-setup) + :config + (setq org-ellipsis " β–Ύ" + org-hide-emphasis-markers t + org-fontify-whole-heading-line t + org-startup-folded 'content) + + ;; Bigger headings for better visual hierarchy + (custom-set-faces + '(org-level-1 ((t (:inherit outline-1 :height 1.4)))) + '(org-level-2 ((t (:inherit outline-2 :height 1.3)))) + '(org-level-3 ((t (:inherit outline-3 :height 1.2)))) + '(org-level-4 ((t (:inherit outline-4 :height 1.1)))) + '(org-level-5 ((t (:inherit outline-5 :height 1.0))))) + + ;; Keep some things fixed-pitch in Org + (set-face-attribute 'org-table nil :inherit 'fixed-pitch) + (set-face-attribute 'org-code nil :inherit 'fixed-pitch) + (set-face-attribute 'org-block nil :inherit 'fixed-pitch) + (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch) + + ;; TODO states with emojis + (setq org-todo-keywords + '((sequence + "πŸ“₯ INBOX(i)" + "πŸ“‹ TODO(t)" + "⚑ NEXT(n)" + "πŸš€ DOING(s!)" + "⏸️ WAIT(w@)" + "πŸ”„ ROUTINE(r)" + "|" + "βœ… DONE(d!)" + "❌ CANCEL(c@)"))) + + ;; Colors for visual processing + (setq org-todo-keyword-faces + '(("πŸ“₯ INBOX" . (:foreground "gray" :weight bold)) + ("πŸ“‹ TODO" . (:foreground "lightblue" :weight bold)) + ("⚑ NEXT" . (:foreground "orange" :weight bold)) + ("πŸš€ DOING" . (:foreground "red" :weight bold :underline t)) + ("⏸️ WAIT" . (:foreground "magenta" :weight bold)) + ("πŸ”„ ROUTINE" . (:foreground "cyan" :weight bold)) + ("βœ… DONE" . (:foreground "green" :weight bold)) + ("❌ CANCEL" . (:foreground "gray" :strike-through t))))) +#+END_SRC + +** Org Bullets +#+BEGIN_SRC emacs-lisp + (use-package org-bullets + :after org + :hook (org-mode . org-bullets-mode) + :config + (setq org-bullets-bullet-list '("β—‰" "β—‹" "●" "β—‹" "●" "β—‹" "●"))) +#+END_SRC + +** Org Appear +#+BEGIN_SRC emacs-lisp + (use-package org-appear + :after org + :hook (org-mode . org-appear-mode) + :config + (setq org-appear-autoemphasis t) + (setq org-appear-autolinks t) + (setq org-appear-autosubmarkers t)) +#+END_SRC + +** Org Roam +#+BEGIN_SRC emacs-lisp + (use-package org-roam + :ensure t + :init + (setq org-roam-v2-ack t) + :custom + (org-roam-directory "~/roam/") + (org-roam-completion-everywhere t) + + ;; Simple capture templates + (org-roam-capture-templates + '(("d" "default" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+title: ${title}\n") + :unnarrowed t) + + ("n" "note" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+title: ${title}\n#+date: %U\n\n") + :unnarrowed t))) + + ;; Simple daily notes + (org-roam-dailies-capture-templates + '(("d" "default" entry + "* %<%H:%M> %?" + :target (file+head "%<%Y-%m-%d>.org" + "#+title: %<%Y-%m-%d>\n\n")))) + + :bind (("C-c n n" . org-roam-buffer-toggle) + ("C-c n f" . org-roam-node-find) + ("C-c n g" . org-roam-graph) + ("C-c n i" . org-roam-node-insert) + ("C-c n c" . org-roam-capture) + ("C-c n j" . org-roam-dailies-capture-today) + ("C-c n t" . org-roam-dailies-goto-today) + ("C-c n y" . org-roam-dailies-capture-yesterday) + ("C-c n d" . org-roam-dailies-goto-date)) + + :config + (org-roam-db-autosync-mode) + + ;; show context in completions + (setq org-roam-node-display-template "${title:*} ${tags:20}") + + ;; Zettelkasten node type indicators + (cl-defmethod org-roam-node-type ((node org-roam-node)) + "Return the type of node based on its tags." + (cond + ((member "literature" (org-roam-node-tags node)) "πŸ“š") + ((member "fleeting" (org-roam-node-tags node)) "πŸ¦‹") + ((member "connection" (org-roam-node-tags node)) "πŸ”—") + ((member "question" (org-roam-node-tags node)) "❓") + ((member "dump" (org-roam-node-tags node)) "🧠") + ((member "journal" (org-roam-node-tags node)) "πŸ“") + ((member "daily" (org-roam-node-tags node)) "πŸ“…") + ((member "habits" (org-roam-node-tags node)) "πŸ”„") + (t "πŸ’‘"))) + + ;; add type to display + (setq org-roam-node-display-template "${type} ${title:*} ${tags:20}")) +#+end_src + +** org roam ui +#+begin_src emacs-lisp + (use-package websocket + :after org-roam) + + (use-package org-roam-ui + :after org-roam + :config + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start nil)) +#+end_src + +** focus modes +#+begin_src emacs-lisp + ;; olivetti - centers text for better focus + (use-package olivetti + :hook (org-mode . olivetti-mode) + :config + (setq olivetti-body-width 100) + (setq olivetti-minimum-body-width 80)) + + ;; focus mode - dims other sections + (use-package focus + :commands focus-mode + :config + (setq focus-dimness 0.3)) + + ;; writeroom mode - distraction free writing + (use-package writeroom-mode + :commands writeroom-mode + :config + (setq writeroom-width 100)) +#+end_src + +** Simple Habit Tracking +#+begin_src emacs-lisp + ;; Simple habit tracking with org-agenda + org-habit + (with-eval-after-load 'org + (require 'org-habit) + (add-to-list 'org-modules 'org-habit) + + ;; Habit display settings - cleaner view + (setq org-habit-graph-column 50) + (setq org-habit-preceding-days 14) + (setq org-habit-following-days 3) + (setq org-habit-show-habits-only-for-today t) + + ;; Agenda configuration for habits + (setq org-agenda-files '("~/roam/habits.org")) + (setq org-agenda-include-diary nil) + (setq org-habit-show-all-today t) + + ;; Create habits.org if it doesn't exist + (let ((habits-file "~/roam/habits.org")) + (unless (file-exists-p habits-file) + (with-temp-buffer + (insert "#+title: Habits\n#+filetags: :habits:\n\n") + (insert "* Daily Habits\n\n") + (insert "** TODO Exercise :habit:daily:\n") + (insert "SCHEDULED: <" (format-time-string "%Y-%m-%d %a") " .+1d>\n") + (insert ":PROPERTIES:\n:STYLE: habit\n:END:\n\n") + (insert "** TODO Read 20min :habit:daily:\n") + (insert "SCHEDULED: <" (format-time-string "%Y-%m-%d %a") " .+1d>\n") + (insert ":PROPERTIES:\n:STYLE: habit\n:END:\n\n") + (insert "** TODO Reflect/Journal :habit:daily:\n") + (insert "SCHEDULED: <" (format-time-string "%Y-%m-%d %a") " .+1d>\n") + (insert ":PROPERTIES:\n:STYLE: habit\n:END:\n\n") + (insert "* Weekly Habits\n\n") + (insert "** TODO Weekly review :habit:weekly:\n") + (insert "SCHEDULED: <" (format-time-string "%Y-%m-%d %a") " .+1w>\n") + (insert ":PROPERTIES:\n:STYLE: habit\n:END:\n\n") + (write-file habits-file))))) +#+end_src + +** org clock +#+begin_src emacs-lisp + ;; time tracking configuration + (with-eval-after-load 'org + (setq org-clock-persist 'history) + (org-clock-persistence-insinuate) + + ;; clock settings + (setq org-clock-in-resume t) + (setq org-clock-into-drawer t) + (setq org-clock-out-remove-zero-time-clocks t) + (setq org-clock-report-include-clocking-task t) + + ;; save clock history across sessions + (setq org-clock-persist-file "~/.emacs.d/org-clock-save.el") + ;; Suppress lexical-binding warnings for auto-generated files + (setq warning-suppress-types '((files))) + + ;; keybindings for clocking + (global-set-key (kbd "C-c C-x C-i") 'org-clock-in) + (global-set-key (kbd "C-c C-x C-o") 'org-clock-out) + (global-set-key (kbd "C-c C-x C-x") 'org-clock-in-last) + (global-set-key (kbd "C-c C-x C-r") 'org-clock-report)) +#+end_src + +** org pomodoro +#+begin_src emacs-lisp + (use-package org-pomodoro + :commands org-pomodoro + :config + (setq org-pomodoro-length 25) + (setq org-pomodoro-short-break-length 5) + (setq org-pomodoro-long-break-length 15) + (setq org-pomodoro-play-sounds t)) +#+end_src + +* command center +#+begin_src emacs-lisp + (use-package hydra) + + ;; Simple command center + (defhydra hydra-capture-menu (:color blue :hint nil) + " + command center + ----------------------------------------------- + capture: _d_: default note _n_: note with date + navigate: _f_: find note _t_: today note _g_: roam graph + focus: _F_: focus mode _w_: writeroom _o_: olivetti + tools: _a_: agenda _P_: pomodoro _C_: claude code + _x_: exit + " + ;; Capture templates + ("d" (lambda () (interactive) (require 'org-roam) (org-roam-capture nil "d"))) ; default note + ("n" (lambda () (interactive) (require 'org-roam) (org-roam-capture nil "n"))) ; note with date + + ;; Navigation + ("f" (lambda () (interactive) (require 'org-roam) (org-roam-node-find))) + ("t" (lambda () (interactive) (require 'org-roam) (org-roam-dailies-goto-today))) + ("g" (lambda () (interactive) (require 'org-roam) (org-roam-ui-open))) + + ;; Focus modes + ("F" focus-mode) + ("w" writeroom-mode) + ("o" olivetti-mode) + + ;; Tools + ("a" org-agenda) + ("P" org-pomodoro) + ("C" claude-code-ide-menu) + + ("x" nil)) + + (global-set-key (kbd "C-c h") 'hydra-capture-menu/body) +#+end_src + +* Completion Stack +** Marginalia +#+BEGIN_SRC emacs-lisp + ;; Enable rich annotations using the Marginalia package + (use-package marginalia + ;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding + ;; available in the *Completions* buffer, add it to the + ;; `completion-list-mode-map'. + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + + ;; The :init section is always executed. + :init + + ;; Marginalia must be activated in the :init section of use-package such that + ;; the mode gets enabled right away. Note that this forces loading the + ;; package. + (marginalia-mode)) +#+END_SRC + +** Orderless +#+BEGIN_SRC emacs-lisp + (use-package orderless + :ensure t + :custom + (completion-styles '(orderless basic)) + (completion-category-defaults nil) + (completion-category-overrides '((file (styles basic partial-completion))))) +#+END_SRC + +** Vertico +#+BEGIN_SRC emacs-lisp + ;; Enable Vertico. + (use-package vertico + :custom + (vertico-cycle t) ;; Enable cycling + :init + (vertico-mode)) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; Emacs minibuffer configurations. + (use-package emacs + :custom + ;; Support opening new minibuffers from inside existing minibuffers. + (enable-recursive-minibuffers t) + ;; Hide commands in M-x which do not work in the current mode. Vertico + ;; commands are hidden in normal buffers. This setting is useful beyond + ;; Vertico. + (read-extended-command-predicate #'command-completion-default-include-p) + ;; Do not allow the cursor in the minibuffer prompt + (minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt))) +#+END_SRC + +** Embark +#+BEGIN_SRC emacs-lisp + (use-package embark + :ensure t + + :bind + (("C-." . embark-act) ;; pick some comfortable binding + ("C-;" . embark-dwim) ;; good alternative: M-. + ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' + + :init + + ;; Optionally replace the key help with a completing-read interface + (setq prefix-help-command #'embark-prefix-help-command) + + :config + + ;; Hide the mode line of the Embark live/completions buffers + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none))))) + + ;; Consult users will also want the embark-consult package. + (use-package embark-consult + :ensure t ; only need to install it, embark loads it after consult if found + :hook + (embark-collect-mode . consult-preview-at-point-mode)) +#+END_SRC + +** Consult +#+BEGIN_SRC emacs-lisp + ;; configuration for Consult + (use-package consult + ;; Replace bindings. Lazily loaded by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c M-x" . consult-mode-command) + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings in `search-map' + ("M-s d" . consult-find) ;; Alternative: consult-fd + ("M-s c" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Tweak the register preview for `consult-register-load', + ;; `consult-register-store' and the built-in commands. This improves the + ;; register formatting, adds thin separator lines, register sorting and hides + ;; the window mode line. + (advice-add #'register-preview :override #'consult-register-window) + (setq register-preview-delay 0.5) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Configure preview for different commands + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep consult-man + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file + ;; :preview-key "M-." + :preview-key '(:debounce 0.4 any)) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<")) ;; "C-+" +#+END_SRC + +* Final Touches +#+BEGIN_SRC emacs-lisp + ;; Frame title + (setq frame-title-format '("" "%b - Tom's Emacs")) + + ;; Create required directories if they don't exist + (dolist (dir '("~/.emacs.d/backups" + "~/.emacs.d/auto-saves" + "~/roam" + "~/roam/fleeting" + "~/roam/dumps" + "~/roam/journal" + "~/roam/daily")) + (unless (file-exists-p dir) + (make-directory dir t))) + +#+END_SRC diff --git a/config.org.old b/config.org.old new file mode 100644 index 0000000..e138aa6 --- /dev/null +++ b/config.org.old @@ -0,0 +1,383 @@ +#+TITLE: My Emacs Configuration +#+AUTHOR: Tom Berg +#+OPTIONS: num:nil +* Lecical Binding +#+BEGIN_SRC emacs-lisp + ;;; ... -*- lexical-binding: nil -*- +#+END_SRC +* Package +#+BEGIN_SRC emacs-lisp + ;; Initialize package sources + (require 'package) + + (setq package-archives '(("melpa" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("elpa" . "https://elpa.gnu.org/packages/"))) + + (unless package-archive-contents + (package-refresh-contents)) + + ;; Bootstrap use-package + (unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + (require 'use-package) + (setq use-package-always-ensure t) +#+END_SRC +* UI +** Clean up +#+BEGIN_SRC emacs-lisp + (setq inhibit-startup-message t) + + (scroll-bar-mode -1) ; Disable visible scrollbar + (tool-bar-mode -1) ; Disable the toolbar + (tooltip-mode -1) ; Disable tooltips + (set-fringe-mode 10) ; Give some breathing room + + (menu-bar-mode -1) ; Disable the menu bar + + (set-face-attribute 'default nil :font "MesloLGS NF" :height 140) +#+END_SRC +** Theme +#+BEGIN_SRC emacs-lisp + (use-package doom-themes + :config + ;; Best dark themes for focus: + ;; doom-one, doom-dracula, doom-tokyo-night, doom-palenight + (load-theme 'doom-tokyo-night t) + + ;; Enable flashing mode-line on errors + (doom-themes-visual-bell-config) + + ;; Corrects org-mode's native fontification + (doom-themes-org-config)) + +;; OR Alternative: Modus themes (high contrast, accessibility focused) +;; (use-package modus-themes +;; :config +;; (load-theme 'modus-vivendi t)) ; Dark theme + +;; All-the-icons for visual indicators +(use-package all-the-icons + :if (display-graphic-p)) + #+END_SRC +** Help +#+BEGIN_SRC emacs-lisp + (which-key-mode) + (use-package helpful + :ensure t ; Install from MELPA if not already present + :bind + ;; Replace default help commands with Helpful equivalents + (("C-h f" . helpful-callable) ; Functions, macros, and special forms + ("C-h v" . helpful-variable) ; Variables + ("C-h k" . helpful-key) ; Keybindings + ("C-h x" . helpful-command) ; Commands only + ("C-h ." . helpful-at-point)) ; Symbol at point + ) +#+END_SRC +* Evil Mode +#+BEGIN_SRC emacs-lisp + ;; Evil setup + (use-package evil + :ensure t + :init + (setq evil-want-integration t) + (setq evil-want-keybinding nil) + :config + (evil-mode 1)) + + ;; Evil Collection setup + (use-package evil-collection + :after evil + :ensure t + :config + (evil-collection-init)) +#+END_SRC +* Progaming +** UI +#+BEGIN_SRC emacs-lisp + (column-number-mode) + (add-hook 'prog-mode-hook 'display-line-numbers-mode) + (use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode) + ) +#+END_SRC +** Magit +#+BEGIN_SRC emacs-lisp + (use-package magit + :commands (magit-status magit-get-current-branch) + :custom + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) +#+END_SRC + +** Format +#+BEGIN_SRC emacs-lisp + (use-package format-all + :commands format-all-mode + :hook (prog-mode . format-all-mode) + :config + (setq-default format-all-formatters + '(("C" (astyle "--mode=c")) + ("Shell" (shfmt "-i" "4" "-ci"))))) +#+END_SRC +** treesit +#+BEGIN_SRC emacs-lisp + (use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (delete 'rust treesit-auto-langs) + (global-treesit-auto-mode)) + +#+END_SRC +** direnv +#+BEGIN_SRC emacs-lisp + (use-package direnv + :config + (direnv-mode)) +#+END_SRC +** Rust +#+BEGIN_SRC emacs-lisp + (use-package rust-mode + :init + (setq rust-mode-treesitter-derive t) + :config + (add-hook 'rust-mode-hook 'eglot-ensure) + (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))) +#+END_SRC +** Haskell +#+BEGIN_SRC emacs-lisp + (use-package haskell-mode + :config + (add-to-list 'auto-mode-alist '("\\.hs\\'" . haskell-mode)) + (add-hook 'haskell-mode-hook 'eglot-ensure)) +#+END_SRC +** Nix +#+BEGIN_SRC emacs-lisp + (add-to-list 'auto-mode-alist '("\\.nix\\'" . nix-ts-mode)) +#+END_SRC + +* Org +** Set up +#+BEGIN_SRC emacs-lisp + (defun dw/org-mode-setup () + (org-indent-mode) + (variable-pitch-mode 1) + (auto-fill-mode 0) + (visual-line-mode 1) + (setq evil-auto-indent nil)) + + (use-package org + :hook (org-mode . dw/org-mode-setup) + :config + (setq org-ellipsis " β–Ύ" + org-hide-emphasis-markers t)) +#+END_SRC + +** Roam +#+BEGIN_SRC emacs-lisp + +#+END_SRC +* Completion Stack +** Marginalia +#+BEGIN_SRC emacs-lisp + ;; Enable rich annotations using the Marginalia package + (use-package marginalia + ;; Bind `marginalia-cycle' locally in the minibuffer. To make the binding + ;; available in the *Completions* buffer, add it to the + ;; `completion-list-mode-map'. + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + + ;; The :init section is always executed. + :init + + ;; Marginalia must be activated in the :init section of use-package such that + ;; the mode gets enabled right away. Note that this forces loading the + ;; package. + (marginalia-mode)) +#+END_SRC +** Orderless +#+BEGIN_SRC emacs-lisp + (use-package orderless + :ensure t + :custom + (completion-styles '(orderless basic)) + (completion-category-defaults nil) + (completion-category-overrides '((file (styles basic partial-completion))))) +#+END_SRC +** Vestico +#+BEGIN_SRC emacs-lisp + ;; Enable Vertico. + (use-package vertico + ;;:custom + ;; (vertico-scroll-margin 0) ;; Different scroll margin + ;; (vertico-count 20) ;; Show more candidates + ;; (vertico-resize t) ;; Grow and shrink the Vertico minibuffer + ;; (vertico-cycle t) ;; Enable cycling for `vertico-next/previous' + :init + (vertico-mode)) + + ;; Persist history over Emacs restarts. Vertico sorts by history position. + (use-package savehist + :init + (savehist-mode)) + + ;; Emacs minibuffer configurations. + (use-package emacs + :custom + ;; Support opening new minibuffers from inside existing minibuffers. + (enable-recursive-minibuffers t) + ;; Hide commands in M-x which do not work in the current mode. Vertico + ;; commands are hidden in normal buffers. This setting is useful beyond + ;; Vertico. + (read-extended-command-predicate #'command-completion-default-include-p) + ;; Do not allow the cursor in the minibuffer prompt + (minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt))) +#+END_SRC +** Embark +#+BEGIN_SRC emacs-lisp + (use-package embark + :ensure t + + :bind + (("C-." . embark-act) ;; pick some comfortable binding + ("C-;" . embark-dwim) ;; good alternative: M-. + ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' + + :init + + ;; Optionally replace the key help with a completing-read interface + (setq prefix-help-command #'embark-prefix-help-command) + + ;; Show the Embark target at point via Eldoc. You may adjust the + ;; Eldoc strategy, if you want to see the documentation from + ;; multiple providers. Beware that using this can be a little + ;; jarring since the message shown in the minibuffer can be more + ;; than one line, causing the modeline to move up and down: + + ;; (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target) + ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly) + + :config + + ;; Hide the mode line of the Embark live/completions buffers + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none))))) + + ;; Consult users will also want the embark-consult package. + (use-package embark-consult + :ensure t ; only need to install it, embark loads it after consult if found + :hook + (embark-collect-mode . consult-preview-at-point-mode)) +#+END_SRC +** Consult +#+BEGIN_SRC emacs-lisp + ;; configuration for Consult + (use-package consult + ;; Replace bindings. Lazily loaded by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c M-x" . consult-mode-command) + ("C-c h" . consult-history) + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings in `search-map' + ("M-s d" . consult-find) ;; Alternative: consult-fd + ("M-s c" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Tweak the register preview for `consult-register-load', + ;; `consult-register-store' and the built-in commands. This improves the + ;; register formatting, adds thin separator lines, register sorting and hides + ;; the window mode line. + (advice-add #'register-preview :override #'consult-register-window) + (setq register-preview-delay 0.5) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep consult-man + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file + ;; :preview-key "M-." + :preview-key '(:debounce 0.4 any)) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (keymap-set consult-narrow-map (concat consult-narrow-key " ?") #'consult-narrow-help) + ) +#+END_SRC +