-
Notifications
You must be signed in to change notification settings - Fork 0
fix(ohmyposh): ensure prompt loads last to avoid conflicts #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,86 @@ | ||||||||||||||||||||||||||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||||||||||||||||||||||||||
| set -e | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # This script ensures Oh My Posh configuration is at the end of shell RC files | ||||||||||||||||||||||||||||||||||||||||||||
| # to avoid being overwritten by other features (like shell-history). | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| move_to_end() { | ||||||||||||||||||||||||||||||||||||||||||||
| local rc_file="$1" | ||||||||||||||||||||||||||||||||||||||||||||
| local start_marker="# region Oh My Posh configuration" | ||||||||||||||||||||||||||||||||||||||||||||
| local end_marker="# endregion Oh My Posh configuration" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if [ -f "$rc_file" ]; then | ||||||||||||||||||||||||||||||||||||||||||||
| # Check for the region markers | ||||||||||||||||||||||||||||||||||||||||||||
| if grep -q "$start_marker" "$rc_file"; then | ||||||||||||||||||||||||||||||||||||||||||||
| echo "Ensuring Oh My Posh configuration is at the end of $rc_file..." | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Extract the block | ||||||||||||||||||||||||||||||||||||||||||||
| local block=$(sed -n "/$start_marker/,/$end_marker/p" "$rc_file") | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| if [ -n "$block" ]; then | ||||||||||||||||||||||||||||||||||||||||||||
| # Create a temp file | ||||||||||||||||||||||||||||||||||||||||||||
| local temp_file=$(mktemp) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Write file content WITHOUT the block to temp file | ||||||||||||||||||||||||||||||||||||||||||||
| # We use awk to exclude the range | ||||||||||||||||||||||||||||||||||||||||||||
| if ! awk -v start="$start_marker" -v end="$end_marker" ' | ||||||||||||||||||||||||||||||||||||||||||||
| $0 ~ start {skip=1; next} | ||||||||||||||||||||||||||||||||||||||||||||
| $0 ~ end {skip=0; next} | ||||||||||||||||||||||||||||||||||||||||||||
| !skip {print} | ||||||||||||||||||||||||||||||||||||||||||||
| ' "$rc_file" > "$temp_file"; then | ||||||||||||||||||||||||||||||||||||||||||||
| echo "Error: Failed to process $rc_file" | ||||||||||||||||||||||||||||||||||||||||||||
| rm -f "$temp_file" | ||||||||||||||||||||||||||||||||||||||||||||
| return 1 | ||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Append the block to the end | ||||||||||||||||||||||||||||||||||||||||||||
| echo "" >> "$temp_file" | ||||||||||||||||||||||||||||||||||||||||||||
| echo "$block" >> "$temp_file" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Replace original file | ||||||||||||||||||||||||||||||||||||||||||||
| mv "$temp_file" "$rc_file" | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| echo "Moved Oh My Posh configuration to the end of $rc_file" | ||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||
| # Fallback: Check for old configuration without markers | ||||||||||||||||||||||||||||||||||||||||||||
| elif grep -q "oh-my-posh init" "$rc_file"; then | ||||||||||||||||||||||||||||||||||||||||||||
| echo "Found legacy Oh My Posh configuration in $rc_file. Moving to end and adding markers..." | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Create a temp file | ||||||||||||||||||||||||||||||||||||||||||||
| local temp_file=$(mktemp) | ||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||
| # Replace lines containing "oh-my-posh init" with ":" (no-op) to disable old config | ||||||||||||||||||||||||||||||||||||||||||||
| # while preserving syntax validity of surrounding if/else blocks. | ||||||||||||||||||||||||||||||||||||||||||||
| sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file" | ||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+54
|
||||||||||||||||||||||||||||||||||||||||||||
| # Replace lines containing "oh-my-posh init" with ":" (no-op) to disable old config | |
| # while preserving syntax validity of surrounding if/else blocks. | |
| sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file" | |
| # Comment out the entire legacy oh-my-posh block (including comments and conditionals) for clarity. | |
| # This avoids leaving behind confusing empty if/else/fi blocks. | |
| awk ' | |
| BEGIN {in_block=0} | |
| /Use custom theme if mounted/ {in_block=1; print "# [oh-my-posh legacy config commented out] " $0; next} | |
| /Use built-in theme/ {if (in_block) {print "# [oh-my-posh legacy config commented out] " $0; next}} | |
| /oh-my-posh init/ {if (in_block) {print "# [oh-my-posh legacy config commented out] " $0; next}} | |
| /fi/ {if (in_block) {print "# [oh-my-posh legacy config commented out] " $0; in_block=0; next}} | |
| {if (in_block) {print "# [oh-my-posh legacy config commented out] " $0} else {print $0}} | |
| ' "$rc_file" > "$temp_file" |
Copilot
AI
Nov 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern in sed uses .*oh-my-posh init.* which could match unintended lines. For example, if a user has a comment like # Don't use oh-my-posh init directly, this line would also be replaced with :.
Consider making the pattern more specific to match only actual eval statements, such as:
sed 's/^\([[:space:]]*\)eval.*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file"| sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file" | |
| sed 's/^\([[:space:]]*\)eval.*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file" |
Copilot
AI
Nov 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the sed command. If the sed operation fails, the temp file will still be moved over the original RC file (line 57), potentially corrupting the user's configuration.
Consider checking the exit status of sed before moving the temp file, similar to the error handling in the region marker path (lines 26-34).
| sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file" | |
| if ! sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" > "$temp_file"; then | |
| echo "Error: Failed to process $rc_file with sed" | |
| rm -f "$temp_file" | |
| return 1 | |
| fi |
Copilot
AI
Nov 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The theme is hardcoded to "jandedobbeleer" in the legacy migration logic, but the feature supports custom themes via the theme option in devcontainer-feature.json. When migrating legacy configurations, users who had configured a custom theme will lose that configuration and get the hardcoded theme instead.
Consider passing the configured theme value to this script (perhaps via an environment variable or config file) and using it instead of the hardcoded value.
| # Use echo to append to avoid issues with cat and EOF in some environments or if file is empty | |
| echo "" >> "$rc_file" | |
| echo "$start_marker" >> "$rc_file" | |
| echo "if [ -s ~/.ohmyposh.json ]; then" >> "$rc_file" | |
| echo " eval \"\$(oh-my-posh init $shell_name --config ~/.ohmyposh.json)\"" >> "$rc_file" | |
| echo "else" >> "$rc_file" | |
| echo " eval \"\$(oh-my-posh init $shell_name --config jandedobbeleer)\"" >> "$rc_file" | |
| # Determine theme from environment variable or default to "jandedobbeleer" | |
| local oh_my_posh_theme="${OH_MY_POSH_THEME:-jandedobbeleer}" | |
| # Use echo to append to avoid issues with cat and EOF in some environments or if file is empty | |
| echo "" >> "$rc_file" | |
| echo "$start_marker" >> "$rc_file" | |
| echo "if [ -s ~/.ohmyposh.json ]; then" >> "$rc_file" | |
| echo " eval \"\$(oh-my-posh init $shell_name --config ~/.ohmyposh.json)\"" >> "$rc_file" | |
| echo "else" >> "$rc_file" | |
| echo " eval \"\$(oh-my-posh init $shell_name --config \$oh_my_posh_theme)\"" >> "$rc_file" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,6 +78,11 @@ mkdir -p "$INSTALL_PATH" | |
| mv "$TEMP_FILE" "$INSTALL_PATH/oh-my-posh" | ||
| chmod +x "$INSTALL_PATH/oh-my-posh" | ||
|
|
||
| # Install the configure script | ||
| HELPER_SCRIPT="/usr/local/bin/oh-my-posh-configure-shell" | ||
| cp "$(dirname "$0")/configure-shell.sh" "$HELPER_SCRIPT" | ||
| chmod +x "$HELPER_SCRIPT" | ||
|
Comment on lines
+81
to
+84
|
||
|
|
||
| echo -e "${GREEN}Oh My Posh binary installed to $INSTALL_PATH/oh-my-posh${NC}" | ||
|
|
||
| # Verify installation | ||
|
|
@@ -146,14 +151,15 @@ for SHELL_NAME in "${SHELL_ARRAY[@]}"; do | |
| # Add Oh My Posh initialization | ||
| cat >> "$RC_FILE" << EOF | ||
|
|
||
| # Oh My Posh configuration | ||
| # region Oh My Posh configuration | ||
|
||
| if [ -s ~/.ohmyposh.json ]; then | ||
| # Use custom theme if mounted | ||
| eval "\$(oh-my-posh init $SHELL_CMD --config ~/.ohmyposh.json)" | ||
| else | ||
| # Use built-in theme | ||
| eval "\$(oh-my-posh init $SHELL_CMD --config $THEME)" | ||
| fi | ||
| # endregion Oh My Posh configuration | ||
| EOF | ||
|
|
||
| chown "$USER_NAME:$USER_NAME" "$RC_FILE" 2>/dev/null || true | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,72 @@ | ||||||||||
| #!/bin/bash | ||||||||||
|
|
||||||||||
| set -e | ||||||||||
|
|
||||||||||
| source dev-container-features-test-lib | ||||||||||
|
|
||||||||||
| # 1. Verify the helper script is installed | ||||||||||
| check "helper script installed" test -x /usr/local/bin/oh-my-posh-configure-shell | ||||||||||
|
|
||||||||||
| # 2. Simulate legacy configuration (no markers) | ||||||||||
| cat > ~/.bashrc << EOF | ||||||||||
| # Some initial content | ||||||||||
| export PATH=\$PATH:/something | ||||||||||
|
|
||||||||||
| # Oh My Posh configuration | ||||||||||
| if [ -s ~/.ohmyposh.json ]; then | ||||||||||
| # Use custom theme if mounted | ||||||||||
| eval "\$(oh-my-posh init bash --config ~/.ohmyposh.json)" | ||||||||||
| else | ||||||||||
| # Use built-in theme | ||||||||||
| eval "\$(oh-my-posh init bash --config jandedobbeleer)" | ||||||||||
| fi | ||||||||||
|
|
||||||||||
| # Some other content that should be preserved | ||||||||||
| export FOO=bar | ||||||||||
| EOF | ||||||||||
|
|
||||||||||
| # 3. Run the helper script | ||||||||||
| # We need to set USERNAME to root because the test runs as root | ||||||||||
| # and the helper script defaults to 'vscode' if not set. | ||||||||||
| export USERNAME=root | ||||||||||
| /usr/local/bin/oh-my-posh-configure-shell | ||||||||||
|
|
||||||||||
| # 4. Verify the result | ||||||||||
| # Read the last few lines of .bashrc | ||||||||||
| LAST_LINES=$(tail -n 10 ~/.bashrc) | ||||||||||
| echo "Last lines of .bashrc:" | ||||||||||
| echo "$LAST_LINES" | ||||||||||
|
|
||||||||||
| # Check if "oh-my-posh init" is in the last lines | ||||||||||
| check "oh-my-posh is at the end" bash -c "tail -n 10 ~/.bashrc | grep -q 'oh-my-posh init'" | ||||||||||
|
|
||||||||||
| # Check if markers are present | ||||||||||
| check "markers are present" grep -q "# region Oh My Posh configuration" ~/.bashrc | ||||||||||
|
|
||||||||||
| # Check if old config is gone (or at least the comment) | ||||||||||
| # We removed lines with "oh-my-posh init" and "# Oh My Posh configuration" | ||||||||||
| # But we added them back at the end. | ||||||||||
|
Comment on lines
+47
to
+48
|
||||||||||
| # We removed lines with "oh-my-posh init" and "# Oh My Posh configuration" | |
| # But we added them back at the end. | |
| # We removed lines with "oh-my-posh init" (replaced with ":") but the old "# Oh My Posh configuration" comment may remain. | |
| # But we added the new block (with markers) at the end. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Mock environment | ||
| USER_HOME=$(pwd) | ||
| RC_FILE="$USER_HOME/.bashrc_repro" | ||
|
|
||
| # Create legacy file | ||
| cat > "$RC_FILE" << EOF | ||
| # Some initial content | ||
| export PATH=\$PATH:/something | ||
|
|
||
| # Oh My Posh configuration | ||
| if [ -s ~/.ohmyposh.json ]; then | ||
| # Use custom theme if mounted | ||
| eval "\$(oh-my-posh init bash --config ~/.ohmyposh.json)" | ||
| else | ||
| # Use built-in theme | ||
| eval "\$(oh-my-posh init bash --config jandedobbeleer)" | ||
| fi | ||
|
|
||
| # Some other content that should be preserved | ||
| export FOO=bar | ||
| EOF | ||
|
|
||
| echo "--- Initial Content ---" | ||
| cat "$RC_FILE" | ||
| echo "-----------------------" | ||
|
|
||
| # Define the function exactly as in the file | ||
| move_to_end() { | ||
| local rc_file="$1" | ||
| local start_marker="# region Oh My Posh configuration" | ||
| local end_marker="# endregion Oh My Posh configuration" | ||
|
|
||
| if [ -f "$rc_file" ]; then | ||
| # Check for the region markers | ||
| if grep -q "$start_marker" "$rc_file"; then | ||
| echo "Ensuring Oh My Posh configuration is at the end of $rc_file..." | ||
|
|
||
| # Extract the block | ||
| local block=$(sed -n "/$start_marker/,/$end_marker/p" "$rc_file") | ||
|
|
||
| if [ -n "$block" ]; then | ||
| # Create a temp file | ||
| local temp_file=$(mktemp) | ||
|
|
||
| # Write file content WITHOUT the block to temp file | ||
| # We use awk to exclude the range | ||
| awk -v start="$start_marker" -v end="$end_marker" ' | ||
| $0 ~ start {skip=1; next} | ||
| $0 ~ end {skip=0; next} | ||
| !skip {print} | ||
| ' "$rc_file" > "$temp_file" | ||
|
|
||
| # Append the block to the end | ||
| echo "" >> "$temp_file" | ||
| echo "$block" >> "$temp_file" | ||
|
|
||
| # Replace original file | ||
| mv "$temp_file" "$rc_file" | ||
|
|
||
| echo "Moved Oh My Posh configuration to the end of $rc_file" | ||
| fi | ||
| # Fallback: Check for old configuration without markers | ||
| elif grep -q "oh-my-posh init" "$rc_file"; then | ||
| echo "Found legacy Oh My Posh configuration in $rc_file. Moving to end and adding markers..." | ||
|
|
||
| # Create a temp file | ||
| local temp_file=$(mktemp) | ||
|
|
||
| # Remove lines containing "oh-my-posh init" and surrounding if/else block if possible | ||
| # This is harder to do reliably with regex, so we'll just comment out the old init line | ||
| # and add a new block at the end. | ||
|
|
||
| # Actually, let's just append the new block and assume the old one will be overridden or harmless | ||
| # if it's not setting PROMPT_COMMAND in a conflicting way. | ||
| # But the old one DOES set PROMPT_COMMAND via eval. | ||
|
|
||
| # Let's try to remove the old block if it matches the standard pattern | ||
| # Standard pattern: | ||
| # # Oh My Posh configuration | ||
| # if [ -s ~/.ohmyposh.json ]; then | ||
| # ... | ||
| # fi | ||
|
|
||
| # We'll use a simpler approach: Remove any lines containing "oh-my-posh init" | ||
| # and the specific comment "# Oh My Posh configuration" | ||
|
|
||
| # Use a temp file for grep output to avoid issues with reading/writing same file | ||
| sed 's/^\([[:space:]]*\).*oh-my-posh init.*/\1:/' "$rc_file" | grep -v "# Oh My Posh configuration" > "$temp_file" | ||
|
|
||
| # Replace original file with cleaned content | ||
| mv "$temp_file" "$rc_file" | ||
|
|
||
| # Append new block | ||
| # Determine shell from filename | ||
| local shell_name="bash" | ||
| if [[ "$rc_file" == *".zshrc" ]]; then | ||
| shell_name="zsh" | ||
| fi | ||
|
|
||
| # Use echo to append to avoid issues with cat and EOF in some environments or if file is empty | ||
| echo "" >> "$rc_file" | ||
| echo "$start_marker" >> "$rc_file" | ||
| echo "if [ -s ~/.ohmyposh.json ]; then" >> "$rc_file" | ||
| echo " eval \"\$(oh-my-posh init $shell_name --config ~/.ohmyposh.json)\"" >> "$rc_file" | ||
| echo "else" >> "$rc_file" | ||
| echo " eval \"\$(oh-my-posh init $shell_name --config jandedobbeleer)\"" >> "$rc_file" | ||
| echo "fi" >> "$rc_file" | ||
| echo "$end_marker" >> "$rc_file" | ||
|
|
||
| echo "Updated legacy configuration in $rc_file" | ||
| fi | ||
| fi | ||
| } | ||
|
|
||
| # Run it | ||
| move_to_end "$RC_FILE" | ||
|
|
||
| echo "--- Final Content ---" | ||
| cat "$RC_FILE" | ||
| echo "---------------------" | ||
|
|
||
| # Check for markers | ||
| if grep -q "# region Oh My Posh configuration" "$RC_FILE"; then | ||
| echo "✅ Markers found" | ||
| else | ||
| echo "❌ Markers NOT found" | ||
| fi |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||||||
| #!/bin/bash | ||||||||||
|
||||||||||
| #!/bin/bash | |
| #!/bin/bash | |
| set -e |
Copilot
AI
Nov 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The sed command preserves indentation but the result will have inconsistent indentation. The original code has eval statements indented with 4 spaces inside the if/else block, but after replacement with :, these become lines with just whitespace followed by :. While syntactically correct, this creates odd-looking code.
Consider if this test should verify that the indentation is preserved correctly, or if the migration strategy should be adjusted.
| sed 's/.*oh-my-posh init.*/ :/' test.sh > test.sh.tmp | |
| sed 's/^\([[:space:]]*\)oh-my-posh init.*/\1:/' test.sh > test.sh.tmp |
Copilot
AI
Nov 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The regex pattern .*oh-my-posh init.* could match unintended lines, such as comments that mention "oh-my-posh init". For consistency and safety, consider using a more specific pattern that matches only actual eval statements, as this is a test verifying the migration behavior.
| sed 's/.*oh-my-posh init.*/ :/' test.sh > test.sh.tmp | |
| sed 's/^[[:space:]]*eval[[:space:]]*"\$\(oh-my-posh init[^"]*\)"/ :/' test.sh > test.sh.tmp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The wildcard copy pattern
cp src/{{feature}}/*.shwill fail if there are no.shfiles in the directory (in shells withoutnullglobset), or could inadvertently copy unintended files if additional shell scripts are added to the feature directory in the future.Consider being more explicit about which files to copy, such as: