summaryrefslogtreecommitdiff
path: root/emacs
diff options
context:
space:
mode:
authorThomas Ulmer <thomasmulmer02@gmail.com>2025-12-14 11:45:28 -0800
committerThomas Ulmer <thomasmulmer02@gmail.com>2025-12-14 11:45:28 -0800
commit9a6b9dd20c9bc79288c06554afffa44dcde8f691 (patch)
tree2c30546d3c5d85a22d07725bddbe947adc128b19 /emacs
parentbddbdfc757c22c386e085ac130858f55aee5aafc (diff)
emacs: move slow loading packages out, window swapping
Diffstat (limited to 'emacs')
-rw-r--r--emacs/init.el32
-rw-r--r--emacs/site-lisp/my-eglot.el7
-rw-r--r--emacs/site-lisp/my-exwm.el191
-rw-r--r--emacs/site-lisp/my-mail.el52
4 files changed, 271 insertions, 11 deletions
diff --git a/emacs/init.el b/emacs/init.el
index 051fa01..12cc4bc 100644
--- a/emacs/init.el
+++ b/emacs/init.el
@@ -182,6 +182,22 @@ given keymap or in the global keymap."
'(0 1 2 3 4 5 6 7 8 9)))
(my/c-x-n-to-m-n)
+(defvar my/layout-pair (cons nil nil) "Cons pair of window configurations.")
+(add-hook 'after-init-hook
+ (lambda ()
+ (setq my/layout-pair (cons (current-window-configuration)
+ (current-window-configuration)))))
+(defun my/layout-swap (&optional arg)
+ "Swap between the two saved configurations. With ARG, don't save the
+current layout."
+ (interactive "P")
+ (let ((left (car my/layout-pair))
+ (right (cdr my/layout-pair)))
+ (unless arg
+ (setq left (current-window-configuration)))
+ (set-window-configuration right t t)
+ (setq my/layout-pair (cons right left))))
+
(use-package server ; allow emacsclient
:demand t
:config
@@ -367,7 +383,7 @@ given keymap or in the global keymap."
(consult-narrow-key ",")
:bind
("C-x b" . consult-buffer)
- ("M-S-w" . consult-buffer)
+ ("M-W" . consult-buffer)
("C-S-y" . consult-yank-from-kill-ring)
("M-g M-g" . consult-goto-line)
("C-S-s" . consult-line-multi)
@@ -582,15 +598,6 @@ given keymap or in the global keymap."
(add-hook 'prog-mode-hook 'my/prog-buffer-setup)
(electric-pair-mode 1)
-
-(use-package eglot
- :demand nil
- )
-(use-package eglot-tempel
- :after eglot tempel
- :config
- (eglot-tempel-mode 1))
-
(use-package haskell-mode
:custom
(haskell-tags-on-save t)
@@ -744,11 +751,14 @@ given keymap or in the global keymap."
(add-to-list 'emulation-mode-map-alists
'((my/keys-mode . my/keys-keymap)))
+ (setq delete-pair-blink-delay 0)
+
(keymap-set my/keys-mode-map "M-S" 'surround-prefix)
(keymap-set my/keys-mode-map "C-x C-C" 'save-buffers-kill-terminal)
(keymap-set my/keys-mode-map "C-x C-c" 'my/close-or-kill)
(keymap-set my/keys-mode-map "M-w" 'copy-region-as-kill) ; make copying not flash cursor
(keymap-set my/keys-mode-map "C-x -" 'my/swap-other-window-buffer)
+ (keymap-set my/keys-mode-map "M-R" 'my/layout-swap)
(keymap-set my/keys-mode-map "M-(" 'my/wrap-region-paren)
(keymap-set my/keys-mode-map "M-z" 'my/zap-whitespace)
(keymap-set my/keys-mode-map "C-M-z" 'my/wrap-sexp)
@@ -764,7 +774,6 @@ given keymap or in the global keymap."
(my/keys-mode 1))
-
(use-package time
:custom
(display-time-day-and-date t)
@@ -804,6 +813,7 @@ given keymap or in the global keymap."
;; if you want exwm, include from ~/.emacs.d/site-lisp/my-exwm.el
;; if you want mail, include from ~/.emacs.d/site-lisp/my-mail.el
+;; if you want eglot, include from ~/.emacs.d/site-lisp/my-eglot.el
;; ----------------------------------------------------------------------
;; theme stuff
diff --git a/emacs/site-lisp/my-eglot.el b/emacs/site-lisp/my-eglot.el
new file mode 100644
index 0000000..f4a00a3
--- /dev/null
+++ b/emacs/site-lisp/my-eglot.el
@@ -0,0 +1,7 @@
+(use-package eglot
+ :demand t)
+(use-package eglot-tempel
+ :after eglot tempel
+ :config
+ (eglot-tempel-mode 1))
+
diff --git a/emacs/site-lisp/my-exwm.el b/emacs/site-lisp/my-exwm.el
new file mode 100644
index 0000000..66e77df
--- /dev/null
+++ b/emacs/site-lisp/my-exwm.el
@@ -0,0 +1,191 @@
+(use-package exwm ; emacs x window manager
+ :demand nil
+ :config
+ (require 'exwm-randr)
+ (require 'exwm-xim)
+ (require 'exwm-systemtray)
+ (require 'exwm-manage)
+ (add-to-list 'exwm-manage-configurations '((equal exwm-class-name "Slack") managed t))
+ (use-package exwm-modeline)
+ ;;(exwm-xim-mode 1)
+
+ (defun my/exwm-auto-workspace-montior ()
+ "Autopopulate exwm-randr-workspace-monitor-plist and attempt to
+have a workspace on each monitor. Try to keep up with xrandr
+changes."
+ (let ((buf (generate-new-buffer "*xrandr-output*"))
+ (out-plist nil))
+ (call-process-shell-command "xrandr --listmonitors -q" nil buf nil)
+ (with-current-buffer buf
+ (keep-lines "[^[:word:]]connected" (point-min) (point-max) nil)
+ ;; (goto-char (point-min))
+ ;; (while (re-search-forward "^\\([a-zA-Z\\-0-9]+\\) .*$" nil t nil)
+ ;; (replace-match "\\1"))
+ ;; (goto-char (point-min))
+ (let ((num-monitors (count-lines (point-min) (point-max)))
+ (i 0))
+ (setq exwm-workspace-number num-monitors)
+ (goto-char (point-min))
+ (while (< i num-monitors)
+ (move-beginning-of-line 1)
+ (push-mark)
+ (search-forward-regexp " ")
+ (backward-char)
+ (push (buffer-substring (mark) (point)) out-plist)
+ (if (> i 0)
+ (let ((prev (caddr out-plist))
+ (cur (car out-plist)))
+ (call-process-shell-command
+ (format "xrandr --output %s --auto --right-of %s" cur prev)
+ nil nil nil))
+ (call-process-shell-command
+ (format "xrandr --output %s --auto" (car out-plist)) nil nil nil))
+ (push i out-plist)
+ (setq i (+ i 1))
+ (pop-mark)
+ (forward-line))))
+ (kill-buffer buf)
+ (setq exwm-randr-workspace-monitor-plist out-plist))
+ (while (> exwm-workspace-number (length exwm-workspace--list))
+ (exwm-workspace-add)))
+ (add-hook 'exwm-randr-screen-change-hook #'my/exwm-auto-workspace-montior)
+
+ (defun my/exwm-set-buffer-name ()
+ (if exwm-title
+ (let* ((shortened-title (replace-regexp-in-string
+ " - Mozilla Firefox"
+ ""
+ exwm-title))
+ (class-and-title (concat
+ exwm-class-name
+ "<"
+ shortened-title
+ ">")))
+ (setq-local exwm-title class-and-title)
+ (exwm-workspace-rename-buffer exwm-title))))
+
+ (defun my/exwm-other-workspace (arg)
+ "Focus other monitor's workspace."
+ (interactive "p")
+ ;; based on other-frame
+ (let ((filter-f (function (lambda (f)
+ (and (exwm-workspace--active-p f)
+ (not (eq (selected-frame) f))))))
+ (sframe (selected-frame))
+ (frame (selected-frame)))
+ (while (> arg 0)
+ (setq frame (next-frame frame))
+ (while (and (not (eq frame sframe))
+ (not (eq (frame-visible-p frame) t))
+ (funcall filter-f frame))
+ (setq frame (next-frame frame)))
+ (setq arg (1- arg)))
+ (while (< arg 0)
+ (setq frame (previous-frame frame))
+ (while (and (not (eq frame sframe))
+ (not (eq (frame-visible-p frame) t))
+ (filter-f frame))
+ (setq frame (previous-frame frame)))
+ (setq arg (1+ arg)))
+ (exwm-workspace-switch frame)))
+
+ (defun my/dmenu (command)
+ (interactive (list (read-shell-command "$ ")))
+ (start-process-shell-command command nil command))
+
+ (defun my/browser ()
+ (interactive)
+ (start-process-shell-command "glide" nil "glide"))
+
+ (defun my/eshell (&optional arg)
+ (interactive "P")
+ (if (eq major-mode 'eshell-mode)
+ ;; switch back
+ (switch-to-prev-buffer)
+ (eshell arg)))
+
+ (defun my/brightnessdown () (interactive) (start-process "" nil "brightnessdown"))
+ (defun my/brightnessup () (interactive) (start-process "" nil "brightnessup"))
+ (defun my/mute () (interactive) (start-process "" nil "pactl" "set-sink-mute" "@DEFAULT_SINK@" "toggle"))
+ (defun my/voldown () (interactive) (start-process "" nil "pactl" "set-sink-volume" "@DEFAULT_SINK@" "-5%"))
+ (defun my/volup () (interactive) (start-process "" nil "pactl" "set-sink-volume" "@DEFAULT_SINK@" "+5%"))
+
+ (push ?\C-\\ exwm-input-prefix-keys) ;;C-\ to switch input method
+ (push ?\C-u exwm-input-prefix-keys) ;; send C-u to all windows too
+ (push ?\M-L exwm-input-prefix-keys)
+ (progn
+ ;; (exwm-enable)
+ ;; (exwm-randr-mode)
+ ;; (ednc-mode 1)
+ ;; (exwm-systemtray-mode)
+ ;; (add-hook 'after-init-hook #'exwm-randr-refresh)
+ )
+ :hook
+ (exwm-update-class . my/exwm-set-buffer-name)
+ (exwm-update-title . my/exwm-set-buffer-name)
+ ;; (after-init . exwm-randr-refresh)
+ ;; (after-init . display-time-mode)
+ ;; (after-init . ednc-mode)
+ ;; (after-init . display-battery-mode)
+ :custom
+ (exwm-replace nil)
+ (exwm-title-length 50)
+ (exwm-workspace-show-all-buffers t)
+ (exwm-layout-show-all-buffers t)
+
+ (exwm-modeline-randr t)
+ (exwm-modeline-short nil)
+ (exwm-modeline-urgent t)
+
+ (exwm-manage-force-tiling t)
+
+ (exwm-input-global-keys
+ `(
+ ([?\M-r] . exwm-reset)
+ ;; Bind "s-w" to window switcher
+ ([?\M-W] . consult-buffer)
+ ([?\M-o] . other-window)
+ ([?\M-O] . my/exwm-other-workspace)
+
+ ([?\M-D] . my/dmenu)
+ ([?\M-E] . my/browser)
+ (,(kbd "M-C-m") . my/eshell)
+ ([?\M-K] . kill-current-buffer)
+
+ ,@(mapcar (lambda (n)
+ (let* ((from (concat "C-x " (format "%d" n)))
+ (to (concat "M-" (format "%d" n)))
+ (bind (keymap-lookup global-map from)))
+ (cons (kbd to) bind)))
+ (number-sequence 0 9))
+
+ ([XF86MonBrightnessDown] . my/brightnessdown)
+ ([XF86MonBrightnessUp] . my/brightnessup)
+ ([XF86AudioMute] . my/mute)
+ ([XF86AudioLowerVolume] . my/voldown)
+ ([XF86AudioRaiseVolume] . my/volup)))
+ (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])
+ ;; edit, copy, paste
+ ([?\C-d] . [delete])
+ ([?\C-k] . [S-end delete])
+ ([M-backspace] . [C-backspace])
+ ([?\M-w] . [?\C-c])
+ ([?\C-y] . [?\C-v])
+ ([?\C-s] . [?\C-f])))
+ (exwm-input-move-event 'M-down-mouse-1)
+ (exwm-input-resize-event 'M-down-mouse-3)
+ :bind (:map exwm-mode-map
+ ("C-q" . 'exwm-input-send-next-key)
+ ("M-!" . 'shell-command)))
+
diff --git a/emacs/site-lisp/my-mail.el b/emacs/site-lisp/my-mail.el
new file mode 100644
index 0000000..bcda232
--- /dev/null
+++ b/emacs/site-lisp/my-mail.el
@@ -0,0 +1,52 @@
+(use-package mu4e
+ :ensure nil
+ :demand nil
+ :init
+ ;; assumed Maildir layout
+ ;; ~/Maildir/Account0/{Inbox,Sent,Trash}
+ ;; ~/Maildir/Account1/{Inbox,Sent,Trash}
+ ;; where Account0 is context name
+ (defun my/make-mu4e-context (context-name full-name mail-address signature)
+ "Return a mu4e context named CONTEXT-NAME with :match-func matching
+ folder name CONTEXT-NAME in Maildir. The context's `user-mail-address',
+ `user-full-name' and `mu4e-compose-signature' is set to MAIL-ADDRESS
+ FULL-NAME and SIGNATURE respectively.
+ Special folders are set to context specific folders."
+ (let ((dir-name (concat "/" context-name)))
+ (make-mu4e-context
+ :name context-name
+ ;; we match based on the maildir of the message
+ ;; this matches maildir /Arkham and its sub-directories
+ :match-func
+ `(lambda (msg)
+ (when msg
+ (string-match-p
+ ,(concat "^" dir-name)
+ (mu4e-message-field msg :maildir))))
+ :vars
+ `((user-mail-address . ,mail-address)
+ (user-full-name . ,full-name)
+ (mu4e-sent-folder . ,(concat dir-name "/sent"))
+ (mu4e-drafts-folder . ,(concat dir-name "/drafts"))
+ (mu4e-trash-folder . ,(concat dir-name "/trash"))
+ (mu4e-refile-folder . ,(concat dir-name "/archive"))
+ (mu4e-compose-signature . ,signature)))))
+ :custom
+ (mu4e-change-filenames-when-moving t)
+ (mu4e-get-mail-command "mbsync --all")
+ :config
+ ;;Fixing duplicate UID errors when using mbsync and mu4e
+ (setq mu4e-contexts
+ `(,(my/make-mu4e-context
+ "thomasmulmer02" "Thomas Ulmer"
+ "thomasmulmer02@gmail.com" "Thanks,
+Thomas Ulmer")))
+
+ (require 'smtpmail)
+ (setq message-send-mail-function 'smtpmail-send-it)
+ (setq smtpmail-default-smtp-server "smtp.gmail.com"
+ smtpmail-smtp-server "smtp.gmail.com"
+ smtpmail-smtp-service 587
+ starttls-use-gnutls t
+ smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
+ smtp-auth-credentials (expand-file-name "~/.authinfo.gpg")))