Initial commit of Hammerspoon config
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
--- === KSheet ===
|
||||
---
|
||||
--- Keybindings cheatsheet for current application
|
||||
---
|
||||
--- Download: [https://github.com/Hammerspoon/Spoons/raw/master/Spoons/KSheet.spoon.zip](https://github.com/Hammerspoon/Spoons/raw/master/Spoons/KSheet.spoon.zip)
|
||||
|
||||
local obj={}
|
||||
obj.__index = obj
|
||||
|
||||
-- Metadata
|
||||
obj.name = "KSheet"
|
||||
obj.version = "1.0"
|
||||
obj.author = "ashfinal <ashfinal@gmail.com>"
|
||||
obj.homepage = "https://github.com/Hammerspoon/Spoons"
|
||||
obj.license = "MIT - https://opensource.org/licenses/MIT"
|
||||
|
||||
-- Workaround for "Dictation" menuitem
|
||||
hs.application.menuGlyphs[148]="fn fn"
|
||||
|
||||
obj.commandEnum = {
|
||||
cmd = '⌘',
|
||||
shift = '⇧',
|
||||
alt = '⌥',
|
||||
ctrl = '⌃',
|
||||
}
|
||||
|
||||
--- KSheet:init()
|
||||
--- Method
|
||||
--- Initialize the spoon
|
||||
function obj:init()
|
||||
self.sheetView = hs.webview.new({x=0, y=0, w=0, h=0})
|
||||
self.sheetView:windowTitle("CheatSheets")
|
||||
self.sheetView:windowStyle("utility")
|
||||
self.sheetView:allowGestures(true)
|
||||
self.sheetView:allowNewWindows(false)
|
||||
self.sheetView:level(hs.drawing.windowLevels.tornOffMenu)
|
||||
local cscreen = hs.screen.mainScreen()
|
||||
local cres = cscreen:fullFrame()
|
||||
self.sheetView:frame({
|
||||
x = cres.x+cres.w*0.15/2,
|
||||
y = cres.y+cres.h*0.25/2,
|
||||
w = cres.w*0.85,
|
||||
h = cres.h*0.75
|
||||
})
|
||||
end
|
||||
|
||||
local function processMenuItems(menustru)
|
||||
local menu = ""
|
||||
for pos,val in pairs(menustru) do
|
||||
if type(val) == "table" then
|
||||
-- TODO: Remove menubar items with no shortcuts in them
|
||||
if val.AXRole == "AXMenuBarItem" and type(val.AXChildren) == "table" then
|
||||
menu = menu .. "<ul class='col col" .. pos .. "'>"
|
||||
menu = menu .. "<li class='title'><strong>" .. val.AXTitle .. "</strong></li>"
|
||||
menu = menu .. processMenuItems(val.AXChildren[1])
|
||||
menu = menu .. "</ul>"
|
||||
elseif val.AXRole == "AXMenuItem" and not val.AXChildren then
|
||||
if not (val.AXMenuItemCmdChar == '' and val.AXMenuItemCmdGlyph == '') then
|
||||
local CmdModifiers = ''
|
||||
for key, value in pairs(val.AXMenuItemCmdModifiers) do
|
||||
CmdModifiers = CmdModifiers .. obj.commandEnum[value]
|
||||
end
|
||||
local CmdChar = val.AXMenuItemCmdChar
|
||||
local CmdGlyph = hs.application.menuGlyphs[val.AXMenuItemCmdGlyph] or ''
|
||||
local CmdKeys = CmdChar .. CmdGlyph
|
||||
menu = menu .. "<li><div class='cmdModifiers'>" .. CmdModifiers .. " " .. CmdKeys .. "</div><div class='cmdtext'>" .. " " .. val.AXTitle .. "</div></li>"
|
||||
end
|
||||
elseif val.AXRole == "AXMenuItem" and type(val.AXChildren) == "table" then
|
||||
menu = menu .. processMenuItems(val.AXChildren[1])
|
||||
end
|
||||
end
|
||||
end
|
||||
return menu
|
||||
end
|
||||
|
||||
local function generateHtml(application)
|
||||
local app_title = application:title()
|
||||
local menuitems_tree = application:getMenuItems()
|
||||
local allmenuitems = processMenuItems(menuitems_tree)
|
||||
|
||||
local html = [[
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
*{margin:0; padding:0;}
|
||||
html, body{
|
||||
background-color:#eee;
|
||||
font-family: arial;
|
||||
font-size: 13px;
|
||||
}
|
||||
a{
|
||||
text-decoration:none;
|
||||
color:#000;
|
||||
font-size:12px;
|
||||
}
|
||||
li.title{ text-align:center;}
|
||||
ul, li{list-style: inside none; padding: 0 0 5px;}
|
||||
footer{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 48px;
|
||||
background-color:#eee;
|
||||
}
|
||||
header{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height:48px;
|
||||
background-color:#eee;
|
||||
z-index:99;
|
||||
}
|
||||
footer{ bottom: 0; }
|
||||
header hr,
|
||||
footer hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
.title{
|
||||
padding: 15px;
|
||||
}
|
||||
li.title{padding: 0 10px 15px}
|
||||
.content{
|
||||
padding: 0 0 15px;
|
||||
font-size:12px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.content.maincontent{
|
||||
position: relative;
|
||||
height: 577px;
|
||||
margin-top: 46px;
|
||||
}
|
||||
.content > .col{
|
||||
width: 23%;
|
||||
padding:20px 0 20px 20px;
|
||||
}
|
||||
|
||||
li:after{
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
.cmdModifiers{
|
||||
width: 60px;
|
||||
padding-right: 15px;
|
||||
text-align: right;
|
||||
float: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
.cmdtext{
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
width: 165px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="title"><strong>]] .. app_title .. [[</strong></div>
|
||||
<hr />
|
||||
</header>
|
||||
<div class="content maincontent">]] .. allmenuitems .. [[</div>
|
||||
<br>
|
||||
|
||||
<footer>
|
||||
<hr />
|
||||
<div class="content" >
|
||||
<div class="col">
|
||||
by <a href="https://github.com/dharmapoudel" target="_parent">dharma poudel</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.2/isotope.pkgd.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var elem = document.querySelector('.content');
|
||||
var iso = new Isotope( elem, {
|
||||
// options
|
||||
itemSelector: '.col',
|
||||
layoutMode: 'masonry'
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
]]
|
||||
|
||||
return html
|
||||
end
|
||||
|
||||
--- KSheet:show()
|
||||
--- Method
|
||||
--- Show current application's keybindings in a view.
|
||||
function obj:show()
|
||||
local capp = hs.application.frontmostApplication()
|
||||
local webcontent = generateHtml(capp)
|
||||
self.sheetView:html(webcontent)
|
||||
self.sheetView:show()
|
||||
end
|
||||
|
||||
--- KSheet:hide()
|
||||
--- Method
|
||||
--- Hide the cheatsheet view.
|
||||
function obj:hide()
|
||||
self.sheetView:hide()
|
||||
end
|
||||
|
||||
--- KSheet:toggle()
|
||||
--- Method
|
||||
--- Alternatively show/hide the cheatsheet view.
|
||||
function obj:toggle()
|
||||
if self.sheetView and self.sheetView:hswindow() and self.sheetView:hswindow():isVisible() then
|
||||
self:hide()
|
||||
else
|
||||
self:show()
|
||||
end
|
||||
end
|
||||
|
||||
--- KSheet:bindHotkeys(mapping)
|
||||
--- Method
|
||||
--- Binds hotkeys for KSheet
|
||||
---
|
||||
--- Parameters:
|
||||
--- * mapping - A table containing hotkey modifier/key details for the following items:
|
||||
--- * show - Show the keybinding view
|
||||
--- * hide - Hide the keybinding view
|
||||
--- * toggle - Show if hidden, hide if shown
|
||||
function obj:bindHotkeys(mapping)
|
||||
local actions = {
|
||||
toggle = hs.fnutils.partial(self.toggle, self),
|
||||
show = hs.fnutils.partial(self.show, self),
|
||||
hide = hs.fnutils.partial(self.hide, self)
|
||||
}
|
||||
hs.spoons.bindHotkeysToSpec(actions, mapping)
|
||||
end
|
||||
|
||||
return obj
|
||||
Reference in New Issue
Block a user