aboutsummaryrefslogtreecommitdiff
path: root/sh/shrc.d/pd.sh
blob: de4ea23b2b2c12e6be9f655e88853fde52653b5d (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
# Attempt to change into the argument's parent directory; This is intended for
# use when you've got a file path in a variable, or in history, or in Alt+.,
# and want to quickly move to its containing directory. In the absence of an
# argument, this just shifts up a directory, i.e. `cd ..`
pd() {

    # Check argument count
    if [ "$#" -gt 1 ] ; then
        printf >&2 'pd(): Too many arguments\n'
        return 2
    fi

    # Change the positional parameters from the target to its containing
    # directory
    set -- "$(

        # Figure out target dirname
        dirname=${1:-..}
        dirname=${dirname%/}
        dirname=${dirname%/*}

        # Check we have a target after that
        if [ -z "$dirname" ] ; then
            printf >&2 'ud(): Destination construction failed\n'
            exit 1
        fi

        # Print the target
        printf '%s\n' "$dirname"
    )"

    # If the subshell printed nothing, return with failure
    [ -n "$1" ] || return

    # Try to change into the determined directory
    command cd -- "$@"
}