Skip to content

Instantly share code, notes, and snippets.

@handcoding
Created July 11, 2020 17:46
Show Gist options
  • Save handcoding/36c3cec6df9a39698ac29072f9967ab7 to your computer and use it in GitHub Desktop.
Save handcoding/36c3cec6df9a39698ac29072f9967ab7 to your computer and use it in GitHub Desktop.
Hammerspoon lua file to remap Excel’s keyboard shortcuts to make them more Mac like
local UP = hs.keycodes.map['up']
local DOWN = hs.keycodes.map['down']
local LEFT = hs.keycodes.map['left']
local RIGHT = hs.keycodes.map['right']
local RETURN = hs.keycodes.map['return']
function hasCmd(event)
local flags = event:getFlags()
return flags.cmd and not (flags.alt or flags.ctrl or flags.shift)
end
function hasCmdShift(event)
local flags = event:getFlags()
return flags.cmd and flags.shift and not (flags.alt or flags.ctrl)
end
function hasNoFlags(event)
local flags = event:getFlags()
return not (flags.alt or flags.cmd or flags.ctrl or flags.shift)
end
excelKeyWatcher = hs.eventtap.new({hs.eventtap.event.types.keyDown}, function(event)
-- First we check to make sure the currently focused window has a
-- subrole of "AXStandardWindow", which will be the case if the window
-- is a standard Excel sheet. If the window has a different subrole,
-- which will be the case when the "Save As..." or "Find..." windows
-- are in focus, we bypass checking if this event is for a hotkey.
local focusedWindow = hs.window.focusedWindow()
if focusedWindow and focusedWindow:subrole() ~= 'AXStandardWindow' then
return false
end
local focusedElement = hs.uielement.focusedElement()
if focusedElement then
local role = focusedElement:role()
if role == 'AXTextArea' or role == 'AXTextField' then
local keyCode = event:getKeyCode()
if keyCode == LEFT and hasCmdShift(event) then
hs.eventtap.keyStroke({'shift'}, 'home', 0)
return true
elseif keyCode == RIGHT and hasCmdShift(event) then
hs.eventtap.keyStroke({'shift'}, 'end', 0)
return true
elseif keyCode == LEFT and hasCmd(event) then
hs.eventtap.keyStroke(nil, 'home', 0)
return true
elseif keyCode == RIGHT and hasCmd(event) then
hs.eventtap.keyStroke(nil, 'end', 0)
return true
elseif keyCode == UP and hasCmdShift(event) then
hs.eventtap.keyStroke({'cmd', 'shift'}, 'home', 0)
return true
elseif keyCode == DOWN and hasCmdShift(event) then
hs.eventtap.keyStroke({'cmd', 'shift'}, 'end', 0)
return true
elseif keyCode == UP and hasCmd(event) then
hs.eventtap.keyStroke({'cmd'}, 'home', 0)
return true
elseif keyCode == DOWN and hasCmd(event) then
hs.eventtap.keyStroke({'cmd'}, 'end', 0)
return true
end
elseif role == 'AXTable' or role == 'AXLayoutArea' then
local keyCode = event:getKeyCode()
if keyCode == RETURN and hasNoFlags(event) then
hs.eventtap.keyStroke(nil, 'f2', 0)
return true
elseif keyCode == LEFT and hasCmd(event) then
hs.eventtap.keyStroke({'alt'}, 'pageup', 0)
return true
elseif keyCode == RIGHT and hasCmd(event) then
hs.eventtap.keyStroke({'alt'}, 'pagedown', 0)
return true
elseif keyCode == UP and hasCmd(event) then
hs.eventtap.keyStroke(nil, 'pageup', 0)
return true
elseif keyCode == DOWN and hasCmd(event) then
hs.eventtap.keyStroke(nil, 'pagedown', 0)
return true
end
end
end
end)
-- Whenever a new window is focused, this will check if that window is a
-- Microsoft Excel window, and if so, it will enable the key watcher,
-- otherwise it will disable it.
excelWindowFilter = hs.window.filter.new('Microsoft Excel')
excelWindowFilter:subscribe(hs.window.filter.windowFocused, function() excelKeyWatcher:start() end)
excelWindowFilter:subscribe(hs.window.filter.windowUnfocused, function() excelKeyWatcher:stop() end)
-- If this script is initialized with a Microsoft Excel window already
-- in focus, this will enable the key watcher from the start.
local focusedWindow = hs.window.focusedWindow()
if focusedWindow and focusedWindow:application():name() == 'Microsoft Excel' then
excelKeyWatcher:start()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment