Setuping mac is definitely not an every day task. It’s usually long process, in order to get an efficient work station. In this article, I want to show you, how I approach to configure M1. I will share the process with the programs and the preferences I use.

Prerequisite

  • prepare some time ~1-2h
  • good internet connection (as there will be plenty things to download)
  • something to drink
  • positive mood 😉 - I will try to make it as easy as possible for you

Browsers

Password managers

  • First download your password manager(s)!
  • Optionally: download browsers extensions for easier usage

Apple Developer Tools

Unfortunately many programs will need Apple developer tools, so we install them as well via terminal command. Pay attention as this step might take a while… (this step took me ~10-15min)

xcode-select --install

Brew Package Manager

The brew is de facto standard macOS Package Manager.

Following https://gist.github.com/ChristopherA/a579274536aab36ea9966f301ff14f3f

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

# disable analytics
brew analytics off

iTerm2

Installed via brew. In case use: brew install --cask iterm2

font, size, window theme

If you like hack font, do not rush with installing it via: brew install font-hack. Instead you may want to have Hack Font with Powerline symbols from the NERD Fonts https://www.nerdfonts.com/font-downloads. To see a small difference take a look on screenshot below with Neovim.

Hack Font (Standard) Hack Nerd Font (with powerline symbols)
brew install font-hack brew tap homebrew/cask-fonts; brew install font-hack-nerd-font
hack-font hack-nerd-font

Below you will find some screenshots with configuration I usually setup.

iterm2-font

iterm2-window-theme

iterm2-general-selection

Colorscheme Gruvbox

curl https://raw.githubusercontent.com/herrbischoff/iterm2-gruvbox/master/gruvbox.itermcolors -o ~/Downloads/gruvbox.itermcolors

Import downloaded gruvbox color preset into iTerm (2), and after importing activate theme (3).

iterm2-colorscheme

Iterate through the arguments of previous commands - this is awesome feature of ZSH shell, so if you are interested follow my other post how to loop through previous arguments.

Finally you should see something like this:

iterm2-final-window

IDEs (VScode, IDEA)

Download the basic editors and IDEs.

  • Sublime - best for fast small changes
  • VS Code - personal coding IDE
  • IDEA - work coding IDE (especially GoLand, DataGrip, WebStorm)

Mobile App development:

Git

I put this out of dotfiles as git is essential to do any further steps. Later we will update .gitconfig to be in synch with our dotfiles repo.

wget https://raw.githubusercontent.com/egel/dotfiles/main/configuration/.gitconfig -P ~/
wget https://raw.githubusercontent.com/egel/dotfiles/main/configuration/.gitconfig.local -P ~/
wget https://raw.githubusercontent.com/egel/dotfiles/main/configuration/.gitconfig.local -O ~/.gitconfig.local_work

Later in GPG section, we will make sure that gpg keys will be properly added to .local & .local_work files, as they will be needed to sign the commits.

For linux & macOS (Intel), at this moment you would need to run this command git config --global gpg.program $(which gpg), so the path to gpg program can be correctly updated in .gitconfig.

SSH

Create ssh keys

I love gitlab page for configuration of SSH keys.

ssh-keygen -t ed25519 -C "johndoe@example.com"

Configure ssh

# ~/.ssh/config

# Connect to gitlab.com
Host gitlab.com
HostName gitlab.com
Preferredauthentications publickey
IdentityFile ~/.ssh/id_ed25519

Synchronize your dotfiles

I like to make my files synchronized with my remote repository - this helps me to update main origin when my local changes arise.

mkdir -p ~/privatespace/github.com/egel
cd ~/privatespace/github.com/egel
git clone git@github.com:egel/dotfiles.git

Re-linking the files that was directly downloaded from the repo, in order to get full synchronization with the private dotfiles repository.

# gitconfig
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gitconfig ~/.gitconfig

# idea (for vim plugin)
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.ideavimrc ~/.ideavimrc

Optional: In my configuration I setup few additional files, that help me manage my dotfiles. Like storing private passwords, having additional private configurations, ect. Those files by the design are meant NOT BE STORED under version control systems.

Also make sure the files have correct permissions, only for you.

touch ~/.zshrc.local
chmod 600 ~/.zshrc.local

touch ~/.envpass.private
chmod 600 ~/.envpass.private

Verify your connection

At this moment you should check if your connection is established. Running the command the second time should give you message with your git user.

ssh -T git@gitlab.com

# run it 2nd time, to get user
$ ssh -T git@gitlab.com
Welcome to GitLab, @john.doe!

GPG

Before starting this section make sure you know and understand why signing your own commits may be so important for you. I better explain this in my another article: The lesson of verifying Git commits.

Let’s start with basics, like linking configuration folder with local directory.

mkdir -p ~/.gnupg
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gnupg/dirmngr.conf ~/.gnupg/dirmngr.conf
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gnupg/gpg-agent.conf ~/.gnupg/gpg-agent.conf
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gnupg/gpg.conf ~/.gnupg/gpg.conf
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gnupg/sks-keyservers.netCA.pem ~/.gnupg/sks-keyservers.netCA.pem

Now, download your gpg keys (private & public) for all your accounts private (or/and work), as we will add them to gpg configuration in order to sign your things (like commits, private emails).

gpg --import public_key.asc
gpg --import private_key.asc

Get your gpg fingerprint as we will need to use in git. Execute command below and get “signingKey” = last 16 chars of your fingerprint key. (I add arrow, to make it easier for you).

$ gpg --list-secret-keys --with-fingerprint --keyid-format LONG your@email.com

                     |- this would be your "signingKey" ------- |- or here
                     ▼                                          |
