@@ -21,79 +21,153 @@ function __gitprofiles_hook() {
2121 return 1
2222 fi
2323
24+ # Ensure glob patterns that don't match don't cause errors
25+ setopt LOCAL_OPTIONS NO_NOMATCH
26+
2427 # # Load all stored profiles
25- local profiles=($( grep -o ' \[profile [^]]*\]' ${profile_filepath} | tr -d ' []" ' | sed ' s/profile//g' | tr ' \n' ' ' ) )
28+ local profiles=()
29+ local current_section=" "
30+
31+ while IFS= read -r line; do
32+ # Skip empty lines and comments
33+ [[ -z " $line " || " $line " == \# * ]] && continue
34+
35+ # Check for profile section
36+ if [[ " $line " =~ ' ^\[profile[[:space:]]+"([^"]+)"\]' ]]; then
37+ current_section=" ${match[1]} "
38+ profiles+=(" $current_section " )
39+ [[ -n " ${GP_DEBUG} " ]] && print -u2 " Found profile: ${current_section} "
40+ fi
41+ done < " ${profile_filepath} "
2642
2743 # # Check if default profile exists
28- if [[ ! " ${profiles} " =~ " default" ]]; then
29- echo " gitprofiles: 'default' profile not found in '${profile_filepath} '"
44+ if [[ ! " ${profiles[(r) default]} " ]]; then
45+ print -u2 " gitprofiles: 'default' profile not found in '${profile_filepath} '"
3046 return 1
3147 fi
3248
33- # Ensure glob patterns that don't match don't cause errors
34- setopt LOCAL_OPTIONS NO_NOMATCH
35-
36- # Function to parse paths into an array and support tidle expansion
49+ # Function to parse paths into an array and support tilde expansion
3750 function __parse_paths() {
38- local raw_paths=" ${(j: \n : )@ } " # join args with newlines
39- local temp=(${(s: ,: )raw_paths} ) # split on commas first
40- # Now split each part by newlines
41- local paths=()
42- for part in $temp ; do
43- paths+=(${(f)part} ) # split on newlines
51+ local raw_paths=" $1 "
52+ # [[ -n "${GP_DEBUG}" ]] && print -u2 "Raw paths input: ${(q)raw_paths}"
53+
54+ local -a path_lines
55+ # split on commas or newlines
56+ path_lines=(${(s: ,: )${(f)raw_paths} } )
57+
58+ # Process each line
59+ local -a paths
60+ local line
61+ for line in $path_lines ; do
62+ # remove newlines
63+ line=" ${line// ' \n' / } "
64+
65+ # remove quotes
66+ line=" ${line// [\"\']} "
67+
68+ # Remove trailing commas
69+ line=" ${line%% ,} "
70+
71+ # Trim whitespace
72+ line=" ${line## } "
73+ line=" ${line%% } "
74+
75+ # Expand tildes
76+ if [[ $line = " ~" * ]]; then
77+ line=${HOME}${line# " ~" }
78+ fi
79+
80+ # Skip empty lines
81+ [[ -n " $line " ]] && paths+=(" $line " )
4482 done
4583
46- # Process each path
47- paths=(${paths## [[:space:]]} ) # Trim leading spaces
48- paths=(${paths%% [[:space:]]} ) # Trim trailing spaces
49- paths=(${~paths} ) # Expand tilde
50- paths=(${paths:# } ) # Remove empty elements
84+ # Expand tildes
85+ # paths=(${~paths}) # this doesnt work as it expands the glob
5186
52- echo ${paths}
53- }
87+ # [[ -n "${GP_DEBUG}" ]] && print -u2 "Final paths: ${paths}"
88+ print -l -- ${paths}
89+ }
5490
55- # # Iterate over all profiles to get the name, email, signingkey and path
91+ # # Parse configuration for each profile
5692 for profile in ${profiles} ; do
5793 typeset -A profile_value_map
94+ local in_current_profile=0
95+ local in_paths=0
96+ local paths_tmp=()
97+
98+ while IFS= read -r line; do
99+ # Skip empty lines and comments
100+ [[ -z " $line " || " $line " == \# * ]] && continue
101+
102+ # Check for profile section
103+ if [[ " $line " =~ ' ^\[profile[[:space:]]+"([^"]+)"\]' ]]; then
104+ if [[ " ${match[1]} " == " $profile " ]]; then
105+ in_current_profile=1
106+ else
107+ in_current_profile=0
108+ in_paths=0
109+ fi
110+ continue
111+ fi
112+
113+ # Only process lines for current profile
114+ (( in_current_profile )) || continue
115+
116+ # Parse key-value pairs
117+ if [[ " $line " =~ ' ^[[:space:]]*([^=]+)[[:space:]]*=[[:space:]]*(.*)' ]]; then
118+ local key=" ${match[1]## } " # Trim leading spaces
119+ key=" ${key%% } " # Trim trailing spaces
120+ local value=" ${match[2]} " # Keep spaces in value for now
121+
122+ case " $key " in
123+ name|email|signingkey)
124+ # Remove quotes and trim for non-path values
125+ value=" ${value## } " # Trim leading spaces
126+ value=" ${value%% } " # Trim trailing spaces
127+ value=" ${value# [\"\']} " # Remove leading quote
128+ value=" ${value% [\"\']} " # Remove trailing quote
129+ profile_value_map[$key ]=" $value "
130+ ;;
131+ path|paths)
132+ in_paths=1
133+ paths_tmp=(" $value " )
134+ ;;
135+ esac
136+ elif (( in_paths )) && [[ " $line " =~ ' ^[[:space:]]+(.*)' ]]; then
137+ # Handle indented continuation lines for paths
138+ local value=" ${match[1]} "
139+ paths_tmp+=(" $value " )
140+ fi
141+ done < " ${profile_filepath} "
58142
59- while read -r key value; do
60- case " ${key} " in
61- name|email|signingkey)
62- profile_value_map[${key} ]=" ${value} "
63- ;;
64- path|paths)
65- profile_value_map[paths]=" ${value} "
66- ;;
67- esac
68- done < <( awk -F ' = ' ' /^\[profile/{p=0} /^\[profile "[^"]*' " ${profile} " ' "/{p=1} p {gsub(/"/, "", $2); print $1,$2}' ${profile_filepath} )
69-
70- # Parse paths
71- if [[ -n " ${profile_value_map[paths]} " ]]; then
72- profile_paths_map[${profile} ]=" $( __parse_paths " ${profile_value_map[paths]} " ) "
143+ # Join and parse paths
144+ if (( ${# paths_tmp} > 0 )) ; then
145+ local joined_paths=" ${(j: \n : )paths_tmp} "
146+ profile_paths_map[$profile ]=" ${(@ f)$(__parse_paths " $joined_paths " )} "
73147 fi
74148
75- profile_cfg_map[${profile} .name]=" ${profile_value_map[name]} "
76- profile_cfg_map[${profile} .email]=" ${profile_value_map[email]} "
149+ # Store other configurations
150+ profile_cfg_map[$profile .name]=" ${profile_value_map[name]} "
151+ profile_cfg_map[$profile .email]=" ${profile_value_map[email]} "
77152
78- if [[ -n " ${profile [signingkey]} " ]]; then
79- profile_cfg_map[${ profile} .signingkey]=" ${profile_value_map[signingkey]} "
153+ if [[ -n " ${profile_value_map [signingkey]} " ]]; then
154+ profile_cfg_map[$profile .signingkey]=" ${profile_value_map[signingkey]} "
80155 fi
81156 done
82157
83158 # Get current directory
84159 local current_dir=$( pwd)
85160 local matched_profile=" default"
86161
87- [[ -n " ${DEBUG } " ]] && echo " Current directory: ${current_dir} "
162+ [[ -n " ${GP_DEBUG } " ]] && print -u2 " Current directory: ${current_dir} "
88163
89164 # Check if current directory matches any profile paths
90165 for profile in ${(k)profile_paths_map} ; do
91- [[ -n " ${DEBUG} " ]] && echo " Testing Profile: ${profile} "
92-
93- local paths=(${=profile_paths_map[${profile}]} ) # Convert to array
166+ [[ -n " ${GP_DEBUG} " ]] && print -u2 " Testing Profile: ${profile} "
94167
168+ local paths=(${=profile_paths_map[$profile]} ) # Convert to array
95169 for path_pattern in $paths ; do
96- [[ -n " ${DEBUG } " ]] && echo " Checking path pattern: ${path_pattern} "
170+ [[ -n " ${GP_DEBUG } " ]] && print -u2 " Testing path pattern: ${path_pattern} "
97171
98172 if [[ " ${current_dir} " =~ " ${path_pattern} " ]]; then
99173 matched_profile=" ${profile} "
@@ -111,17 +185,16 @@ function __gitprofiles_hook() {
111185 git config --global user.signingkey " ${profile_cfg_map[${matched_profile}.signingkey]} "
112186 fi
113187
114- # Print debug information if DEBUG is set
115- if [[ -n " ${DEBUG } " ]]; then
116- echo " Matched profile: ${matched_profile} "
117- echo " Using configuration:"
118- echo " name: ${profile_cfg_map[${matched_profile}.name]} "
119- echo " email: ${profile_cfg_map[${matched_profile}.email]} "
188+ # Print debug information if GP_DEBUG is set
189+ if [[ -n " ${GP_DEBUG} " ]] && [[ -n " ${matched_profile }" ]]; then
190+ print -u2 " Matched profile: ${matched_profile} "
191+ print -u2 " Using configuration:"
192+ print -u2 " name: ${profile_cfg_map[${matched_profile}.name]} "
193+ print -u2 " email: ${profile_cfg_map[${matched_profile}.email]} "
120194 if [[ -n " ${profile_cfg_map[${matched_profile}.signingkey]} " ]]; then
121- echo " signingkey: ${profile_cfg_map[${matched_profile}.signingkey]} "
195+ print -u2 " signingkey: ${profile_cfg_map[${matched_profile}.signingkey]} "
122196 fi
123197 fi
124198}
125199
126-
127200add-zsh-hook chpwd __gitprofiles_hook
0 commit comments