-
Notifications
You must be signed in to change notification settings - Fork 167
Expand file tree
/
Copy pathinit.lua
More file actions
150 lines (130 loc) · 4.18 KB
/
init.lua
File metadata and controls
150 lines (130 loc) · 4.18 KB
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
--- === InputSourceSwitch ===
---
--- Automatically switch the input source when switching applications.
---
--- Example:
--- ```
--- hs.loadSpoon("InputSourceSwitch")
---
--- spoon.InputSourceSwitch:setApplications({
--- ["WeChat"] = "Pinyin - Simplified",
--- ["Mail"] = "ABC",
--- -- Use application watcher for apps that window filter can't capture
--- ["kitty-quick-access"] = { source = "ABC", watcher = "application" }
--- })
---
--- spoon.InputSourceSwitch:start()
--- ```
---
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/InputSourceSwitch.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/InputSourceSwitch.spoon.zip)
local obj = {}
obj.__index = obj
-- Metadata
obj.name = "InputSourceSwitch"
obj.version = "1.1"
obj.author = "eks5115 <eks5115@gmail.com>"
obj.homepage = "https://github.com/Hammerspoon/Spoons"
obj.license = "MIT - https://opensource.org/licenses/MIT"
local log = hs.logger.new('InputSourceSwitch','debug')
log.d('Init')
-- Internal function used to get enabled input sources
local function isLayout(layoutName)
local layouts = hs.keycodes.layouts()
for key, value in pairs(layouts) do
if (value == layoutName) then
return true
end
end
return false
end
local function isMethod(methodName)
local methods = hs.keycodes.methods()
for key, value in pairs(methods) do
if (value == methodName) then
return true
end
end
return false
end
local function switchInputSource(sourceName, appName)
local r = true
if (isLayout(sourceName)) then
r = hs.keycodes.setLayout(sourceName)
elseif isMethod(sourceName) then
r = hs.keycodes.setMethod(sourceName)
else
hs.alert.show(string.format('sourceName: %s is not layout or method', sourceName))
end
if (not r) then
hs.alert.show(string.format('set %s to %s failure', appName, sourceName))
end
end
local function setAppInputSourceWithWindowFilter(appName, sourceName, event)
event = event or hs.window.filter.windowFocused
hs.window.filter.new(appName):subscribe(event, function()
switchInputSource(sourceName, appName)
end)
end
local function setAppInputSourceWithAppWatcher(appName, sourceName)
local watcher = hs.application.watcher.new(function(name, eventType, appObj)
if eventType == hs.application.watcher.activated and name == appName then
switchInputSource(sourceName, appName)
end
end)
watcher:start()
return watcher
end
--- InputSourceSwitch.applicationMap
--- Variable
--- Mapping the application name to the input source
obj.applicationsMap = {}
-- Store application watchers to prevent garbage collection
obj.appWatchers = {}
--- InputSourceSwitch:setApplications()
--- Method
--- Set that mapping the application name to the input source
---
--- Parameters:
--- * applications - A table containing that mapping the application name to the input source
--- key is the application name
--- value can be:
--- - a string: the input source name (uses window filter, default)
--- - a table: { source = "input source name", watcher = "window" | "application" }
--- example:
--- ```
--- {
--- ["WeChat"] = "Pinyin - Simplified",
--- ["Mail"] = "ABC",
--- ["kitty-quick-access"] = { source = "ABC", watcher = "application" }
--- }
--- ```
function obj:setApplications(applications)
for key, value in pairs(applications) do
obj.applicationsMap[key] = value
end
end
--- InputSourceSwitch:start()
--- Method
--- Start InputSourceSwitch
---
--- Parameters:
--- * None
function obj:start()
for appName, config in pairs(self.applicationsMap) do
local sourceName, watcherType
if type(config) == "string" then
sourceName = config
watcherType = "window"
else
sourceName = config.source
watcherType = config.watcher or "window"
end
if watcherType == "application" then
self.appWatchers[appName] = setAppInputSourceWithAppWatcher(appName, sourceName)
else
setAppInputSourceWithWindowFilter(appName, sourceName)
end
end
return self
end
return obj