X-Git-Url: https://git.shemshak.org/gitweb.cgi/~bandali/configs/blobdiff_plain/1bd1c70127ea81da229294d2b8da3dd55854c096..fa9943dccbfd6cd3d7cefa8777e340e9d0b686b4:/.emacs.d/init.el diff --git a/.emacs.d/init.el b/.emacs.d/init.el index 8088ce0..4355ad6 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -39,9 +39,13 @@ (defvar b/before-user-init-time (current-time) "Value of `current-time' when Emacs begins loading `user-init-file'.") -(message "Loading Emacs...done (%.3fs)" - (float-time (time-subtract b/before-user-init-time - before-init-time))) +(defvar b/emacs-initialized nil + "Whether Emacs has been initialized.") + +(when (not (bound-and-true-p b/emacs-initialized)) + (message "Loading Emacs...done (%.3fs)" + (float-time (time-subtract b/before-user-init-time + before-init-time)))) ;; temporarily increase `gc-cons-threshhold' and `gc-cons-percentage' ;; during startup to reduce garbage collection frequency. clearing @@ -57,8 +61,10 @@ ;; set them back to their defaults once we're done initializing (defun b/post-init () - (setq gc-cons-threshold b/gc-cons-threshold - gc-cons-percentage b/gc-cons-percentage + "My post-initialize function, run after loading `user-init-file'." + (setq b/emacs-initialized t + gc-cons-threshold b/gc-cons-threshold + gc-cons-percentage b/gc-cons-percentage file-name-handler-alist b/file-name-handler-alist)) (add-hook 'after-init-hook #'b/post-init) @@ -152,9 +158,10 @@ (expand-file-name "~/.emacs.d/straight/build/"))) (defun b/reload-init () - "Reload init.el." + "Reload `user-init-file'." (interactive) - (setq b/file-name-handler-alist file-name-handler-alist) + (setq b/before-user-init-time (current-time) + b/file-name-handler-alist file-name-handler-alist) (load user-init-file nil 'nomessage) (b/post-init)) @@ -174,8 +181,6 @@ (setq use-package-always-defer t) (require 'bind-key) -(use-package delight) - ;;; Initial setup @@ -345,7 +350,7 @@ For disabling the behaviour for certain buffers and/or modes." ;; i don't need the default hint (initial-scratch-message nil) ;; use customizable text-mode as major mode for *scratch* - (initial-major-mode 'text-mode) + ;; (initial-major-mode 'text-mode) ;; inhibit buffer list when more than 2 files are loaded (inhibit-startup-buffer-menu t) ;; don't need to see the startup screen or echo area message @@ -388,16 +393,20 @@ For disabling the behaviour for certain buffers and/or modes." (global-auto-revert-non-file-buffers nil)) ;; time and battery in mode-line -(comment - (use-feature time - :init - (setq display-time-default-load-average nil) - :config - (display-time-mode)) +(use-feature time + :demand + :config + (display-time-mode) + :custom + (display-time-default-load-average nil) + (display-time-format "%a %b %-e, %-l:%M%P")) - (use-feature battery - :config - (display-battery-mode))) +(use-feature battery + :demand + :config + (display-battery-mode) + :custom + (battery-mode-line-format " %p%% %t")) (use-feature fringe :demand @@ -513,22 +522,24 @@ For disabling the behaviour for certain buffers and/or modes." (bind-keys ;; for back and forward mouse keys + ("" . previous-buffer) ("" . previous-buffer) ("" . previous-buffer) + ("" . next-buffer) ("" . next-buffer) ("" . next-buffer) ("" . kill-this-buffer) ("" . ivy-switch-buffer)) (bind-keys - :prefix-map mab/straight-prefix-map + :prefix-map b/straight-prefix-map :prefix "C-c p s" ("u" . straight-use-package) ("f" . straight-freeze-versions) ("t" . straight-thaw-versions) ("P" . straight-prune-build) ("g" . straight-get-recipe) - ("r" . mab/reload-init) + ("r" . b/reload-init) ;; M-x ^straight-.*-all$ ("a c" . straight-check-all) ("a f" . straight-fetch-all) @@ -549,6 +560,175 @@ For disabling the behaviour for certain buffers and/or modes." ;;; Essential packages +(use-package exwm + :demand + :config + ;; make class name the buffer name, truncating beyond 60 characters + (defun b/exwm-rename-buffer () + (interactive) + (exwm-workspace-rename-buffer + (concat exwm-class-name ":" + (if (<= (length exwm-title) 60) exwm-title + (concat (substring exwm-title 0 59) "..."))))) + ;; Enable EXWM + (exwm-enable) + :hook ((exwm-update-class . b/exwm-rename-buffer) + (exwm-update-title . b/exwm-rename-buffer))) + +(use-feature exwm-config + :demand + :after exwm + :hook (exwm-init . exwm-config--fix/ido-buffer-window-other-frame)) + +(use-feature exwm-input + :demand + :after exwm + :config + (defun b/exwm-ws-prev-index () + "Return the index for the previous EXWM workspace, wrapping +around if needed." + (if (= exwm-workspace-current-index 0) + (1- exwm-workspace-number) + (1- exwm-workspace-current-index))) + + (defun b/exwm-ws-next-index () + "Return the index for the next EXWM workspace, wrapping +around if needed." + (if (= exwm-workspace-current-index + (1- exwm-workspace-number)) + 0 + (1+ exwm-workspace-current-index))) + + ;; shorten 'C-c C-q' to 'C-q' + (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key) + + (setq exwm-input-global-keys + `(([?\s-R] . exwm-reset) + ([?\s-\\] . exwm-workspace-switch) + ([?\s-\s] . (lambda (command) + (interactive + (list (read-shell-command "➜ "))) + (start-process-shell-command + command nil command))) + ([s-return] . (lambda () + (interactive) + (start-process "" nil "urxvt"))) + ([?\C-\s-\s] . counsel-linux-app) + ([?\M-\s-\s] . (lambda () + (interactive) + (start-process-shell-command + "rofi-pass" nil "rofi-pass"))) + ([?\s-\[] . (lambda () + (interactive) + (exwm-workspace-switch-create + (b/exwm-ws-prev-index)))) + ([?\s-\]] . (lambda () + (interactive) + (exwm-workspace-switch-create + (b/exwm-ws-next-index)))) + ([?\s-{] . (lambda () + (interactive) + (exwm-workspace-move-window + (b/exwm-ws-prev-index)))) + ([?\s-}] . (lambda () + (interactive) + (exwm-workspace-move-window + (b/exwm-ws-next-index)))) + ,@(mapcar (lambda (i) + `(,(kbd (format "s-%d" i)) . + (lambda () + (interactive) + (exwm-workspace-switch-create ,i)))) + (number-sequence 0 (1- exwm-workspace-number))) + ([?\s-t] . exwm-floating-toggle-floating) + ([?\s-f] . exwm-layout-toggle-fullscreen) + ([?\s-w] . (lambda () + (interactive) + (kill-buffer (current-buffer)))) + ([?\s-q] . (lambda () + (interactive) + (exwm-manage--kill-client))) + ([?\s-\'] . (lambda () + (interactive) + (start-process-shell-command + "rofi-light" nil "rofi-light"))) + ([XF86AudioMute] . + (lambda () + (interactive) + (start-process "" nil "pamixer" "--toggle-mute"))) + ([XF86AudioLowerVolume] . + (lambda () + (interactive) + (start-process + "" nil "pamixer" "--allow-boost" "--decrease" "5"))) + ([XF86AudioRaiseVolume] . + (lambda () + (interactive) + (start-process + "" nil "pamixer" "--allow-boost" "--increase" "5"))) + ([XF86AudioPlay] . + (lambda () + (interactive) + (start-process "" nil "mpc" "toggle"))) + ([XF86AudioPrev] . + (lambda () + (interactive) + (start-process "" nil "mpc" "prev"))) + ([XF86AudioNext] . + (lambda () + (interactive) + (start-process "" nil "mpc" "next"))) + ([XF86ScreenSaver] . + (lambda () + (interactive) + (start-process "" nil "dm-tool" "lock"))))) + + ;; Line-editing shortcuts + (setq exwm-input-simulation-keys + '(;; movement + ([?\C-b] . [left]) + ([?\M-b] . [C-left]) + ([?\C-f] . [right]) + ([?\M-f] . [C-right]) + ([?\C-p] . [up]) + ([?\C-n] . [down]) + ([?\C-a] . [home]) + ([?\C-e] . [end]) + ([?\M-v] . [prior]) + ([?\C-v] . [next]) + ([?\C-d] . [delete]) + ([?\C-k] . [S-end ?\C-x]) + ([?\M-<] . C-home) + ([?\M->] . C-end) + ;; cut/copy/paste + ([?\C-w] . [?\C-x]) + ([?\M-w] . [?\C-c]) + ([?\C-y] . [?\C-v]) + ([?\M-d] . [C-S-right ?\C-x]) + ([?\M-\d] . [C-S-left ?\C-x]) + ;; search + ([?\C-s] . [?\C-f]) + ;; escape + ([?\C-g] . [escape])))) + +(use-feature exwm-randr + :demand + :after exwm + :config + (exwm-randr-enable)) + +(use-feature exwm-systemtray + :demand + :after exwm + :config + (exwm-systemtray-enable)) + +(use-feature exwm-workspace + :demand + :after exwm + :custom + (exwm-workspace-number 4)) + ;; use the org-plus-contrib package to get the whole deal (use-package org-plus-contrib) @@ -670,7 +850,9 @@ For disabling the behaviour for certain buffers and/or modes." (nconc magit-section-initial-visibility-alist '(([unpulled status] . show) ([unpushed status] . show))) - :custom (magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1) + :custom + (magit-diff-refine-hunk t) + (magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1) :custom-face (magit-diff-file-heading ((t (:weight normal))))) ;; recently opened files @@ -686,7 +868,6 @@ For disabling the behaviour for certain buffers and/or modes." (use-package ivy :defer 0.3 - :delight ;; " 🙒" :bind (:map ivy-minibuffer-map ([escape] . keyboard-escape-quit) @@ -727,7 +908,6 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package counsel :after ivy - :delight :bind (([remap execute-extended-command] . counsel-M-x) ([remap find-file] . counsel-find-file) ("C-c b b" . ivy-switch-buffer) @@ -850,10 +1030,11 @@ This function is intended for use with `ivy-ignore-buffers'." (or (name . "^\\*scratch\\*$") (name . "^\\*Messages\\*$"))) + ("exwm" (mode . exwm-mode)) ("erc" (mode . erc-mode))))) (ibuffer-formats '((mark modified read-only locked " " - (name 18 18 :left :elide) + (name 72 72 :left :elide) " " (size-h 9 -1 :right) " " @@ -867,7 +1048,6 @@ This function is intended for use with `ivy-ignore-buffers'." (use-feature outline :disabled :hook (prog-mode . outline-minor-mode) - :delight (outline-minor-mode " outl") :bind (:map outline-minor-mode-map @@ -968,7 +1148,6 @@ This function is intended for use with `ivy-ignore-buffers'." ;; display Lisp objects at point in the echo area (use-feature eldoc :when (version< "25" emacs-version) - :delight " eldoc" :config (global-eldoc-mode)) ;; highlight matching parens @@ -981,7 +1160,6 @@ This function is intended for use with `ivy-ignore-buffers'." :config (electric-pair-mode)) (use-feature simple - :delight (auto-fill-function " fill") :config (column-number-mode) :custom ;; Save what I copy into clipboard from other applications into Emacs' @@ -1019,7 +1197,6 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package company :defer 0.6 - :delight " comp" :bind (:map company-active-map ([tab] . company-complete-common-or-cycle) @@ -1048,8 +1225,7 @@ This function is intended for use with `ivy-ignore-buffers'." (setq flycheck-check-syntax-automatically '(mode-enabled save)) :custom (flycheck-mode-line-prefix "flyc")) -(use-feature flyspell - :delight " flysp") +(use-feature flyspell) ;; http://endlessparentheses.com/ispell-and-apostrophes.html (use-feature ispell @@ -1079,7 +1255,6 @@ This function is intended for use with `ivy-ignore-buffers'." #'endless/replace-quote)) (use-feature abbrev - :delight " abbr" :hook (text-mode . abbrev-mode)) @@ -1092,12 +1267,9 @@ This function is intended for use with `ivy-ignore-buffers'." (add-hook 'lisp-interaction-mode-hook #'indent-spaces-mode)) (use-feature reveal - :delight (reveal-mode " reveal") :hook (emacs-lisp-mode . reveal-mode)) -(use-feature elisp-mode - :delight (emacs-lisp-mode "Elisp" :major)) - +(use-feature elisp-mode) (use-package alloy-mode :straight (:host github :repo "dwwmmn/alloy-mode") @@ -1210,8 +1382,8 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package lsp-java :config (add-hook 'java-mode-hook - (lambda () - (setq-local company-backends (list 'company-lsp)))) + (lambda () + (setq-local company-backends (list 'company-lsp)))) (add-hook 'java-mode-hook 'lsp-java-enable) (add-hook 'java-mode-hook 'flycheck-mode) @@ -1270,8 +1442,7 @@ This function is intended for use with `ivy-ignore-buffers'." (lambda (p) (string-match "^---?" (car p))) tex--prettify-symbols-alist) :hook ((tex-mode . auto-fill-mode) - (tex-mode . flyspell-mode) - (tex-mode . (lambda () (electric-indent-local-mode -1))))) + (tex-mode . flyspell-mode))) ;;; Theme @@ -1288,6 +1459,13 @@ This function is intended for use with `ivy-ignore-buffers'." (sml/setup) (smart-mode-line-enable)) +(use-package doom-modeline + :disabled + :demand + :hook (after-init . doom-modeline-init) + :custom + (doom-modeline-buffer-file-name-style 'relative-to-project)) + (use-package doom-themes) (defvar b/org-mode-font-lock-keywords @@ -1309,7 +1487,7 @@ This function is intended for use with `ivy-ignore-buffers'." "Go dark." (interactive) (mapc #'disable-theme custom-enabled-themes) - ;; (load-theme 'doom-tomorrow-night t) + (load-theme 'doom-tomorrow-night t) (sml/apply-theme 'automatic) (font-lock-add-keywords 'org-mode b/org-mode-font-lock-keywords t)) @@ -1326,7 +1504,6 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package which-key :defer 0.4 - :delight :config (which-key-add-key-based-replacements ;; prefixes for global prefixes and minor modes @@ -1364,7 +1541,7 @@ This function is intended for use with `ivy-ignore-buffers'." ;; prefixes for major modes (which-key-add-major-mode-key-based-replacements 'message-mode - "C-c f" "footnote") + "C-c f n" "footnote") (which-key-add-major-mode-key-based-replacements 'org-mode "C-c C-v" "org-babel") (which-key-add-major-mode-key-based-replacements 'web-mode @@ -1383,9 +1560,9 @@ This function is intended for use with `ivy-ignore-buffers'." :defer 0.4 :bind (("C-c d" . crux-duplicate-current-line-or-region) ("C-c D" . crux-duplicate-and-comment-current-line-or-region) - ("C-c f c" . crux-copy-file-preserve-attributes) - ("C-c f d" . crux-delete-file-and-buffer) - ("C-c f r" . crux-rename-file-and-buffer) + ("C-c f C" . crux-copy-file-preserve-attributes) + ("C-c f D" . crux-delete-file-and-buffer) + ("C-c f R" . crux-rename-file-and-buffer) ("C-c j" . crux-top-join-line) ("C-S-j" . crux-top-join-line))) @@ -1480,7 +1657,6 @@ This function is intended for use with `ivy-ignore-buffers'." ;; easily type pretty quotes & other typography, like ‘’“”-–—«»‹› (use-package typo :defer 0.5 - :delight " typo" :config (typo-global-mode 1) :hook (((text-mode erc-mode) . typo-mode) @@ -1513,6 +1689,7 @@ This function is intended for use with `ivy-ignore-buffers'." :commands eshell-up) (use-package multi-term + :disabled :defer 0.6 :bind (("C-c a s m m" . multi-term) ("C-c a s m d" . multi-term-dedicated-toggle) @@ -1566,7 +1743,6 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package page-break-lines :defer 0.5 - :delight " pgln" :custom (page-break-lines-max-width fill-column) :config @@ -1585,11 +1761,9 @@ This function is intended for use with `ivy-ignore-buffers'." ("p" . mc/mark-previous-like-this) ("a" . mc/mark-all-like-this)))) -(comment - ;; TODO - (use-package forge - :after magit - :demand)) +(use-package forge + :demand + :after magit) (use-package yasnippet :defer 0.6 @@ -1665,9 +1839,13 @@ This function is intended for use with `ivy-ignore-buffers'." (use-package pdf-tools :defer 0.5 :bind (:map pdf-view-mode-map - ("" . pdf-history-backward) - ("" . pdf-history-forward) - ("M-RET" . image-previous-line)) + ("" . pdf-history-backward) + ("" . pdf-history-backward) + ("" . pdf-history-backward) + ("" . pdf-history-forward) + ("" . pdf-history-forward) + ("" . pdf-history-forward) + ("M-RET" . image-previous-line)) :config (pdf-tools-install nil t) :custom (pdf-view-resize-factor 1.05)) @@ -1690,6 +1868,17 @@ This function is intended for use with `ivy-ignore-buffers'." (goto-char (cdr macro))) (reftex-this-word))))) +(use-package minions + :demand + :config (minions-mode)) + +(use-package dmenu + :disabled + :custom + (dmenu-history-size 0) + (dmenu-prompt-string "run: ") + (dmenu-save-file (b/var "dmenu-items"))) + ;;; Email (with Gnus) @@ -1913,10 +2102,6 @@ This function is intended for use with `ivy-ignore-buffers'." gnus-interactive-exit nil gnus-gcc-mark-as-read t) :config - (require 'ebdb) - (require 'ebdb-mua) - (require 'ebdb-gnus) - (when (version< emacs-version "27") (add-to-list 'nnmail-split-abbrev-alist @@ -2045,6 +2230,11 @@ https://csclub.uwaterloo.ca/~abandali") mm-decrypt-option 'known mm-verify-option 'known)) +(use-feature mm-uu + :custom + (mm-uu-diff-groups-regexp + "\\(gmane\\|gnu\\|l\\)\\..*\\(diff\\|commit\\|cvs\\|bug\\|dev\\)")) + (use-feature sendmail :config (setq sendmail-program (executable-find "msmtp") @@ -2060,7 +2250,7 @@ https://csclub.uwaterloo.ca/~abandali") "Return the In-Reply-To header for this message." (when message-reply-headers (let ((from (mail-header-from message-reply-headers)) - (msg-id (mail-header-id message-reply-headers))) + (msg-id (mail-header-id message-reply-headers))) (when from msg-id)))) @@ -2097,10 +2287,10 @@ https://csclub.uwaterloo.ca/~abandali") ;; (message-header-subject ((t (:foreground "#111" :weight semi-bold)))) ;; (message-header-to ((t (:foreground "#111" :weight normal)))) ;; (message-header-cc ((t (:foreground "#333" :weight normal)))) - ) + :custom + (message-elide-ellipsis "[...]\n")) -(use-feature mml - :delight " mml") +(use-feature mml) (use-feature mml-sec :custom @@ -2116,7 +2306,7 @@ https://csclub.uwaterloo.ca/~abandali") :bind (:map message-mode-map :prefix-map b/footnote-prefix-map - :prefix "C-c f" + :prefix "C-c f n" ("a" . footnote-add-footnote) ("b" . footnote-back-to-message) ("c" . footnote-cycle-style) @@ -2126,6 +2316,7 @@ https://csclub.uwaterloo.ca/~abandali") ("s" . footnote-set-style))) (use-package ebdb + :demand :after gnus :bind (:map gnus-group-mode-map ("e" . ebdb)) :config @@ -2146,20 +2337,15 @@ https://csclub.uwaterloo.ca/~abandali") (defun company-ebdb--post-complete (_) nil)) (use-feature ebdb-gnus + :demand :after ebdb :custom - (ebdb-gnus-window-configuration - '(article - (vertical 1.0 - (summary 0.25 point) - (horizontal 1.0 - (article 1.0) - (ebdb-gnus 0.3)))))) + (ebdb-gnus-window-size 0.3)) (use-feature ebdb-mua + :demand :after ebdb - ;; :custom (ebdb-mua-pop-up nil) - ) + :custom (ebdb-mua-pop-up nil)) ;; (use-package ebdb-message ;; :after ebdb) @@ -2195,6 +2381,8 @@ https://csclub.uwaterloo.ca/~abandali") :demand :load-path "lisp/" :config + ;; note: be sure to customize faces with `:foreground "white"' when + ;; using a theme with a white/light background :) (setq ft/gnus-article-patch-conditions '("^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@")))