Home

Table of Contents

Welcome to my humble home. I like to keep it tidy just in case someone extraordinary; such as yourself, come to visit.

Shell

Most of my shell-configuration is compatible with various shell's. I typically use eshell, but I sometimes dabble with both bash and zsh, so I tend to keep them in parity.
All of the shared configuration is tangled to the ~/shell directory, where it is split into environment, login and interactive. These are then loaded in the order that's required by the specific shell, along with more tailored configurations. Each shell will also look for a local run-com file that can be used for additional configuration or overrides.

Environment

Before doing much, we need some environment-variables set. The most important one being the PATH-variable. The PATH is used by your shell whenever you're trying to execute a program without specifying it's full path.

For MacOS, there's now a utility for maintaining the PATH named path-helper. It will look for paths in /etc/paths, /etc/paths.d & /etc/manpaths.d, so I think you can have almost automatic PATH-handling by setting that up. I do however like having full control and consistent behavior between environments. That's why I've created a table that I construct environment-variables from, as you can see below.

CARGOHOME $HOME/.cargo
ANDROIDSDKROOT $HOME/Library/Android/sdk
JAVAHOME $(/usr/libexec/javahome -v11)
RUSTUPHOME $HOME/.rustup
CLASSPATH $HOME/jdt-language-server/plugins/org.eclipse.equinox.launcher1.6.200.v20210416-2027.jar
CLASSPATH $ANDROIDSDKROOT/platforms/android-30/android.jar
PATH $ANDROIDSDKROOT/emulator
PATH $ANDROIDSDKROOT/platform-tools
PATH $ANDROIDSDKROOT/tools
PATH $ANDROIDSDKROOT/tools/bin
PATH $HOME/bin
PATH $HOME/.local/bin
PATH $HOME/.ghcup/bin
PATH $CARGO/bin
PATH /usr/local/bin
MANPATH /opt/homebrew/opt/erlang/lib/erlang/man
GRABHOME $HOME/Projects

Login

A login shell is the first shell ran with your user-id. So in this shell we would only set up environment and don't bother with TUI.

EDITOR editor
VISUAL $EDITOR
LANG enUS.UTF-8
LCALL $LANG
LCCOLLATE $LANG
LCCTYPE $LANG
LCMESSAGES $LANG
LCMONETARY $LANG
LCNUMERIC $LANG
LCTIME $LANG
PAGER less -RXFSiw
MANPAGER $PAGER
HISTSIZE 10000
HISTFILE $HOME/.history

There's a shortcoming in zsh of how it treats $EDITOR, where it cannot have any flags or arguments. We circumvent this by calling a wrapper-script. This wrapper also allows Emacs to be used when piping commands.

Interactive

An interactive shell is what you get when you boot up a terminal. Typically you would want utility-functions, aliases and coloring to become available at this point to make a ritcher experience.

I've added a bunch of functions to my configuration that I've found helpfull over the years. Most of these are all available directly from the shell as small programs. I haven't kept track of which of these I've created myself or which I've found on the great interweb unfortunately.

Starship is a fast and feature-full command-prompt. It's also very customizable, so I've finally scrapped my old hacky personal one.

Fzf is a fast and easy to use fuzzy-matcher.

Fif uses a combination of fzf and fast grep alternatives to achieve a better search-experience for code in the terminal.

Lesspipe is an input-filter for less that makes it possible to view the content of binaries and archives.

Thefuck will try to correct your last run command. Just write fuck and it will do it's best.

o is a wrapper of open on MacOS and xdg-open on linux. If it's not given any arguments, it will open the current directory in finder or nautilus respectively.

mcd is a quick way of creating a directory and moving into that directory in one go.

extract can be used to extract various types of archives without having to remember all the various additional arguments.

ip will output your local ip-address.

remoteip outputs your remote ip-address

I've hi-jacked cd, so that I can easily jump to the root of a git repository by issuing cd :/.

hide sends a process to the background and hides std(out|err); "deamonize".

ssht opens an ssh-connection in a tmux-pane.

auth copies my public ssh-key to the active remote ssh.

ts will tail a file or socket. The second argument should be a regex that you would like to highlight.

j is a wrapper of z with some additional help from fzf if you don't provide any arguments. Navigating this way is very efficient.

fd lists all subdirectories. That list is filtered by fzf and you cd into the candidate you choose.

