Preparing a Mac for Engineering work

Preparing a Mac for Engineering work

in

Motivation

Due to the circumstances that unfolded over the past 3 months, I had to switch and set up my work laptop 4 times. From scratch. It’s seriously annoying to go through the same setup every time… and that’s why I wanted to be smarter and take notes to remind myself about all the little things I have to repeat during setups. The goal is have the same work environment on each new machine.

This is more of a checklist for me than it is for you, but you’re welcome to steal some ideas. I stole many myself. 😬

Keyboard Setup

Open System Preferences and go through every menu and sub-menu, everywhere. You’ll see preferences that need changing.

One example of that – all of my recent devices had a TouchBar. I find it useless and laggy, and I never found myself using the extra buttons. Good old Function keys are great for me. The setting for this is in System PreferencesKeyboard

Keyboard Settings My TouchBar, disabled

Another example – I’m very used to Linux/Windows modifier keys (Ctrl, Alt, Super). It has always been just easier to continue with whatever I was used to… especially knowing that Apple isn’t forcing their opinion on this – macOS allows you to easily swap all modifiers, even Caps Lock. It’s done through System PreferencesKeyboardModifier Keys.

Modifier Keys My Modifier Keys, swapped

This is the moment when I also connect my Magic Keyboard and my MX Master, because the keyboard behavior is per-device and not system-wide.

Terminal Setup

Mac Terminal The look of my Terminal

Let’s make things easy first.

Homebrew

How would setting up a development environment on a Mac without Homebrew work? It’s the “unofficial Mac package manager”. Well, I won’t say that it’s impossible to maintain such an environment, it’s totally doable… but it’s definitely super inconvenient.

You should check the project’s homepage for the latest installation instructions. Here’s what I did from my Terminal:

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

That’s all. Installing new software is now a breeze using brew.

Z-Shell

Your Mac probably already has Z-Shell (zsh) installed and set as the default shell. Z-Shell provides a better UX and more features than the basic shells. You can check with:

$ which $SHELL # should output: /bin/zsh
$ echo $0      # should output: -zsh

If it’s there, skip to the next section.

If you’re not getting zsh, you’ll need to install and set up Z-Shell manually. Your default is probably Bash (/bin/bash). This Shell was the default before macOS Catalina. With the Catalina release, Apple switched to a new default: Z-Shell. You’ll anyway still have your basic shells available in case you need them – /bin/bash and /bin/sh – but here are some reasons for why zsh is better than bash and sh.

To install zsh using Homebrew:

$ brew install zsh

Super simple, right? Homebrew is awesome. Check out Homebrew’s author too.

After installing Z-Shell, you need to set it as your default. If you already see Z-Shell in your path (run which zsh to check), you can set it as default like so:

$ chsh -s $(which zsh)

If it’s not available immediately, it’s probably stuck in your Homebrew Cellar. Then it’s going to be something like this:

$ chsh -s /usr/local/Cellar/zsh/5.8/bin/zsh # might not be 5.8 for you

Restart your Terminal to see the change.

Fast text editing

You might not like editing files in the Terminal. I can take nano, but even that is often slow… so, I do it in a standalone app. My favorite text editor is Sublime Text. It’s much better than the default TextEdit app you get with your Mac.

Sublime Text also has fancy code coloring, syntax-related completion, plugins… but I really only see it as a text editor that is also capable of displaying code – and that’s how I use it.

Downloading from the official website works, although it’s easier to maintain through Homebrew:

$ brew install --cask sublime-text

Pro tip #1: after installing, open Sublime Text and choose the Adaptive theme from the settings.

Pro tip #2: you’ll also get a subl command-line helper:

$ subl my_file.txt       # opens file
$ subl Documents/project # opens project

Next-gen Terminal tools

Using grep and find to search for files from the Terminal is fine. Also, using cd to enter directories is fine, and ls to list the contents is fine. But all of these can start feeling very repetitive if you often go through a deep structure of directories. Same goes for sed.

I found some nice utilities built on top of these ideas that are (1) faster, and (2) provide a better UX.

1. AutoJump

This one learns from your usage of cd, and gives you the ability to jump across directories with only a few characters typed.

Here’s an example of what you can do with AutoJump:

$ pwd
/Users/m.marinkovic

$ j open
Jumped to 'open-source'

$ pwd
/Users/m.marinkovic/dev/open-source

It can also guess correctly even with simpler and shorter jump directions, like this one:

$ pwd
/Users/m.marinkovic

$ j a
Jumped to 'android'

$ pwd
/Users/m.marinkovic/dev/android

2. RipGrep

This one provides really fast text search. Like, reeeeally fast.

RipGrep Usage of rg in a directory

In my case, it takes around 100ms to search any text through all of my projects (27 projects, including the .git directories).

3. Tree

This one is used for displaying deep directories in the Terminal.

$ tree .how-to
.how-to
├── assets
│   ├── css
│   │   └── style.css
│   └── img
│       ├── analytics.png
│       ├── config.png
│       ├── disqus.png
│       ├── page.png
│       └── post.png
├── index.html
└── styleguide.md

3 directories, 8 files

4. FD

While find works fine, fd is a simple, fast and user-friendly alternative to it. While it does not aim to support all of find’s powerful functionality, it provides sensible (and opinionated) defaults for the majority of use cases.

$ fd mac

