Skip to content

fix: style the variable name in ${VAR} as an env var - #1030

Merged
HalFrgrd merged 1 commit into
HalFrgrd:masterfrom
WynandVStaden:fix/env-var-style-brace-expansion
Oct 10, 2026
Merged

HalFrgrd merged 1 commit into
HalFrgrd:masterfrom
WynandVStaden:fix/env-var-style-brace-expansion

Conversation

@WynandVStaden

Copy link
Copy Markdown
Contributor

Fixes #1029.

Problem

echo $BASH colours the variable with the env-var style, but echo ${BASH} does not, and the name gets no variable tooltip either.

Cause

In DParser, a word is marked is_env_var only when the previous token is Dollar. In ${BASH} the previous token is ParamExpansion (${), so the name was treated as ordinary text.

Change

Mark the word that directly follows ${ as an env var too, when that word is a plain variable name (letters, digits, underscores, not starting with a digit).

The name check is there because of how these forms lex:

Input Word after ${ Marked
${HOME} HOME yes
"${USER}" USER yes
${ARR[0]} ARR yes
"${LOGNAME:-nobody}" LOGNAME:-nobody (one word inside double quotes) no
${#PATH} # no
'${PWD}' whole thing is one single-quoted word no

Without the check, LOGNAME:-nobody and # would be looked up as variable names and painted with the unrecognised-env-var colour, which is worse than today. Those three "no" rows are styled exactly as before this PR.

The ${ and } tokens are not marked. They carry a bracket_depth, and token_to_style gives rainbow bracket colouring priority over the env-var colour, so they stay bracket-coloured like every other delimiter. If you would rather have the whole ${BASH} in the env-var colour, as the issue's wording suggests, that needs a change in token_to_style and I'm happy to do it.

Tests

  • grammar::dparser::tests::test_param_expansion_name_is_env_var covers the table above.
  • app::formatted_buffer::tests::test_brace_delimited_env_var_styling checks that ${HOME} gets palette.env_var() and ${UNRECOGNISED_VAR_XYZ} gets palette.unrecognised_env_var(), mirroring the existing $HOME test.

Both fail with the parser change disabled and pass with it.

Run on Ubuntu 24.04, rustc 1.99.0:

  • cargo test --lib: 876 passed, 0 failed, 1 ignored (874 on main)
  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo doc --workspace --no-deps --document-private-items: builds, 43 warnings, the same count as main

Not done: I did not run the Docker integration tests, and I did not check the colours by eye in a terminal; the styling is covered by the unit test only.

The parser marked a word as an environment variable only when it followed
a bare $, so ${BASH} was not coloured like $BASH and got no tooltip.
Mark the name that directly follows ${ as well. The ${ and } tokens keep
their bracket colouring.

Fixes HalFrgrd#1029
@HalFrgrd

Copy link
Copy Markdown
Owner

Thanks!

@HalFrgrd
HalFrgrd merged commit 6277121 into HalFrgrd:master Oct 10, 2026
@MartenBE

Copy link
Copy Markdown

The ${ and } tokens are not marked. They carry a bracket_depth, and token_to_style gives rainbow bracket colouring priority over the env-var colour, so they stay bracket-coloured like every other delimiter. If you would rather have the whole ${BASH} in the env-var colour, as the issue's wording suggests, that needs a change in token_to_style and I'm happy to do it.

This works! I think it would be better to also color the ${ and } token in this case as they are an integral part of the variable. This would also come closer to zsh syntax highlighting.

@WynandVStaden

Copy link
Copy Markdown
Contributor Author

Agreed, that reads better. I opened #1036 for it: ${ and } take the variable's colour when the braces hold just a name. Forms like ${VAR:-default} keep their bracket colour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: env-var is not used for bracket delimited env vars e.g. "I am ${USER}"

3 participants