summaryrefslogtreecommitdiff
path: root/emacs/site-lisp/my-exwm.el
blob: 66e77df95dc8978a3a5b96597948638ce9311bb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
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)))