ColorEchoForShell icon indicating copy to clipboard operation
ColorEchoForShell copied to clipboard

feat: add tcsh support

Open moormaster opened this issue 4 months ago • 5 comments

User description

See Issue #2


PR Type

Enhancement


Description

  • Add tcsh shell support with alias-based color functions

  • Refactor generator to support one-line function declarations

  • Update existing shell outputs to use condensed format

  • Fix character escaping for cross-shell compatibility


Diagram Walkthrough

flowchart LR
  A["Generator Script"] --> B["Shell Variables"]
  B --> C["tcsh Aliases"]
  B --> D["Other Shell Functions"]
  C --> E["ColorEcho.tcsh"]
  D --> F["Updated Shell Files"]
  G["Color Table"] --> A

File Walkthrough

Relevant files
Enhancement
generator.sh
Add tcsh support and refactor generator                                   

generator.sh

  • Add tcsh to supported shells list
  • Refactor shell-specific variables for one-line declarations
  • Add tcsh-specific configuration using aliases instead of functions
  • Simplify color table reading logic
+69/-34 
ColorEcho.tcsh
New tcsh color echo implementation                                             

dist/ColorEcho.tcsh

  • New tcsh shell support file with 1270+ color alias definitions
  • Uses alias instead of function declarations
  • Implements tcsh-specific parameter syntax with \!*
  • Includes Rainbow and Reset functionality with tcsh-compatible syntax
+1270/-0
Formatting
ColorEcho.bash
Refactor to one-line declarations                                               

dist/ColorEcho.bash

  • Convert multi-line if-else statements to one-line format
  • Update character class escaping in tr command
+2/-6     
ColorEcho.ksh
Refactor to one-line declarations                                               

dist/ColorEcho.ksh

  • Convert multi-line if-else statements to one-line format
  • Update character class escaping in tr command
+2/-6     
ColorEcho.sh
Refactor to one-line declarations                                               

dist/ColorEcho.sh

  • Convert multi-line if-else statements to one-line format
  • Update character class escaping in tr command
+2/-6     
ColorEcho.zsh
Refactor to one-line declarations                                               

dist/ColorEcho.zsh

  • Convert multi-line if-else statements to one-line format
  • Update character class escaping in tr command
+2/-6     
ColorEcho.fish
Refactor to one-line declarations                                               

dist/ColorEcho.fish

  • Convert multi-line if-else statements to one-line format
  • Update character class escaping in tr command
+2/-6     
Tests
tcsh
Add tcsh testing script                                                                   

test-scripts/tcsh

  • New test script for tcsh shell validation
  • Sources ColorEcho.tcsh and tests all alias functions
  • Uses tcsh-specific syntax for testing
+13/-0   

Summary by CodeRabbit

  • New Features
    • Added tcsh support and unified per-shell handling across sh, bash, zsh, ksh, fish, tcsh.
  • Refactor
    • Reworked per-shell templates and standardized inline generation for color, rainbow, and reset outputs; adjusted temporary/redirection semantics.
  • Bug Fixes
    • Replaced fragile extraction with a robust loop for color table processing.
  • Tests
    • Added a tcsh test harness and appended final colored-output checks in bash, fish, ksh, sh, and zsh test scripts.
  • Chores
    • Updated build/dist flow for the expanded shell set.

moormaster avatar Oct 01 '25 22:10 moormaster

[!NOTE]

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds tcsh support and a tcsh test harness; refactors generator.sh to use per-shell inline templates for escaping and control flow, replaces awk color parsing with while/read loops, consolidates inline generation for Rainbow/Reset blocks, and appends nested-color test outputs to existing shell test scripts.

Changes

