aboutsummaryrefslogtreecommitdiffstats
path: root/hammerspoon/.hammerspoon/init.fnl
blob: 3aa6b4f2174262db9b6c8eb8869cd1f3361a8c49 (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
(fn show-window-information []
  (let [window (hs.window.focusedWindow)]
    (if (= window nil)
        (hs.alert.show "no window")
        (hs.alert.show (.. "Title: " (window:title) "\n"
                           "Application: " (: (window:application) :name))))))

(hs.hotkey.bind ["cmd" "alt" "ctrl"] "e" show-window-information)
(hs.hotkey.bind ["cmd" "shift"] "r" hs.reload)

(fn make-config-path-watcher []
  (hs.pathwatcher.new
   (.. (os.getenv "HOME")
       "/code/personal/dotfiles/hammerspoon/.hammerspoon")
   (fn [] (print "Reload!") (hs.reload))))

(let [watcher (make-config-path-watcher)]
  (watcher:start))

;;; Layout -- Automatically put windows in their place.

(fn apply-layout []
  (let [my-screen (hs.screen.primaryScreen)
        screen-mode (: my-screen :currentMode)
        geom [(. screen-mode "w") (. screen-mode "h")]
        max (. hs "layout" "maximized")]
    (case geom
      [3440 1440] (hs.layout.apply
                   [["Emacs" nil nil (. hs "layout" "left70") nil nil]
                    ["WezTerm" nil nil (. hs "layout" "right30") nil nil]
                    ["Glide" nil nil max nil nil]])

      [5120 1440] (hs.layout.apply
                   [["Glide" nil nil (. hs "layout" "left25") nil nil]
                    ["Emacs" nil nil (hs.geometry.rect 0.25 0 0.5 1) nil nil]
                    ["WezTerm" nil nil (. hs "layout" "right25") nil nil]])

      _ (hs.layout.apply
         [["Glide" nil nil max nil nil]
          ["Emacs" nil nil max nil nil]
          ["WezTerm" nil nil max nil nil]]))))

(fn make-application-watcher []
  (fn match-application [name event-type application]
    (when (and (= event-type (. hs :application :watcher :launched))
               (or (= name "Emacs")
                   (= name "WezTerm")
                   (= name "Glide")))
      (apply-layout)))
  (hs.application.watcher.new match-application))

(fn make-screen-watcher []
  (hs.screen.watcher.new apply-layout))

(apply-layout)

(let [watcher (make-application-watcher)]
  (watcher:start))
(let [watcher (make-screen-watcher)]
  (watcher:start))

;;; Mouse -- Automatically set primary button based on mouse connected.

(fn set-mouse-buttons! [swap?]
  (let [task (hs.task.new
              "/usr/bin/defaults" nil []
              ["-currentHost"
               "write"
               ".GlobalPreferences"
               "com.apple.mouse.swapLeftRightButton"
               "-bool"
               (tostring swap?)])]
    (task:start)
    (task:waitUntilExit))
  (print (.. "Changed mouse button to: " (if swap? "left" "right"))))

(fn make-mouse-watcher []
  (fn match-device [{:eventType event-type :productName name}]
    (let [connected? (= event-type "added")]
      (print (.. "Device " (if connected? "" "dis") "connected: " name))
      (when (= name "USB Optical Mouse")
        (set-mouse-buttons! connected?))))
  (hs.usb.watcher.new match-device))

(fn mouse-connected? []
  (fn find-mouse-device [devices]
    (if (= (next devices) nil)
        false
        (let [device (table.remove devices 1)]
          (if (= (. device "productName") "USB Optical Mouse")
              true
              (tail! (find-mouse-device devices))))))
  (find-mouse-device (hs.usb.attachedDevices)))

(set-mouse-buttons! (mouse-connected?))

(let [watcher (make-mouse-watcher)]
  (watcher:start))

;; Done

(hs.alert.show "Loaded!" [] (hs.screen.primaryScreen) 0.5)