-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathinit.lua
272 lines (228 loc) · 9.79 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
local lVer = _VERSION:match("Lua (.+)$")
-- or specify luarocks path yourself if this doesn't find it in the normal places
local luarocks = hs.execute("which luarocks"):gsub("\n", "")
if #luarocks > 0 then
package.path = package.path .. ";" .. hs.execute(
luarocks .. " --lua-version " .. lVer .. " path --lr-path"
):gsub("\n", "")
package.cpath = package.cpath .. ";" .. hs.execute(
luarocks .. " --lua-version " .. lVer .. " path --lr-cpath"
):gsub("\n", "")
end
local logger = require("hs.logger")
logger.historySize(10000)
logger.truncateID = "head"
logger.truncateIDWithEllipsis = true
uitk = require("hs._asm.uitk")
-- I do too much with developmental versions of HS -- I don't need
-- extraneous info in the Console application for every require; very
-- few of my crashes make it into Crashlytics anyways...
--
-- I don't recommend this unless you like doing your own troubleshooting
-- since it defeats some of the data captured for crash reports.
--
_asm = {}
_asm.hs_default_require = require
require = rawrequire
-- I link the Spoons dir to the primary repo's Source directory, so this is where I'll put in progress or
-- personal Spoons
package.path = hs.configdir .. "/_Spoons/?.spoon/init.lua;" .. package.path
-- override print so that it can render styled text objects directly in the console
-- this needs to happen before hs.ipc is loaded since it also overrides print for mirroring
local console = require("hs.console")
_asm.hs_default_print = print
print = console.printStyledtext
local requirePlus = require("utils.require")
local crash = require("hs.crash")
local window = require("hs.window")
local application = require("hs.application")
local timer = require("hs.timer")
local ipc = require("hs.ipc")
local image = require("hs.image")
local math = require("hs.math")
local settings = require("hs.settings")
local fs = require("hs.fs")
-- wrap these here so my personal modules see the wrapped versions
local _hsrelaunch = hs.relaunch
hs.relaunch = function(...)
local hspoon = application.applicationsForBundleID(hs.processInfo.bundleID)[1]
local conswin = hspoon:mainWindow()
if conswin and conswin:title() == "Hammerspoon Console" then
settings.set("openConsoleOnLoad", true)
local fr = conswin:frame()
-- stupid hs.geometry doesn't allow settings to serialize this properly
fr = { x = fr.x, y = fr.y, h = fr.h, w = fr.w }
settings.set("positionConsoleOnLoad", fr)
end
return _hsrelaunch(...)
end
local _hsreload = hs.reload
hs.reload = function(...)
local hspoon = application.applicationsForBundleID(hs.processInfo.bundleID)[1]
local conswin = hspoon:mainWindow()
if conswin and conswin:title() == "Hammerspoon Console" then
local fr = conswin:frame()
-- stupid hs.geometry doesn't allow settings to serialize this properly
fr = { x = fr.x, y = fr.y, h = fr.h, w = fr.w }
settings.set("positionConsoleOnLoad", fr)
end
return _hsreload(...)
end
-- something steals focus from an application which was focused before HS starts; capture that
-- window and then we'll switch back to it at the end
local fmW = window.frontmostWindow()
crash.crashLogToNSLog = true
-- local coreCrashLog = crash._crashLog
-- crash._crashLog = function(message, passAlong)
-- print("** " .. timestamp() .. " " .. message)
-- return coreCrashLog(message, passAlong)
-- end
crash.crashLog("Disabled require logging to make log file sane")
window.animationDuration = 0 -- I'm a philistine, sue me
ipc.cliInstall("/opt/amagill")
-- adjust hotkey logging... info as the default is too much.
require("hs.hotkey").setLogLevel("warning")
-- If something grows into usefulness, I'll modularize it.
_xtras = require("hs._asm.extras")
_xtras.launchNewBuild = function()
local full, dir, app = hs.processInfo.bundlePath:match("^((.+/)(.+%.app))$")
local zipFile = app:match("^(.+)%.app$") .. ".zip"
local srcZipFile = os.getenv("HOME") .. "/" .. zipFile
assert((fs.attributes(srcZipFile) or {}).mode == "file", srcZipFile .. " not found or wrong type")
local prevDir = fs.currentDir()
-- force return to original dir, even if we error out
local onClose <close> = setmetatable({}, { __close = function(_) fs.chdir(prevDir) end })
fs.chdir(dir)
assert(os.execute([[rm -f "]] .. zipFile .. [["]]), "Unable to remove previous " .. app .. " archive")
assert(os.execute([[zip -yqr "]] .. zipFile .. [[" "]] .. app .. [["]]), "Unable to archive current " .. app)
fs.chdir(os.getenv("HOME"))
assert(os.execute([[unzip "]] .. srcZipFile .. [["]]), "Unable to expand " .. srcZipFile)
os.execute([[
(while ps -p ]] .. hs.processInfo.processID .. [[ > /dev/null ; do
sleep 1
done
rm -fr "]] .. full .. [["
mv Hammerspoon.app "]] .. full .. [["
open -a "]] .. full .. [[" ) &
]])
local hspoon = application.applicationsForBundleID(hs.processInfo.bundleID)[1]
local conswin = hspoon:mainWindow()
if conswin then
settings.set("openConsoleOnLoad", true)
local fr = conswin:frame()
-- stupid hs.geometry doesn't allow settings to serialize this properly
fr = { x = fr.x, y = fr.y, h = fr.h, w = fr.w }
settings.set("positionConsoleOnLoad", fr)
end
hs._exit(true, true)
end
-- _asm.relaunch = function()
-- os.execute([[ (while ps -p ]]..hs.processInfo.processID..[[ > /dev/null ; do sleep 1 ; done ; open -a "]]..hs.processInfo.bundlePath..[[" ) & ]])
-- hs._exit(true, true)
-- end
_asm.hexstring2ascii = function(stuff)
stuff = stuff:lower():gsub("[<>\n\r ]+", ""):gsub("0x", "")
local result = ""
for k in stuff:gmatch("(..)") do result = result .. string.char(tonumber(k, 16)) end
return result
end
_asm._panels = requirePlus.requirePath("utils._panels")
_asm._keys = requirePlus.requirePath("utils._keys")
_asm._actions = requirePlus.requirePath("utils._actions")
_asm._menus = requirePlus.requirePath("utils._menus")
-- terminal shell equivalencies...
edit = function(where)
where = where or "."
os.execute("/usr/local/bin/bbedit "..where)
end
history = _asm._actions.consoleHistory.history
minimalHS = function()
settings.set("MJConfigFile", "~/.config/hammerspoon/_minimal/init.lua")
hs.relaunch()
end
-- preview = _asm._actions.quickPreview.preview
_asm.gc = require("utils.gc")
print()
print("++ Application Path: "..hs.processInfo.bundlePath)
print("++ Accessibility: "..tostring(hs.accessibilityState()))
if hs.processInfo.debugBuild then
local gitbranchfile = hs.processInfo.resourcePath .. "/gitbranch"
local gfile = io.open(gitbranchfile, "r")
if gfile then
GITBRANCH = gfile:read("l")
gfile:close()
else
GITBRANCH = "<" .. gitbranchfile .. " missing>"
end
print("++ Debug Version: " .. hs.processInfo.version .. ", " .. hs.processInfo.buildTime)
print("++ Build: " .. GITBRANCH)
else
print("++ Release Version: " .. hs.processInfo.version)
end
print()
require"hs.doc".preloadSpoonDocs()
hs.loadSpoon("AnyComplete")
spoon.AnyComplete:bindHotkeys{ toggle = { { "cmd", "alt", "ctrl" }, "g" } }
hs.loadSpoon("SleepCorners"):start()
hs.loadSpoon("BonjourLauncher"):start():addRecipes("SSH", "SMB", "AFP", "VNC_RealVNC_Alternate"):bindHotkeys{
toggle = { { "cmd", "alt", "ctrl" }, "=" },
toggle_SSH = { { "cmd", "alt", "ctrl" }, "s" },
toggle_HTTP = { { "cmd", "alt", "ctrl" }, "w" },
toggle_VNC = { { "cmd", "alt", "ctrl" }, "v" },
}
-- using ESP8266 with ESP-Link on some, my own code on others; ESP-Link advertises only one type; mine both
-- _http._tcp. and _arduino._tcp. but on differing ports; this captures the _arduino._tcp. entries and filters
-- out those that are on the default arduino OTA update port (or that haven't been resolved yet as -1 indicates
-- that the service is still being resolved) under the assumption that such an advertisement that uses a
-- different port is probably a web server... So far, this has held, but we'll see about future updates...
table.insert(spoon.BonjourLauncher.templates, {
image = hs.image.imageFromAppBundle("cc.arduino.Arduino"),
label = "Arduino",
type = "_arduino._tcp.",
text = "%name% (%txt:vendor %)",
subText = "http://%hostname%:%port%/%txt:path%",
url = "http://%hostname%:%port%/%txt:path%",
filter = function(svc) local p = svc:port() ; return (p ~= 8266) and (p ~= -1) end,
hidden = false,
})
-- if package.searchpath("EmmyLua", package.path) then
-- hs.loadSpoon("EmmyLua")
-- end
_objc = require("hs._asm.objc")
_hex = require("hs.utf8").hexDump
which = function(what)
local results = {}
for _,v in ipairs(package.searchers) do
local fn, where = v(tostring(what))
if type(fn) == "function" then table.insert(results, where) end
end
if #results == 0 then
return nil, tostring(what) .. " not found"
else
return table.unpack(results)
end
end
-- if set, restore console and its position, otherwise restore
-- last window before HS started...
local restoreTimer
if settings.get("openConsoleOnLoad") then
restoreTimer = timer.doAfter(math.minFloat, function()
hs.openConsole()
local prevFrame = settings.get("positionConsoleOnLoad")
if prevFrame then
local hspoon = application.applicationsForBundleID(hs.processInfo.bundleID)[1]
local conswin = hspoon:mainWindow()
if conswin then conswin:setFrame(prevFrame) end
end
settings.clear("openConsoleOnLoad")
settings.clear("positionConsoleOnLoad")
restoreTimer = nil
end)
else
-- refocus captured window from begining
restoreTimer = timer.doAfter(math.minFloat, function()
if fmW then fmW:focus() end
restoreTimer = nil
end)
end
hs.loadSpoon("FadeLogo"):start(.5)