summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.emacs.d/init.el290
1 files changed, 285 insertions, 5 deletions
diff --git a/.emacs.d/init.el b/.emacs.d/init.el
index 381bcef..a712bb1 100644
--- a/.emacs.d/init.el
+++ b/.emacs.d/init.el
@@ -221,7 +221,19 @@ plain variables. This means that `setopt' will execute any
(run-with-idle-timer 0.5 nil #'require 'winner)
(with-eval-after-load 'winner
- (winner-mode 1))
+ (winner-mode 1)
+ (when (featurep 'exwm)
+ ;; prevent a bad interaction between EXWM and winner-mode, where
+ ;; sometimes closing a window (like closing a terminal after
+ ;; entering a GPG password via pinentry-gnome3's floating window)
+ ;; results in a dead frame somewhere and effectively freezes EXWM.
+ (advice-add
+ 'winner-insert-if-new
+ :around
+ (lambda (orig-fun &rest args)
+ ;; only add the frame if it's live
+ (when (frame-live-p (car args))
+ (apply orig-fun args))))))
(run-with-idle-timer 0.5 nil #'require 'windmove)
(with-eval-after-load 'windmove
@@ -372,7 +384,9 @@ for all frames."
(let ((frame (unless arg
(selected-frame))))
(invert-face 'default frame)
- (invert-face 'mode-line frame)))
+ (invert-face 'mode-line frame)
+ (when (fboundp #'exwm-systemtray--refresh-background-color)
+ (exwm-systemtray--refresh-background-color 'remap))))
;;; General key bindings
@@ -416,12 +430,278 @@ for all frames."
(add-to-list 'load-path (b/emacs.d "lisp"))
-(when (member (system-name) '("adelita"))
+(when (and
+ (display-graphic-p)
+ ;; we're not running in another WM/DE
+ (not (or
+ (getenv "XDG_CURRENT_DESKTOP")
+ (getenv "WAYLAND_DISPLAY")))
+ (member (system-name) '("adelita")))
(add-to-list 'load-path (b/emacs.d "lisp/xelb"))
(add-to-list 'load-path (b/emacs.d "lisp/exwm"))
(require 'exwm)
- (require 'exwm-config)
- (exwm-config-example))
+
+ (global-set-key (kbd "C-x b") #'exwm-workspace-switch-to-buffer)
+
+ (menu-bar-mode -1)
+ (tool-bar-mode -1)
+
+ (defun b/exwm-rename-buffer ()
+ "Make class name the buffer name, truncating beyond 60 characters."
+ (interactive)
+ (exwm-workspace-rename-buffer
+ (concat exwm-class-name ":"
+ (if (<= (length exwm-title) 60) exwm-title
+ (concat (substring exwm-title 0 59) "...")))))
+
+ (defvar b/shifted-ws-names
+ '(0 \) 1 \! 2 \@ 3 \# 4 \$
+ 5 \% 6 \^ 7 \& 8 \* 9 \()
+ "Mapping of shifted numbers on my keyboard.")
+
+ (setq
+ ;; Initial number of workspaces
+ exwm-workspace-number 4
+ ;; Global keybindings
+ exwm-input-global-keys
+ `(([?\s-r] . exwm-reset) ; Reset (to line-mode)
+ ([?\s-/] . exwm-workspace-switch)
+ ([?\s-\s] . (lambda (command)
+ (interactive (list (read-shell-command "$ ")))
+ (start-process-shell-command command nil command)))
+ ([?\s-\\] . (lambda ()
+ (interactive)
+ (start-process-shell-command
+ "passmenu" nil "passmenu --type")))
+ ([s-return] . (lambda ()
+ (interactive)
+ (start-process "" nil "xterm")))
+ ([S-s-return] . (lambda ()
+ (interactive)
+ (start-process "" nil "xterm"
+ "-name" "floating")))
+ ([?\s-h] . windmove-left)
+ ([?\s-j] . windmove-down)
+ ([?\s-k] . windmove-up)
+ ([?\s-l] . windmove-right)
+ ([?\s-H] . windmove-swap-states-left)
+ ([?\s-J] . windmove-swap-states-down)
+ ([?\s-K] . windmove-swap-states-up)
+ ([?\s-L] . windmove-swap-states-right)
+ ([?\M-\s-h] . shrink-window-horizontally)
+ ([?\M-\s-l] . enlarge-window-horizontally)
+ ([?\M-\s-k] . shrink-window)
+ ([?\M-\s-j] . enlarge-window)
+ ([mode-line mouse-4] . b/exwm-ws-prev) ; up
+ ([mode-line mouse-5] . b/exwm-ws-next) ; down
+ ([mode-line mouse-6] . b/exwm-ws-prev) ; left
+ ([mode-line mouse-7] . b/exwm-ws-next) ; right
+ ([?\s-\[] . b/exwm-ws-prev)
+ ([?\s-\]] . b/exwm-ws-next)
+ ([?\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)))
+ ,@(mapcar
+ (lambda (i)
+ `(,(kbd (format "s-%s"
+ (plist-get b/shifted-ws-names i)))
+ .
+ (lambda ()
+ (interactive)
+ (exwm-workspace-move-window ,i))))
+ (number-sequence 0 (1- exwm-workspace-number)))
+ ([?\s-.] . 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
+ "dmneu-light" nil "dmenu-light")))
+ ([\s-XF86Back] . previous-buffer)
+ ([\s-XF86Forward] . next-buffer))
+ ;; Line-editing shortcuts
+ 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 delete])
+ ([?\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])
+ ;; closing/quite
+ ([?\s-w] . [?\C-w])
+ ([?\s-q] . [?\C-q])
+ ;; misc
+ ([?\C-s] . [?\C-f])
+ ([?\s-g] . [?\C-g])
+ ([?\s-s] . [?\C-s])
+ ([?\C-g] . [escape])
+ ([?\C-/] . [?\C-z])))
+
+ (with-eval-after-load 'exwm-manage
+ (setq
+ exwm-manage-configurations
+ '(((equal exwm-instance-name "floating")
+ floating t
+ floating-mode-line nil)))
+ (add-hook
+ 'exwm-manage-finish-hook
+ (lambda ()
+ (when exwm-class-name
+ (cond
+ ((member exwm-class-name '("Abrowser" "IceCat" "Firefox-esr"))
+ (exwm-input-set-local-simulation-keys
+ `(,@exwm-input-simulation-keys
+ ([?\C-\S-d] . [?\C-d]))))
+ ((member exwm-class-name '("XTerm" "Mate-terminal"))
+ (exwm-input-set-local-simulation-keys
+ '(([?\C-c ?\C-c] . [?\C-c])
+ ([?\C-c ?\C-u] . [?\C-u]))))
+ ((string= exwm-class-name "Zathura")
+ (exwm-input-set-local-simulation-keys
+ '(([?\C-p] . [C-up])
+ ([?\C-n] . [C-down])))))))))
+
+ ;; Enable EXWM
+ (exwm-enable)
+ (add-hook 'exwm-update-class-hook #'b/exwm-rename-buffer)
+ (add-hook 'exwm-update-title-hook #'b/exwm-rename-buffer)
+
+ (defun b/fix-ido-buffer-window-other-frame ()
+ "Fix `ido-buffer-window-other-frame'."
+ (defalias 'b/ido-buffer-window-other-frame-orig
+ (symbol-function 'ido-buffer-window-other-frame))
+ (defun ido-buffer-window-other-frame (buffer)
+ "This is a version redefined for EXWM.
+
+The original one is at `b/ido-buffer-window-other-frame-orig'."
+ (with-current-buffer (window-buffer (selected-window))
+ (if (and (derived-mode-p 'exwm-mode)
+ exwm--floating-frame)
+ ;; Switch from a floating frame.
+ (with-current-buffer buffer
+ (if (and (derived-mode-p 'exwm-mode)
+ exwm--floating-frame
+ (eq exwm--frame exwm-workspace--current))
+ ;; Switch to another floating frame.
+ (frame-root-window exwm--floating-frame)
+ ;; Do not switch if the buffer is not on the current workspace.
+ (or (get-buffer-window buffer exwm-workspace--current)
+ (selected-window))))
+ (with-current-buffer buffer
+ (when (derived-mode-p 'exwm-mode)
+ (if (eq exwm--frame exwm-workspace--current)
+ (when exwm--floating-frame
+ ;; Switch to a floating frame on the current workspace.
+ (frame-selected-window exwm--floating-frame))
+ ;; Do not switch to exwm-mode buffers on other workspace (which
+ ;; won't work unless `exwm-layout-show-all-buffers' is set)
+ (unless exwm-layout-show-all-buffers
+ (selected-window)))))))))
+ (add-hook 'exwm-init-hook #'b/fix-ido-buffer-window-other-frame)
+
+ (require 'exwm-input)
+ (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)))
+
+ (defun b/exwm-ws-prev ()
+ "Switch to previous EXWM workspace, wrapping around if needed."
+ (interactive)
+ (exwm-workspace-switch-create
+ (b/exwm-ws-prev-index)))
+
+ (defun b/exwm-ws-next ()
+ "Switch to next EXWM workspace, wrapping around if needed."
+ (interactive)
+ (exwm-workspace-switch-create
+ (b/exwm-ws-next-index)))
+
+ ;; Shorten 'C-c C-q' to 'C-q'
+ (define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
+
+ ;; Scroll up/down/left/right on the echo area
+ (define-key minibuffer-inactive-mode-map [mouse-4] #'b/exwm-ws-prev)
+ (define-key minibuffer-inactive-mode-map [mouse-5] #'b/exwm-ws-next)
+ (define-key minibuffer-inactive-mode-map [mouse-6] #'b/exwm-ws-prev)
+ (define-key minibuffer-inactive-mode-map [mouse-7] #'b/exwm-ws-next)
+
+ ;; (require 'exwm-randr)
+ ;; (setq
+ ;; exwm-randr-workspace-monitor-plist
+ ;; '(0 "eDP-1"
+ ;; 1 "eDP-1" 2 "eDP-1" 3 "eDP-1"
+ ;; 4 "eDP-1" 5 "eDP-1" 6 "eDP-1"
+ ;; 7 "HDMI-1" 8 "HDMI-1" 9 "HDMI-1"))
+ ;; ;; (add-hook
+ ;; ;; 'exwm-randr-screen-change-hook
+ ;; ;; (lambda ()
+ ;; ;; (start-process-shell-command
+ ;; ;; "xrandr" nil
+ ;; ;; "xrandr --output HDMI-1 --mode 1280x720 --above eDP-1 --auto")))
+ ;; (exwm-randr-enable)
+
+ (require 'exwm-systemtray)
+ (exwm-systemtray-enable)
+
+ ;; (add-to-list 'load-path (b/lisp "exwm-edit"))
+ ;; (require 'exwm-edit)
+
+ (with-eval-after-load 'exwm-workspace
+ (setq exwm-workspace-show-all-buffers t)
+ ;; Display current EXWM workspace in mode-line
+ (setq-default
+ mode-line-format
+ (append
+ mode-line-format
+ '((:eval
+ (format
+ " [%s]" (number-to-string
+ exwm-workspace-current-index)))))))
+
+ (with-eval-after-load 'exwm-layout
+ (setq exwm-layout-show-all-buffers t)))
;; recently opened files
(run-with-idle-timer 0.2 nil #'require 'recentf)