fh makes command-history fuzzy-searchable

At my current workplace, we use Jira. I've made a few functions that makes it a little less annoying
jc, you can think of as (j)ira-(c)hange. It is for changing the status of a ticket.

jg, you can think of as (j)ira-(g)rab. It will list tickets that are not assigned to anyone, so you can choose one that you would like to work on.

json is a wrapper of jq where giving it just a json-file will output it nicely instead of barfing out.

If you've evaluated make install, this little snippet should have been compiled and your terminal will support 24-bit colors.

Aliases

– - cd -
.. cd ..
…. cd ../..
…… cd ../../..
:q exit
_ sudo
c clear
cat bat
clip nc localhost 8377
cpu-temp osx-cpu-temp
df df -h
du du -ch
du1 du -ch -d 1
e $EDITOR
f fd
g 'hub '
grep grep –color=auto
hr echo ; hr -; echo ;
ip dig +short myip.opendns.com @resolver1.opendns.com
l lunchy
ls exa
la ls -la
ll ls -1
localip ipconfig getifaddr en0
lt ls –tree
magit $EDITOR -e \(magit-status\)
manpath echo -e ${MANPATH//:/\\n}
mkdir mkdir -p
mv mv -i
path echo -e ${PATH//:/\\n}
please sudo
classpath echo -e ${CLASSPATH//:/\\n}
ql qlmanage -p
running jobs -r
s rg -S
sd rga
sloc sloccount
stopped jobs -s
sys grc tail -100 "/var/log/system.log"
syn synonym
timestamp date "+%s"
tmux tmux -2
today date "+%Y-%m-%d"
wget wget -c
hide SetFile -a V
show SetFile -a v
~ cd ~
deeplink adb shell am start -W -a android.intent.action.VIEW -d

Git

These are global git-configurations that people most often set using git config --global. Since those would be overwritten upon tangling this document, I advise against it. Use git config --(system|local) or manually add to ~/.gitconfig.local instead.

Custom functionality

Words diff

Will get the number of words that's been changed. This is useful if you use a service like ex. Crowdin for translations, where they charge for number of words translated.

#!/bin/sh
set -euo pipefail

function usage {
  cat << EOT

  Usage: git words-diff [options] [<commit>] [--] [<path>...]

  Options:

    -h, --help     output usage information

EOT
}

function git_words_added {
    git diff --word-diff=porcelain "$@" | grep -e "^+[^+]" | wc -w | xargs
}

function git_words_removed {
    git diff --word-diff=porcelain "$@" | grep -e "^-[^-]" | wc -w | xargs
}

function git_words_diff {
    echo $(($(git_words_added "$@") - $(git_words_removed "$@")))
}

while test $# -ne 0; do
  arg=$1; shift
  case $arg in
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Words added:   $(git_words_added $arg $@)"
      echo "Words removed: $(git_words_removed $arg $@)"
      echo "Sum:           $(git_words_diff $arg $@)"
      break;
      ;;
  esac
done

Who am I

Run git whoami to see what's your user local to the repository you're in.

#!/bin/sh

# git-whoami
# Author: Peter Eisentraut <peter@eisentraut.org>
# Created: 2011-10-27
# License: WTFPL; see http://sam.zoy.org/wtfpl/

# exact logic in ident.c in git source tree

set -e

get_email() {
        git config user.email || ( [ -n "$EMAIL" ] && echo "$EMAIL" ) || echo "$(id -nu)@$(hostname --fqdn)"
}

get_name() {
        git config user.name || getent passwd $(id -un) | cut -d : -f 5 | cut -d , -f 1
}

: ${GIT_AUTHOR_NAME=$(get_name)}
: ${GIT_COMMITTER_NAME=$(get_name)}
: ${GIT_AUTHOR_EMAIL=$(get_email)}
: ${GIT_COMMITTER_EMAIL=$(get_email)}

author="$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>"
commit="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"

if [ "$author" = "$commit" ]; then
        echo "$author"
else
        echo "Author: $author"
        echo "Commit: $commit"
fi

Core

commitGraph true

Alias

amm commit -v –amend –no-edit
appraise !git-appraise
authors shortlog -sn
br branch
bra branch -a
cb checkout -b
ci commit -v
cl clone –recursive
clone clone –recursive
co checkout
cp !git rev-parse HEAD ¦ tr -d "\\r" ¦ pbcopy
create-graph commit-graph write –reachable
ctags !.git/hooks/ctags
d diff –word-diff
f !git-fresh
g grep –break –heading –line-number
ignored check-ignore -v
lc show -s –format="%ct" HEAD
lg log –graph –pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' –abbrev-commit
ls ls-files
m merge
mt mergetool
mysprint log –since 1.week –author "$(git config user.name)"
next !git add -A; git rebase –continue
p pull
perfect rebase -i @{u}
pf push –force-with-lease
pr pull-request
rb rebase
rba rebase –abort
rbc rebase –continue
rbi rebase -i origin/master
remotes remote -v
rm remove-commit
rm-r push origin –delete
root !pwd
s status -sb
sa submodule add
sci dcommit -v
sf submodule foreach
sh !git-sh
sha !fcs
sprint log –format "[%an] %s" –since 1.week
sr submodule remove
st stash
sta stash apply
standup log –since "1 day ago" –oneline –author "$(git config user.name)"
std stash drop
stls stash list
stp stash pop
sts stash save
stu stash unstaged
tags tag -l
today log –since 7am
undo reset –soft HEAD^
unstage reset HEAD --
update pull –rebase
fix !TARGET=$(git log –oneline ¦ fzf ¦ awk '{print $1}') && git commit –fixup=$TARGET && GITSEQUENCEEDITOR=: git rebase -i –autostash –autosquash $TARGET~
ico !git checkout $(git branch ¦ fzf)
icor !git checkout $(git branch -r ¦ fzf)

Color

ui true
branch auto
diff auto
status auto

Credential

helper osxkeychain

Status

showUntrackedFiles all

Diff

tool difftastic
mnemonicprefix true
algorithm histogram
cmd difftastic "$LOCAL" "$REMOTE"
xfuncname (^\\(.* ¦ \\s*\\(defn.*)
xfuncname '^[ \t]*(pub¦)[ \t]*((fn¦struct¦enum¦impl¦trait¦mod)[^;]*)$'

Pager

difftool true

Push

default current
followTags true

Pull

rebase true

Commit

gpgSign false

Fetch

writeCommitGraph true

GC

auto 1
writeCommitGraph true

Branch

autosetuprebase always

Grep

extendRegexp true
lineNumber true

Filters

clean git media clean %f
smudge git media smudge %f
required true
clean git-lfs clean – %f
smudge git-lfs smudge – %f
required true
process git-lfs filter-process

Magit

hideCampaign true

Apply

whitespace nowarn

Merge

conflictstyle diff3
tool ediff

Transfer

We validate objects and their connection to commits before transferring.

fsckObjects true

Include

We use a separate file for configurations that should not be pushed to a remote. Could be for security purposes.

path ~/.gitconfig.local

Tmux

Configuration

# Home. PC configuration files
# Copyright (C) 2022  Henrik Kjerringvåg
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

set -g mouse on
set -g mode-keys vi
set -g history-limit 10000

# Plugins
set -g @plugin tmux-plugins/tpm
set -g @plugin tmux-plugins/tmux-copycat
set -g @plugin tmux-plugins/tmux-open
set -g @plugin tmux-plugins/tmux-pain-control
set -g @plugin tmux-plugins/tmux-prefix-highlight
set -g @plugin tmux-plugins/tmux-resurrect
set -g @plugin tmux-plugins/tmux-sensible
set -g @plugin tmux-plugins/tmux-yank
set -g @plugin roosta/tmux-fuzzback

# One indexed panes for easier switching
set -g base-index 1

# MacOS clipboard
set -g default-shell $SHELL
set -g default-command "reattach-to-user-namespace -l ${SHELL}"

# Synchronize panes
bind * set-window-option synchronize-pane

# Open an ssh-connection in another window
bind S command-prompt -p ssh: "new-window -n %1 'ssh %1'"

# Automatic window-naming
setw -g automatic-rename on
setw -g automatic-rename-format '#{b:pane_current_path}'

# Theme
set -g status-interval 5
set -g status-justify centre
set-window-option -g window-status-current-format "| #I:#W "
set -g status-left "#{prefix_highlight}"
set -g status-right ""

# Initialize package-manager
run-shell "~/.tmux/plugins/tpm/tpm"

License

Home. PC configuration files
Copyright (C) 2022  Henrik Kjerringvåg

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.