aboutsummaryrefslogtreecommitdiffstats
path: root/zsh_aliases
blob: e49846a2e5f099342a3d254b331855f8a4929013 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# -*- mode: sh -*-

function cond-alias {
    # Split on = and extract 1st word (alias name) and 2nd word (alias value)
    local -r name=${1[(ws:=:)1]}
    local -r value=${1[(ws:=:)2]}
    # Command is the first word of the alias value
    local cmd=${value[(w)1]}
    # If command match any of the below, the actual command is the second word
    case "$cmd" in
        sudo|noglob|cd|cat)
            # Remove $( and <( prefixes from command
            cmd=${value[(w)2]}
            cmd=${cmd:s/$\(//}
            cmd=${cmd:s/<\(//}
            ;;
    esac
    if whence $cmd > /dev/null; then
        alias $name=$value
    fi
}

cond-alias aptup='sudo apt update && sudo apt upgrade'
cond-alias curl='noglob curl'
cond-alias ec='emacsclient -nq'
cond-alias find='noglob bfs'
cond-alias git-root='cd $(git rev-parse --show-toplevel)'
cond-alias grep='grep --color=auto'
cond-alias hstat="history 0 | awk '{print \$2}' | sort | uniq -c | sort -nr | head"
cond-alias mg='mg -n'
cond-alias ta='tmux new-session -AD -s $LOGNAME'
cond-alias week='date +%V'
cond-alias reload='exec zsh'
if (( $+commands[apt-mark] )); then
    # This is the most precise method I've found for answering the question
    # "which packages did I install explicitly?"
    #
    # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727799
    # https://stackoverflow.com/q/58309013/22831
    alias apt-leaves='sudo grep -oP "Unpacking \K[^: ]+" /var/log/installer/syslog | sort -u | comm -13 /dev/stdin <(apt-mark showmanual | sort)'
fi

# Display ANSI art typically found .nfo files correctly
function nfoless {
    iconv -f 437 -t utf-8 "$@" | ${PAGER:-less}
}

# Show restic diff for the most recent snapshot. If offset is given, show the
# diff for the nth most recent snapshot instead
function restic-review {
    local -r offset="${1:-0}"
    if [[ $# -gt 1 || ! "$offset" =~ ^[0-9]+$ ]]; then
        echo "usage: restic-review [OFFSET]" 1>&2
        return 1
    fi
    restic snapshots --group-by host --host $(hostname -s) | \
        grep -Eo "^[a-f0-9]{8,}" | \
        tail -$(( 2 + $offset )) | \
        head -2 | \
        xargs -r restic diff
}

# Fuzzy-finding wrapper for brew install, info and uninstall
function brew-fzf {
    case "$1" in
        info|install|uninstall)
            cat <(brew formulae) <(brew casks | sed "s/^/--cask /") | fzf --multi | xargs -r brew "$1"
            ;;
        *)
            echo "usage: brew-fzf [ info | install | uninstall ]" 1>&2
            return 1
            ;;
    esac
}

(( $+commands[brew] )) || unfunction brew-fzf

# Alias diff
function alias-diff {
    # Use colors in diff output when supported
    if diff --color=auto /dev/null /dev/null 2> /dev/null; then
       alias diff='diff --color=auto'
    fi
}

alias-diff

# Alias ls
function alias-ls {
    local -r ls_opts='--group-directories-first --color=auto'
    case "$OSTYPE" in
        darwin*|freebsd*)
            if (( $+commands[gls] )); then
                alias ls="gls ${ls_opts}"
                alias ll="gls ${ls_opts} -lh"
            elif (( $+commands[gnuls] )); then
                alias ls="gnuls ${ls_opts}"
                alias ll="gnuls ${ls_opts} -lh"
            else
                alias ls='ls -G'
                alias ll='ls -Glh'
            fi
            ;;
        *)
            alias ls="ls ${ls_opts}"
            alias ll="ls ${ls_opts} -lh"
            ;;
    esac
}

alias-ls

# Activate or deactivate a virtualenv in the directory venv
function venv {
    local -r venv="$(realpath ${1:-.venv})"
    local -r activate="${venv}/bin/activate"
    if [[ -n "$VIRTUAL_ENV" ]]; then
        echo "venv: deactivating $VIRTUAL_ENV" 1>&2
        deactivate
    elif [[ -f "$activate" ]]; then
        echo "venv: activating $venv" 1>&2
        source "$activate"
    else
        echo "venv: $activate not found" 1>&2
        return 1
    fi
}

# A shell variant of the locate-dominating-file function found in Emacs
function locate-dominating-file {
    local -r file="$1"
    local -r name="$2"
    local dir="$file"
    # If given file is indeed a file, we start in its directory
    if [[ ! -d "$dir" ]]; then
        dir="${dir:h}"
    fi
    if [[ ! -d "$dir" ]]; then
        echo "locate-dominating-file: $dir is not a directory" 1>&2
        return 1
    fi
    local cur_dir="$dir"
    while true; do
        cur_dir="${cur_dir:P}" # P converts to realpath
        if [[ -e "$cur_dir/$name" ]]; then
            echo "$cur_dir"
            break
        elif [[ "$cur_dir" == "/" ]]; then
            echo "locate-dominating-file: $name not found in $dir or any of its parents" 1>&2
            return 1
        fi
        cur_dir="$cur_dir/.."
    done
}

# Change directory to the nearest one containing the given file or directory
#
# Example:
#
# ~/project/some/deep/path$ cdn .git # or README.md, go.mod etc.
# ~/project$
#
function cdn {
    cd "$(locate-dominating-file "$PWD" "$1")"
}

# Local aliases
source "$HOME/.zsh_aliases.local" 2> /dev/null

# Clean up functions
unfunction cond-alias alias-diff alias-ls