My Personal Mac Productivity Setup
I will update both posts on future adjustments to my setup, so stay tuned! I would say this is not a perfect setup, but for me, it saves a lot of time and context switchings on my day to day activities on my Macbook. This setup can be used by anyone who has Mac no matter what job he/she has & activity she/he does, but some sections are for software engineer/developer or whatever engineer you name it. Please be reminded that this is only my preference of setup, so this may not suit your workflow and needs.
Why would you invest time on this?
I love the idea of automation, shortcuts, and simplicity. That brought me to this setup with a lot of keyboard movements, simple, unified plus beautiful integrations across apps.
- Efficient & fast
- Less context-switching - Our focus span is limited even for small switching like from keyboard to mouse
- Well integrated
- Simple, seamless and unified
I think those are enough to justify one hour of your time for setting this up. Let's get started!
Karabiner-Elements + Hammerspoon ⚡
Aren't you ever tired of pressing ⌘ + tab
every time you want to switch between apps?
And how many times have you missed the apps that you want to switch on so you have to go through the cycle again? I felt your pain.
Fortunately, I found something that can mitigate this problem, Karabiner-Elements + Hammerspoon
So let's begin. First download and install Karabiner-Elements & Hammerspoon. Alternatively, you can use Brew
brew cask install hammerspoon
brew cask install karabiner-elements
After you have downloaded and installed both of them, the next step is to set up a hyperkey on Karabiner-Elements
.
This hyperkey will be your primary access button to hammerspoon shortcuts.
On my setup, because I barely used capslock
, I made it as my hyperkey and translate it as ⌘ + control + option + shift
.
The next step is to setup hammerspoon. Let's make the configuration file in ~/.hammerspoon/init.lua
First thing first, let's add our hyperkey
-- Specify your combination (your hyperkey)
local hyper = { "cmd", "alt", "ctrl", "shift" }
then reload the configuration through hammerspoon. But wait, isn't that inefficient we have to open the hammerspoon app and click reload every time we change the configuration file? Yes, it is, so a better option to have a shortcut for reloading the configuration.
Let's add the code to our configuration.
-- Specify your combination (your hyperkey)
local hyper = { "cmd", "alt", "ctrl", "shift" }
-- We use 0 to reload the configuration
hs.hotkey.bind(hyper, "0", function()
hs.reload()
end)
-- Notify about the config reload
hs.notify.new({title="Hammerspoon", informativeText="Config loaded"}):send()
So that's it, let's reload manually again (I promise, just one more time).
After that, try to reload it using shortcut, press hyperkey + 0
to reload.
Cool! Now we're able to quickly reload our configuration every time we change it. Let's add some useful stuff there.
Window Control
I like the idea of being able to move around apps' windows as quickly as possible without moving my mouse any inch.
So let's try to add these features using our hyperkey. First, the very basic thing is that we want to move a focused app's window to
left side
, top
, right side
, bottom
, top-left
, top-right
, bottom-left
and bottom-right
.
Add this code to the existing configuration
function move_window(direction)
return function()
local win = hs.window.focusedWindow()
local app = win:application()
local app_name = app:name()
local f = win:frame()
local screen = win:screen()
local max = screen:frame()
if direction == "left" then
-- +-----------------+
-- | | |
-- | HERE | |
-- | | |
-- +-----------------+
f.x = max.x
f.y = max.y
f.w = max.w / 2
f.h = max.h
elseif direction == "right" then
-- +-----------------+
-- | | |
-- | | HERE |
-- | | |
-- +-----------------+
f.x = max.x + (max.w / 2)
f.y = max.y
f.w = max.w / 2
f.h = max.h
elseif direction == "up" then
-- +-----------------+
-- | HERE |
-- +-----------------+
-- | |
-- +-----------------+
f.x = max.x
f.w = max.w
f.y = max.y
f.h = max.h / 2
elseif direction == "down" then
-- +-----------------+
-- | |
-- +-----------------+
-- | HERE |
-- +-----------------+
f.x = max.x
f.w = max.w
f.y = max.y + (max.h / 2)
f.h = max.h / 2
elseif direction == "upLeft" then
-- +-----------------+
-- | HERE | |
-- +--------+ |
-- | |
-- +-----------------+
f.x = max.x
f.y = max.y
f.w = max.w/2
f.h = max.h/2
elseif direction == "upRight" then
-- +-----------------+
-- | | HERE |
-- | +--------|
-- | |
-- +-----------------+
f.x = max.x + (max.w / 2)
f.y = max.y
f.w = max.w/2
f.h = max.h/2
elseif direction == "downLeft" then
-- +-----------------+
-- | |
-- +--------+ |
-- | HERE | |
-- +-----------------+
f.x = max.x
f.y = max.y + (max.h / 2)
f.w = max.w/2
f.h = max.h/2
elseif direction == "downRight" then
-- +-----------------+
-- | |
-- | +--------|
-- | | HERE |
-- +-----------------+
f.x = max.x + (max.w / 2)
f.y = max.y + (max.h / 2)
f.w = max.w/2
f.h = max.h/2
end
end
hs.hotkey.bind(hyper, "Left", move_window("left"))
hs.hotkey.bind(hyper, "Right", move_window("right"))
hs.hotkey.bind(hyper, "Up", move_window("up"))
hs.hotkey.bind(hyper, "Down", move_window("down"))
hs.hotkey.bind(hyper, "[", move_window("upLeft"))
hs.hotkey.bind(hyper, "\\", move_window("upRight"))
hs.hotkey.bind(hyper, "'", move_window("downLeft"))
hs.hotkey.bind(hyper, "home", move_window("downRight"))
With this, now we're able to move our app's window easily using hyperkey + (any direction)
.
The other thing that we need to add is the ability to quickly make an app into fullscreen and resize it to screen-size.
So let's add below code
hs.hotkey.bind(hyper, "return", function()
-- +--------------+
-- | |
-- | HERE |
-- | |
-- +---------------+
local win = hs.window.focusedWindow();
if not win then return end
win:moveToUnit(hs.layout.maximized)
end)
-- this one for fullscreen mode
hs.hotkey.bind(hyper, "f", function()
local win = hs.window.frontmostWindow()
win:setFullscreen(not win:isFullscreen())
end)
Now, give it a try, move your window around while reading this.
For me, this is productive and efficient enough for window management.
Launch Our Favorite Apps Quickly
We ain't got time to move our mouse to click or spotlight to search for apps that we love between our nice-to-have-but-barely-used apps. We also got no time for scrolling through tons of active applications to switch into the one that we want to focus on. A better way to deal with this is that with hammerspoon we can quickly launch or focus our favorite apps. It's just a couple of LOCs to enable this ability in our configuration. Let's add it
-- these are only my favourite apps, you can replace it with yours
local applicationHotkeys = {
c = 'Google Chrome',
t = 'iTerm',
s = 'Slack',
e = 'IntelliJ IDEA',
q = 'WebStorm',
j = 'Music',
i = 'Spark',
r = 'Reminders',
w = 'Bear',
d = 'Stocks'
}
for key, app in pairs(applicationHotkeys) do
hs.hotkey.bind(hyper, key, function()
hs.application.launchOrFocus(app)
end)
end
How to use it:
e.g. Google Chrome → Hyperkey + c
and that's it, now no more tabs-cycling / apps-clicking / spotlight-search-typing. Awesome!
Miscellaneous
These are only nice-to-have configurations which I think worth mentioning
- Check Network Connection Quickly (using Google DNS)
function pingResult(object, message, seqnum, error)
if message == "didFinish" then
avg = tonumber(string.match(object:summary(), '/(%d+.%d+)/'))
if avg == 0.0 then
hs.alert.show("No network")
elseif avg < 200.0 then
hs.alert.show("Network good (" .. avg .. "ms)")
elseif avg < 500.0 then
hs.alert.show("Network poor(" .. avg .. "ms)")
else
hs.alert.show("Network bad(" .. avg .. "ms)")
end
end
end
hs.hotkey.bind(hyper, "p", function()
hs.network.ping.ping("8.8.8.8", 1, 0.01, 1.0, "any", pingResult)
end)
Use hyperkey + p
to run it.
- Lock Screen & Put your system to sleep
-- this one for lock the screen
hs.hotkey.bind(hyper, "l", function()
hs.caffeinate.lockScreen()
end)
-- this one is for putting the system to sleep
hs.hotkey.bind(hyper, "z", function()
hs.caffeinate.systemSleep()
end)
Hyperkey + l
to lock the screen and Hyperkey + z
to put the system to sleep
To summarize, we now have:
- Window Control
- Quick App Switcher
- Browser Keyboard Only Mode
Beyond above, there are tons of uncovered karabiner-elements + hammerspoon
potentials. So keep exploring its possibilities!
Spotlight Better Replacement
I guess most of you have known this great software, Alfred Not only this has most of the spotlight's features, but it does offer additional features and extensive workflows. Alfred has a huge potential if we tweak it to its limit, especially on the workflow part.
Alfred's Most Useful Features
By default, Alfred comes with very useful additional features beyond spotlight's features, including:
- Websearch
- Clipboard History
- Terminal action
- Of course, Music Control 🎵 (there's also a Spotify version)
- etc
Alfred's Workflow
To empower its hidden abilities, we should go further into its workflow parts.
The essentials workflows to me that the community has offered are:
-
Language Translate by hanwen.huang
We can configure it to our languages of preference. For me it's en - idGoogle Translate on Alfred -
Currency Converter by Jeppe Stærk
We also need to configure our currencies preferencesConvert Currency on Alfred
There are other nice-to-have workflows like Airpod & Reminder workflows etc. Spare your time to explore other workflows here
Theme
A very useful app is not complete without a beautiful UI, and I don't like Alfred's default theme to be honest.
Fortunately, there are tons of Alfred's themes offered by Alfred's community, but my solid choice would be Simple Dark by Sindre Sorhus
Super Power Browser
Let's admit it, browser is one of the crucial parts in our day to day activities on the laptop, and for this my choice of browser would be the most popular browser: Google Chrome. It's super fast and super extensive with the cons of RAM consumption sadly. But with what it offers is a really good trade-off in my opinion. So let's charge Chrome with these awesome extensions and configurations.
Vimium
This extension lets us extend our keyboard-only mode by selecting different parts of the page and annotates it with a set of key combinations that we can use to determine which part we want to click/focus. Pretty awesome right?
By default, to start vimium-state and open selected part (if link) we can either press f
to do it on the current tab or shift + f
to do it on a new tab.
After that followed by annotation combination keys, you want to select. For the example above, selecting C
would make it to focuses on the search bar and selecting
A + M
will follow the Wikipedia link for vimium.
Dark Reader
This extension is not related to our ultimate keyboard-only mode setup, but this is worth mentioning. Dark Reader, in the simplest definition (at least this is what I do with this extension) is an extension that lets you make any page to be in dark mode. It's a huge deal for me because sometimes my eyes can't stand again those lights coming up from bright sites and not every site has dark mode toggle right?
This is an example for above same Google search result for vimium keyword with Dark Reader
It works perfectly on almost all pages. I recommend this one into your browser extension list.
Remote Desktop Chrome
Remote Desktop is essential to me when I'm AFK or too lazy to sit in front of my computer. I like to control it through my phone, and it gives me the ability to turn my phone into a remote control for my computer. So if you have some similar situations like me, then this extension is a good one to pick up.
Site Blocker
Chrome can help us to be more productive, but sometimes it's also a great source of distractions, it's like a two-edged sword. I found an extension to reduce the distractions, at least on chrome, it's Block Site.
This extensive works by blocking certain websites that you want to be blocked during your work mode
or manually block it.
Session Box
It's a tedious work when you want to switch between your accounts in the same websites.
Wouldn't it be cool if we can have those sessions alive and switch between them easily?
Session Box is here to solve this kind of problem. It offers session grouping as well.
Terminal
This section is mostly for developers who may need this, but it may apply for others to set up as well. So this is basically my terminal overview:
I'm using iTerm2 for my default MacOS' terminal replacement. I'm also using ZSH with OhMyZSH config, which is way better compared to default sh from MacOS.
For countless ZSH theme switching, I ended up with this gorgeous theme; PowerLevel10K
Editor
Intellij IDEA
Probably I'm not in the part of the widest open-source code editor, VSCode. Previously I was using it, but I felt like it lacked some features that I needed, for example, intelligent refactoring. That made me decided to move to IntelliJ by Jetbrain.
At first, I was having multiple jetbrain editors for each purpose and language. But then over time, it became more like bloated unused Editors rather than efficient. So I took research for a while, and I found that what I needed can be achieved with one Jetbrain's editor through plugins. My choice is IntelliJ IDEA. By default, it's more like a JVM-centric code editor.
Here are my top plugins for Intellij IDEA:
Other plugins are mostly programming language plugins & miscellaneous. Be careful to not bloat the IDE with unnecessary plugins, or its performance will suffer a lot.
Utilities
LastPass
This is my go-to password manager, it's free, rich features and well integrated across environments. For those who are into a password manager, I suggest going with LastPass both App and Extension
There is also an alfred's workflow for lastpass by Stuart Ryan
Bear
Most popular note-taking app out there is Evernote, but I don't like its complicated features and bloated stuff.
I prefer to have a simple, cheap, useful, efficient yet beautiful Note App; Bear.
Bear offers markdown-like syntax in its editor, so it's a developer-friendly note app. It offers tons of features that they mention in their sites, but the most useful features so far to me are:
- Hashtag Organization (Can be multi-level nested hashtags) & Cross-Note Links
- Programming Language Syntax supports (over 150 Programming Languages)
- Portability (export notes to various formats)
- Well-integrated with Alfred (Bear workflow by drgrib)
That's it, my overall not so detailed Personal Mac Productivity Setup that to me has shifted my velocity of productivity.
I admit that it's a quite long, complicated, and confusing article. This is my first article
, so any feedback is appreciated.
if you found this article is useful, share it with others. Try to revisit it once in a while for my updated setup. Thanks for reading.