diff options
author | Martin Polden <mpolden@mpolden.no> | 2023-05-11 18:01:07 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2023-05-11 18:04:34 +0200 |
commit | 265d15d633871d780ef54b2c68cfe3789a40cd9e (patch) | |
tree | d8c6fba07b59ba1ed5cb94eb0d46b1475093fa65 | |
parent | bfa86962ee1e191b5334ebd0dadba46f2e55fcde (diff) |
zsh: add cdn alias
-rw-r--r-- | zsh_aliases | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/zsh_aliases b/zsh_aliases index e95febf..12e6c28 100644 --- a/zsh_aliases +++ b/zsh_aliases @@ -126,6 +126,48 @@ function venv { 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 directory is the current one, we replace it with $PWD + if [[ "$dir" == "." ]]; then + dir="$PWD" + 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 + 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/.." + cur_dir="${cur_dir:P}" # P converts to realpath + 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 [[ -s "$HOME/.zsh_aliases.local" ]] && source "$HOME/.zsh_aliases.local" |