From dc3f81336ec346521921fe650db5513bc8cc585d Mon Sep 17 00:00:00 2001 From: Jor Sanders Date: Sat, 25 Jul 2026 03:38:32 +0200 Subject: [PATCH] feat: sw suffix-copy resolution and git branch prompt - sw: when multiple matches only differ by a suffix (nos-next vs nos-next-copy), open the main one instead of failing as ambiguous - profile/prompt: oh-my-zsh style prompt with the current git branch, for both zsh and bash Co-Authored-By: Claude Fable 5 --- bin/sw | 49 ++++++++++++++++++++++++++++++++++++++++++------- profile/prompt | 20 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 7 deletions(-) create mode 100755 profile/prompt diff --git a/bin/sw b/bin/sw index 6726332..ed6a6e0 100755 --- a/bin/sw +++ b/bin/sw @@ -10,8 +10,10 @@ and one level deeper. is matched against folder names as a case-insensitive extended regex; whole-name matches win over partial matches, and direct children win over deeper folders. -If multiple folders match equally well, all matches are listed and nothing -is opened. +If multiple folders match equally well but one folder's name is a prefix +of all the others (nos-next among nos-next-copy and nos-next-2), that main +folder is opened. Genuinely different matches are listed and nothing is +opened. EOF } @@ -35,6 +37,34 @@ if ! command -v code >/dev/null 2>&1; then exit 1 fi +# Prints the match whose folder name is a prefix of all other matches' +# names (e.g. nos-next among nos-next-copy and nos-next-2). Prints nothing +# when the matches are genuinely different. +main_of() { + shortest='' + main='' + while IFS= read -r dir; do + base=$(basename "$dir" | tr '[:upper:]' '[:lower:]') + if [ -z "$shortest" ] || [ "${#base}" -lt "${#shortest}" ]; then + shortest=$base + main=$dir + fi + done <&2 - printf '%s\n' "$matches" | sed 's/^/ /' >&2 - exit 1 + match=$(main_of "$matches") + if [ -z "$match" ]; then + echo "'$name' matches multiple projects:" >&2 + printf '%s\n' "$matches" | sed 's/^/ /' >&2 + exit 1 + fi + echo "The other matches are copies of $(basename "$match") with a suffix" fi - echo "Opening $matches" - code "$matches" + echo "Opening $match" + code "$match" exit $? } diff --git a/profile/prompt b/profile/prompt new file mode 100755 index 0000000..bddecd1 --- /dev/null +++ b/profile/prompt @@ -0,0 +1,20 @@ +#!/bin/sh + +# Show the current git branch in the prompt, oh-my-zsh style: +# ➜ dir (branch) + +git_branch() { + branch=$(git symbolic-ref --short -q HEAD 2>/dev/null) || + branch=$(git rev-parse --short HEAD 2>/dev/null) || + return 0 + printf ' (%s)' "$branch" +} + +if [ -n "$ZSH_VERSION" ]; then + setopt PROMPT_SUBST + # shellcheck disable=SC2016,SC2034 + PROMPT='%(?.%F{green}.%F{red})➜%f %F{cyan}%c%f%F{blue}$(git_branch)%f ' +elif [ -n "$BASH_VERSION" ]; then + # shellcheck disable=SC2016 + PS1='➜ \[\e[36m\]\W\[\e[34m\]$(git_branch)\[\e[0m\] ' +fi