;;; ;;; Internal features ;;; (use-feature emacs :demand t :custom (scroll-conservatively 101 "Scroll just enough to bring text into view") (enable-recursive-minibuffers t "Allow minibuffer commands in minibuffer") (frame-title-format '(buffer-file-name "%f" ("%b")) "Make frame title current file's name.") (find-library-include-other-files nil) (indent-tabs-mode nil "Use spaces, not tabs") (tab-always-indent 'complete) (text-mode-ispell-word-completion nil) (read-extended-command-predicate #'command-completion-default-include-p) (tab-stop-list (number-sequence 2 120 2)) (report-emacs-bug-no-explanations t) (report-emacs-bug-no-confirmation t)) (use-feature epa :config ;; (setenv "GPG_AGENT_INFO" nil) (setf epg-pinentry-mode 'loopback) ) (use-feature winner :config (winner-mode +1)) (use-feature notmuch :config (setq notmuch-show-logo nil)) (use-feature tramp :config (setq tramp-default-method "rsync") (setq remote-file-name-inhibit-locks t tramp-use-scp-direct-remote-copying t remote-file-name-inhibit-auto-save-visited t tramp-copy-size-limit (* 1024 1024) ;; 1MB tramp-verbose 2) (setq magit-tramp-pipe-stty-settings 'pty) (connection-local-set-profile-variables 'remote-direct-async-process '((tramp-direct-async-process . t))) (connection-local-set-profiles '(:application tramp :protocol "rsync") 'remote-direct-async-process) (with-eval-after-load 'tramp (with-eval-after-load 'compile (remove-hook 'compilation-mode-hook #'tramp-compile-disable-ssh-controlmaster-options))) ) (use-feature compile-mode :config (setq compilation-scroll-output t) :bind ("C-c C-c" . compile)) (use-feature compile :commands (compile recompile) :custom (compilation-scroll-output 'first-error) :config (defun +compilation-colorize () "Colorize from `compilation-filter-start' to `point'." (require 'ansi-color) (let ((inhibit-read-only t)) (ansi-color-apply-on-region (point-min) (point-max)))) (add-hook 'compilation-filter-hook #'+compilation-colorize)) ;; Persist history over Emacs restarts. Vertico sorts by history position. (use-feature savehist :init (savehist-mode)) (use-feature dired :commands (dired) :custom (dired-mouse-drag-files t) (dired-listing-switches "-alh" "Human friendly file sizes.") (dired-kill-when-opening-new-dired-buffer t) (dired-omit-files "\\(?:\\.+[^z-a]*\\)") :hook (dired-mode-hook . dired-omit-mode)) (use-feature ediff :defer t :custom (ediff-window-setup-function #'ediff-setup-windows-plain) (ediff-split-window-function #'split-window-horizontally)) (use-feature autorevert :defer 2 :custom (auto-revert-interval 0.01 "Instantaneously revert") :config (global-auto-revert-mode t)) ;;; ;;; General ;;; (use-package age :ensure t :config (age-file-enable)) (use-package easy-kill :bind (([remap kill-ring-save] . easy-kill))) (use-package doom-themes :ensure t :config (load-theme 'doom-sourcerer t) (setq doom-themes-disable-italic t) ) (use-package corfu :config (global-corfu-mode)) (use-package avy :bind (("C-:" . avy-goto-char))) (use-package git-timemachine :ensure t) (use-package crux :ensure t :config (crux-with-region-or-buffer indent-region) (crux-with-region-or-buffer untabify) (crux-with-region-or-line comment-or-uncomment-region) :bind (("C-c o" . crux-open-with) ([remap default-indent-new-line] . crux-smart-open-line) ("C-M-j" . crux-smart-open-line-above) ("C-c u" . crux-view-url) ("C-c n" . crux-cleanup-buffer-or-region) ("C-c f d" . crux-recentf-find-directory) ("C-," . crux-duplicate-current-line-or-region) ("C-c M-d" . crux-duplicate-and-comment-current-line-or-region) ("C-c r" . crux-rename-file-and-buffer) ("C-c b k" . crux-kill-other-buffers))) ;; (use-package company ;; :config ;; (setq company-format-margin-function nil) ;; (setq company-tooltip-scrollbar-width 0) ;; (global-company-mode)) (use-package magit :defer t :bind (("C-c v C" . magit-clone) ("C-c v ." . magit-file-dispatch) ("C-c v /" . magit-dispatch) ("C-c v g" . magit-status) ("C-c v G" . magit-status-here) ("C-c v x" . magit-file-delete) ("C-c v B" . magit-blame-addition) ("C-c v F" . magit-fetch) ("C-c v L" . magit-log-buffer-file) ("C-c v S" . magit-stage-file) ("C-c v U" . magit-unstage-file)) :custom (magit-repository-directories (list (cons elpaca-repos-directory 1))) (magit-diff-refine-hunk 'all) (magit-deisplay-buffer-function #'+magit-display-buffer) :config (transient-bind-q-to-quit)) (use-package transient :defer t) ;; Use MELPA until built-in version updated. (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) (vertico-multiform-mode) :config (add-to-list 'vertico-multiform-categories '(embark-keybinding grid)) ;; Configure the display per command. ;; Use a buffer with indices for imenu ;; and a flat (Ido-like) menu for M-x. (setq vertico-multiform-commands '((consult-imenu buffer indexed))) ;; Configure the display per completion category. ;; Use the grid display for files and a buffer ;; for the consult-grep commands. (setq vertico-multiform-categories '((embark-keybinding grid) (consult-grep buffer)))) ;; (use-package org-caldav ;; :ensure t) (use-package consult-yasnippet :bind ("C-c C-y" . consult-yasnippet)) (use-package yasnippet :bind (:map global-map ("C-z" . nil) :map yas-minor-mode-map ("TAB" . nil) ("C-z" . yas-expand)) :config (yas-global-mode +1)) (use-package yasnippet-snippets :after (yasnippet) :ensure t) (use-package embark :ensure t :bind (("C-." . embark-act) ("M-." . embark-dwim) ("C-h B" . embark-bindings)) :init (setq prefix-help-command #'embark-prefix-help-command) :config (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil (window-parameters (mode-line-format . none))))) (use-package embark-consult :ensure t :hook (embark-collect-mode . consult-preview-at-point-mode)) (use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles partial-completion))))) (use-package rg :when (executable-find "rg") :config (setq xref-search-program 'ripgrep)) (use-package volatile-highlights :config (volatile-highlights-mode t)) (use-package vundo) (use-package marginalia :ensure t :config (marginalia-mode)) (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 C-b" . consult-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 :hook (completion-list-mode . consult-preview-at-point-mode) :init (setq register-preview-delay 0.5 register-preview-function #'consult-register-format) (advice-add #'register-preview :override #'consult-register-window) (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 '(:debounce 0.4 any)) (setq consult-narrow-key "<") ;; "C-+" ) (use-package ace-window :ensure t :bind (("M-o" . ace-window)) :config (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)) (setq aw-scope 'frame) (marginalia-mode)) (use-package golden-ratio :config (golden-ratio-mode 1) ;; Refer to issue #57 for the complete code, this is just for ease (add-hook 'buffer-list-update-hook #'golden-ratio) (add-hook 'focus-in-hook #'golden-ratio) (add-hook 'focus-out-hook #'golden-ratio)) (use-package dired-subtree :ensure t :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)) (use-package transpose-frame :ensure t) (use-package rainbow-mode :ensure t) ;; ;; Language modes ;; (use-package tide :config (defun +turn-on-tide-and-flycheck () (interactive) (tide-setup) (flycheck-mode 1)) (add-hook 'typescript-mode-hook '+turn-on-tide-and-flycheck)) ;; (use-package rust-mode ;; :ensure t ;; :config ;; (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))) (use-package zig-mode :config (add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode))) (use-package yaml-mode :config (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))) (use-package typescript-mode :config (add-to-list 'auto-mode-alist '("\\.mts\\'" . typescript-mode))) (use-package lua-mode :config (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-mode))) (use-package dockerfile-mode :config (add-to-list 'auto-mode-alist '("\\Dockerfile\\'" . dockerfile-mode))) (use-package markdown-mode :hook (markdown-mode-hook . visual-line-mode) :config (add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))) (use-package haskell-mode :config (require 'haskell-mode-autoloads) (add-to-list 'Info-default-directory-list "~/lib/emacs/haskell-mode/") (add-to-list 'auto-mode-alist '("\\.hs\\'" . haskell-mode))) (use-package kotlin-mode :config (add-to-list 'auto-mode-alist '("\\.kt\\'" . kotlin-mode))) (use-package php-mode :config (add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))) (use-package terraform-mode :config (add-to-list 'auto-mode-alist '("\\.\\(hcl\\|tf\\)\\'" . terraform-mode)))