sec   rsa4096/RPGLBRKNFTAZ2S9K 2019-03-17 [SC]                  ▼
      Key fingerprint = VXE7 T2QX FCJZ YQ6L BEGJ  MLMM RPGL BRKN FTAZ 2S9K
uid                 [ unknown] John Doe <johndoe@example.com>
ssb   rsa4096/EBEE77C5734494A6 2019-08-23 [E]

Restart gpg-agent in order to use latest configuration.

$ killall gpg-agent
2023-03-27 15:13:12 gpg-agent[2253] SIGTERM received - shutting down ...
2023-03-27 15:13:12 gpg-agent[2253] gpg-agent (GnuPG) 2.4.0 stopped

$ gpg-agent --daemon
2023-03-27 15:14:46 gpg-agent[2253] gpg-agent (GnuPG) 2.4.0 started

Fill the key in ~/.gitconfig.local. So it’s look more-less like:

[user]
    user = "John Doe"
    email = johndoe@example.com
    signingKey = RPGLBRKNFTAZ2S9K

[commit]
    gpgsign = true

Test applied config by reloading terminal and commit something, to see if your commits are signed successfully.

git commit -S "test commit with signing"

If everything will went successfully, you should get pinentry window, like the one below:

GPG pinentry-mac

Vim & Neovim

Without a doubt vim is the king of simple text editors. Many of you may argue, but I don’t want to lead you astray 😆. When I discoverd vim, I was so much confused “why the heck there is so much noise about this thing”! After looong time later, I understood why and I wrote Is worth to know the Vim Editor and why? and The Vim’s hidden superpowers.

Let’s start as usual with configuring vim and neovim.

# nvim (my primary editor)
mkdir -p ~/.config
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.config/nvim ~/.config/nvim

# vim (after switch to nvim, using this config rarely)
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.vimrc ~/.vimrc
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.vim/ ~/.vim/

# Open nvim & vim and install plugins via
:PlugInstall

iterm2-nvim

Tmux

Tmux - terminal multiplexer and Tmux Plugin Manager.

# link configuration
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.tmux.conf ~/.tmux.conf
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.tmux-osx.conf ~/.tmux-osx.conf

# install tmux-plugin manager
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

# type this in terminal if tmux is already running
tmux source ~/.tmux.conf

Open new session abd type tmux new -t new. Next, install plugins from the .tmux.conf file via prefix + I (pay attention, it’s big “i”. Prefix = ctrl + b).

iterm2-tmux

ZSH + oh-my-zsh

I was positively surprised that by default M1 use zsh shell.

terminal-default-shell

Install missing oh-my-zsh

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

For years I use honukai theme, as it gives me best orientation in the shell.

mkdir -p ~/.oh-my-zsh/custom/themes/
curl https://raw.githubusercontent.com/oskarkrawczyk/honukai-iterm/master/honukai.zsh-theme -o ~/.oh-my-zsh/custom/themes/honukai.zsh-theme

Reopen terminal to apply changes.

System Preferences

Screenshots

For all types of screen records, I use default mac screenshot tool, with some combinations from Snagit. The combination of both give the fastest experience to finish a screenshot or record a screen for documentation.

I like to have one path for all type of screen records and usually choose something like:

# Set new default path
defaults write com.apple.screencapture $HOME/Documents/Screenrecords

# kill current UI to apply new write path (no worries, it will not destroy anything)
killall SystemUIServer

Finder

Setup list view as a default view for all folders.

  1. Open hard drive view (usually it’s called “Macintosh HD”)
  2. Press + j

Finder hard drive settings

Next after accepting “Use as Defaults”, open terminal and remove all .DS_Store files from system used by the Finder, in order to remove all overrides (finder save all meta data about folders in .DS_Store).

sudo find / -name ".DS_Store"  -exec rm {} \;

Additionally, I like to display file extensions and sort folder first, therefore my usually setting for finder window is like following:

  1. Open finder
  2. Press + , to open window “Finder Settings”

Finder settings

Trackpad

For the mac trackpad I like to setup 2 things I am so get used to, that I cannot imagine work without:

Swiping between screens with 4 fingers

Preferences trackpad swipe screens

dragging elements with 3 fingers

preferences-accessibility-pointer-control

Displays

I think this is pretty standard, although having one screen in vertical position is very helpful as this sometimes enable to look on things from different perspective.

preferences-displays

Desktop & Stage Manager

In new version of macOS Sonoma, they introduce widgets on the desktop. One of the new default features is when user will click on the background it reveals the desktop.

I prefere to disable this feature and below paste small video-tutorial.

disable-stage-manage-on-desktop


Additional libs and setups

NVM & yarn

# install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

# install specific version of node
nvm install 18
nvm alias default 18

# test
which node
node --version

# apply changes
source ~/.zshrc

yarn

Yarn is connected to version of node running, so best way to install it is via current used node/npm.

Info: If you will use many node versions (via nvm), you also should to install yarn for each node version.

# install yarn globaly
npm install -g yarn

# test
yarn -v

Ruby

Follow my other post how to setup ruby on macOS - If possible do not use the ruby system version on mac osx

Standard link for configuration file

# create symlink from dotfiles dotfiles repository
ln -sf ~/privatespace/github.com/egel/dotfiles/configuration/.gemrc ~/.gemrc

Python

Follow my other post how to setup python on macOS - How to properly set up Python project?

JAVA

I did not found better way to install Java, like through SDK-MAN. I am not much fan of Java but this is really awesome Java Version Manager similar to rbenv.

To install it start with:

# install
curl -s "https://get.sdkman.io" | bash`

# test if succeeded (or reload terminal)
skd version
In case you wondering, my configuration for SDK-MAN you can find in my .zshrc

Apple Silicon - Rosetta

Some programs may require installing Apple’s rosetta

softwareupdate --install-rosetta