Skip to content

Document Color support #13122

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

Open
Veykril opened this issue Aug 26, 2022 · 2 comments
Open

Document Color support #13122

Veykril opened this issue Aug 26, 2022 · 2 comments
Labels
A-ide general IDE features C-feature Category: feature request fun A technically challenging issue with high impact

Comments

@Veykril
Copy link
Member

Veykril commented Aug 26, 2022

The LSP has this interesting feature for document color requests https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentColor which allows a client to ask a server for color-like things in a document, giving the client the ability to render color swatches and the like to edit these color-like things. Now rust as a language doesn't have the concept of first class colors, but there are several libraries that model colors and I believe we can make this feature work for those.

As an example for palette::rgb::Rgb::new(0.0, 0.0, 0.0) we should be able to make use of this feature. But this will certainly require information from the library/user code itself, building heuristic for this is non-feasible, but there is something we will hopefully have in the future that will allow libaries/user code to give r-a the needed information, tool attributes.

So I would envision this as something like #[rust_analyzer::color(red, green, blue)] that you can attach to function definitions, where the components would match up with the functions arguments. Obviously this would need to be fleshed out more, are there more thing this would apply to than just function calls? What about hex strings, we wouldn't want to always interpret them as colors, but there should probably be a way to support these in some fashion as well

@Veykril Veykril added S-unactionable Issue requires feedback, design decisions or is blocked on other work C-feature Category: feature request A-ide general IDE features labels Aug 26, 2022
@nik-rev
Copy link

nik-rev commented May 7, 2025

I think this can potentially be a very useful feature, especially when used with UI frameworks. And I have a couple of brainstorm ideas for how this can work

iced for example which has a Color struct, which we'll be able to annotate:

#[rust_analyzer(color(rgb))]
pub struct Color {
    #[rust_analyzer(color(rgb(r)))]
    pub r: f32,
    #[rust_analyzer(color(rgb(g)))]
    pub g: f32,
    #[rust_analyzer(color(rgb(b)))]
    pub b: f32,
    #[rust_analyzer(color(rgb(a)))]
    pub a: f32,
}

Values of type Color will then have a ColorInformation for them.

I annotate the range field of ColorInformation with comments, and color with words

For basic projects I define a few constants:

const RED: Color = Color { r: 1.0, g: 0.0, b: 0.0, a: 1.0 };
//                 \______________________________________/ <- red
const GREEN: Color = Color { r: 0.0, g: 1.0, b: 0.0, a: 1.0 };
//                   \______________________________________/ <- green
const BLUE: Color = Color { r: 0.0, g: 0.0, b: 1.0, a: 1.0 };
//                        \________________________________/ <- blue

I might also like to have a Theme struct:

struct Theme {
    primary: Color,
    accent: Color,
    danger: Color
}

const THEME: Theme = Theme {
    primary: RED,
//           \_/ <- red
    accent: GREEN,
//          \___/ <- green
    danger: BLUE
//          \__/ <- blue
}

Each RED, GREEN and BLUE are of type Color. We know their rgba, so we can create a ColorInformation for each of them!

I might store my Colors in a [Color], and then index it:

const CHANNELS: [Color; 3] = [RED, GREEN, BLUE];
//                            \_/ <- red
//                                 \___/ <- green
//                                        \__/ <- blue
const COLOR: Color = CHANNELS[2];
//                   \__________/ <- green

As you see, this should work with values of type const. We'll know their exact fields and what they represent.


More on the attributes

#[rust_analyzer(color(rgb))]

This one means that a struct may have fields which will have the following attributes applied to a field:

  • #[rust_analyzer(color(rgb(r)))]
  • #[rust_analyzer(color(rgb(g)))]
  • #[rust_analyzer(color(rgb(b)))]
  • #[rust_analyzer(color(rgb(a)))]

Each field may only have 1 attribute.

The types of the fields needs to be:

  • f32 or f64, for which values 0.0 to 1.0 will represent % of the respective channel, e.g. red = 0.4 would represent 40% of red channel
  • u8, for which values 0 to 255 represents one of the 256 possible values for each channel

I assume RGB will be most used so it would be good to prioritize that.
However, it'd be good to also consider:

  • color(hex)
  • color(hsl)

And other channels.


Some more questions that may pop up

  • Should we allow more granular control? E.g., what if I want to store my 0 - 255 channel in an f32, f64, i32, f64

@Veykril Veykril added fun A technically challenging issue with high impact and removed S-unactionable Issue requires feedback, design decisions or is blocked on other work labels May 8, 2025
@Veykril
Copy link
Member Author

Veykril commented May 8, 2025

Note that it is unlikely we'll try to support more color spaces than simple rgb(a) as that would require us to pull in a color library (though I think hsl might have a simple enough conversion between rgb iirc?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ide general IDE features C-feature Category: feature request fun A technically challenging issue with high impact
Projects
None yet
Development

No branches or pull requests

2 participants