-
Notifications
You must be signed in to change notification settings - Fork 2
/
init.lua
632 lines (534 loc) · 20.8 KB
/
init.lua
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
----------------------------------------------------------------
-- REQUIRE CMD Q TO BE PRESSED TO QUIT
----------------------------------------------------------------
-- https://github.com/pqrs-org/Karabiner-Elements/issues/242#issuecomment-277330358
local quitModal = hs.hotkey.modal.new("cmd", "q")
function quitModal:entered()
hs.alert.show("Press Cmd+Q again to quit", 1)
hs.timer.doAfter(1, function() quitModal:exit() end)
end
local function doQuit()
local app = hs.application.frontmostApplication()
app:kill()
end
quitModal:bind("cmd", "q", doQuit)
quitModal:bind("", "escape", function() quitModal:exit() end)
----------------------------------------------------------------
-- GENERAL WINDOW MANAGEMENT SETUP
----------------------------------------------------------------
-- http://bezhermoso.github.io/2016/01/20/making-perfect-ramen-lua-os-x-automation-with-hammerspoon#cycle-displays
-- DISPLAY FOCUS SWITCHING --
--One hotkey should just suffice for dual-display setups as it will naturally
--cycle through both.
--A second hotkey to reverse the direction of the focus-shift would be handy
--for setups with 3 or more displays.
--Predicate that checks if a window belongs to a screen
function isInScreen(screen, win)
return win:screen() == screen
end
function centerMouseOnWindow(window)
local pt = hs.geometry.rectMidPoint(window:frame())
hs.mouse.absolutePosition(pt)
end
-- Brings focus to the screen by setting focus on the front-most application in it.
-- Also move the mouse cursor to the center of the screen. This is because
-- Mission Control gestures & keyboard shortcuts are anchored, oddly, on where the
-- mouse is focused.
function focusScreen(screen)
--Get windows within screen, ordered from front to back.
--If no windows exist, bring focus to desktop. Otherwise, set focus on
--front-most application window.
local windows = hs.fnutils.filter(
hs.window.orderedWindows(),
hs.fnutils.partial(isInScreen, screen))
local windowToFocus = #windows > 0 and windows[1] or hs.window.desktop()
windowToFocus:focus()
centerMouseOnWindow(windowToFocus)
end
-- END DISPLAY FOCUS SWITCHING --
-- https://github.com/Hammerspoon/Spoons/blob/master/Source/WindowHalfsAndThirds.spoon/init.lua#L177
function round(x, places)
local places = places or 0
local x = x * 10^places
return (x + 0.5 - (x + 0.5) % 1) / 10^places
end
-- https://github.com/Hammerspoon/Spoons/blob/master/Source/WindowHalfsAndThirds.spoon/init.lua#L183
function current_window_rect(win)
local win = win or hs.window.frontmostWindow()
local ur, r = win:screen():toUnitRect(win:frame()), round
return {r(ur.x,2), r(ur.y,2), r(ur.w,2), r(ur.h,2)} -- an hs.geometry.unitrect table
end
function exitFullScreen(win)
local win = win or hs.window.frontmostWindow()
if win:isFullScreen() then
win:setFullScreen(false)
end
end
-- https://stackoverflow.com/a/58398311
function moveWindowToDisplay(d)
return function()
win = hs.window.frontmostWindow()
exitFullScreen(win)
win:moveToScreen(hs.screen.allScreens()[d], true, true)
centerMouseOnWindow(win)
end
end
----------------------------------------------------------------
-- CTRL ONLY SHORTCUTS
----------------------------------------------------------------
-- The ctrl only bindings only affect the currently focused window
-- Mnemonic: only
-- https://github.com/miromannino/miro-windows-manager
hs.loadSpoon("MiroWindowsManager")
-- Ctrl Tab is used as a switcher in many apps
-- ASCII character 9
-- Ctrl Space ( ) alternates between maximized, 3/4 and 1/2 in the center
-- Ctrl Quote (') alternates between 1/2, 1/3, and 2/3 split at the top
-- Ctrl Forward slash (/) alternates between 1/2, 1/3, and 2/3 split at the bottom
-- Ctrl Open square bracket ([) alternates between 1/2, 1/3, and 2/3 split on the left
-- Ctrl Close square bracket (]) alternates between 1/2, 1/3, and 2/3 split on the right
-- Ctrl Space is switch input source in macOS, but I just want to stick to the undead layout
-- Ctrl Space is used for completion in IDEs, but this shows up automatically
-- ASCII characters 32, 39, 47, 91, 93
hs.window.animationDuration = 0 -- disable animations
spoon.MiroWindowsManager:bindHotkeys({
fullscreen = {"ctrl", "space"}, -- Mnemonic: space is the widest key on the keyboard
up = {"ctrl", "'"}, -- Mnemonic: " creates a horizontal split in tmux
down = {"ctrl", "/"}, -- Mnemonic: the slash is falling down
left = {"ctrl", "["},
right = {"ctrl", "]"},
nextscreen = {"ctrl", "0"},
})
-- Ctrl Comma (,) shrinks the window horizontally
-- ASCII character 44
-- https://github.com/Hammerspoon/Spoons/blob/master/Source/WindowHalfsAndThirds.spoon/init.lua#L392
hs.hotkey.bind("ctrl", ",", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
local cw = current_window_rect(win)
local move_to_rect = {}
move_to_rect[1] = cw[1] == 0 and 0 or math.min(cw[1]+0.04,1) -- x
move_to_rect[2] = cw[2]
move_to_rect[3] = cw[1] + cw[3] > 0.99 and 1 or math.max(cw[3]-0.04,0.1) -- w
move_to_rect[4] = cw[4]
win:move(move_to_rect)
end)
-- Ctrl Hyphen (-) shrinks the window horizontally
-- ASCII character 45
hs.hotkey.bind("ctrl", "-", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
local cw = current_window_rect(win)
local move_to_rect = {}
move_to_rect[1] = cw[1]
move_to_rect[2] = cw[2] == 0 and 0 or math.min(cw[2]+0.04,1)
move_to_rect[3] = cw[3]
move_to_rect[4] = cw[2] + cw[4] > 0.99 and 1 or math.max(cw[4]-0.04,0.1) -- some windows (MacVim) don't size to 1
win:move(move_to_rect)
end)
-- Ctrl Period (.) expands window horizontally
-- https://github.com/Hammerspoon/Spoons/blob/master/Source/WindowHalfsAndThirds.spoon/init.lua#L368
-- ASCII character 46
hs.hotkey.bind("ctrl", ".", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
local cw = current_window_rect(win)
local move_to_rect = {}
move_to_rect[1] = math.max(cw[1]-0.04,0) -- x
move_to_rect[3] = math.min(cw[3]+0.04,1 - move_to_rect[1]) -- w
move_to_rect[2] = cw[2]
move_to_rect[4] = cw[4]
win:move(move_to_rect)
end)
-- Ctrl Zero (0) moves the current window to the next screen
-- Close Parentheses goes to next session in tmux
-- ASCII character 48
hs.hotkey.bind("ctrl", "0", function()
local win = hs.window.frontmostWindow()
if win:isFullScreen() then
win:setFullScreen(false)
win:moveToScreen(win:screen():next(), true, true, 1)
else
win:moveToScreen(win:screen():next(), true, true)
end
centerMouseOnWindow(win)
end)
-- Ctrl and the numbers 1-4 move the current window to screen 1-4
-- This requires changing the "Switch to Desktop" shortcuts...
-- in System Preferences > Keyboard > Shortcuts > Mission Control
-- ASCII characters 49-52
hs.hotkey.bind("ctrl", "1", moveWindowToDisplay(1))
hs.hotkey.bind("ctrl", "2", moveWindowToDisplay(2))
hs.hotkey.bind("ctrl", "3", moveWindowToDisplay(3))
hs.hotkey.bind("ctrl", "4", moveWindowToDisplay(4))
hs.hotkey.bind("ctrl", "5", moveWindowToDisplay(5))
-- Ctrl Nine (9) moves the current window to the previous screen
-- Open parentheses goes to previous session in tmux
-- ASCII character 57
hs.hotkey.bind("ctrl", "9", function()
local win = hs.window.frontmostWindow()
if win:isFullScreen() then
win:setFullScreen(false)
win:moveToScreen(win:screen():previous(), true, true, 1)
else
win:moveToScreen(win:screen():previous(), true, true)
end
centerMouseOnWindow(win)
end)
-- Ctrl Semicolon (;) is my tmux prefix thanks to my iTerm config
-- ASCII character 59
-- Ctrl Equals (=) expands the window vertically
-- ASCII character 61
hs.hotkey.bind("ctrl", "=", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
local cw = current_window_rect(win)
local move_to_rect = {}
move_to_rect[1] = cw[1]
move_to_rect[2] = math.max(cw[2]-0.04,0) -- y
move_to_rect[3] = cw[3]
move_to_rect[4] = math.min(cw[4]+0.04,1 - move_to_rect[2]) -- h
win:move(move_to_rect)
end)
-- Ctrl Backslash (\) centers the window,
-- works great with [ and ] to create a triple vertical split
-- works great with / and ' to create a triple horizontal split
-- ASCII character 92
hs.hotkey.bind("ctrl", "\\", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
win:centerOnScreen(nil, true)
end)
-- Ctrl A goes to the beginning of the line in macOS and GNU Emacs/Readline
-- Ctrl B goes one character backward in macOS and GNU Emacs/Readline
-- Ctrl C cancels and clears line in Bash/Zsh
-- Ctrl D deletes next character in macOS and GNU Emacs/Readline
-- Ctrl E goes to the end of the line in macOS and GNU Emacs/Readline
-- Ctrl F goes one character forward in macOS and GNU Emacs/Readline
-- Ctrl G cancels in GNU Emacs/Readline and in Bash/Zsh
-- Ctrl H deletes previous character in macOS and GNU Emacs/Readline
-- Ctrl I is equivalent to Tab and redos previous jump in Vim
-- Ctrl J is equivalent to Enter/Return
-- Ctrl K deletes to the end of the line in macOS and GNU Emacs/Readline
-- Ctrl L clears the screen but not the line in Bash/Zsh
-- Ctrl M is equivalent to Enter/Return
-- Ctrl N moves down
-- Ctrl O undos previous jump in Vim
-- Ctrl P moves up
-- Ctrl Q triggers Vimac Hint mode
-- Ctrl R pastes from register in Vim and does a recursive search in Bash/Zsh
-- Ctrl S triggers Vimac Scroll mode
-- Ctrl T transposes letters
-- Ctrl U deletes to the beginning of the line in GNU Readline
-- Ctrl V puts a character literally or enters block visual mode in Vim
-- Ctrl W deletes previous word
-- Ctrl X is used for chords in Vim and GNU Emacs/Readline
-- Ctrl Y is used to accept completion in Vim and pasting GNU Emacs/Readline
-- Ctrl Z suspends the current process
-- The arrow keys move the current window
-- This requires changing the
-- - "Mission Control",
-- - "Application windows", and
-- - "Move left/right a space" shortcuts
-- in System Preferences > Keyboard > Shortcuts > Mission Control
-- I hate the macOS Spaces feature with the passion of infinite burning suns
-- Arrow keys have no ASCII code
-- Ctrl Left nudges the focused window to the left
function nudgeLeft(d)
return {
x = d.x - 40,
y = d.y,
h = d.h,
w = d.w,
}
end
hs.hotkey.bind("ctrl", "left", function()
win = hs.window.frontmostWindow()
exitFullScreen(win)
win:setFrame(nudgeLeft(win:frame()))
end)
-- Ctrl Right nudges the focused window to the right
function nudgeRight(d)
return {
x = d.x + 40,
y = d.y,
h = d.h,
w = d.w,
}
end
hs.hotkey.bind("ctrl", "right", function()
win = hs.window.frontmostWindow()
exitFullScreen(win)
win:setFrame(nudgeRight(win:frame()))
end)
-- Ctrl Down nudges the focused window downward
function nudgeDown(d)
return {
x = d.x,
y = d.y + 40,
h = d.h,
w = d.w,
}
end
hs.hotkey.bind("ctrl", "down", function()
win = hs.window.frontmostWindow()
exitFullScreen(win)
win:setFrame(nudgeDown(win:frame()))
end)
-- Ctrl Up nudges the focused window upward
function nudgeUp(d)
return {
x = d.x,
y = d.y - 40,
h = d.h,
w = d.w,
}
end
hs.hotkey.bind("ctrl", "up", function()
win = hs.window.frontmostWindow()
exitFullScreen(win)
win:setFrame(nudgeUp(win:frame()))
end)
----------------------------------------------------------------
-- ALT ONLY SHORTCUTS
----------------------------------------------------------------
-- The alt only bindings focus something other than the current window
-- Alt Tab is used as a switcher by the AltTab macOS application
-- ASCII character 9
-- Alt Quote goes to the previously focused window
-- like the last jump ('') mark in Vim
-- ASCII character 39
hs.hotkey.bind("alt", "'", function()
local target = hs.window.filter.new():getWindows(hs.window.filter.sortByFocusedLast)[2]
target:application():activate()
target:focus()
centerMouseOnWindow(target)
end)
function focusDisplay(d)
return function()
focusScreen(hs.screen.allScreens()[d])
end
end
-- Alt Comma (,) is not used for anything
-- ASCII characters 44
-- Alt - focuses the window below the current window
-- Alt Hyphen (-) is begin negative argument in Emacs
-- ASCII character 45
hs.hotkey.bind("alt", "-", function()
local win = hs.window.frontmostWindow()
exitFullScreen(win)
win:focusWindowSouth()
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt Period (.) is insert previous argument in bash / zsh
-- Alt Forwardslash (/) is hippie completion in Emacs, analogous to omnicompletion in vim
-- ASCII characters 46-47
-- Note: Alt Shift Period (.) goes to the end of the document in Emacs
-- Note: Alt Shift Comma (,) goes to the start of the document in Emacs
-- In Vim, use G
-- In macOS, use Ctrl Command N instead of Alt Shift .
-- Alt 0 brings focus to next display/screen
-- Close parentheses goes to next session in tmux
-- ASCII character 48
hs.hotkey.bind("alt", "0", function ()
focusScreen(hs.window.frontmostWindow():screen():next())
end)
-- Alt and the numbers 1-4 brings focus to screens 104
-- Alt 1 thru 0 (create and) switch to windows 1-10 in tmux
-- ASCII characters 49-52
hs.hotkey.bind("alt", "1", focusDisplay(1))
hs.hotkey.bind("alt", "2", focusDisplay(2))
hs.hotkey.bind("alt", "3", focusDisplay(3))
hs.hotkey.bind("alt", "4", focusDisplay(4))
hs.hotkey.bind("alt", "5", focusDisplay(5))
-- Alt 9 brings focus to previous display/screen
-- Open parentheses goes to previous session in tmux
-- ASCII character 57
hs.hotkey.bind("alt", "9", function()
focusScreen(hs.window.frontmostWindow():screen():previous())
end)
-- Alt Semicolon (;) is not used for anything
-- ASCII character 59
-- Alt = focuses the window above the current window
-- Alt = (ASCII character 61) is count words in region in Emacs
-- ASCII character 61
hs.hotkey.bind("alt", "=", function()
hs.window.frontmostWindow():focusWindowNorth()
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt [ focuses the window to the left of the current window
-- Alt [ is undefined in Emacs
-- ASCII character 91
hs.hotkey.bind("alt", "[", function()
hs.window.frontmostWindow():focusWindowWest()
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt \ focuses the window behind the current window
-- Mnemonic: BACKslash
-- Alt \ deletes all whitespace around the cursor
-- ASCII character 92
hs.hotkey.bind("alt", "\\", function()
hs.window.frontmostWindow():sendToBack()
end)
-- Alt ] focuses the window to the right of the current window
-- Alt ] is undefined in Emacs
-- ASCII character 93
hs.hotkey.bind("alt", "]", function()
hs.window.frontmostWindow():focusWindowEast()
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt Backtick (`) brings up the Hammerspoon console,
-- like Ctrl ` in VS Code and GitHub Desktop
-- Alt Backtick is used by Alt tab and needs to be unmapped
-- Alt `(ASCII character 96) runs the command tmm-menubar in Emacs
hs.hotkey.bind("alt", "`", function()
hs.toggleConsole()
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt A is move to start of previous sentence in Emacs
-- Use Alt A to focus menu bar, Mnemonic: A is Apple
-- System Preferences > Keyboard > Shortcuts > Keyboard > Move focus to menu bar
-- Alt B is move one word backward in Emacs
-- Alt C is capitalize next word in Emacs
-- Alt D is delete next word in Emacs
-- Alt E is go to end of sentence in Emacs
-- Alt F is move one word forward in Emacs
-- Alt G launches or focuses Google Chrome
-- Alt G, G is go to line; Alt G, C is go to char in Emacs
hs.hotkey.bind("alt", "g", function()
hs.application.launchOrFocus("Google Chrome")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt H shows Hammerspoon window hints
-- Alt H is mark paragraph in Emacs
hs.hotkey.bind("alt", "h", hs.hints.windowHints)
-- Alt I launches or focuses iTerm
-- Alt I inserts spaces or tabs to next defined tab-stop column in Emacs
hs.hotkey.bind("alt", "i", function()
hs.application.launchOrFocus("iTerm")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt J breaks line at point and indents in Emacs
-- J focuses to your favorite Jetbrains IDE
hs.hotkey.bind("alt", "j", function()
hs.application.launchOrFocus("PyCharm")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Use Alt K to toggle macOS keyboard access
-- System Preferences > Keyboard > Shortcuts > Keyboard > Turn keyboard access on or off
-- Alt K is delete to end of sentence in Emacs
-- Alt L is lowercase to end of word in Emacs
-- Alt M is for maximize (unminimize) windows for the focused app
-- Alt M is back to indentation in Emacs
hs.hotkey.bind("alt", "m", function()
local app = hs.application.frontmostApplication()
for k, w in ipairs(app:allWindows()) do w:unminimize() end
end)
-- Alt N goes to the next window in the Hammerspoon window switcher
-- Alt N is undefined in Emacs
hs.hotkey.bind("alt", "n", hs.window.switcher.nextWindow)
-- Alt O is for Outlook
-- Alt O is set face in Emacs
hs.hotkey.bind("alt", "o", function()
hs.application.launchOrFocus("Microsoft Outlook")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt P goes to the next window in the Hammerspoon window switcher
-- Alt P is undefined in Emacs
hs.hotkey.bind("alt", "p", hs.window.switcher.previousWindow)
-- Alt Q is for CopyQ, as in queue
-- Alt Q is fill/format paragraph in Emacs, like gq or gw in vim
hs.hotkey.bind("alt", "q", function()
hs.application.launchOrFocus("CopyQ")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Use Alt R to focus window toolbar (mnemonic: toolbaR, works a bit like Alt R in Emacs in that it jumps back and forth)
-- In Emacs, Alt R positions the cursor at the center of window, then alternates between top, middle, bottom
-- Use Alt S to focus status menus
-- Alt S is search forward in Emacs
-- System Preferences > Keyboard > Shortcuts > Keyboard > Move focus to status menus
-- Mnemonic: S is to the right of A on the keyboard
-- Alt T is transpose words in Emacs
-- Alt U is uppercase word in Emacs
-- Alt V launches or focuses VSCode
-- Alt V is page down in Emacs
hs.hotkey.bind("alt", "v", function()
hs.application.launchOrFocus("Visual Studio Code")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Use Alt W to focus floating window
-- Alt W saves the marked region in Emacs
-- X is for eXpose
-- Alt X brings up a list of commands in Emacs
hs.hotkey.bind("alt", "x", function()
hs.expose.new():toggleShow()
end)
-- Alt V launches or focuses System Preferences
-- Mnemonic: sYstem Preferences
-- Alt Y rotates the kill ring (replaces last yank with previous kill) in Emacs
hs.hotkey.bind("alt", "y", function()
hs.application.launchOrFocus("System Preferences")
centerMouseOnWindow(hs.window.frontmostWindow())
end)
-- Alt Z is zap to char, same as dt in vim
-- Use Alt Z to focus Dock; mnemonic: z is below a (apple) and s (status menus)
-- Alt Bar (|) deletes all spaces and tabs around cursor
-- ASCII character 124
-- https://github.com/Hammerspoon/hammerspoon/issues/2022#issuecomment-518754783
-- Alt Delete reduces indentation of lines to match a line above in Emacs
-- Alt Delete also deletes previous word in macOS
-- ASCII character 127
----------------------------------------------------------------
-- MISCELLANEOUS BINDINGS
----------------------------------------------------------------
-- Miscellaneous Bindings all use Ctrl Alt
-- CopyQ shortcuts, which also use Ctrl Alt, are described below
local ctrl_alt = {"ctrl", "alt"}
-- CLIPBOARD MANAGEMENT
-- Ctrl Alt C summons the CopyQ window
-- Ctrl Alt D pastes the today's ISO date
-- Ctrl Alt J pastes and copies next
-- Ctrl Alt K pastes and copies previous
-- Ctrl Alt S shows the CopyQ tray (mnemonic: show tray)
-- Ctrl Alt V edits the clipboard (mnemonic: vim)
-- Ctrl Alt X pastes as plain text (mnemonic: remove (x) formatting)
-- Y imitates typing while pasting, Y is for yank, like Ctrl Y in GNU Emacs and Readline
-- https://www.hammerspoon.org/go/#defeating-paste-blocking
hs.hotkey.bind(ctrl_alt, "y", function()
hs.eventtap.keyStrokes(hs.pasteboard.getContents())
end)
-- RELOAD HAMMERSPOON CONFIG
-- Ctrl Alt R reloads the config
hs.hotkey.bind(ctrl_alt, "r", hs.reload)
-- TOGGLE SYSTEM SYSTEM
-- Use menubar instead of terminal to disable system sleep
-- https://www.hammerspoon.org/go/#creating-a-simple-menubar-item
caffeine = hs.menubar.new()
function setCaffeineDisplay(state)
if state then
caffeine:setTitle("AWAKE")
else
caffeine:setTitle("DECAF")
end
end
function caffeineClicked()
setCaffeineDisplay(hs.caffeinate.toggle("displayIdle"))
end
if caffeine then
caffeine:setClickCallback(caffeineClicked)
setCaffeineDisplay(hs.caffeinate.get("displayIdle"))
end
hs.hotkey.bind(ctrl_alt, "z", caffeineClicked)
-- DISABLE ALL KEY BINDINGS
local hk = hs.hotkey.getHotkeys()
local hkEnabled = true
-- Delete is on the opposite side of the keyboard from Backtick
hs.hotkey.bind(ctrl_alt, "delete", function()
if hkEnabled then
for k, v in ipairs(hk) do v:disable() end
hkEnabled = false
else
for k, v in ipairs(hk) do v:enable() end
hkEnabled = true
end
end)