Skip to content
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

Support setting extended ansi colors (16-255) #3905

Merged
merged 2 commits into from
Jul 18, 2022

Conversation

silamon
Copy link
Contributor

@silamon silamon commented Jul 18, 2022

The API is slightly different than proposed in #3601. It is aligned with the current ITheme variables and taking a string[] array of hex values.

Fixes #3601

Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one suggestion 👍

Comment on lines 165 to 169
if (theme.extendedAnsi) {
for (let ansiColor = 0; ansiColor < theme.extendedAnsi.length && ansiColor <= 255 - 16; ansiColor++) {
this.colors.ansi[ansiColor + 16] = this._parseColor(theme.extendedAnsi[ansiColor], DEFAULT_ANSI_COLORS[ansiColor + 16]);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't test this but it would lead to less work:

Suggested change
if (theme.extendedAnsi) {
for (let ansiColor = 0; ansiColor < theme.extendedAnsi.length && ansiColor <= 255 - 16; ansiColor++) {
this.colors.ansi[ansiColor + 16] = this._parseColor(theme.extendedAnsi[ansiColor], DEFAULT_ANSI_COLORS[ansiColor + 16]);
}
}
if (theme.extendedAnsi) {
const colorCount = Math.max(256, theme.extendedAnsi.length + 16);
for (let i = 16; i < colorCount; i++) {
this.colors.ansi[i] = this._parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i]);
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure thats doing the right thing? 🙈
If the purpose is to skip first 16 entries and to cap at 256, maybe this will work:

    if (theme.extendedAnsi) {
      const colorCount = Math.min(240, theme.extendedAnsi.length);
      for (let i = 0; i < colorCount; i++) {
        this.colors.ansi[i + 16] = this._parseColor(theme.extendedAnsi[i], DEFAULT_ANSI_COLORS[i + 16]);
      }
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll set up another pr soon to fix that. Thanks @jerch .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah there was an issue with my code above, I think it was fixed in c786c6a though

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah partially (though I dont like i-16 on indexes, but thats just my defensive coding style to avoid potential underruns). Whats with max vs. min?

Another minor code smell:
It might be a good idea not to limit on a magic number of 256. Could this be pulled from this.colors.ansi.length or some setup value of the default containers? Again defensive style - just in case the number of colors might change in the future. Always fun to debug magic numbers later on, that seemed so obvious in the first place.

Copy link
Member

@jerch jerch Jul 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@silamon Oh well, this seems to be a rather good idea, otherwise thats not possible at all from outside?

Edit: Maybe setTheme should always start from a DEFAULT_ANSI_COLORS clone? Or are there any downsides to such a clean startover beside losing "stacking" setTheme usage? (which seems weird to me in the first place, not sure if ppl use it that way)
Edit2: Nevermind, stacking is not possible for setTheme, as it always pulls from DEFAULT_ANSI_COLORS for color 0-15, if the obj does not contain the corresponding entry. So yeah, maybe do it likewise for extended colors (reset first + apply new ones)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about setTheme({extendedAnsi: []}) to unset?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't a simple this.colors.ansi = DEFAULT_ANSI_COLORS.slice(); infront of all ansi color code do?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't a simple this.colors.ansi = DEFAULT_ANSI_COLORS.slice(); infront of all ansi color code do?

setTheme does indeed reset everything after looking at the code, so this would be the right approach. That makes sense as taking VS Code as an example, a theme may not specify some colors, in which case we would want the defaults not the previously active theme colors.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create a PR to address this.

@Tyriar Tyriar added this to the 4.20.0 milestone Jul 18, 2022
Copy link
Member

@Tyriar Tyriar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@Tyriar Tyriar enabled auto-merge July 18, 2022 17:40
@Tyriar Tyriar merged commit cbb13aa into xtermjs:master Jul 18, 2022
@Tyriar Tyriar modified the milestones: 4.20.0, 5.0.0 Jul 28, 2022
@silamon silamon deleted the extendedcolors branch October 16, 2022 09:51
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.

Support setting extended ansi colors (16-255)
3 participants