Cohort / File(s) Summary
Generator: multi-shell templating & parsing
generator.sh
- Add tcsh as a target with alias-based function emulation, single-line control-flow, and adjusted quoting/escaping.
- Replace awk color-table parsing with while read loops using a colorCode variable.
- Introduce per-shell templates for escaping, conditionals, start/end symbols and para formatting.
- Convert multi-line echo/print constructions into inline single-line template usage for Rainbow/Reset blocks.
- Update end-of-block handling, inline condition checks, operator usage, and temp file/redirection assembly.
Testing: new tcsh harness
test-scripts/tcsh
- Add a Bash test harness that generates and pipes a temporary tcsh script which sources ColorEcho.tcsh.
- Extract alias +echo* lines from ColorEcho.tcsh to capture alias names and emit tcsh alias mappings, then execute via tcsh.
Testing: append nested-color output (existing shells)
test-scripts/bash, test-scripts/fish, test-scripts/ksh, test-scripts/sh, test-scripts/zsh
- Append a final test line that emits a nested colored message using the Reset wrapper around a Red-colored string with an embedded \033[32m sequence (e.g., echo.Reset "$( echo.Red "Red and \033[32m'green'" )" or shell-appropriate variant). No other control-flow or error-handling changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Developer
  participant Gen as generator.sh
  participant FS as Filesystem
  participant Shells as Target Shells (sh/bash/zsh/ksh/fish/tcsh)
  participant TestRunner as test-scripts/*

  Dev->>Gen: run generator.sh
  Gen->>FS: read color table files
  FS-->>Gen: return color lines
  Gen->>Gen: parse with while/read -> colorCode, labels
  Gen->>Gen: select per-shell templates (escape/if/startSym/endSym/para)
  loop generate per target shell
    Gen->>FS: write ColorEcho.<shell> using inline templates
    Gen->>FS: append Rainbow/Reset conditionals using shell template
  end
  Note right of Shells: tcsh uses alias-based handlers and single-line conditionals
  Dev->>TestRunner: run test-scripts/<shell>
  TestRunner->>FS: (for tcsh) generate runtime tcsh script mapping aliases
  TestRunner->>Shells: pipe or invoke shell to execute tests
  Shells->>FS: source ColorEcho.<shell> and run echo tests (including nested-color output)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary enhancement of adding tcsh support, directly reflecting the PR’s main objective of extending shell compatibility without unnecessary detail.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Oct 01 '25 22:10 coderabbitai[bot]

Summary of Changes

Hello @moormaster, I'm Gemini Code Assist[^1]! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the ColorEcho utility by introducing comprehensive support for the tcsh shell. This expansion allows tcsh users to leverage the tool's rich color output capabilities. The changes include the creation of a new tcsh-specific script, updates to the build generator to correctly handle tcsh's unique syntax, and minor code optimizations for existing shell scripts to improve readability and conciseness.

Highlights

  • tcsh Support Added: Introduced a new ColorEcho.tcsh script, extending color output functionality to the tcsh shell.
  • Generator Script Update: The generator.sh script was updated to include tcsh in its build process and adapt its syntax generation for tcsh's alias-based functions and conditional logic.
  • Code Refactoring for Conciseness: Existing echo.Rainbow and echo.Reset functions across various shell scripts (bash, fish, ksh, sh, zsh) were refactored to be more concise, consolidating multi-line if/else blocks into single lines.
  • New Test Script: A dedicated test script for tcsh was introduced to ensure proper functionality of the newly added support.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with :thumbsup: and :thumbsdown: on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

[^1]: Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

gemini-code-assist[bot] avatar Oct 01 '25 22:10 gemini-code-assist[bot]

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Insecure command lookup

Description: Using which lolcat to detect command availability can invoke user-controlled PATH lookups
and is discouraged; prefer command -v or explicit path to reduce risk of PATH hijacking in
privileged contexts.
ColorEcho.tcsh [1269-1269]

Referred Code
alias echo.Rainbow 'which lolcat >& /dev/null && echo "\!*" | lolcat || echo "\!*"'
alias echo.Reset 'echo "\!*" | tr -d \[\:cntrl\:\] | sed -E "s/\[((;)?[0-9]{1,3}){0,3}m//g" | xargs'
PATH hijack risk

Description: Piping untrusted input into lolcat without quoting the command path relies on PATH
resolution and could be abused in misconfigured environments; safer to use command -v
lolcat result to invoke with absolute path.
ColorEcho.bash [2518-2518]

Referred Code
  if command -v lolcat > /dev/null 2>&1; then echo "$*" | lolcat; else echo "$*"; fi
}
PATH hijack risk

Description: The generated rainbow logic for multiple shells executes lolcat via PATH resolution, which
could be hijacked if PATH is untrusted; capturing command -v lolcat and invoking the
absolute path would mitigate.
generator.sh [221-229]

Referred Code
        ifCond='which lolcat >& /dev/null'
        ;;
      *)
        ifCond='command -v lolcat > /dev/null 2>&1'
        ;;
    esac

    cat << LOLCAT >> "${tempDist}"
${fnName}${startSym}${if}${ifCond}${then}echo "${para}" | lolcat${else}echo "${para}"${endIf}${endSym}
Unsafe xargs usage

Description: echo "$*" | tr -d [:cntrl:] | sed -E ... | xargs may strip control characters and then
pass output to xargs, which can execute unintended behavior with leading/trailing
whitespace or embedded quotes; safer to avoid xargs and print directly.
ColorEcho.bash [2521-2521]

Referred Code
  echo "$*" | tr -d \[\:cntrl\:\] | sed -E "s/\\[((;)?[0-9]{1,3}){0,3}m//g" | xargs
}
Unsafe xargs usage

Description: xargs at the end of the Reset pipeline can transform or drop data and may execute commands
if misused; prefer sed alone or printf without xargs.
ColorEcho.sh [2528-2528]

Referred Code
  echo "$*" | tr -d \[\:cntrl\:\] | sed -E "s/\\[((;)?[0-9]{1,3}){0,3}m//g" | xargs
}
Unsafe xargs usage

Description: Reset pipeline ends with xargs, which can alter output semantics and poses risk if
extended; remove xargs and print the sanitized string directly.
ColorEcho.ksh [2521-2521]

Referred Code
  echo "$*" | tr -d \[\:cntrl\:\] | sed -E "s/\\[((;)?[0-9]{1,3}){0,3}m//g" | xargs
}
Unsafe xargs usage

Description: Reset function uses xargs on piped input which may lead to unexpected trimming or command
execution in future modifications; output directly without xargs.
ColorEcho.zsh [2521-2521]

Referred Code
  echo "$*" | tr -d \[\:cntrl\:\] | sed -E "s/\\[((;)?[0-9]{1,3}){0,3}m//g" | xargs
}
Unsafe xargs usage

Description: Reset implementation pipes to xargs, which is unnecessary and could introduce risks or
alter user data; avoid xargs and echo/printf the sanitized content.
ColorEcho.fish [2521-2521]

Referred Code
  echo "$argv" | tr -d \[\:cntrl\:\] | sed -E "s/\\[((;)?[0-9]{1,3}){0,3}m//g" | xargs
end
Unsafe xargs usage

Description: tcsh Reset alias ends with xargs, potentially altering output and enabling undesirable
behavior in edge cases; safer to omit xargs.
ColorEcho.tcsh [1270-1270]

Referred Code
alias echo.Reset 'echo "\!*" | tr -d \[\:cntrl\:\] | sed -E "s/\[((;)?[0-9]{1,3}){0,3}m//g" | xargs'
Ticket Compliance
🟡
🎫 #2
🔴 Explore and possibly add support for dash.
Explore and possibly add support for sash (Stand-alone shell).
Explore and possibly add support for wish (Tcl/Tk shell).
Explore and possibly add support for Thompson shell.
Explore and possibly add support for tcsh.
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • [ ] Update <!-- /compliance --update_compliance=true -->
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

PR Code Suggestions ✨

Latest suggestions up to 58d242d

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix fish if/else syntax

The single-line if-else-end statement in dist/ColorEcho.fish is invalid syntax
for the fish shell. Refactor it into a multi-line block to fix the syntax error.

dist/ColorEcho.fish [2517-2519]

 function echo.Rainbow
-  if command -v lolcat > /dev/null; echo "$argv" | lolcat; else; echo "$argv"; end
+  if command -v lolcat > /dev/null
+    echo "$argv" | lolcat
+  else
+    echo "$argv"
+  end
 end
  • [ ] Apply / Chat <!-- /improve --apply_suggestion=0 -->
Suggestion importance[1-10]: 10

__

Why: The suggestion correctly identifies a critical syntax error in the generated dist/ColorEcho.fish file, where the single-line if-else-end statement is invalid in fish shell, causing the function to fail.

High
Generate correct fish if blocks

The generator.sh script produces an invalid single-line if statement for the
fish shell. Add a case statement to generate a correct, multi-line if block
specifically for fish.

generator.sh [234-236]

-cat << LOLCAT >> "${tempDist}"
+case "${shell}" in
+  "fish")
+    cat << LOLCAT >> "${tempDist}"
+${fnName}${startSym}
+  ${ifCond}
+    echo "${para}" | lolcat
+  else
+    echo "${para}"
+  end
+${endSym}
+LOLCAT
+    ;;
+  *)
+    cat << LOLCAT >> "${tempDist}"
 ${fnName}${startSym}${if}${ifCond}${then}echo "${para}" | lolcat${else}echo "${para}"${endIf}${endSym}
 LOLCAT
+    ;;
+esac

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 10

__

Why: This suggestion correctly identifies the root cause of the syntax error in the generated fish script, which is the generic single-line if statement generation in generator.sh. It provides a correct and robust fix.

High
Fix sed escape sequence
Suggestion Impact:The sed command generation was modified at the echo.Reset block; although implemented differently (using leftQuote/rightQuote and removing the // replacement), it adjusted the pattern to correctly handle the escape before the bracket, addressing the escape issue highlighted by the suggestion.

code diff:

     # echo.Reset to remove color code on output
     fnName="${fn}echo${dot}Reset${brackets}"
     cat << RESET >> "${tempDist}"
-${fnName}${startSym}echo "${para}" | tr -d ${trCntrl} | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
+${fnName}${startSym}${exec}echo "${para}" | tr -d ${trCntrl} | sed -E ${leftQuote}s/${escape}[((;)?[0-9]{1,3}){0,3}m//g${rightQuote} | xargs${endSym}
 RESET

The sed pattern in generator.sh is malformed because it lacks a properly escaped
backslash. Correct this by using ${escape}${escape} to ensure the generated sed
command has the correct \[ pattern.

generator.sh [240-242]

 cat << RESET >> "${tempDist}"
-${fnName}${startSym}echo "${para}" | tr -d ${trCntrl} | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
+${fnName}${startSym}echo "${para}" | tr -d ${trCntrl} | sed -E "s/${escape}${escape}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
 RESET

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 10

__

Why: The suggestion correctly identifies a critical bug in the sed command generation. The escape variable needs to be doubled to correctly escape the backslash in the final script, and the suggestion provides the correct fix.

High
Possible issue
Fix fish single-line conditionals

In dist/ColorEcho.fish, fix the invalid single-line if/else syntax by using the
and/or operators for conditional execution.

dist/ColorEcho.fish [2518]

-if command -v lolcat > /dev/null; echo "$argv" | lolcat; else; echo "$argv"; end
+command -v lolcat > /dev/null; and echo "$argv" | lolcat; or echo "$argv"
  • [ ] Apply / Chat <!-- /improve --apply_suggestion=3 -->
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a syntax error in the generated fish script, as if/else cannot be chained with semicolons on a single line, and provides a valid fix using and/or.

High
Fix tcsh logical operator grouping

In dist/ColorEcho.tcsh, group the && expression in the echo.Rainbow alias with
parentheses to ensure the || part only executes if the which lolcat command
fails.

dist/ColorEcho.tcsh [1269]

-alias echo.Rainbow 'which lolcat >& /dev/null && echo "\!*" | lolcat || echo "\!*"'
+alias echo.Rainbow '( which lolcat >& /dev/null && echo "\!*" | lolcat ) || echo "\!*"'
  • [ ] Apply / Chat <!-- /improve --apply_suggestion=4 -->
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential logic bug in tcsh where the || part could execute incorrectly, and proposes a valid fix by grouping the && condition with parentheses.

Medium
  • [ ] Update <!-- /improve_multi --more_suggestions=true -->

Previous suggestions

✅ Suggestions up to commit 6820bcd
CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix incorrect tr character class
Suggestion Impact:The commit replaced the hardcoded incorrect tr class with a variable set to the correct '[:cntrl:]' (and a tcsh-safe variant), and used that variable in the echo.Reset pipeline, fixing the bug.

code diff:

+        trCntrl="'[:cntrl:]'"
         ;;
       "ksh")
         ifCond='command -v lolcat 2> /dev/null >&2'
+        trCntrl="'[:cntrl:]'"
         ;;
       "tcsh")
         ifCond='which lolcat >& /dev/null'
+        # tcsh uses aliases instead of functions -> replace ', [ and ] with quoted chars
+        trCntrl='\\x27\[:cntrl:\]\\x27'
         ;;
       *)
         ifCond='command -v lolcat > /dev/null 2>&1'
+        trCntrl="'[:cntrl:]'"
         ;;
     esac
 
@@ -232,7 +237,7 @@
     # echo.Reset to remove color code on output
     fnName="${fn}echo${dot}Reset${brackets}"
     cat << RESET >> "${tempDist}"
-${fnName}${startSym}echo "${para}" | tr -d \[\:cntrl\:\] | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
+${fnName}${startSym}echo "${para}" | tr -d ${trCntrl} | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
 RESET

Correct the tr command by replacing the improperly escaped character class
[:cntrl:] with the correctly quoted POSIX character class '[:cntrl:]' to fix
a bug in the echo.Reset function.

generator.sh [235]

-${fnName}${startSym}echo "${para}" | tr -d \[\:cntrl\:\] | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}
+${fnName}${startSym}echo "${para}" | tr -d '[:cntrl:]' | sed -E "s/${escape//\//\/\/}[((;)?[0-9]{1,3}){0,3}m//g" | xargs${endSym}

[Suggestion processed]

Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a significant bug introduced in the PR that breaks the echo.Reset functionality by using an incorrect character class syntax for tr.

High
General
Avoid useless use of cat
Suggestion Impact:The pipeline using cat was removed and the loop now reads directly, with input redirection added to read from the file.

code diff:

-    cat "${table}" | while read -r color colorCode; do
+    while read -r color colorCode; do
       # light or not
       for light in "" "Light"; do
         if [ "${light}" = "" ]; then
@@ -206,22 +206,28 @@
           done
         done
       done
-    done
+    done < "${table}"

Refactor the while loop to read directly from the file using input redirection
instead of piping from cat.

generator.sh [165]

-cat "${table}" | while read -r color colorCode; do
+while read -r color colorCode; do
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies a "useless use of cat" and proposes a more efficient shell scripting pattern, which is a valid code quality improvement.

Low

@codex review

PeterDaveHello avatar Oct 02 '25 18:10 PeterDaveHello