;; init.el --- -*- lexical-binding: t; -*- ;; Use this at the top of your .emacs file for local overrides: ;; (let ((init "~/.emacs.d/init.elc")) ;; (if (file-exists-p init) ;; (load-file init) ;; (load-file (substring init 0 -1)))) (add-to-list 'load-path "~/.emacs.d/lisp") (with-eval-after-load 'package (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)) (setopt inhibit-splash-screen t) ;; No Bell. (setq ring-bell-function 'ignore) ;; Don't litter. (setopt make-backup-files nil) (setopt create-lockfiles nil) ;; Ensure that scratch starts in fundamental-mode. (setopt initial-major-mode 'fundamental-mode) ;; Don't show load average in modeline. (setopt display-time-default-load-average nil) ;; Automatically reread from disk if the underlying file changes. (setopt auto-revert-avoid-polling t) (setopt auto-revert-interval 5) (setopt auto-revert-check-vc-info t) (global-auto-revert-mode) ;; Save history in EMACS DIR. (savehist-mode) ;; Setup ctrl+arrowkey to move between emacs defined windows. Will try to make vim-like at some point. (windmove-default-keybindings 'control) ;; Define killing current buffer using C-x c. (global-set-key (kbd "C-x c") #'kill-current-buffer) ;; Some legacy shit. (setopt sentence-end-double-space nil) ;; Fix backups. (setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups")))) ;; Globally escape. (global-set-key (kbd "") 'keyboard-escape-quit) ;; Fix some bs with 2~. (global-set-key (kbd "S-SPC") 'just-one-space) (use-package which-key :ensure t :config (which-key-mode)) (use-package evil :ensure t :init (setq evil-respect-visual-line-mode t) (setq evil-undo-system 'undo-redo) (setq evil-want-C-u-scroll t) :config (evil-mode) (define-key evil-normal-state-map (kbd "C-v") 'evil-visual-block) (define-key evil-visual-state-map (kbd "C-v") 'evil-visual-block) (evil-set-initial-state 'vterm-mode 'emacs) ) (use-package cua-base :ensure nil :config (define-key evil-insert-state-map (kbd "C-S-v") 'cua-paste) (define-key evil-normal-state-map (kbd "C-S-v") 'cua-paste) (define-key evil-visual-state-map (kbd "C-S-v") 'cua-paste)) (setopt enable-recursive-minibuffers t) (setopt completion-cycle-threshold 1) (setopt completions-detailed t) (setopt tab-always-indent 'complete) (setopt completion-styles '(basic initials substring)) (setopt completion-auto-help 'always) (setopt completions-max-height 20) (setopt completions-detailed t) (setopt completions-format 'one-column) (setopt completions-group t) (setopt completion-auto-select 'second-tab) ; Much more eager (setopt completion-auto-select t) ; See `C-h v completion-auto-select' for more possible values (keymap-set minibuffer-mode-map "TAB" 'minibuffer-complete) ;; Interface Things. (setopt line-number-mode t) (setopt column-number-mode t) (setopt scroll-margin 10) (setq scroll-conservatively 10) (setopt x-underline-at-descent-line nil) (setopt switch-to-buffer-obey-display-actions t) (setopt show-trailing-whitespace t) (setopt indicate-buffer-boundaries 'left) (blink-cursor-mode -1) ; Steady cursor (pixel-scroll-precision-mode) ; Smooth Scrolling. ;; Line number displays. (add-hook 'prog-mode-hook 'display-line-numbers-mode) (setopt display-line-numbers-width 1) (add-hook 'text-mode-hook 'visual-line-mode) (let ((hl-line-hooks '(text-mode-hook prog-mode-hook))) (mapc (lambda (hook) (add-hook hook 'hl-line-mode)) hl-line-hooks)) (setopt tab-bar-show 1) ;; Gruvbox theme. (setq custom-safe-themes t) (use-package gruvbox-theme :ensure t :init (load-theme 'gruvbox-dark-medium) ) (use-package vertico :ensure t :init (vertico-mode)) (use-package vertico-directory :after vertico :bind (:map vertico-map ("M-DEL" . vertico-directory-delete-word))) (use-package marginalia :ensure t :config (marginalia-mode)) ;; Special, telescope-like bindings. (use-package consult :ensure t :bind ( ("C-x b" . consult-buffer) ; orig. switch-to-buffer ("M-y" . consult-yank-pop) ; orig. yank-pop ("M-s r" . consult-ripgrep) ("M-s l" . consult-line) ("C-s" . consult-line) ("M-s s" . consult-line) ; consult-line instead of isearch, bind ("M-s L" . consult-line-multi) ; isearch to M-s s ("M-s o" . consult-outline) :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 ) :config (setq consult-narrow-key "<")) ;; Magit: (use-package magit :ensure t :bind (("C-x g" . magit-status))) ;; Completion: (use-package company :ensure t :config (global-company-mode)) ;; Language specific major modes. (use-package markdown-mode :ensure t :hook (markdown-mode . (lambda () (visual-line-mode 1) (flyspell-mode 1)))) (use-package yaml-mode :ensure t) (use-package nix-mode :ensure t) (use-package json-mode :ensure t) (use-package rust-mode :ensure t) (use-package protobuf-mode :ensure t) ;; Use python-mode for .bazel files (add-to-list 'auto-mode-alist '("\\.bazel\\'" . python-mode)) (add-to-list 'auto-mode-alist '("\\(BUILD\\|WORKSPACE\\|MODULE\\)\\'" . python-mode)) (use-package emacs :config ;; Treesitter gramar remap. (setq major-mode-remap-alist '((yaml-mode . yaml-ts-mode) (bash-mode . bash-ts-mode) (js2-mode . js-ts-mode))) ;; Auto wrap parens. :hook ((prog-mode . electric-pair-mode))) (use-package eglot :bind ("C-x f" . eglot-format-buffer) ;; Configure hooks to automatically turn-on eglot for selected modes ;; :hook ;; (((python-mode ruby-mode elixir-mode) . eglot)) :custom (eglot-send-changes-idle-time 0.1) (eglot-extend-to-xref t) ; activate Eglot in referenced non-project files :config (fset #'jsonrpc--log-event #'ignore) ; massive perf boost---don't log every event ;; Sometimes you need to tell Eglot where to find the language server ; (add-to-list 'eglot-server-programs ; '(haskell-mode . ("haskell-language-server-wrapper" "--lsp"))) ) (use-package flycheck :ensure t :init (global-flycheck-mode)) (use-package projectile :ensure t :config (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map) (projectile-mode)) (use-package eshell :init (defun foehammer/setup-eshell () ;; Something funny is going on with how Eshell sets up its keymaps; this is ;; a work-around to make C-r bound in the keymap (keymap-set eshell-mode-map "C-r" 'consult-history)) :hook ((eshell-mode . foehammer/setup-eshell))) (use-package claude-code-ide :vc (:url "https://github.com/manzaltu/claude-code-ide.el" :rev :newest) :bind ("C-c '" . claude-code-ide-menu) ; Set your favorite keybinding :custom (claude-code-ide-terminal-backend 'eat) :config (claude-code-ide-emacs-tools-setup)) ;; Eat: Emulate A Terminal (use-package eat :ensure t :custom (eat-term-name "xterm") :config (eat-eshell-mode) (eat-eshell-visual-command-mode)) ;; Don't change this (or else gg). (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. '(package-selected-packages '(claude-code-ide company consult eat elcord evil flycheck gruvbox-theme json-mode magit marginalia markdown-mode nix-mode projectile protobuf-mode rust-mode vertico vterm which-key yaml-mode)) '(package-vc-selected-packages '((claude-code-ide :url "https://github.com/manzaltu/claude-code-ide.el")))) (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. )