@@ -21,79 +21,153 @@ function __gitprofiles_hook() {
21
21
return 1
22
22
fi
23
23
24
+ # Ensure glob patterns that don't match don't cause errors
25
+ setopt LOCAL_OPTIONS NO_NOMATCH
26
+
24
27
# # 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} "
26
42
27
43
# # 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} '"
30
46
return 1
31
47
fi
32
48
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
37
50
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 " )
44
82
done
45
83
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
51
86
52
- echo ${paths}
53
- }
87
+ # [[ -n "${GP_DEBUG}" ]] && print -u2 "Final paths: ${paths}"
88
+ print -l -- ${paths}
89
+ }
54
90
55
- # # Iterate over all profiles to get the name, email, signingkey and path
91
+ # # Parse configuration for each profile
56
92
for profile in ${profiles} ; do
57
93
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} "
58
142
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 " )} "
73
147
fi
74
148
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]} "
77
152
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]} "
80
155
fi
81
156
done
82
157
83
158
# Get current directory
84
159
local current_dir=$( pwd)
85
160
local matched_profile=" default"
86
161
87
- [[ -n " ${DEBUG } " ]] && echo " Current directory: ${current_dir} "
162
+ [[ -n " ${GP_DEBUG } " ]] && print -u2 " Current directory: ${current_dir} "
88
163
89
164
# Check if current directory matches any profile paths
90
165
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} "
94
167
168
+ local paths=(${=profile_paths_map[$profile]} ) # Convert to array
95
169
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} "
97
171
98
172
if [[ " ${current_dir} " =~ " ${path_pattern} " ]]; then
99
173
matched_profile=" ${profile} "
@@ -111,17 +185,16 @@ function __gitprofiles_hook() {
111
185
git config --global user.signingkey " ${profile_cfg_map[${matched_profile}.signingkey]} "
112
186
fi
113
187
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]} "
120
194
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]} "
122
196
fi
123
197
fi
124
198
}
125
199
126
-
127
200
add-zsh-hook chpwd __gitprofiles_hook
0 commit comments