Show color swatches for LSP completions (#18665)

Closes #11991

Release Notes:

- Added support for color swatches for language server completions.

<img width="502" alt="Screenshot 2024-10-02 at 19 02 22"
src="https://github.com/user-attachments/assets/57e85492-3760-461a-9b17-a846dc40576b">

<img width="534" alt="Screenshot 2024-10-02 at 19 02 48"
src="https://github.com/user-attachments/assets/713ac41c-16f0-4ad3-9103-d2c9b3fa8b2e">

This implementation is mostly a port of the VSCode version of the
ColorExtractor. It seems reasonable the we should support _at least_
what VSCode does for detecting color swatches from LSP completions.

This implementation could definitely be better perf-wise by writing a
dedicated color parser. I also think it would be neat if, in the future,
Zed handled _more_ color formats — especially wide-gamut colors.

There are a few differences to the regexes in the VSCode implementation
but mainly so simplify the implementation :
- The hex vs rgb/hsl regexes were split into two parts
- The rgb/hsl regexes allow 3 or 4 color components whether hsla/rgba or
not and the parsing implementation accepts/rejects colors as needed

---------

Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
Jordan Pittman 2024-10-03 14:38:17 -04:00 committed by GitHub
parent cddd7875a4
commit cac98b7bbf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 320 additions and 3 deletions

View file

@ -1,4 +1,5 @@
pub mod buffer_store;
mod color_extractor;
pub mod connection_manager;
pub mod debounced_delay;
pub mod lsp_command;
@ -36,7 +37,7 @@ use futures::{
use git::{blame::Blame, repository::GitRepository};
use gpui::{
AnyModel, AppContext, AsyncAppContext, BorrowAppContext, Context, EventEmitter, Model,
AnyModel, AppContext, AsyncAppContext, BorrowAppContext, Context, EventEmitter, Hsla, Model,
ModelContext, SharedString, Task, WeakModel, WindowContext,
};
use itertools::Itertools;
@ -47,7 +48,9 @@ use language::{
Documentation, File as _, Language, LanguageRegistry, LanguageServerName, PointUtf16, ToOffset,
ToPointUtf16, Transaction, Unclipped,
};
use lsp::{CompletionContext, DocumentHighlightKind, LanguageServer, LanguageServerId};
use lsp::{
CompletionContext, CompletionItemKind, DocumentHighlightKind, LanguageServer, LanguageServerId,
};
use lsp_command::*;
use node_runtime::NodeRuntime;
use parking_lot::{Mutex, RwLock};
@ -4445,6 +4448,16 @@ impl Completion {
pub fn is_snippet(&self) -> bool {
self.lsp_completion.insert_text_format == Some(lsp::InsertTextFormat::SNIPPET)
}
/// Returns the corresponding color for this completion.
///
/// Will return `None` if this completion's kind is not [`CompletionItemKind::COLOR`].
pub fn color(&self) -> Option<Hsla> {
match self.lsp_completion.kind {
Some(CompletionItemKind::COLOR) => color_extractor::extract_color(&self.lsp_completion),
_ => None,
}
}
}
#[derive(Debug)]