emacs.d

My Emacs configuration
git clone https://git.jamzattack.xyz/emacs.d
Log | Files | Refs | LICENSE

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