custom-exwm-config.el (7091B)
1 ;;; custom-exwm-config.el --- My EXWM configuration -*- lexical-binding: t; -*- 2 3 ;; Copyright (C) 2020 Jamie Beardslee 4 5 ;; Author: Jamie Beardslee <jdb@jamzattack.xyz> 6 ;; Keywords: 7 8 ;; This program is free software; you can redistribute it and/or modify 9 ;; it under the terms of the GNU General Public License as published by 10 ;; the Free Software Foundation, either version 3 of the License, or 11 ;; (at your option) any later version. 12 13 ;; This program is distributed in the hope that it will be useful, 14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 ;; GNU General Public License for more details. 17 18 ;; You should have received a copy of the GNU General Public License 19 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 20 21 ;;; Commentary: 22 23 ;; This file contains my settings for EXWM. Notable features: 24 ;; - Functions `exwm-fullscreen-or-reset' and `exwm-quit' 25 ;; - Keybindings for `eshell' and `helm-mini' 26 ;; - A bunch of prefix keys for use with Edwina 27 ;; - All the annoying bars are disabled. 28 29 ;;; Code: 30 31 (require 'exwm) 32 (require 'exwm-xim) 33 34 (defun custom-exwm-window-setup () 35 "Make some extra room in the frame. 36 37 This disables `menu-bar-mode', `tool-bar-mode', and 38 `scroll-bar-mode'" 39 (menu-bar-mode -1) 40 (tool-bar-mode -1) 41 (scroll-bar-mode -1)) 42 43 ;;; Toggle fullscreen 44 (defvar exwm-fullscreen--old-window nil 45 "The last window to be focused before 46 `exwm-fullscreen-or-reset' was called.") 47 48 (defun exwm-fullscreen-or-reset () 49 "Toggle EXWM fullscreen layout. Use either the current exwm 50 window or the first exwm window found." 51 (interactive) 52 (let* ((exwm-window (if (eq major-mode 'exwm-mode) 53 (selected-window) 54 (let ((ht (make-hash-table))) 55 (dolist (window (window-list)) 56 (puthash 57 (buffer-local-value 'major-mode 58 (window-buffer window)) 59 window 60 ht)) 61 (or (gethash 'exwm-mode ht) 62 (user-error "No EXWM windows"))))) 63 (exwm-buffer (window-buffer exwm-window)) 64 (id (exwm--buffer->id exwm-buffer))) 65 (if (exwm-layout--fullscreen-p) 66 (progn 67 (exwm-input-grab-keyboard id) 68 (exwm-layout-unset-fullscreen id) 69 (when (window-live-p exwm-fullscreen--old-window) 70 (select-window exwm-fullscreen--old-window))) 71 (progn 72 (setq exwm-fullscreen--old-window (selected-window)) 73 (select-window exwm-window) 74 (exwm-layout-set-fullscreen id))))) 75 76 ;; Start a program without creating a buffer 77 (defun exwm-shell-command (command) 78 "Executes a shell command, but doesn't create a buffer for the 79 output." 80 (interactive (list (read-shell-command "$ "))) 81 (start-process-shell-command command nil command)) 82 83 ;; Change buffer name to "title <class>" 84 (defun custom-exwm-buffer-name () 85 "Rename exwm buffers the window class name." 86 (add-hook 'exwm-update-class-hook 87 (lambda () 88 (exwm-workspace-rename-buffer exwm-class-name))) 89 (add-hook 'exwm-update-title-hook 90 (lambda () 91 (exwm-workspace-rename-buffer 92 (format "%s <%s>" exwm-title exwm-class-name))))) 93 94 95 ;;; Keybindings 96 97 ;; Prefix keys 98 (defun custom-exwm-prefix-keys () 99 "Sets up prefix keys for exwm." 100 (customize-set-variable 101 'exwm-input-prefix-keys 102 `([XF86AudioMute] 103 [XF86AudioLowerVolume] 104 [XF86AudioRaiseVolume] 105 [XF86TouchpadToggle] 106 [XF86Launch1] 107 [XF86Back] 108 [XF86Forward] 109 [?\M-!] 110 [?\M-&] 111 [?\M-`] 112 [?\M-:] 113 [?\M-x] 114 [?\C-x] 115 [?\C-z] 116 [?\C-u] 117 [?\C-h] 118 [menu] 119 [f8] 120 [?\C-\\] 121 122 ;; Open up potential for keybindings with super modifier 123 ;; (there must be a better way to do this) 124 ,@(mapcar (lambda (k) 125 (kbd (format "s-%s" k))) 126 `(,@(number-sequence 0 9) "`" 127 "'" "," "." "p" "y" "f" "g" "c" "r" "l" "/" "=" "\\" 128 "a" "o" "e" "u" "i" "d" "h" "t" "n" "s" "-" "<return>" "SPC" 129 ";" "q" "j" "k" "x" "b" "m" "w" "v" "z" "[" "]" "<backspace>" 130 131 "!" "@" "#" "$" "%" "^" "&" "*" "(" ")" "~" 132 "\"" "<" ">" "P" "Y" "F" "G" "C" "R" "L" "?" "+" "|" 133 "A" "O" "E" "U" "I" "D" "H" "T" "N" "S" "_" "S-<return>" "S-SPC" 134 ":" "Q" "J" "K" "X" "B" "M" "W" "V" "Z" "{" "}" "S-<backspace>"))))) 135 136 ;; Global keybindings. 137 (defun custom-exwm-input-global-keys () 138 (customize-set-variable 139 'exwm-input-global-keys 140 `(;; 's-f' and '<f11>': Toggle fullscreen. 141 (,(kbd "s-f") . exwm-fullscreen-or-reset) 142 (,(kbd "<f11>") . exwm-fullscreen-or-reset) 143 144 ;; 's-&': Launch application. 145 (,(kbd "s-&") . exwm-shell-command) 146 147 ;; Don't accidentally suspend Emacs 148 (,(kbd "C-x C-z") . ignore) 149 150 ;; Frames/workspaces 151 ,@(mapcar (lambda (i) 152 `(,(kbd (format "<s-f%d>" i)) . 153 (lambda () 154 (interactive) 155 (exwm-workspace-switch-create ,(1- i))))) 156 (number-sequence 1 4)) 157 158 ;; Tab movement 159 (,(kbd "s-r") . tab-next) 160 (,(kbd "s-g") . tab-previous) 161 ,@(mapcar (lambda (k) 162 (cons (kbd (format "s-%s" k)) 'tab-bar-select-tab)) 163 (number-sequence 0 9))))) 164 165 ;; Line-editing shortcuts 166 (defun custom-exwm-input-simulation-keys () 167 (customize-set-variable 168 'exwm-input-simulation-keys 169 `(;; Basic movement 170 (,(kbd "C-b") . [left]) 171 (,(kbd "C-f") . [right]) 172 (,(kbd "C-p") . [up]) 173 (,(kbd "C-n") . [down]) 174 175 (,(kbd "M-f") . [C-right]) 176 (,(kbd "M-b") . [C-left]) 177 178 (,(kbd "C-a") . [home]) 179 (,(kbd "C-e") . [end]) 180 181 (,(kbd "M-v") . [prior]) 182 (,(kbd "C-v") . [next]) 183 184 ;; Deleting text 185 (,(kbd "C-d") . [delete]) 186 (,(kbd "C-k") . [S-end delete]) 187 (,(kbd "M-d") . [S-C-right delete]) 188 (,(kbd "<M-DEL>") . [C-DEL]) 189 190 (,(kbd "C-x h") . [C-a]) 191 (,(kbd "C-/") . [C-z]) 192 193 ;; clipboard/kill-ring 194 (,(kbd "C-w") . [C-x]) 195 (,(kbd "M-w") . [C-c]) 196 (,(kbd "C-y") . [C-v]) 197 (,(kbd "C-c C-y") . [S-insert])))) 198 199 (defun custom-exwm-input-terminal-keys () 200 "Set up simulation keys for terminal programs. 201 202 When `exwm-class-name' matches \"st\" or \"XTerm\", the following 203 simulation keys are defined: 204 205 C-c C-c C-c 206 C-c C-k C-c 207 C-c C-z C-z 208 C-c C-o C-l 209 C-c C-y S-insert 210 211 These keybindings are to aid with muscle memory from using 212 `comint' and `eshell', as well as some keys (C-c and C-z) being 213 somewhat awkward because they're used as prefix keys." 214 (when (string-match "\\(st-.*\\|XTerm\\)" exwm-class-name) 215 (exwm-input-set-local-simulation-keys 216 (list (cons (kbd "C-c C-c") (kbd "C-c")) 217 (cons (kbd "C-c C-k") (kbd "C-c")) 218 (cons (kbd "C-c C-z") (kbd "C-z")) 219 (cons (kbd "C-c M-o") (kbd "C-l")) 220 (cons (kbd "C-c C-y") (kbd "S-<insert>")))))) 221 222 223 224 (defun custom-exwm-config () 225 ;; Don't start with extra workspaces 226 (setq exwm-workspace-number 1) 227 (exwm-xim--init) 228 (add-hook 'exwm-manage-finish-hook 'custom-exwm-input-terminal-keys) 229 (custom-exwm-input-global-keys) 230 (custom-exwm-input-simulation-keys) 231 (define-key exwm-mode-map (kbd "C-q") #'exwm-input-send-next-key) 232 (custom-exwm-prefix-keys) 233 (custom-exwm-buffer-name) 234 (custom-exwm-window-setup)) 235 236 (provide 'custom-exwm-config) 237 ;;; custom-exwm-config.el ends here