init-base.el (11624B)
1 ;;; init-base.el --- base config -*- lexical-binding: t -*- 2 3 ;;; Commentary: 4 5 ;;; Code: 6 7 ;; keybindings 8 (use-package general) 9 10 ;; mode names in mode line 11 (use-package delight 12 :config 13 (delight 14 `((eldoc-mode nil eldoc) 15 (org-indent-mode nil org-indent) 16 (desktop-environment-mode nil desktop-environment) 17 (hs-minor-mode nil hideshow) 18 (rainbow-delimiters-mode ,(propertize " Rdelimiters" 'face 'rainbow-delimiters-depth-1-face) rainbow-delimiters) 19 (hywiki-mode nil hywiki) 20 (hyperbole-mode nil hyperbole)))) 21 22 ;; garbage collection 23 (use-package gcmh 24 :delight 25 :hook 26 (emacs-startup . gcmh-mode) 27 :init 28 (setq gcmh-idle-delay 'auto 29 gcmh-auto-idle-delay-factor 10 30 gcmh-high-cons-threshold #x4000000)) 31 32 ;; benchmark 33 (use-package benchmark-init 34 :init 35 (benchmark-init/activate) 36 :hook 37 (after-init . benchmark-init/deactivate)) 38 39 ;; server-mode 40 (use-package server 41 :straight nil 42 :demand t 43 :hook 44 (emacs-startup . (lambda () 45 (unless (server-running-p) 46 (server-mode 1))))) 47 48 ;; recently opened files 49 (if (or (display-graphic-p) *is-android*) 50 (use-package recentf 51 :straight nil 52 :hook 53 (after-init . recentf-mode) 54 :init 55 (setq recentf-max-saved-items 30) 56 :config 57 (if *is-android* 58 (add-to-list 'recentf-exclude "~/storage/shared/my-org-note/journal/.*\\.org\\'") 59 (add-to-list 'recentf-exclude "~/org/my-org-note/journal/.*\\.org\\'") 60 (add-to-list 'recentf-exclude "~/org/my-org-note/20260509T232442==agenda--all-my-todos\\.org") 61 (add-to-list 'recentf-exclude "~/org/my-org-note/20260810T233455==agenda--all-about-game__game\\.org")) 62 (add-to-list 'recentf-exclude "~/.emacs.d/emms/history") 63 (add-to-list 'recentf-exclude "~/.emacs.d/bookmarks"))) 64 65 ;; save minibuffer history 66 (use-package savehist 67 :straight nil 68 :hook 69 (after-init . savehist-mode) 70 :init 71 (setq enable-recursive-minibuffers t 72 history-length 50 73 savehist-additional-variables '(mark-ring 74 global-mark-ring 75 search-ring 76 regexp-search-ring 77 extended-command-history) 78 savehist-autosave-interval 300)) 79 80 ;; save cursor place 81 (use-package saveplace 82 :straight nil 83 :hook 84 (after-init . save-place-mode)) 85 86 ;; restart emacs 87 (use-package restart-emacs) 88 89 ;; async 90 (unless *is-android* 91 (use-package async 92 :hook 93 (after-init . dired-async-mode))) 94 95 ;; autorevert buffer 96 (use-package autorevert 97 :straight nil 98 :delight 99 :hook 100 (after-init . global-auto-revert-mode)) 101 102 ;; display keybindings 103 (use-package which-key 104 :straight nil 105 :delight 106 :hook 107 (after-init . which-key-mode)) 108 109 ;; save window changes 110 (use-package winner 111 :straight nil 112 :hook 113 (after-init . winner-mode)) 114 115 ;; ibuffer 116 (use-package ibuffer 117 :straight nil 118 :config 119 (setq ibuffer-saved-filter-groups 120 '(("Main" 121 ("App" (mode . exwm-mode)) 122 ("Scratch" (or 123 (name . "^*scratch"))) 124 ("Text" (or 125 (and (mode . org-mode) (not (name . "^\\*gptel"))) 126 (mode . markdown-mode) 127 (mode . rst-mode) 128 (filename . ".\\.md") 129 (name . "^\\*\\[D\\] FILE backlinks for"))) 130 ("Scripts" (or 131 (mode . shell-script-mode) 132 (mode . sh-mode) 133 (mode . bat-mode))) 134 ("Config" (or 135 (mode . conf-mode) 136 (mode . conf-desktop-mode) 137 (mode . conf-toml-mode) 138 (mode . conf-xdefaults-mode) 139 (mode . conf-javaprop-mode) 140 (mode . conf-unix-mode) 141 (mode . toml-ts-mode) 142 (mode . yaml-ts-mode) 143 (mode . json-ts-mode))) 144 ("Elisp" (mode . emacs-lisp-mode)) 145 ("Scheme" (or 146 (mode . scheme-mode))) 147 ("Geiser" (or 148 (name . "^Geiser") 149 (mode . geiser-repl-mode) 150 (mode . geiser-debug-mode) 151 (mode . geiser-messages-mode) 152 (mode . geiser-debug-mode) 153 (mode . geiser-doc-mode) 154 (mode . geiser-autodoc-mode))) 155 ("Common-lisp" (or 156 (mode . common-lisp-mode) 157 (mode . lisp-mode))) 158 ("Sly" (or 159 (mode . lisp-data-mode) 160 (mode . sly-db-mode) 161 (mode . sly-mrepl-mode) 162 (name . "\\*sly-compilation\\*") 163 (name . "^\\*img-cache\\*"))) 164 ("Shell" (or 165 (mode . shell-mode) 166 (mode . eshell-mode) 167 (mode . ghostel-mode) 168 (mode . vterm-mode))) 169 ("Tramp"(or 170 (name . "^\\*tramp"))) 171 ("VC" (or 172 (mode . magit-blame-mode) 173 (mode . magit-cherry-mode) 174 (mode . magit-diff-mode) 175 (mode . magit-log-mode) 176 (mode . magit-process-mode) 177 (mode . magit-status-mode) 178 (mode . magit-revision-mode) 179 (mode . magit-refs-mode) 180 (name . "^\\*vc"))) 181 ("Directories" (or 182 (mode . dired-mode) 183 (name . "^*dirvish") 184 (mode . trashed-mode))) 185 ("eww" (or 186 (mode . eww-mode) 187 (mode . eww-bookmark-mode) 188 (mode . eww-buffers-mode) 189 (mode . eww-history-mode))) 190 ("Feeds" (or 191 (name . "\\*elfeed-"))) 192 ("AI" (or 193 (name . "^\\*OpenCode") 194 (name . "\\*opencode-serve\\*") 195 (name . "^\\*gptel") 196 (name . "^\\*pi-coding-agent"))) 197 ("Calc" (or 198 (mode . calc-mode) 199 (mode . calc-trail-mode))) 200 ("Help" (or 201 (mode . help-mode) 202 (mode . helpful-mode) 203 (mode . man-mode) 204 (mode . Info-mode))) ;`Info' must be capitalized 205 ("Grep" (or 206 (mode . grep-mode) 207 (mode . rg-mode) 208 (mode . xref--xref-buffer-mode) 209 (mode . xref-edit-mode) 210 (mode . occur-mode) 211 (mode . occur-edit-mode))) 212 ("Diff" (or 213 (name . "^*Diff") 214 (mode . diff-mode) 215 (mode . ediff-mode) 216 (mode . vundo-diff-mode))) 217 ("Emacs" (or 218 (name . "^\\*Help\\*$") 219 (name . "^\\*Custom.*") 220 (name . "^\\*EMMS Playlist\\*") 221 (name . "^\\*Messages\\*$") 222 (name . "*Chinese-word-segmentation*") 223 (name . "^*Buffer List*") 224 (name . "\\*discomfort\\*") 225 (mode . calendar-mode) 226 (mode . grep-mode) 227 (mode . proced-mode) 228 (mode . syncthing-mode)))))) 229 230 (add-hook 'ibuffer-hook 231 (lambda () 232 (ibuffer-switch-to-saved-filter-groups "Main") 233 (unless (eq ibuffer-sorting-mode 'alphabetic) 234 (ibuffer-do-sort-by-alphabetic)))) 235 236 (setq ibuffer-show-empty-filter-groups nil 237 ibuffer-use-other-window t 238 ibuffer-human-readable-size t)) 239 240 (use-package simple 241 :straight nil 242 :hook 243 (after-init . size-indication-mode) 244 (after-init . column-number-mode) 245 :config 246 (setq kill-whole-line t 247 set-mark-command-repeat-pop t)) ;easier to pop marks 248 249 ;; scroll 250 (unless *is-mac* 251 (use-package pixel-scroll 252 :straight nil 253 :hook 254 (after-init . pixel-scroll-precision-mode) 255 :init 256 (setq scroll-preserve-screen-position t 257 scroll-conservatively 101) 258 :config 259 (advice-add 'pixel-scroll-precision :around 260 (lambda (orig event) 261 (cl-letf (((symbol-function 'device-class) 262 (lambda (&rest _) 'mouse))) 263 (funcall orig event)))))) 264 265 ;; eww 266 (use-package eww 267 :straight nil 268 :config 269 (setq eww-auto-rename-buffer t)) 270 271 ;; tramp 272 (use-package tramp 273 :straight nil 274 :config 275 (setq tramp-default-method 'ssh 276 tramp-auto-save-directory "~/.emacs.d/tramp-auto-save") 277 (setq tramp-completion-use-auth-sources nil)) 278 279 ;; speedbar 280 (use-package speedbar 281 :straight nil 282 :init 283 (setq speedbar-window-default-width 30) 284 285 (defun my-speedbar () 286 "Run `speedbar-get-focus' if current buffer is not speedbar, otherwise run `speedbar'" 287 (interactive) 288 (if (or (not (boundp 'speedbar-buffer)) 289 (eq (current-buffer) speedbar-buffer)) 290 (speedbar) 291 (speedbar-get-focus))) 292 293 :config 294 (defun my-speedbar-line-expanded-p () 295 "Return non-nil if the speedbar line at point is expanded." 296 (save-excursion 297 (beginning-of-line) 298 (and (re-search-forward ":\\s-*.\\([-+?]\\)" (line-end-position) t) 299 (equal (match-string 1) "-")))) 300 301 (defun my-speedbar-tab () 302 "Expand or contract current line." 303 (interactive) 304 (if (my-speedbar-line-expanded-p) 305 (speedbar-contract-line) 306 (speedbar-expand-line))) 307 308 (if (boundp 'speedbar-prefer-window) 309 (setq speedbar-prefer-window t)) 310 (setq speedbar-use-images nil)) 311 312 ;; isearch 313 (use-package isearch 314 :straight nil 315 :init 316 ;; move lazy count numbers to mode-line 317 (setq isearch-lazy-count t 318 lazy-count-prefix-format nil) 319 320 (defface my-isearch-count 321 '((t (:inherit font-lock-type-face :weight bold))) 322 "Face for the isearch match count in the mode-line.") 323 324 (defconst my-isearch-count--mode-line-construct 325 '(:eval (my-isearch-count-format))) 326 327 (defun my-isearch-count-format () 328 "Like `isearch-lazy-count-format' but use custom format." 329 (when (and isearch-mode 330 isearch-lazy-count 331 isearch-lazy-count-current 332 (not isearch-error) 333 (not isearch-suspended)) 334 (propertize 335 (format "(%s/%s) " 336 (if isearch-lazy-highlight-forward 337 isearch-lazy-count-current 338 (if (eq isearch-lazy-count-current 0) 339 0 340 (- isearch-lazy-count-total 341 isearch-lazy-count-current 342 -1))) 343 (if (and isearch-lazy-count-invisible 344 lazy-count-invisible-format) 345 (concat (format "%s" (or isearch-lazy-count-total "?")) 346 (format lazy-count-invisible-format 347 isearch-lazy-count-invisible)) 348 (or isearch-lazy-count-total "?"))) 349 'face 'my-isearch-count))) 350 351 (unless (member my-isearch-count--mode-line-construct 352 (default-value 'mode-line-format)) 353 (setq-default mode-line-format 354 (cons my-isearch-count--mode-line-construct 355 (default-value 'mode-line-format)))) 356 357 (add-hook 'lazy-count-update-hook #'force-mode-line-update)) 358 359 (provide 'init-base) 360 ;;; init-base.el ends here