diff --git a/Spoons/BCSPresentation.spoon/init.lua b/Spoons/BCSPresentation.spoon/init.lua index 76cf6c8..d7512b0 100644 --- a/Spoons/BCSPresentation.spoon/init.lua +++ b/Spoons/BCSPresentation.spoon/init.lua @@ -1,3 +1,4 @@ +--↔ local obj = { __gc = true } setmetatable(obj, obj) obj.__gc = function(t) @@ -26,7 +27,8 @@ function obj:init() -- Create a menubar object to initiate the presentation self.presentationControl = hs.menubar.new() --presentationControl:setIcon(hs.image.imageFromName(hs.image.systemImageNames["EnterFullScreenTemplate"])) - self.presentationControl:setIcon(hs.image.imageFromName("NSComputer")) + --self.presentationControl:setIcon(hs.image.imageFromName("NSSecurity")) + self.presentationControl:setTitle("Presentation") self.presentationControl:setMenu({{ title = "Start Presentation", fn = obj.setupPresentation }}) end @@ -62,12 +64,22 @@ function obj.setDefaultFontSizes() obj.slideFooterSize = obj.screenFrame["h"] / 30 end +function obj.get_left_frame(percent) + local factor = percent/100 + local fakeBodyFrame = obj.get_body_frame(obj.screenFrame, 100) + local x = fakeBodyFrame["x"] + local y = obj.slideHeaderFrame["y"] + obj.slideHeaderFrame["h"] + 10 + local w = fakeBodyFrame["w"] * factor - 5 + local h = fakeBodyFrame["h"] + return {x=x, y=y, w=w, h=h} +end + function obj.get_right_frame(percent) local factor = percent/100 local fakeBodyFrame = obj.get_body_frame(obj.screenFrame, 100) - local x = fakeBodyFrame["x"] + (fakeBodyFrame["w"] *(1-factor)) + local x = fakeBodyFrame["x"] + (fakeBodyFrame["w"] *(1-factor)) + 5 local y = obj.slideHeaderFrame["y"] + obj.slideHeaderFrame["h"] + 10 - local w = fakeBodyFrame["w"] * factor + local w = fakeBodyFrame["w"] * factor - 5 local h = fakeBodyFrame["h"] return {x=x, y=y, w=w, h=h} end @@ -88,6 +100,8 @@ function obj.makecodeview(slideView, name, place, code, percent) codeViewRect = obj.get_right_frame(33) elseif place == "righthalf" then codeViewRect = obj.get_right_frame(50) + elseif place == "lefthalf" then + codeViewRect = obj.get_left_frame(50) elseif place == "body" then codeViewRect = obj.get_body_frame(obj.screenFrame, 100) end @@ -95,7 +109,7 @@ function obj.makecodeview(slideView, name, place, code, percent) slideView:appendElements({action="fill", type="rectangle", frame=codeViewRect, - fillColor=hs.drawing.color.x11.gainsboro}, + fillColor=hs.drawing.color.x11.white}, {action="fill", type="text", frame=codeViewRect, @@ -136,6 +150,8 @@ function obj.makewebview(name, place, url, html) webViewRect = obj.get_right_frame(33) elseif place == "righthalf" then webViewRect = obj.get_right_frame(50) + elseif place == "lefthalf" then + webViewRect = obj.get_left_frame(50) elseif place == "body" then webViewRect = obj.get_body_frame(obj.screenFrame, 100) end @@ -156,13 +172,17 @@ end -- Definitions of the slides obj.slides = { { - ["header"] = "Hammerspoon", + ["header"] = "Hammerspoon - Chris Jones", ["body"] = [[ • Ng on IRC • cmsj everywhere else • Work at Red Hat on OpenStack - • Do we have any Mac users present? - (this could be very boring if not!)]], + + + • Any Mac users in? + • Anyone used Objective C? + • Anyone used Lua? +]], ["enterFn"] = function() obj.makeimageview(obj.slideView, "hammerspoon", "righthalf", "hammerspoon.png") end, @@ -172,11 +192,11 @@ obj.slides = { ["header"] = "Agenda", ["body"] = [[We will cover: • A little Apple history - • Hammerspoon's birth - • How the app works - • Questions - - (the whole talk is a demo)]] + • How Hammerspoon came to exist + • What can it do? + • How Hammerspoon works + • Questions? +]], }, { ["header"] = "A little Apple history", @@ -187,92 +207,98 @@ obj.slides = { • 2007 - ScriptingBridge (OS X 10.5) Third party: - • 1991 onwards - AppleScript libraries, many utilities]] - }, - { - ["header"] = "AppleScript", - ["enterFn"] = function() - obj.makecodeview(obj.slideView, "appleScriptCodeView", "righthalf", [[tell application "Hammerspoon" - execute lua code "hs.reload()" -end tell - -tell application "Safari" - set currentURL to URL of document 1 -end tell -return currentURL]]) - end, - ["bodyWidth"] = 50, - ["body"] = [[ • Supposedly simple, natural language - • Very powerful despite its awful syntax - • High level messages passed to apps via Apple Events - • Apps expected to expose their functionality - • Apps can expose object hierarchies (e.g. a browser can expose page elements within tabs within windows)]] - }, - { - ["header"] = "Receiving AppleScript events", - ["enterFn"] = function() - obj.makecodeview(obj.slideView, "appleScriptCodeView", "righthalf", [[@implementation executeLua --(id)performDefaultImplementation { - // Get the arguments: - NSDictionary *args = [self evaluatedArguments]; - NSString *stringToExecute = [args valueForKey:@""]; - if (HSAppleScriptEnabled()) { - // Execute Lua Code: - return executeLua(self, stringToExecute); - } else { - // Raise AppleScript Error: - [self setScriptErrorNumber:-50]; - [self setScriptErrorString:someErrorMessage]; - return @"Error"; - } -} -@end]]) - end, - ["body"] = [[ • Application defines the commands it accepts (in this case "executeLua") in an XML "dictionary" - • Commands are mapped to Objective C interfaces (like protocols/traits in other languages) - • Foundation.framework calls the implementation method of the relevant interface - • Dictionaries can be browsed by the user using Script Editor.app]], - ["bodyWidth"] = 50 - }, - { - ["header"] = "How Hammerspoon came to exist: Motivation", - ["enterFn"] = function() - obj.makeimageview(obj.slideView, "keyboardMaestro", "righthalf", "keyboardmaestro.png") - end, - ["bodyWidth"] = 50, - ["body"] = [[ • I was using Keyboard Maestro to automate tasks - • Very powerful, can react to lots of system events - • Ideal for non-programmer power users - • As a programmer, became frustrated with graphical programming - • Not open source]] - }, - { - ["header"] = "How Hammerspoon came to exist: Circumstance", - ["body"] = [[ • Others also wanted something programmable - • First notable app was Slate (used JavaScript) - • Quickly went unmaintained, never really recovered - • Steven Degutis began a series of open source experiments - • Hydra, Phoenix, Penknife (used various languages) - • Culminated in Mjolnir, simple bridge between Lua and OS X]] + • 1991 onwards - AppleScript libraries, many utilities + • 2014 - Hammerspoon is forked from Mjolnir]] }, +-- { +-- ["header"] = "AppleScript", +-- ["enterFn"] = function() +-- obj.makecodeview(obj.slideView, "appleScriptCodeView", "righthalf", [[tell application "Hammerspoon" +-- execute lua code "hs.reload()" +-- end tell +-- +-- tell application "Safari" +-- set currentURL to URL of document 1 +-- end tell +-- return currentURL]]) +-- end, +-- ["bodyWidth"] = 50, +-- ["body"] = [[ • Supposedly simple, natural language +-- • Very powerful despite its awful syntax +-- • High level messages passed to apps via Apple Events +-- • Apps expected to expose their functionality +-- • Apps can expose object hierarchies (e.g. a browser can expose page elements within tabs within windows)]] +-- }, +-- { +-- ["header"] = "Receiving AppleScript events", +-- ["enterFn"] = function() +-- obj.makecodeview(obj.slideView, "appleScriptCodeView", "righthalf", [[@implementation executeLua +-- -(id)performDefaultImplementation { +-- // Get the arguments: +-- NSDictionary *args = [self evaluatedArguments]; +-- NSString *stringToExecute = [args valueForKey:@""]; +-- if (HSAppleScriptEnabled()) { +-- // Execute Lua Code: +-- return executeLua(self, stringToExecute); +-- } else { +-- // Raise AppleScript Error: +-- [self setScriptErrorNumber:-50]; +-- [self setScriptErrorString:someErrorMessage]; +-- return @"Error"; +-- } +-- } +-- @end]]) +-- end, +-- ["body"] = [[ • Application defines the commands it accepts (in this case "executeLua") in an XML "dictionary" +-- • Commands are mapped to Objective C interfaces (like protocols/traits in other languages) +-- • Foundation.framework calls the implementation method of the relevant interface +-- • Dictionaries can be browsed by the user using Script Editor.app]], +-- ["bodyWidth"] = 50 +-- }, +-- { +-- ["header"] = "How Hammerspoon came to exist: Motivation", +-- ["enterFn"] = function() +-- obj.makeimageview(obj.slideView, "keyboardMaestro", "righthalf", "keyboardmaestro.png") +-- end, +-- ["bodyWidth"] = 50, +-- ["body"] = [[ • I was using Keyboard Maestro to automate tasks +-- • Very powerful, can react to lots of system events +-- • Ideal for non-programmer power users +-- • As a programmer, became frustrated with graphical programming +-- • Not open source]] +-- }, +-- { +-- ["header"] = "How Hammerspoon came to exist: Circumstance", +-- ["body"] = [[ • Others also wanted something programmable +-- • First notable app was Slate (used JavaScript) +-- • Quickly went unmaintained, never really recovered +-- • Steven Degutis began a series of open source experiments +-- • Hydra, Phoenix, Penknife (used various languages) +-- • Culminated in Mjolnir, simple bridge between Lua and OS X]] +-- }, { ["header"] = "How Hammerspoon came to exist: The Fork", - ["body"] = [[ • Steven wanted to keep Mjolnir small and pure - • It didn't ship with any OS integrations + ["body"] = [[ • Mjolnir is a very simple Lua ↔ ObjC bridge + • Shipped with no OS integrations • They were supposed to be distributed separately • Small group of us disagreed and decided to fork in October 2014 • Aim was a "batteries included" automation app - • Started with ~15000 lines of code (13000 being Lua 5.2.3, 500 being integrations) - • Now have ~100000 lines of code (15000 being Lua 5.3.4, 37500 being integrations)]] + • Started with ~15000 lines of code (13000 being Lua) + • Now have ~100000 lines of code (37500 being OS integrations)]] }, { ["header"] = "So what can it do?", - ["body"] = [[• Window management -• Reacting to all kinds of events - • WiFi, USB, path/file changes, location, audio devices + ["body"] = [[• Reacting to all kinds of events + • WiFi, USB, path/file changes, + • Location, audio devices + • Keyboard/Mouse/Scroll inputs + • Application launch/hide/quit + • Battery, Screen, Speech +• Window management • Interacting with applications (menus) • Drawing custom interfaces on the screen -• HTTP client/server, raw socket client/server +• HTTP client/server +• Raw socket client/server • URL handling/mangling • MIDI, SQLite3, Timers, Processes, etc.]], ["enterFn"] = function() @@ -305,73 +331,228 @@ return currentURL]]) • Ripe for abstraction • Handles errors with setjmp/longjmp • We built "LuaSkin" + • Lua state lifecycle + • Argument checking + • Library/Object creation + • Lua ↔ ObjC type translation (including ObjC objects) + • Lua errors → ObjC exceptions ]], + }, +-- { +-- ["header"] = "Lua vs LuaSkin - Lifecycle", +-- ["enterFn"] = function() +-- obj.makecodeview(obj.slideView, "LuaVsLuaSkinILeft", "lefthalf", [[lua_State *createLua() { +-- lua_State *L = luaL_newstate(); +-- luaL_openlibs(); +-- luaL_loadfile(L, "~/.hammerspoon/init.lua"); +-- lua_pcall(L, 0, 0, 0); +-- return L; +--} +-- +--void destroyLua(lua_State *L) { +-- lua_close(L); +-- L = NULL; +--} +--]]) +-- obj.makecodeview(obj.slideView, "LuaVsLuaSkinIRight", "righthalf", [[LuaSkin *createLua() { +-- return [LuaSkin shared]; +--} +-- +--void destroyLua(LuaSkin *skin) { +-- [skin destroyLuaState]; +--} +--]]) +-- end, +-- }, + { + ["header"] = "Lua vs LuaSkin - Argument checking", ["enterFn"] = function() - obj.makecodeview(obj.slideView, "howDoesItWorkCodeView", "righthalf", [[luaL_Reg counterLib[] = { - {"increment", incrementCounter}, {NULL, NULL} -}; -void main() { - lua_State *L = luaL_newstate(); luaL_openlibs(); - luaL_newlib(L, counterLib); - fictionalEventLoop(); -} - -static int incrementCounter(lua_State *L) { - if (lua_type(L, 1) != LUA_TINTEGER) { - luaL_error(L, "increment requires an integer"); + obj.makecodeview(obj.slideView, "LuaVsLuaSkinArgCheckLeft", "lefthalf", [[static int foo(lua_State *L) { + if (lua_type(L, 1) != LUA_TINTEGER && \ + lua_type(L, 1) != LUA_TSTRING) { + luaL_error(L, "argument 1 must be an integer or a string"); + } + if (lua_type(L, 2) != LUA_TSTRING && \ + lua_type(L, 2) != LUA_TBOOLEAN) { + luaL_error(L, "argument 2 must be a string or a boolean"); } - int counter = lua_tointeger(L, 1); - counter++; - lua_pushinteger(L, counter); - return 1; -} +]]) + obj.makecodeview(obj.slideView, "LuaVsLuaSkinArgCheckRight", "righthalf", [[LuaSkin *skin = [LuaSkin shared]; +[skin argcheck:LS_TINTEGER|LS_TSTRING, LS_TSTRING|LS_TBOOLEAN, LS_TBREAK]; ]]) end, }, +-- { +-- ["header"] = "Lua vs LuaSkin - Library creation", +-- ["enterFn"] = function() +-- obj.makecodeview(obj.slideView, "LuaVsLuaSkinLibCreationLeft", "lefthalf", [[luaL_Reg lib[] = { +-- {"someUsefulThing", someCFunction}, +-- {NULL, NULL} +--}; +-- +--luaL_Reg lib_meta[] = { +-- {"__gc", someCleanupFunction}, +-- {NULL, NULL} +--}; +-- +--luaL_newlib(L, lib); +--luaL_newlib(L, lib_meta); +--lua_setmetatable(L, -2); +--]]) +-- obj.makecodeview(obj.slideView, "LuaVsLuaSkinLibCreationRight", "righthalf", [[luaL_Reg lib[] = { +-- {"someUsefulThing", someCFunction}, +-- {NULL, NULL} +--}; +-- +--luaL_Reg lib_meta[] = { +-- {"__gc", someCleanupFunction}, +-- {NULL, NULL} +--}; +-- +--LuaSkin *skin = [LuaSkin shared]; +--[skin registerLibrary:lib metaFunctions:lib_meta]; +--]]) +-- end, +-- }, { - ["header"] = "LuaSkin", - ["body"] = [[• Singleton for Lua state -• Lua state lifecycle -• Library creation -• Object creation -• Object Lua/ObjC glue -• Lua/ObjC type translation -• Lua errors → ObjC exceptions -• Standalone in theory]], + ["header"] = "Lua vs LuaSkin - Object creation", ["enterFn"] = function() - obj.makecodeview(obj.slideView, "luaSkinPart1", "righthalf", [[luaL_Reg lib[] = {{"new", new}, {NULL, NULL}}; -luaL_Reg obj[] = {{"inc", inc}, {NULL, NULL}}; -void main() { - LuaSkin *skin = [LuaSkin shared]; - [skin registerLibrary:lib metaFunctions:nil]; - [skin registerObject:"counter" objectFunctions:obj]; -} -static int new(lua_State *L) { - LuaSkin *skin = [LuaSkin shared]; - [skin checkArgs:LS_TINTEGER, LS_TBREAK]; - Counter *c = [SomeCounterClass newClass]; - c.value = lua_tointeger(L, 1); - [skin pushNSObject:c]; - return 1; -} -static int inc(lua_State *L) { - LuaSkin *skin = [LuaSkin shared]; - [skin checkArgs:LS_TUSERDATA, "counter", LS_TBREAK]; - Counter *c = get_object(Counter, L, 1, "counter"); - c.value++; - return 0; + obj.makecodeview(obj.slideView, "LuaVsLuaSkinObjCreationLeft", "lefthalf", [[luaL_Reg obj[] = { + {"methodA", someCFunction}, + {"methodB", otherCFunction}, + {NULL, NULL} +}; + +luaL_newlib(L, obj); +lua_pushvalue(L, -1); +lua_setfield(L, -2, "__index"); +lua_pushstring(L, "objectName"); +lua_setfield(L, -2, "__type"); +lua_pushstring(L, "objectName"); +lua_setfield(L, -2, "__name"); +lua_setfield(L, LUA_REGISTRYINDEX, "objectName"); +]]) + obj.makecodeview(obj.slideView, "LuaVsLuaSkinObjCreationRight", "righthalf", [[luaL_Reg obj[] = { + {"methodA", someCFunction}, + {"methodB", otherCFunction}, + {NULL, NULL} +}; + +LuaSkin *skin = [LuaSkin shared]; +[skin registerObject:"objectName" objectFunctions:obj]; +]]) + end + }, + { + ["header"] = "Lua vs LuaSkin - Type translation", + ["enterFn"] = function() + obj.makecodeview(obj.slideView, "LuaVsLuaSkinTypeTransLeft", "lefthalf", [[NSString *obj = @"hello world"; +size_t size = [obj lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; +lua_pushlstring(L, obj.UTF8String, size); + +NSString *foo = [NSString stringWithUTF8String:lua_tostring(L, 1)]; + +NSArray *list = @[@"hi", @(42), [SomeClass newClass] ]; +for (int i=0; i < list.allKeys; i++) { + id obj = [list objectAtIndex:i]; + + if ([obj isKindOfClass:[NSNull class] ]) + lua_pushnil(L); + else if ([obj isKindOfClass:[NSNumber class] ]) + lua_pushinteger(L, [(NSNumber *)obj intValue]); + else if ([obj isKindOfClass:[NSArray class] ]) { + // Oh no, we need to recurse + lua_pushSOMETHING(L, I_HATE_MY_LIFE); + } + // Repeat for every type of class and cry } ]]) - end, + obj.makecodeview(obj.slideView, "LuaVsLuaSkinTypeTransRight", "righthalf", [[NSString *obj = @"hello world"; +[skin pushNSObject:obj]; + +NSString *foo = [skin toNSObjectAtIndex:1]; + +NSArray *list = @[@"hi", @(42), [SomeClass newClass] ]; +[skin pushNSObject:list]; +]]) + end }, +-- { +-- ["header"] = "Lua vs LuaSkin Part 2", +-- ["exitFn"] = function() +-- local webview = obj.refs["LuaVsLuaSkinIILeft"] +-- webview:hide(0.1) +-- end, +-- ["enterFn"] = function() +-- local webview = obj.makewebview("LuaVsLuaSkinIILeft", "lefthalf", nil, [[ +--
luaL_Reg lib[] = {{"new", new}, {NULL, NULL}};
+-- luaL_Reg obj[] = {{"inc", inc}, {NULL, NULL}};
+-- void main() {
+--     lua_State *L = luaL_newstate(); luaL_openlibs();
+--     luaL_newlib(L, lib);
+--     luaL_newlib(L, obj);
+--     lua_pushvalue(L, -1);
+--     lua_setfield(L, -2, "__index");
+--     lua_setfield(L, LUA_REGISTRYINDEX, "counter");
+-- }
+-- static int new(lua_State *L) {
+--     if (lua_type(L, 1) != LUA_TINTEGER) {
+--         lua_pushnil(L);
+--         return;
+--     }
+--     int *c_ptr = lua_newuserdata(L, sizeof(int));
+--     *c_ptr = lua_tointeger(L, 1);
+--     luaL_getmetatable(L, "counter");
+--     lua_setmetatable(L, -2);
+--     return 1;
+-- }
+-- static int inc(lua_State *L) {
+--     luaL_checktype(L, 1, LUA_TUSERDATA);
+--     int *c_ptr = luaL_checkudata(L, 1, "counter");
+--     if (!c_ptr) luaL_typerror(L, 1, "counter");
+--     (*c_ptr)++;
+--     return 0;
+-- }
+-- 
]]) +-- webview:show(0.1) +-- obj.makecodeview(obj.slideView, "LuaVsLuaSkinIIRight", "righthalf", [[luaL_Reg lib[] = {{"new", new}, {NULL, NULL}}; +-- luaL_Reg obj[] = {{"inc", inc}, {NULL, NULL}}; +-- void main() { +-- LuaSkin *skin = [LuaSkin shared]; +-- [skin registerLibrary:lib metaFunctions:nil]; +-- [skin registerObject:"counter" objectFunctions:obj]; +-- } +-- static int new(lua_State *L) { +-- LuaSkin *skin = [LuaSkin shared]; +-- [skin checkArgs:LS_TINTEGER, LS_TBREAK]; +-- Counter *c = [SomeCounterClass newClass]; +-- c.value = lua_tointeger(L, 1); +-- [skin pushNSObject:c]; +-- return 1; +-- } +-- static int inc(lua_State *L) { +-- LuaSkin *skin = [LuaSkin shared]; +-- [skin checkArgs:LS_TUSERDATA, "counter", LS_TBREAK]; +-- Counter *c = get_object(Counter, L, 1, "counter"); +-- c.value++; +-- return 0; +-- } +-- ]]) +-- end, +-- }, { - ["header"] = "LuaSkin (real example)", + ["header"] = "LuaSkin - Custom object translation", ["enterFn"] = function() obj.makeimageview(obj.slideView, "streamdeck", "body", "streamdeck.jpg") end, }, { - ["header"] = "LuaSkin (real example)", + ["header"] = "LuaSkin - Custom object translation", ["enterFn"] = function() obj.makecodeview(obj.slideView, "luaSkinPart2", "body", [[ static int pushHSStreamDeckDevice(lua_State *L, id obj) { @@ -399,7 +580,7 @@ static id toHSStreamDeckDeviceFromLua(lua_State *L, int idx) { end, }, { - ["header"] = "LuaSkin (real example)", + ["header"] = "LuaSkin - Custom object translation", ["enterFn"] = function() obj.makecodeview(obj.slideView, "luaSkinPart3", "body", [[ static int streamdeck_setButtonImage(lua_State *L __unused) { @@ -413,11 +594,19 @@ static int streamdeck_setButtonImage(lua_State *L __unused) { lua_pushvalue(skin.L, 1); return 1; } - ]]) +]]) end, }, { - ["header"] = "Questions?" + ["header"] = "Questions?", + ["body"] = [[ + + +Resources: + • http://www.hammerspoon.org/ + • https://github.com/Hammerspoon/ + • #hammerspoon on Freenode +]], } } @@ -457,7 +646,6 @@ function obj:renderSlide(slideNum) if self.slideView:elementCount() > self.numDefaultElements then print("Removing "..(self.slideView:elementCount() - self.numDefaultElements).." elements") for i=self.numDefaultElements+1,self.slideView:elementCount() do - print(".") self.slideView:removeElement(self.numDefaultElements + 1) end end diff --git a/Spoons/Seal.spoon/docs.json b/Spoons/Seal.spoon/docs.json index 7a5078e..c9408a2 100644 --- a/Spoons/Seal.spoon/docs.json +++ b/Spoons/Seal.spoon/docs.json @@ -1,528 +1,870 @@ [ { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [ + "Constant" : [ + + ], + "submodules" : [ + "plugins" + ], + "Function" : [ + + ], + "Variable" : [ { - "def": "Seal:bindHotkeys(mapping)", - "desc": "Binds hotkeys for Seal", - "doc": "Binds hotkeys for Seal\n\nParameters:\n * mapping - A table containing hotkey modifier/key details for the following (optional) items:\n * show - This will cause Seal's UI to be shown\n * toggle - This will cause Seal's UI to be shown or hidden depending on its current state\n\nReturns:\n * The Seal object", - "name": "bindHotkeys", - "parameters": [ - " * mapping - A table containing hotkey modifier/key details for the following (optional) items:", - " * show - This will cause Seal's UI to be shown", - " * toggle - This will cause Seal's UI to be shown or hidden depending on its current state" - ], - "returns": [ + "name" : "plugin_search_paths", + "desc" : "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory.", + "stripped_doc" : [ + "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory." + ], + "doc" : "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory.", + "notes" : [ + + ], + "signature" : "Seal.plugin_search_paths", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugin_search_paths", + "parameters" : [ + + ] + } + ], + "stripped_doc" : [ + + ], + "Deprecated" : [ + + ], + "desc" : "Pluggable launch bar", + "type" : "Module", + "Constructor" : [ + + ], + "items" : [ + { + "name" : "plugin_search_paths", + "desc" : "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory.", + "stripped_doc" : [ + "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory." + ], + "doc" : "List of directories where Seal will look for plugins. Defaults to `~\/.hammerspoon\/seal_plugins\/` and the Seal Spoon directory.", + "notes" : [ + + ], + "signature" : "Seal.plugin_search_paths", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugin_search_paths", + "parameters" : [ + + ] + }, + { + "name" : "bindHotkeys", + "desc" : "Binds hotkeys for Seal", + "stripped_doc" : [ + "Binds hotkeys for Seal", + "" + ], + "doc" : "Binds hotkeys for Seal\n\nParameters:\n * mapping - A table containing hotkey modifier\/key details for the following (optional) items:\n * show - This will cause Seal's UI to be shown\n * toggle - This will cause Seal's UI to be shown or hidden depending on its current state\n\nReturns:\n * The Seal object", + "notes" : [ + + ], + "signature" : "Seal:bindHotkeys(mapping)", + "type" : "Method", + "returns" : [ " * The Seal object" ], - "signature": "Seal:bindHotkeys(mapping)", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:bindHotkeys(mapping)", + "parameters" : [ + " * mapping - A table containing hotkey modifier\/key details for the following (optional) items:", + " * show - This will cause Seal's UI to be shown", + " * toggle - This will cause Seal's UI to be shown or hidden depending on its current state", + "" + ] }, { - "def": "Seal:loadPluginFromFile(plugin_name, file)", - "desc": "Loads a plugin from a given file", - "doc": "Loads a plugin from a given file\n\nParameters:\n * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end\n * file - the file where the plugin code is stored.\n\nReturns:\n * The Seal object if the plugin was successfully loaded, `nil` otherwise\n\nNotes:\n * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins\n from non-standard locations and is mostly a development interface.\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", - "name": "loadPluginFromFile", - "notes": [ + "name" : "loadPluginFromFile", + "desc" : "Loads a plugin from a given file", + "stripped_doc" : [ + "Loads a plugin from a given file", + "" + ], + "doc" : "Loads a plugin from a given file\n\nParameters:\n * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end\n * file - the file where the plugin code is stored.\n\nReturns:\n * The Seal object if the plugin was successfully loaded, `nil` otherwise\n\nNotes:\n * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins\n from non-standard locations and is mostly a development interface.\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", + "notes" : [ " * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins", " from non-standard locations and is mostly a development interface.", " * Some plugins may immediately begin doing background work (e.g. Spotlight searches)" ], - "parameters": [ - " * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end", - " * file - the file where the plugin code is stored." - ], - "returns": [ - " * The Seal object if the plugin was successfully loaded, `nil` otherwise" + "signature" : "Seal:loadPluginFromFile(plugin_name, file)", + "type" : "Method", + "returns" : [ + " * The Seal object if the plugin was successfully loaded, `nil` otherwise", + "" ], - "signature": "Seal:loadPluginFromFile(plugin_name, file)", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:loadPluginFromFile(plugin_name, file)", + "parameters" : [ + " * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end", + " * file - the file where the plugin code is stored.", + "" + ] }, { - "def": "Seal:loadPlugins(plugins)", - "desc": "Loads a list of Seal plugins", - "doc": "Loads a list of Seal plugins\n\nParameters:\n * plugins - A list containing the names of plugins to load\n\nReturns:\n * The Seal object\n\nNotes:\n * The plugins live inside the Seal.spoon directory\n * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", - "name": "loadPlugins", - "notes": [ + "name" : "loadPlugins", + "desc" : "Loads a list of Seal plugins", + "stripped_doc" : [ + "Loads a list of Seal plugins", + "" + ], + "doc" : "Loads a list of Seal plugins\n\nParameters:\n * plugins - A list containing the names of plugins to load\n\nReturns:\n * The Seal object\n\nNotes:\n * The plugins live inside the Seal.spoon directory\n * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", + "notes" : [ " * The plugins live inside the Seal.spoon directory", " * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end", " * Some plugins may immediately begin doing background work (e.g. Spotlight searches)" ], - "parameters": [ - " * plugins - A list containing the names of plugins to load" - ], - "returns": [ - " * The Seal object" - ], - "signature": "Seal:loadPlugins(plugins)", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:loadPlugins(plugins)", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:loadPlugins(plugins)", + "parameters" : [ + " * plugins - A list containing the names of plugins to load", + "" + ] }, { - "def": "Seal:refreshAllCommands()", - "desc": "Refresh the list of commands provided by all the currently loaded plugins.", - "doc": "Refresh the list of commands provided by all the currently loaded plugins.\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", - "name": "refreshAllCommands", - "notes": [ + "name" : "refreshAllCommands", + "desc" : "Refresh the list of commands provided by all the currently loaded plugins.", + "stripped_doc" : [ + "Refresh the list of commands provided by all the currently loaded plugins.", + "" + ], + "doc" : "Refresh the list of commands provided by all the currently loaded plugins.\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", + "notes" : [ " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." ], - "parameters": [ - " * None" - ], - "returns": [ - " * The Seal object" - ], - "signature": "Seal:refreshAllCommands()", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:refreshAllCommands()", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:refreshAllCommands()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:refreshCommandsForPlugin(plugin_name)", - "desc": "Refresh the list of commands provided by the given plugin.", - "doc": "Refresh the list of commands provided by the given plugin.\n\nParameters:\n * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", - "name": "refreshCommandsForPlugin", - "notes": [ + "name" : "refreshCommandsForPlugin", + "desc" : "Refresh the list of commands provided by the given plugin.", + "stripped_doc" : [ + "Refresh the list of commands provided by the given plugin.", + "" + ], + "doc" : "Refresh the list of commands provided by the given plugin.\n\nParameters:\n * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", + "notes" : [ " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." ], - "parameters": [ - " * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`." - ], - "returns": [ - " * The Seal object" - ], - "signature": "Seal:refreshCommandsForPlugin(plugin_name)", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:refreshCommandsForPlugin(plugin_name)", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:refreshCommandsForPlugin(plugin_name)", + "parameters" : [ + " * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.", + "" + ] }, { - "def": "Seal:show()", - "desc": "Shows the Seal UI", - "doc": "Shows the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None\n\nNotes:\n * This may be useful if you wish to show Seal in response to something other than its hotkey", - "name": "show", - "notes": [ + "name" : "show", + "desc" : "Shows the Seal UI", + "stripped_doc" : [ + "Shows the Seal UI", + "" + ], + "doc" : "Shows the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None\n\nNotes:\n * This may be useful if you wish to show Seal in response to something other than its hotkey", + "notes" : [ " * This may be useful if you wish to show Seal in response to something other than its hotkey" ], - "parameters": [ - " * None" - ], - "returns": [ - " * None" - ], - "signature": "Seal:show()", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:show()", + "type" : "Method", + "returns" : [ + " * None", + "" + ], + "def" : "Seal:show()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:start()", - "desc": "Starts Seal", - "doc": "Starts Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object", - "name": "start", - "parameters": [ - " * None" - ], - "returns": [ + "name" : "start", + "desc" : "Starts Seal", + "stripped_doc" : [ + "Starts Seal", + "" + ], + "doc" : "Starts Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object", + "notes" : [ + + ], + "signature" : "Seal:start()", + "type" : "Method", + "returns" : [ " * The Seal object" ], - "signature": "Seal:start()", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:start()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:stop()", - "desc": "Stops Seal", - "doc": "Stops Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)", - "name": "stop", - "notes": [ + "name" : "stop", + "desc" : "Stops Seal", + "stripped_doc" : [ + "Stops Seal", + "" + ], + "doc" : "Stops Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)", + "notes" : [ " * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)" ], - "parameters": [ - " * None" - ], - "returns": [ - " * The Seal object" - ], - "signature": "Seal:stop()", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:stop()", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:stop()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:toggle()", - "desc": "Shows or hides the Seal UI", - "doc": "Shows or hides the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None", - "name": "toggle", - "parameters": [ + "name" : "toggle", + "desc" : "Shows or hides the Seal UI", + "stripped_doc" : [ + "Shows or hides the Seal UI", + "" + ], + "doc" : "Shows or hides the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None", + "notes" : [ + + ], + "signature" : "Seal:toggle()", + "type" : "Method", + "returns" : [ " * None" ], - "returns": [ - " * None" - ], - "signature": "Seal:toggle()", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:toggle()", + "parameters" : [ + " * None", + "" + ] } ], - "Variable": [ + "Method" : [ { - "def": "Seal.plugin_search_paths", - "desc": "List of directories where Seal will look for plugins. Defaults to `~/.hammerspoon/seal_plugins/` and the Seal Spoon directory.", - "doc": "List of directories where Seal will look for plugins. Defaults to `~/.hammerspoon/seal_plugins/` and the Seal Spoon directory.", - "name": "plugin_search_paths", - "signature": "Seal.plugin_search_paths", - "stripped_doc": "", - "type": "Variable" - } - ], - "desc": "Pluggable launch bar", - "doc": "Pluggable launch bar\n\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/Seal.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/Seal.spoon.zip)\n\nSeal includes a number of plugins, which you can choose to load (see `:loadPlugins()` below):\n * apps : Launch applications by name\n * safari_bookmarks : Open Safari bookmarks (this is broken since at least High Sierra)\n * calc : Simple calculator\n * vpn : Connect and disconnect VPNs (currently supports Viscosity and macOS system preferences)A\n * useractions : User defined custom actions\n * screencapture : Lets you take screenshots in various ways\n * urlformats : User defined URL formats to open", - "items": [ - { - "def": "Seal:bindHotkeys(mapping)", - "desc": "Binds hotkeys for Seal", - "doc": "Binds hotkeys for Seal\n\nParameters:\n * mapping - A table containing hotkey modifier/key details for the following (optional) items:\n * show - This will cause Seal's UI to be shown\n * toggle - This will cause Seal's UI to be shown or hidden depending on its current state\n\nReturns:\n * The Seal object", - "name": "bindHotkeys", - "parameters": [ - " * mapping - A table containing hotkey modifier/key details for the following (optional) items:", - " * show - This will cause Seal's UI to be shown", - " * toggle - This will cause Seal's UI to be shown or hidden depending on its current state" + "name" : "refreshCommandsForPlugin", + "desc" : "Refresh the list of commands provided by the given plugin.", + "stripped_doc" : [ + "Refresh the list of commands provided by the given plugin.", + "" + ], + "doc" : "Refresh the list of commands provided by the given plugin.\n\nParameters:\n * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", + "notes" : [ + " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." ], - "returns": [ - " * The Seal object" + "signature" : "Seal:refreshCommandsForPlugin(plugin_name)", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:refreshCommandsForPlugin(plugin_name)", + "parameters" : [ + " * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.", + "" + ] + }, + { + "name" : "refreshAllCommands", + "desc" : "Refresh the list of commands provided by all the currently loaded plugins.", + "stripped_doc" : [ + "Refresh the list of commands provided by all the currently loaded plugins.", + "" + ], + "doc" : "Refresh the list of commands provided by all the currently loaded plugins.\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", + "notes" : [ + " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." ], - "signature": "Seal:bindHotkeys(mapping)", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:refreshAllCommands()", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:refreshAllCommands()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:loadPluginFromFile(plugin_name, file)", - "desc": "Loads a plugin from a given file", - "doc": "Loads a plugin from a given file\n\nParameters:\n * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end\n * file - the file where the plugin code is stored.\n\nReturns:\n * The Seal object if the plugin was successfully loaded, `nil` otherwise\n\nNotes:\n * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins\n from non-standard locations and is mostly a development interface.\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", - "name": "loadPluginFromFile", - "notes": [ + "name" : "loadPluginFromFile", + "desc" : "Loads a plugin from a given file", + "stripped_doc" : [ + "Loads a plugin from a given file", + "" + ], + "doc" : "Loads a plugin from a given file\n\nParameters:\n * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end\n * file - the file where the plugin code is stored.\n\nReturns:\n * The Seal object if the plugin was successfully loaded, `nil` otherwise\n\nNotes:\n * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins\n from non-standard locations and is mostly a development interface.\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", + "notes" : [ " * You should normally use `Seal:loadPlugins()`. This method allows you to load plugins", " from non-standard locations and is mostly a development interface.", " * Some plugins may immediately begin doing background work (e.g. Spotlight searches)" ], - "parameters": [ - " * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end", - " * file - the file where the plugin code is stored." + "signature" : "Seal:loadPluginFromFile(plugin_name, file)", + "type" : "Method", + "returns" : [ + " * The Seal object if the plugin was successfully loaded, `nil` otherwise", + "" ], - "returns": [ - " * The Seal object if the plugin was successfully loaded, `nil` otherwise" - ], - "signature": "Seal:loadPluginFromFile(plugin_name, file)", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:loadPluginFromFile(plugin_name, file)", + "parameters" : [ + " * plugin_name - the name of the plugin, without \"seal_\" at the beginning or \".lua\" at the end", + " * file - the file where the plugin code is stored.", + "" + ] }, { - "def": "Seal:loadPlugins(plugins)", - "desc": "Loads a list of Seal plugins", - "doc": "Loads a list of Seal plugins\n\nParameters:\n * plugins - A list containing the names of plugins to load\n\nReturns:\n * The Seal object\n\nNotes:\n * The plugins live inside the Seal.spoon directory\n * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", - "name": "loadPlugins", - "notes": [ + "name" : "loadPlugins", + "desc" : "Loads a list of Seal plugins", + "stripped_doc" : [ + "Loads a list of Seal plugins", + "" + ], + "doc" : "Loads a list of Seal plugins\n\nParameters:\n * plugins - A list containing the names of plugins to load\n\nReturns:\n * The Seal object\n\nNotes:\n * The plugins live inside the Seal.spoon directory\n * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end\n * Some plugins may immediately begin doing background work (e.g. Spotlight searches)", + "notes" : [ " * The plugins live inside the Seal.spoon directory", " * The plugin names in the list, should not have `seal_` at the start, or `.lua` at the end", " * Some plugins may immediately begin doing background work (e.g. Spotlight searches)" ], - "parameters": [ - " * plugins - A list containing the names of plugins to load" - ], - "returns": [ - " * The Seal object" - ], - "signature": "Seal:loadPlugins(plugins)", - "stripped_doc": "", - "type": "Method" - }, - { - "def": "Seal.plugin_search_paths", - "desc": "List of directories where Seal will look for plugins. Defaults to `~/.hammerspoon/seal_plugins/` and the Seal Spoon directory.", - "doc": "List of directories where Seal will look for plugins. Defaults to `~/.hammerspoon/seal_plugins/` and the Seal Spoon directory.", - "name": "plugin_search_paths", - "signature": "Seal.plugin_search_paths", - "stripped_doc": "", - "type": "Variable" + "signature" : "Seal:loadPlugins(plugins)", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:loadPlugins(plugins)", + "parameters" : [ + " * plugins - A list containing the names of plugins to load", + "" + ] }, { - "def": "Seal:refreshAllCommands()", - "desc": "Refresh the list of commands provided by all the currently loaded plugins.", - "doc": "Refresh the list of commands provided by all the currently loaded plugins.\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", - "name": "refreshAllCommands", - "notes": [ - " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." - ], - "parameters": [ - " * None" - ], - "returns": [ + "name" : "bindHotkeys", + "desc" : "Binds hotkeys for Seal", + "stripped_doc" : [ + "Binds hotkeys for Seal", + "" + ], + "doc" : "Binds hotkeys for Seal\n\nParameters:\n * mapping - A table containing hotkey modifier\/key details for the following (optional) items:\n * show - This will cause Seal's UI to be shown\n * toggle - This will cause Seal's UI to be shown or hidden depending on its current state\n\nReturns:\n * The Seal object", + "notes" : [ + + ], + "signature" : "Seal:bindHotkeys(mapping)", + "type" : "Method", + "returns" : [ " * The Seal object" ], - "signature": "Seal:refreshAllCommands()", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:bindHotkeys(mapping)", + "parameters" : [ + " * mapping - A table containing hotkey modifier\/key details for the following (optional) items:", + " * show - This will cause Seal's UI to be shown", + " * toggle - This will cause Seal's UI to be shown or hidden depending on its current state", + "" + ] }, { - "def": "Seal:refreshCommandsForPlugin(plugin_name)", - "desc": "Refresh the list of commands provided by the given plugin.", - "doc": "Refresh the list of commands provided by the given plugin.\n\nParameters:\n * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`.\n\nReturns:\n * The Seal object\n\nNotes:\n * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands.", - "name": "refreshCommandsForPlugin", - "notes": [ - " * Most Seal plugins expose a static list of commands (if any), which are registered at the time the plugin is loaded. This method is used for plugins which expose a dynamic or changing (e.g. depending on configuration) list of commands." - ], - "parameters": [ - " * plugin_name - the name of the plugin. Should be the name as passed to `loadPlugins()` or `loadPluginFromFile`." - ], - "returns": [ + "name" : "start", + "desc" : "Starts Seal", + "stripped_doc" : [ + "Starts Seal", + "" + ], + "doc" : "Starts Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object", + "notes" : [ + + ], + "signature" : "Seal:start()", + "type" : "Method", + "returns" : [ " * The Seal object" ], - "signature": "Seal:refreshCommandsForPlugin(plugin_name)", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:start()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:show()", - "desc": "Shows the Seal UI", - "doc": "Shows the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None\n\nNotes:\n * This may be useful if you wish to show Seal in response to something other than its hotkey", - "name": "show", - "notes": [ - " * This may be useful if you wish to show Seal in response to something other than its hotkey" - ], - "parameters": [ - " * None" - ], - "returns": [ - " * None" - ], - "signature": "Seal:show()", - "stripped_doc": "", - "type": "Method" - }, - { - "def": "Seal:start()", - "desc": "Starts Seal", - "doc": "Starts Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object", - "name": "start", - "parameters": [ - " * None" - ], - "returns": [ - " * The Seal object" + "name" : "stop", + "desc" : "Stops Seal", + "stripped_doc" : [ + "Stops Seal", + "" + ], + "doc" : "Stops Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)", + "notes" : [ + " * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)" ], - "signature": "Seal:start()", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:stop()", + "type" : "Method", + "returns" : [ + " * The Seal object", + "" + ], + "def" : "Seal:stop()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:stop()", - "desc": "Stops Seal", - "doc": "Stops Seal\n\nParameters:\n * None\n\nReturns:\n * The Seal object\n\nNotes:\n * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)", - "name": "stop", - "notes": [ - " * Some Seal plugins will continue performing background work even after this call (e.g. Spotlight searches)" - ], - "parameters": [ - " * None" - ], - "returns": [ - " * The Seal object" + "name" : "show", + "desc" : "Shows the Seal UI", + "stripped_doc" : [ + "Shows the Seal UI", + "" + ], + "doc" : "Shows the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None\n\nNotes:\n * This may be useful if you wish to show Seal in response to something other than its hotkey", + "notes" : [ + " * This may be useful if you wish to show Seal in response to something other than its hotkey" ], - "signature": "Seal:stop()", - "stripped_doc": "", - "type": "Method" + "signature" : "Seal:show()", + "type" : "Method", + "returns" : [ + " * None", + "" + ], + "def" : "Seal:show()", + "parameters" : [ + " * None", + "" + ] }, { - "def": "Seal:toggle()", - "desc": "Shows or hides the Seal UI", - "doc": "Shows or hides the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None", - "name": "toggle", - "parameters": [ + "name" : "toggle", + "desc" : "Shows or hides the Seal UI", + "stripped_doc" : [ + "Shows or hides the Seal UI", + "" + ], + "doc" : "Shows or hides the Seal UI\n\nParameters:\n * None\n\nReturns:\n * None", + "notes" : [ + + ], + "signature" : "Seal:toggle()", + "type" : "Method", + "returns" : [ " * None" ], - "returns": [ - " * None" - ], - "signature": "Seal:toggle()", - "stripped_doc": "", - "type": "Method" + "def" : "Seal:toggle()", + "parameters" : [ + " * None", + "" + ] } ], - "name": "Seal", - "stripped_doc": "\nDownload: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/Seal.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/Seal.spoon.zip)\n\nSeal includes a number of plugins, which you can choose to load (see `:loadPlugins()` below):\n * apps : Launch applications by name\n * safari_bookmarks : Open Safari bookmarks (this is broken since at least High Sierra)\n * calc : Simple calculator\n * vpn : Connect and disconnect VPNs (currently supports Viscosity and macOS system preferences)A\n * useractions : User defined custom actions\n * screencapture : Lets you take screenshots in various ways\n * urlformats : User defined URL formats to open", - "submodules": [ - "plugins" + "doc" : "Pluggable launch bar\n\nDownload: [https:\/\/github.com\/Hammerspoon\/Spoons\/raw\/master\/Spoons\/Seal.spoon.zip](https:\/\/github.com\/Hammerspoon\/Spoons\/raw\/master\/Spoons\/Seal.spoon.zip)\n\nSeal includes a number of plugins, which you can choose to load (see `:loadPlugins()` below):\n * apps : Launch applications by name\n * safari_bookmarks : Open Safari bookmarks (this is broken since at least High Sierra)\n * calc : Simple calculator\n * vpn : Connect and disconnect VPNs (currently supports Viscosity and macOS system preferences)A\n * useractions : User defined custom actions\n * screencapture : Lets you take screenshots in various ways\n * urlformats : User defined URL formats to open", + "Field" : [ + + ], + "Command" : [ + ], - "type": "Module" + "name" : "Seal" }, { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [], - "Variable": [ + "Constant" : [ + + ], + "submodules" : [ + "urlformats", + "useractions" + ], + "Function" : [ + + ], + "Variable" : [ { - "def": "Seal.plugins.safari_bookmarks.always_open_with_safari", - "desc": "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `/usr/bin/open` command.", - "doc": "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `/usr/bin/open` command.", - "name": "always_open_with_safari", - "signature": "Seal.plugins.safari_bookmarks.always_open_with_safari", - "stripped_doc": "", - "type": "Variable" + "name" : "safari_bookmarks", + "desc" : "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command.", + "stripped_doc" : [ + "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command." + ], + "doc" : "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command.", + "notes" : [ + + ], + "signature" : "Seal.plugins.safari_bookmarks.always_open_with_safari", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.safari_bookmarks.always_open_with_safari", + "parameters" : [ + + ] } ], - "desc": "Various APIs for Seal plugins", - "doc": "Various APIs for Seal plugins", - "items": [ + "stripped_doc" : [ + + ], + "Deprecated" : [ + + ], + "desc" : "Various APIs for Seal plugins", + "type" : "Module", + "Constructor" : [ + + ], + "items" : [ { - "def": "Seal.plugins.safari_bookmarks.always_open_with_safari", - "desc": "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `/usr/bin/open` command.", - "doc": "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `/usr/bin/open` command.", - "name": "always_open_with_safari", - "signature": "Seal.plugins.safari_bookmarks.always_open_with_safari", - "stripped_doc": "", - "type": "Variable" + "name" : "safari_bookmarks", + "desc" : "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command.", + "stripped_doc" : [ + "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command." + ], + "doc" : "If `true` (default), bookmarks are always opened with Safari, otherwise they are opened with the default application using the `\/usr\/bin\/open` command.", + "notes" : [ + + ], + "signature" : "Seal.plugins.safari_bookmarks.always_open_with_safari", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.safari_bookmarks.always_open_with_safari", + "parameters" : [ + + ] } ], - "name": "Seal.plugins", - "stripped_doc": "", - "submodules": [ - "urlformats", - "useractions" + "Method" : [ + + ], + "doc" : "Various APIs for Seal plugins", + "Field" : [ + + ], + "Command" : [ + ], - "type": "Module" + "name" : "Seal.plugins" }, { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [ + "Constant" : [ + + ], + "submodules" : [ + + ], + "Function" : [ + + ], + "Variable" : [ + + ], + "stripped_doc" : [ + + ], + "Deprecated" : [ + + ], + "desc" : "A plugin to quickly open URLs containing a search\/query term", + "type" : "Module", + "Constructor" : [ + + ], + "items" : [ { - "def": "Seal.plugins.urlformats:providersTable(aTable)", - "desc": "Gets or sets the current providers table", - "doc": "Gets or sets the current providers table\n\nParameters:\n * aTable - An optional table of providers, which must contain the following keys:\n * name - A string naming the provider, which will be shown in the Seal results\n * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`\n\nReturns:\n * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.\n\nNotes:\n * An example table might look like:\n```lua\n{\n rhbz = { name = \"Red Hat Bugzilla\", url = \"https://bugzilla.redhat.com/show_bug.cgi?id=%s\", },\n lp = { name = \"Launchpad Bug\", url = \"https://launchpad.net/bugs/%s\", },\n}\n```", - "name": "providersTable", - "notes": [ + "name" : "providersTable", + "desc" : "Gets or sets the current providers table", + "stripped_doc" : [ + "Gets or sets the current providers table", + "" + ], + "doc" : "Gets or sets the current providers table\n\nParameters:\n * aTable - An optional table of providers, which must contain the following keys:\n * name - A string naming the provider, which will be shown in the Seal results\n * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`\n\nReturns:\n * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.\n\nNotes:\n * An example table might look like:\n```lua\n{\n rhbz = { name = \"Red Hat Bugzilla\", url = \"https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=%s\", },\n lp = { name = \"Launchpad Bug\", url = \"https:\/\/launchpad.net\/bugs\/%s\", },\n}\n```", + "notes" : [ " * An example table might look like:", "```lua", "{", - " rhbz = { name = \"Red Hat Bugzilla\", url = \"https://bugzilla.redhat.com/show_bug.cgi?id=%s\", },", - " lp = { name = \"Launchpad Bug\", url = \"https://launchpad.net/bugs/%s\", },", + " rhbz = { name = \"Red Hat Bugzilla\", url = \"https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=%s\", },", + " lp = { name = \"Launchpad Bug\", url = \"https:\/\/launchpad.net\/bugs\/%s\", },", "}", "```" ], - "parameters": [ + "signature" : "Seal.plugins.urlformats:providersTable(aTable)", + "type" : "Method", + "returns" : [ + " * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.", + "" + ], + "def" : "Seal.plugins.urlformats:providersTable(aTable)", + "parameters" : [ " * aTable - An optional table of providers, which must contain the following keys:", " * name - A string naming the provider, which will be shown in the Seal results", - " * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`" - ], - "returns": [ - " * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed." - ], - "signature": "Seal.plugins.urlformats:providersTable(aTable)", - "stripped_doc": "", - "type": "Method" + " * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`", + "" + ] } ], - "Variable": [], - "desc": "A plugin to quickly open URLs containing a search/query term", - "doc": "A plugin to quickly open URLs containing a search/query term\nThis plugin is invoked with the `uf` keyword and requires some configuration, see `:providersTable()`\n\nThe way this works is by defining a set of providers, each of which contains a URL with a `%s` somewhere insert it.\nWhen the user types `uf` in Seal, followed by some more characters, those characters will be inserted into the string at the point where the `%s` is.\n\nBy way of an example, you could define a provider with a url like `http://bugs.mycorp.com/showBug?id=%s`, and just need to type `uf 123456` in Seal to get a quick shortcut to open the full URL.", - "items": [ + "Method" : [ { - "def": "Seal.plugins.urlformats:providersTable(aTable)", - "desc": "Gets or sets the current providers table", - "doc": "Gets or sets the current providers table\n\nParameters:\n * aTable - An optional table of providers, which must contain the following keys:\n * name - A string naming the provider, which will be shown in the Seal results\n * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`\n\nReturns:\n * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.\n\nNotes:\n * An example table might look like:\n```lua\n{\n rhbz = { name = \"Red Hat Bugzilla\", url = \"https://bugzilla.redhat.com/show_bug.cgi?id=%s\", },\n lp = { name = \"Launchpad Bug\", url = \"https://launchpad.net/bugs/%s\", },\n}\n```", - "name": "providersTable", - "notes": [ + "name" : "providersTable", + "desc" : "Gets or sets the current providers table", + "stripped_doc" : [ + "Gets or sets the current providers table", + "" + ], + "doc" : "Gets or sets the current providers table\n\nParameters:\n * aTable - An optional table of providers, which must contain the following keys:\n * name - A string naming the provider, which will be shown in the Seal results\n * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`\n\nReturns:\n * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.\n\nNotes:\n * An example table might look like:\n```lua\n{\n rhbz = { name = \"Red Hat Bugzilla\", url = \"https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=%s\", },\n lp = { name = \"Launchpad Bug\", url = \"https:\/\/launchpad.net\/bugs\/%s\", },\n}\n```", + "notes" : [ " * An example table might look like:", "```lua", "{", - " rhbz = { name = \"Red Hat Bugzilla\", url = \"https://bugzilla.redhat.com/show_bug.cgi?id=%s\", },", - " lp = { name = \"Launchpad Bug\", url = \"https://launchpad.net/bugs/%s\", },", + " rhbz = { name = \"Red Hat Bugzilla\", url = \"https:\/\/bugzilla.redhat.com\/show_bug.cgi?id=%s\", },", + " lp = { name = \"Launchpad Bug\", url = \"https:\/\/launchpad.net\/bugs\/%s\", },", "}", "```" ], - "parameters": [ + "signature" : "Seal.plugins.urlformats:providersTable(aTable)", + "type" : "Method", + "returns" : [ + " * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed.", + "" + ], + "def" : "Seal.plugins.urlformats:providersTable(aTable)", + "parameters" : [ " * aTable - An optional table of providers, which must contain the following keys:", " * name - A string naming the provider, which will be shown in the Seal results", - " * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`" - ], - "returns": [ - " * Either a table of current providers, if no parameter was passed, or nothing if a parmameter was passed." - ], - "signature": "Seal.plugins.urlformats:providersTable(aTable)", - "stripped_doc": "", - "type": "Method" + " * url - A string containing the URL to insert the user's query into. This should contain one and only one `%s`", + "" + ] } ], - "name": "Seal.plugins.urlformats", - "stripped_doc": "This plugin is invoked with the `uf` keyword and requires some configuration, see `:providersTable()`\n\nThe way this works is by defining a set of providers, each of which contains a URL with a `%s` somewhere insert it.\nWhen the user types `uf` in Seal, followed by some more characters, those characters will be inserted into the string at the point where the `%s` is.\n\nBy way of an example, you could define a provider with a url like `http://bugs.mycorp.com/showBug?id=%s`, and just need to type `uf 123456` in Seal to get a quick shortcut to open the full URL.", - "submodules": [], - "type": "Module" + "doc" : "A plugin to quickly open URLs containing a search\/query term\nThis plugin is invoked with the `uf` keyword and requires some configuration, see `:providersTable()`\n\nThe way this works is by defining a set of providers, each of which contains a URL with a `%s` somewhere insert it.\nWhen the user types `uf` in Seal, followed by some more characters, those characters will be inserted into the string at the point where the `%s` is.\n\nBy way of an example, you could define a provider with a url like `http:\/\/bugs.mycorp.com\/showBug?id=%s`, and just need to type `uf 123456` in Seal to get a quick shortcut to open the full URL.", + "Field" : [ + + ], + "Command" : [ + + ], + "name" : "Seal.plugins.urlformats" }, { - "Command": [], - "Constant": [], - "Constructor": [], - "Deprecated": [], - "Field": [], - "Function": [], - "Method": [], - "Variable": [ + "Constant" : [ + + ], + "submodules" : [ + + ], + "Function" : [ + + ], + "Variable" : [ { - "def": "Seal.plugins.useractions.actions", - "desc": "", - "doc": "\nA table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\n\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http://hammerspoon.org/docs/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http://dict.leo.org/ende/index_de.html#/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", - "name": "actions", - "signature": "Seal.plugins.useractions.actions", - "stripped_doc": "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http://hammerspoon.org/docs/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http://dict.leo.org/ende/index_de.html#/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", - "type": "Variable" + "name" : "actions", + "desc" : "", + "stripped_doc" : [ + "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):", + " * fn - A function which will be called when the entry is selected. The function receives no arguments.", + " * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.", + " * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.", + " * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:", + " * For `fn` actions, passed as an argument to the function", + " * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.", + " * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.", + "", + "Example configuration:", + "```", + "spoon.Seal:loadPlugins({\"useractions\"})", + "spoon.Seal.plugins.useractions.actions =", + " {", + " [\"Hammerspoon docs webpage\"] = {", + " url = \"http:\/\/hammerspoon.org\/docs\/\",", + " icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),", + " hotkey = { hyper, \"h\" }", + " },", + " [\"Leave corpnet\"] = {", + " fn = function()", + " spoon.WiFiTransitions:processTransition('foo', 'corpnet01')", + " end,", + " },", + " [\"Arrive in corpnet\"] = {", + " fn = function()", + " spoon.WiFiTransitions:processTransition('corpnet01', 'foo')", + " end,", + " },", + " [\"Translate using Leo\"] = {", + " url = \"http:\/\/dict.leo.org\/ende\/index_de.html#\/search=${query}\",", + " icon = 'favicon',", + " keyword = \"leo\",", + " },", + " [\"Tell me something\"] = {", + " keyword = \"tellme\",", + " fn = function(str) hs.alert.show(str) end,", + " }", + "```" + ], + "doc" : "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\n\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http:\/\/hammerspoon.org\/docs\/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http:\/\/dict.leo.org\/ende\/index_de.html#\/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", + "notes" : [ + + ], + "signature" : "Seal.plugins.useractions.actions", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.useractions.actions", + "parameters" : [ + + ] }, { - "def": "Seal.plugins.useractions.get_favicon", - "desc": "", - "doc": "\nIf `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", - "name": "get_favicon", - "signature": "Seal.plugins.useractions.get_favicon", - "stripped_doc": "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", - "type": "Variable" + "name" : "get_favicon", + "desc" : "", + "stripped_doc" : [ + "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser." + ], + "doc" : "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", + "notes" : [ + + ], + "signature" : "Seal.plugins.useractions.get_favicon", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.useractions.get_favicon", + "parameters" : [ + + ] } ], - "desc": "Allow accessing user-defined bookmarks and arbitrary actions from Seal.", - "doc": "Allow accessing user-defined bookmarks and arbitrary actions from Seal.\n", - "items": [ + "stripped_doc" : [ + + ], + "Deprecated" : [ + + ], + "desc" : "Allow accessing user-defined bookmarks and arbitrary actions from Seal.", + "type" : "Module", + "Constructor" : [ + + ], + "items" : [ { - "def": "Seal.plugins.useractions.actions", - "desc": "", - "doc": "\nA table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\n\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http://hammerspoon.org/docs/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http://dict.leo.org/ende/index_de.html#/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", - "name": "actions", - "signature": "Seal.plugins.useractions.actions", - "stripped_doc": "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http://hammerspoon.org/docs/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http://dict.leo.org/ende/index_de.html#/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", - "type": "Variable" + "name" : "actions", + "desc" : "", + "stripped_doc" : [ + "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):", + " * fn - A function which will be called when the entry is selected. The function receives no arguments.", + " * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.", + " * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.", + " * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:", + " * For `fn` actions, passed as an argument to the function", + " * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.", + " * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.", + "", + "Example configuration:", + "```", + "spoon.Seal:loadPlugins({\"useractions\"})", + "spoon.Seal.plugins.useractions.actions =", + " {", + " [\"Hammerspoon docs webpage\"] = {", + " url = \"http:\/\/hammerspoon.org\/docs\/\",", + " icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),", + " hotkey = { hyper, \"h\" }", + " },", + " [\"Leave corpnet\"] = {", + " fn = function()", + " spoon.WiFiTransitions:processTransition('foo', 'corpnet01')", + " end,", + " },", + " [\"Arrive in corpnet\"] = {", + " fn = function()", + " spoon.WiFiTransitions:processTransition('corpnet01', 'foo')", + " end,", + " },", + " [\"Translate using Leo\"] = {", + " url = \"http:\/\/dict.leo.org\/ende\/index_de.html#\/search=${query}\",", + " icon = 'favicon',", + " keyword = \"leo\",", + " },", + " [\"Tell me something\"] = {", + " keyword = \"tellme\",", + " fn = function(str) hs.alert.show(str) end,", + " }", + "```" + ], + "doc" : "A table containing the definitions of static user-defined actions. Each entry is indexed by the name of the entry as it will be shown in the chooser. Its value is a table which can have the following keys (one of `fn` or `url` is required. If both are provided, `url` is ignored):\n * fn - A function which will be called when the entry is selected. The function receives no arguments.\n * url - A URL which will be opened when the entry is selected. Can also be non-HTTP URLs, such as `mailto:` or other app-specific URLs.\n * icon - (optional) An `hs.image` object that will be shown next to the entry in the chooser. If not provided, `Seal.plugins.useractions.default_icon` is used. For `url` bookmarks, it can be set to `\"favicon\"` to fetch and use the website's favicon.\n * keyword - (optional) A command by which this action will be invoked, effectively turning it into a Seal command. Any arguments passed to the command will be handled as follows:\n * For `fn` actions, passed as an argument to the function\n * For `url` actions, substituted into the URL, taking the place of any occurrences of `${query}`.\n * hotkey - (optional) A hotkey specification in the form `{ modifiers, key }` by which this action can be invoked.\n\nExample configuration:\n```\nspoon.Seal:loadPlugins({\"useractions\"})\nspoon.Seal.plugins.useractions.actions =\n {\n [\"Hammerspoon docs webpage\"] = {\n url = \"http:\/\/hammerspoon.org\/docs\/\",\n icon = hs.image.imageFromName(hs.image.systemImageNames.ApplicationIcon),\n hotkey = { hyper, \"h\" }\n },\n [\"Leave corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('foo', 'corpnet01')\n end,\n },\n [\"Arrive in corpnet\"] = {\n fn = function()\n spoon.WiFiTransitions:processTransition('corpnet01', 'foo')\n end,\n },\n [\"Translate using Leo\"] = {\n url = \"http:\/\/dict.leo.org\/ende\/index_de.html#\/search=${query}\",\n icon = 'favicon',\n keyword = \"leo\",\n },\n [\"Tell me something\"] = {\n keyword = \"tellme\",\n fn = function(str) hs.alert.show(str) end,\n }\n```", + "notes" : [ + + ], + "signature" : "Seal.plugins.useractions.actions", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.useractions.actions", + "parameters" : [ + + ] }, { - "def": "Seal.plugins.useractions.get_favicon", - "desc": "", - "doc": "\nIf `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", - "name": "get_favicon", - "signature": "Seal.plugins.useractions.get_favicon", - "stripped_doc": "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", - "type": "Variable" + "name" : "get_favicon", + "desc" : "", + "stripped_doc" : [ + "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser." + ], + "doc" : "If `true`, attempt to obtain the favicon for URLs added through the `add` command, and use it in the chooser.", + "notes" : [ + + ], + "signature" : "Seal.plugins.useractions.get_favicon", + "type" : "Variable", + "returns" : [ + + ], + "def" : "Seal.plugins.useractions.get_favicon", + "parameters" : [ + + ] } ], - "name": "Seal.plugins.useractions", - "stripped_doc": "", - "submodules": [], - "type": "Module" + "Method" : [ + + ], + "doc" : "Allow accessing user-defined bookmarks and arbitrary actions from Seal.", + "Field" : [ + + ], + "Command" : [ + + ], + "name" : "Seal.plugins.useractions" } ] \ No newline at end of file