;;; 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], 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 (" 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 ("" . dired-subtree-toggle) ("TAB" . dired-subtree-toggle) ("" . 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")))) (add-to-list 'treesit-language-source-alist grammar) ;; Only install `grammar' if we don't already have it ;; installed. However, if you want to *update* a grammar then ;; this obviously prevents that from happening. (unless (treesit-language-available-p (car grammar)) (treesit-install-language-grammar (car grammar))))) (dolist (mapping '((python-mode . python-ts-mode) (typescript-mode . typescript-ts-mode) (js2-mode . js-ts-mode) (bash-mode . bash-ts-mode) (conf-toml-mode . toml-ts-mode) (go-mode . go-ts-mode) (css-mode . css-ts-mode) (json-mode . json-ts-mode) (js-json-mode . json-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 ("" . copilot-accept-completion))) ;;; Tools (use-package kubernetes :commands (kubernetes-overview) :config (setq kubernetes-poll-frequency 3600 ; kubernetes-redraw-frequency 3600)) ;; org-mode (setq org-agenda-files '("~/org")) (setq org-return-follows-link t) (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode)) (add-hook 'org-mode-hook 'org-indent-mode) (setq org-hide-emphasis-markers t) (add-hook 'org-mode-hook 'visual-line-mode) (let* ((variable-tuple (cond ((x-list-fonts "ETBembo") '(:font "ETBembo")) ((x-list-fonts "Source Sans Pro") '(:font "Source Sans Pro")) ((x-list-fonts "Lucida Grande") '(:font "Lucida Grande")) ((x-list-fonts "Verdana") '(:font "Verdana")) ((x-family-fonts "Sans Serif") '(:family "Sans Serif")) (nil (warn "Cannot find a Sans Serif Font. Install Source Sans Pro.")))) (base-font-color (face-foreground 'default nil 'default)) (headline `(:inherit default :weight bold :foreground ,base-font-color))) (custom-theme-set-faces 'user `(org-level-8 ((t (,@headline ,@variable-tuple)))) `(org-level-7 ((t (,@headline ,@variable-tuple)))) `(org-level-6 ((t (,@headline ,@variable-tuple)))) `(org-level-5 ((t (,@headline ,@variable-tuple)))) `(org-level-4 ((t (,@headline ,@variable-tuple :height 1.1)))) `(org-level-3 ((t (,@headline ,@variable-tuple :height 1.2)))) `(org-level-2 ((t (,@headline ,@variable-tuple :height 1.3)))) `(org-level-1 ((t (,@headline ,@variable-tuple :height 1.5)))) `(org-document-title ((t (,@headline ,@variable-tuple :height 1.6 :underline nil)))))) (use-package ob-typescript) (org-babel-do-load-languages 'org-babel-load-languages '((typescript . t) ))