The modifications that I made were - "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\([ \t]*\\)[ \t]*" - so that is allows foo() and foo ( ). "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\([ \t]*\\)[ \t]*(\\{|\\(|\\[\\[)" - so that it recognises {, (, or [[ as function bodies "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\([ \t]*\\)[ \t]*(\\{|\\(|\\[\\[)|\\\\\n"- so that it matches "function foo \ { echo "hello"; }" "(?:function[ \t]+(?=[a-zA-Z_]))?[a-zA-Z_][a-zA-Z0-9_]*(([ \t]*\\([ \t]*\\))|([ \t]+))?" - so that it matches function foo() { echo "hello"; } and also function bar { echo "no parens"; } "|\\$[a-zA-Z_][a-zA-Z0-9_]*|\\$\\{[^}]+\\}"- It seperates ${} expansions "|--?[a-zA-Z0-9_-]+" - It ensures -opt and --long-opt are treated as whole tokens. "|[0-9]+(\\.[0-9]*)?" - It matches numbers without +/- Moumita Dhar (1): userdiff: extend Bash pattern to cover more shell function forms userdiff.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) Range-diff against v1: 1: 683ea08819 ! 1: de2e8f9792 userdiff : Added built in function recognition for shell @@ ## Metadata ## -Author: Moumita <dhar61595@xxxxxxxxx> +Author: Moumita Dhar <dhar61595@xxxxxxxxx> ## Commit message ## - userdiff : Added built in function recognition for shell + userdiff: extend Bash pattern to cover more shell function forms - Introduced a built-in userdiff driver for shell scripts, enabling - accurate function name recognition in `git diff` hunk headers. + The existing Bash userdiff pattern misses some shell function forms, such as + `function foo()`, multi-line definitions, and extra whitespace. - Enhancements include: - - Function name detection for both POSIX and Bash/Ksh-style functions: - - `function_name() { ... }` - - `function function_name { ... }` - - Exclusion of shell keywords that can resemble function names, - preventing false matches (e.g., `if`, `for`, `while`, `return`, etc.). - - Improved tokenization support for: - - Identifiers (variable and function names) - - Numeric constants (integers and decimals) - - Shell variables (`$VAR`, `${VAR}`) - - Logical (`&&`, `||`, `==`, `!=`, `<=`, `>=`) and arithmetic operators - - Assignment and redirection operators - - Brackets and grouping symbols + Extend the pattern to: + - Support `function foo()` syntax. + - Allow spaces in `foo ( )` definitions. + - Recognize multi-line definitions with backslashes. + - Broaden function body detection. - This update improves Git’s diff readability for shell scripts, - bringing it in line with existing built-in userdiff drivers. - - Signed-off-by: Moumita <dhar61595@xxxxxxxxx> + Signed-off-by: Moumita Dhar <dhar61595@xxxxxxxxx> ## userdiff.c ## -@@ userdiff.c: PATTERNS("scheme", - "\\|([^\\\\]*)\\|" - /* All other words should be delimited by spaces or parentheses */ - "|([^][)(}{[ \t])+"), -+PATTERNS("shell", -+ /* Negate shell keywords that can look like functions */ -+ "!^[ \t]*(if|elif|else|fi|for|while|until|case|esac|then|do|done|return|break|continue)\\b\n" -+ /* POSIX-style shell functions: function_name() { ... } */ -+ "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\(\\)[ \t]*\\{\n" -+ /* Bash/Ksh-style functions: function function_name { ... } */ -+ "^[ \t]*function[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*\\{\n", -+ /* -- */ +@@ userdiff.c: IPATTERN("ada", + "|[-+]?[0-9][0-9#_.aAbBcCdDeEfF]*([eE][+-]?[0-9_]+)?" + "|=>|\\.\\.|\\*\\*|:=|/=|>=|<=|<<|>>|<>"), + PATTERNS("bash", +- /* Optional leading indentation */ ++ /* Optional leading indentation */ + "^[ \t]*" +- /* Start of captured text */ ++ /* Start of captured function name */ + "(" + "(" +- /* POSIX identifier with mandatory parentheses */ +- "[a-zA-Z_][a-zA-Z0-9_]*[ \t]*\\([ \t]*\\))" ++ /* POSIX identifier with mandatory parentheses (allow spaces inside) */ ++ "[a-zA-Z_][a-zA-Z0-9_]*[ \t]*\\([ \t]*\\)" + "|" +- /* Bashism identifier with optional parentheses */ +- "(function[ \t]+[a-zA-Z_][a-zA-Z0-9_]*(([ \t]*\\([ \t]*\\))|([ \t]+))" ++ /* Bash-style function definitions, allowing optional `function` keyword */ ++ "(?:function[ \t]+(?=[a-zA-Z_]))?[a-zA-Z_][a-zA-Z0-9_]*(([ \t]*\\([ \t]*\\))|([ \t]+))?" + ")" + /* Optional whitespace */ + "[ \t]*" +- /* Compound command starting with `{`, `(`, `((` or `[[` */ +- "(\\{|\\(\\(?|\\[\\[)" +- /* End of captured text */ ++ /* Allow function body to start with `{`, `(` (subshell), `[[` */ ++ "(\\{|\\(|\\[\\[)" ++ /* End of captured function name */ + ")", + /* -- */ +- /* Characters not in the default $IFS value */ +- "[^ \t]+"), + /* Identifiers: variable and function names */ + "[a-zA-Z_][a-zA-Z0-9_]*" + /* Numeric constants: integers and decimals */ -+ "|[-+]?[0-9]+(\\.[0-9]*)?" -+ /* Shell variables: $VAR and ${VAR} */ ++ "|[-+]?[0-9]+(\\.[0-9]*)?|[-+]?\\.[0-9]+" ++ /* Shell variables: `$VAR`, `${VAR}` */ + "|\\$[a-zA-Z_][a-zA-Z0-9_]*|\\$\\{[^}]+\\}" + /* Logical and comparison operators */ + "|\\|\\||&&|<<|>>|==|!=|<=|>=" + /* Assignment and arithmetic operators */ + "|[-+*/%&|^!=<>]=?" ++ /* Command-line options (to avoid splitting `-option`) */ ++ "|--?[a-zA-Z0-9_-]+" + /* Brackets and grouping symbols */ + "|\\(|\\)|\\{|\\}|\\[|\\]"), - PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$", - "\\\\[a-zA-Z@]+|\\\\.|([a-zA-Z0-9]|[^\x01-\x7f])+"), - { .name = "default", .binary = -1 }, + PATTERNS("bibtex", + "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$", + /* -- */ -- 2.48.0