_posts/op-ed/2020-03-23-Preparing-Mac-Engineering.md
images/posts/keyboard-mac.png
images/posts/mac-setup-iterm.png
images/posts/mac-setup-keyboard.png
images/posts/mac-setup-modifiers.png
images/posts/mac-setup-ripgrep.png
images/posts/mac-setup-terminal.png
images/posts/work-desk-mac.jpg

5. SD

Unix’ default sed (stream editor) is… well, let’s just say that nobody likes to use it. 😝

So, sd is the arguably better alternative. It’s more intuitive and has different defaults.

Removing chars and whitespace looks like this:

$ echo '"lots((([]))) of special chars"' | sd -s '((([])))' ''
"lots of special chars"

$ echo '"lorem ipsum 23   "' | sd '\s+$' ''
"lorem ipsum 23"

Replacing text in file and in project looks like this:

$ sd 'window.fetch' 'fetch' http.js
Replaced in http.js

$ sd 'from "react"' 'from "preact"' $(fd --type file)
Replaced in project

The Terminal

This is the main dish, it’s about iTerm, the ‘Terminal on steroids’ that does everything that your standard Terminal does, plus a bunch of other useful things you never knew you needed. It won’t make you a 10x developer, but will surely make you feel like one.

It’s super easy to install using Homebrew:

$ brew cask install iterm2

Once installed, you should immediately open iTerm’s settings and reconfigure the defaults. For example, choose the Minimal theme.

iTerm Theme iTerm’s theming settings

You can also specify a directory where to keep your iTerm settings, in case you need to migrate everything to a new machine later.

If you want a fancy color scheme (and you do), check out this page – it has a lot of different configuration schemes. Check the installation instructions on top.

Z-Shell plugins

Oh My Z-Shell

This is, arguably, the most interesting part of the process. It’s a cosmetical change, sure, but it makes things so much cleaner and easier to navigate through. It’s all about picking the right zsh theme with a few great plugins. My favorite Z-Shell framework is OhMyZsh, but there are other options like Prezto and others.

OhMyZsh is a zsh framework that makes you feel like your doing something important. No joke. It also supports a bunch of plugins that could boost your productivity (or at least help with readability) and lots of great themes.

To install OhMyZsh, I ran this:

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

You might need to restart your Terminal for the changes to take effect.

PowerLevel 10k

I like the powerlevel10k theme on top of OhMyZsh, it’s configurable and has support for a bunch of dev tools. Their git support is awesome, for example.

To install powerlevel10k on top of OhMyZsh, I ran this:

$ git clone --depth=1 https://github.com/romkatv/powerlevel10k.git $ZSH_CUSTOM/themes/powerlevel10k

This command installs the theme, but you still need to specify that you want to use it. You need to change the ZSH_THEME variable value to "powerlevel10k/powerlevel10k" inside of your home directory’s .zshrc.

Restart your Terminal after. Follow the on-screen instructions once you open it again.

Additional plugins

You can see a bunch of other plugins for OhMyZsh here. I set my favorites in the same ~/.zshrc file, just find the plugins line:

plugins=(git colored-man-pages colorize pip python macos docker kubectl)

Java Virtual Machines

I usually need a JVM environment. You may be aware of the Java licensing change… basically, Oracle changed their Java license, so their JDK and JRE are not commercially usable anymore. Not for free, anyway… Update: it seems like they changed back to free licensing. But yeah… no thanks.

The “open” version of Java is still free, and can be installed through Homebrew from AdoptOpenJDK, for example.

I ran this:

$ brew tap AdoptOpenJDK/openjdk
$ brew cask install adoptopenjdk8-openj9-jre-large

Environment Variables

To be future-proof, and to make sure that all of my Java programs run with the same (default) JVM version, I specify the JAVA_HOME variable in my .zshrc. There are also some other things I configure in that file, like ANDROID_HOME, which is useful for automated processes and testing CI pipelines. Android SDK comes bundled with your Android Studio installation, and you can point to that one.

Here’s a snippet from my .zshrc config that sets up Java and Android, and also updates the global PATH to include all of the tools.

# Custom Locations
LOCAL_LINKS_HOME=$HOME/bin:/usr/local/bin
SCRIPTS_HOME=$HOME/Scripts
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-8-openj9.jdk/Contents/Home
export ANDROID_HOME=$HOME/Library/Android/sdk
export GRADLE_HOME=/usr/local/Cellar/gradle/5.6.4

# Here's a multi-line PATH hack!
export PATH=$ANDROID_HOME/platform-tools:$PATH
export PATH=$ANDROID_HOME/tools:$PATH
export PATH=$JAVA_HOME/bin:$PATH
export PATH=$SCRIPTS_HOME:$PATH
export PATH=$LOCAL_LINKS:$PATH

Oh, did I already mention you can also install a local distribution of Gradle using brew install gradle?

IDEs

To manage my main IDEs, I use JetBrains Toolbox with sync settings to remote repo feature turned on. You can store settings in a private GitHub repository, for example.

My other tools and code editors are automatically updated anyway, so no need to worry about them.

Other tips
  • Check for discounts at Humble Bundle and Stack Social
  • Migrating your scripts? I use ~/Scripts to store all of mine, this way I can backup and restore easily using a single Git repository
  • Migrating XCode configuration? It’s in ~/Library/Developer/Xcode/UserData, including key mappings and color configurations

Be sure to also check out my Curated list of Mac tools!