Home
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/>.