2025-01-02 15:40:22 -07:00

516 lines
17 KiB
EmacsLisp

;;; Grant Hunters init.el
(setq-default backup-directory-alist `((".*" . ,(concat user-emacs-directory "backups")))
undo-tree-history-directory-alist `((".*" . ,(concat user-emacs-directory "undo")))
auto-save-file-name-transforms `((".*" ,(concat user-emacs-directory "autosave") t))
custom-file (locate-user-emacs-file "custom.el")
confirm-kill-emacs 'y-or-n-p
frame-title-format "%F %b "
gc-cons-threshold (* (* 1
128)
1024
1024) ;; 100mb
indent-tabs-mode nil
tab-width 2
inhibit-splash-screen t
inhibit-startup-message t
lazy-highlight-cleanup nil
make-backup-files nil
read-process-output-max (* 1 (* 1024
1024)) ;; 1mb
ring-bell-function 'ignore
uniquify-buffer-name-style 'forward
vc-follow-symlinks t
warning-minimum-level
:error whitespace-line-column 500
package-enable-at-startup nil
browse-url-generic-program (executable-find "firefox"))
(load custom-file :no-error-if-file-is-missing)
;; Package manager
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 7))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
;; Integrates `straight' directly into the `use-package' package through the
;; `:straight' expression.
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
(add-to-list 'display-buffer-alist
'("\\`\\*\\(Warnings\\|Compile-Log\\)\\*\\'"
(display-buffer-no-window)
(allow-no-window . t)))
;; Basic behaviour
(defun prot/keyboard-quit-dwim ()
"Do-What-I-Mean behaviour for a general `keyboard-quit'.
The generic `keyboard-quit' does not do the expected thing when
the minibuffer is open. Whereas we want it to close the
minibuffer, even without explicitly focusing it.
The DWIM behaviour of this command is as follows:
- When the region is active, disable it.
- When a minibuffer is open, but not focused, close the minibuffer.
- When the Completions buffer is selected, close it.
- In every other case use the regular `keyboard-quit'."
(interactive)
(cond
((region-active-p)
(keyboard-quit))
((derived-mode-p 'completion-list-mode)
(delete-completion-window))
((> (minibuffer-depth) 0)
(abort-recursive-edit))
(t
(keyboard-quit))))
(define-key global-map (kbd "C-g") #'prot/keyboard-quit-dwim)
(fset 'yes-or-no-p 'y-or-n-p)
;; Look and Feel
(let ((mono-spaced-font "Monospace")
(proportionately-spaced-font "Sans"))
(set-face-attribute 'default nil :family mono-spaced-font :height 100)
(set-face-attribute 'fixed-pitch nil :family mono-spaced-font :height 1.0)
(set-face-attribute 'variable-pitch nil :family proportionately-spaced-font :height 1.0))
(show-paren-mode)
(setq linum-format
(lambda (line)
(propertize (number-to-string (1- line)) 'face 'linum)))
(global-display-line-numbers-mode)
(column-number-mode)
(pixel-scroll-precision-mode)
(use-package
material-theme
:config
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(select-frame frame)
(load-theme 'material t)
(set-frame-size (selected-frame) 150 48)))
(load-theme 'material t)))
(use-package nerd-icons)
(use-package nerd-icons-completion
:after marginalia
:config
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
(use-package nerd-icons-corfu
:after corfu
:config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(use-package nerd-icons-dired
:hook
(dired-mode . nerd-icons-dired-mode))
;; Minibuffer
(use-package vertico
:init
(vertico-mode))
(use-package marginalia
:init (marginalia-mode)
:bind (("M-A" . marginalia-cycle)
:map minibuffer-local-map
("M-A" . marginalia-cycle)))
(use-package orderless
:config
(setq completion-styles '(orderless basic))
(setq completion-category-defaults nil)
(setq completion-category-overrides nil))
(use-package savehist
:ensure nil
:hook (after-init . savehist-mode))
(use-package emacs
:custom
(tab-always-indent 'complete)
(enable-recursive-minibuffers t)
;; Hide commands in M-x which do not work in the current mode.
(read-extended-command-predicate #'command-completion-default-include-p)
:init
;; Add prompt indicator to `completing-read-multiple'.
;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma.
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode))
(use-package
corfu
:custom
(corfu-auto t)
(corfu-auto-delay 0)
(corfu-auto-prefix 1)
(corfu-cycle t)
(corfu-min-width 1)
:bind
(:map corfu-map
("TAB" . corfu-next)
([tab] . corfu-next)
("S-TAB" . corfu-previous)
([backtab] . corfu-previous))
:init
(global-corfu-mode)
(setq corfu-popupinfo-delay '(1.25 . 0.5))
(corfu-popupinfo-mode 1) ; shows documentation after `corfu-popupinfo-delay'
;; Sort by input history (no need to modify `corfu-sort-function').
(with-eval-after-load 'savehist
(corfu-history-mode 1)
(add-to-list 'savehist-additional-variables 'corfu-history)))
(use-package consult
:preface
(defun consult-ripgrep-at-point ()
(interactive)
(consult-ripgrep nil (thing-at-point 'symbol)))
:bind (;; C-c bindings (mode-specific-map)
("C-c h" . consult-history)
("C-c m" . consult-mode-command)
("C-c k" . consult-kmacro)
;; C-x bindings (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 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
("<help> a" . consult-apropos) ;; orig. apropos-command
;; M-g bindings (goto-map)
("M-g e" . consult-compile-error)
("M-g f" . consult-flycheck) ;; 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 (search-map)
("M-s d" . consult-find)
("M-s D" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep-at-point)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s m" . consult-multi-occur)
("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
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
(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)
:config
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
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 "<"))
;; File Manager
(use-package dired
:ensure nil
:straight (:type built-in)
:commands (dired)
:hook
((dired-mode . dired-hide-details-mode)
(dired-mode . hl-line-mode))
:config
(setq dired-recursive-copies 'always)
(setq dired-recursive-deletes 'always)
(setq delete-by-moving-to-trash t)
(setq dired-dwim-target t))
(use-package dired-subtree
:after dired
:bind
( :map dired-mode-map
("<tab>" . dired-subtree-toggle)
("TAB" . dired-subtree-toggle)
("<backtab>" . dired-subtree-remove)
("S-TAB" . dired-subtree-remove))
:config
(setq dired-subtree-use-backgrounds nil))
;; Customization
(use-package
multiple-cursors
:bind(("C-}" . mc/mark-next-like-this)
("C-{" . mc/mark-previous-like-this)
("C-|" . mc/mark-all-like-this)))
(use-package
crux
:bind (("C-c r" . crux-rename-file-and-buffer)))
(use-package
whitespace
:hook (before-save-hook . delete-trailing-whitespace))
(use-package indent-bars
:hook ((prog-mode yaml-ts-mode) . indent-bars-mode)
:config
(require 'indent-bars-ts)
:custom
(indent-bars-treesit-support t)
(indent-bars-width-frac 0.05)
(indent-bars-pad-frac 0.4)
(indent-bars-pattern " . .")
(indent-bars-treesit-ignore-blank-lines-types '("module")))
(global-auto-revert-mode t)
(global-set-key (kbd "C-x O") 'previous-multiframe-window)
(use-package flyspell
:hook ((text-mode . flyspell-mode)
(prog-mode . flyspell-prog-mode)))
(use-package
undo-tree
:config (global-undo-tree-mode))
;; Programming
(use-package flycheck
:config
(add-hook 'after-init-hook #'global-flycheck-mode))
(use-package
consult-flycheck)
(use-package
rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package
magit
:bind (("C-x g" . magit-status))
:custom (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
(use-package
lsp-mode
:init
(setq lsp-keymap-prefix "C-c l" lsp-use-plists t)
(defun my/lsp-mode-setup-completion()
(setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
'(orderless))) ;; Configure orderless
:hook ((js-ts-mode . lsp-deferred)
(typescript-ts-mode . lsp-deferred)
(python-ts-mode . lsp-deferred)
(sql-ts-mode . lsp-deferred)
(yaml-ts-mode . lsp-deferred)
(lsp-completion-mode . my/lsp-mode-setup-completion))
:commands (lsp lsp-deferred)
:config (setq lsp-idle-delay 0.500)
(add-to-list 'lsp-file-watch-ignored-directories "\\.pyenv\\/")
:custom
(lsp-enable-folding nil)
(lsp-enable-links nil)
(lsp-enable-snippet nil)
(lsp-completion-provider :none)
(lsp-treemacs-sync-mode 1)
(defun lsp-set-cfg ()
(let ((lsp-cfg `(:yaml (:tabSize 2))))
(lsp--set-configuration lsp-cfg)))
(add-hook 'lsp-after-initialize-hook 'lsp-set-cfg))
(use-package
lsp-ui
:after lsp-mode
:commands lsp-ui-mode
:config (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
(define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references))
(use-package consult-lsp
:config (define-key lsp-mode-map [remap xref-find-apropos] #'consult-lsp-symbols))
(use-package
dap-mode
:config
(setq dap-auto-configure-features '(sessions locals controls tooltip))
(require 'dap-python)
(setq dap-python-debugger 'debugpy)
:hook ((python-mode . dap-mode)
(python-mode . dap-ui-mode)))
(use-package treesit
:straight (:type built-in)
:preface
(defun gh-setup-install-grammars ()
"Install Tree-sitter grammars if they are absent."
(interactive)
(dolist (grammar
;; Note the version numbers. These are the versions that
;; are known to work with Combobulate *and* Emacs.
'((css . ("https://github.com/tree-sitter/tree-sitter-css" "v0.20.0"))
(go . ("https://github.com/tree-sitter/tree-sitter-go" "v0.20.0"))
(html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.20.1"))
(javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.20.1" "src"))
(json . ("https://github.com/tree-sitter/tree-sitter-json" "v0.20.2"))
(markdown . ("https://github.com/ikatyang/tree-sitter-markdown" "v0.7.1"))
(python . ("https://github.com/tree-sitter/tree-sitter-python" "v0.20.4"))
(rust . ("https://github.com/tree-sitter/tree-sitter-rust" "v0.21.2"))
(toml . ("https://github.com/tree-sitter/tree-sitter-toml" "v0.5.1"))
(tsx . ("https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "tsx/src"))
(typescript . ("https://github.com/tree-sitter/tree-sitter-typescript" "v0.20.3" "typescript/src"))
(yaml . ("https://github.com/ikatyang/tree-sitter-yaml" "v0.5.0")))))
;; Optional, but recommended. Tree-sitter enabled major modes are
;; distinct from their ordinary counterparts.
;;
;; You can remap major modes with `major-mode-remap-alist'. Note
;; that this does *not* extend to hooks! Make sure you migrate them
;; also
(dolist (mapping '((python-mode . python-ts-mode)
(css-mode . css-ts-mode)
(typescript-mode . tsx-ts-mode)
(json-mode . json-ts-mode)
(js-mode . js-ts-mode)
(css-mode . css-ts-mode)
(yaml-mode . yaml-ts-mode)))
(add-to-list 'major-mode-remap-alist mapping)))
:config
(gh-setup-install-grammars)
;; Do not forget to customize Combobulate to your liking:
;;
;; M-x customize-group RET combobulate RET
;;
(use-package combobulate
:straight ( :type git :repo "mickeynp/combobulate" :nonrecursive t)
:custom
;; You can customize Combobulate's key prefix here.
;; Note that you may have to restart Emacs for this to take effect!
(combobulate-key-prefix "C-c o")
;; Optional, but recommendned.
;;
;; You can manually enable Combobulate with `M-x
;; combobulate-mode'.
:hook ((prog-mode . combobulate-mode))
;; Amend this to the directory where you keep Combobulate's source
;; code.
)
)
(use-package
python
:after lsp-mode
:ensure flycheck
:preface
(defun lsp-fix-all ()
(interactive)
(condition-case nil
(lsp-execute-code-action-by-kind "source.fixAll")
(lsp-no-code-actions
(when (called-interactively-p 'any)
(lsp--info "source.fixAll action not available")))))
:hook ((before-save . lsp-fix-all)
(before-save . lsp-organize-imports)
(before-save . lsp-format-buffer)))
(use-package
lsp-pyright
:after lsp-mode
:custom (lsp-pyright-langserver-command "pyright")
:hook (python-ts-mode . (lambda ()
(require 'lsp-pyright))))
(use-package yaml-ts-mode
:config
(setq yaml-indent-offset 2)
(setq lsp-yaml-format-enable nil))
(use-package
markdown-mode
:mode ("README\\.md\\.'" . gfm-mode)
:init (setq markdown-command "pandoc"))
(use-package
dockerfile-mode)
(use-package copilot
:straight (:host github :repo "copilot-emacs/copilot.el" :files ("dist" "*.el"))
:hook ((prog-mode . copilot-mode))
:bind (:map copilot-mode-map
("<C-return>" . copilot-accept-completion)))
;;; Tools
(use-package kubernetes
:commands (kubernetes-overview)
:config
(setq kubernetes-poll-frequency 3600 ;
kubernetes-redraw-frequency 3600))