Skip to content

Commit

Permalink
Show default per-kind icons for all entries in Component Browser. (#3587
Browse files Browse the repository at this point in the history
)

Show default icons for all entries in the Component Browser. The icons are assigned to each entry depending on its kind.

https://www.pivotaltracker.com/story/show/182584326

#### Visuals

See below for a video showing entries of 5 different kinds in the Component Browser, each having a different icon. When watching the video, please note that the following are preexisting, known issues, not introduced by this PR:
- Selection is misaligned when hovering the mouse over the "new" component in the "Mcdbg Group 1" group - reported as issue 2 [in comments to PR 3530](#3530 (review)).
- [Names of Modules and Atoms displayed in Component Browser start with a small letter.](https://www.pivotaltracker.com/story/show/182745386)




https://user-images.githubusercontent.com/273837/179016109-c3ebab5a-0205-4b44-85b8-df3129edd75d.mov

# Important Notes
- A new derive macro `ForEachVariant` is defined and added to the `enso-prelude` crate.
  • Loading branch information
akavel authored Jul 21, 2022
1 parent f699a64 commit 07df7fa
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 3 deletions.
2 changes: 1 addition & 1 deletion app/gui/src/model/suggestion_database/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl<'a> IntoIterator for &'a QualifiedName {
// =============

/// A type of suggestion entry.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, ForEachVariant)]
#[allow(missing_docs)]
pub enum Kind {
Atom,
Expand Down
31 changes: 30 additions & 1 deletion app/gui/src/presenter/searcher/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ impl ide_view::searcher::DocumentationProvider for Action {
}
}



// ===========================
// === provider::Component ===
// ===========================

/// Component Provider getting entries from a [`controller::searcher::component::Group`].
#[derive(Clone, CloneRef, Debug)]
pub struct Component {
Expand All @@ -170,23 +176,40 @@ impl Component {
}
}

macro_rules! kind_to_icon {
([ $( $variant:ident ),* ] $kind:ident) => {
{
use component_group_view::icon::Id;
use suggestion_database::entry::Kind;
match $kind {
$( Kind::$variant => Id::$variant, )*
}
}
}
}

impl list_view::entry::ModelProvider<component_group_view::Entry> for Component {
fn entry_count(&self) -> usize {
self.group.matched_items.get()
}

fn get(&self, id: usize) -> Option<component_group_view::entry::Model> {
use suggestion_database::entry::for_each_kind_variant;
let component = self.group.get_entry(id)?;
let match_info = component.match_info.borrow();
let label = component.label();
let highlighted = bytes_of_matched_letters(&*match_info, &label);
let kind = component.suggestion.kind;
Some(component_group_view::entry::Model {
icon: component_group_view::icon::Id::AddColumn,
icon: for_each_kind_variant!(kind_to_icon(kind)),
highlighted_text: list_view::entry::GlyphHighlightedLabelModel { label, highlighted },
})
}
}


// === Component Provider helpers ===

fn bytes_of_matched_letters(match_info: &MatchInfo, label: &str) -> Vec<text::Range<text::Bytes>> {
if let MatchInfo::Matches { subsequence } = match_info {
let mut char_iter = label.char_indices().enumerate();
Expand All @@ -211,6 +234,12 @@ fn bytes_of_matched_letters(match_info: &MatchInfo, label: &str) -> Vec<text::Ra
}
}



// ===========================
// === Converter functions ===
// ===========================

/// Get [`LabeledAnyModelProvider`] for given component group.
pub fn from_component_group(
group: &controller::searcher::component::Group,
Expand Down
9 changes: 8 additions & 1 deletion lib/rust/prelude/src/macros.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
//! This macro defines set of common macros which are useful across different projects.
//! This module defines set of common macros which are useful across different projects.

// ==============
// === Export ===
// ==============

pub use enso_shapely::ForEachVariant;



Expand Down
44 changes: 44 additions & 0 deletions lib/rust/shapely/macros/src/derive_for_each_variant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! This module contains the [`derive`] function (implementing the [`crate::ForEachVariant`] derive
//! macro) as well as its helper functions.
use inflector::cases::snakecase::to_snake_case;
use proc_macro2::TokenStream;
use quote::quote;
use syn::punctuated::Punctuated;
use syn::Token;



// ======================
// === ForEachVariant ===
// ======================

/// Implementation of the `ForEachVariant` derive macro. For details, see the documentation of the
/// [`crate::derive_for_each_variant`] function.
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let decl = syn::parse_macro_input!(input as syn::DeriveInput);
let ret = match decl.data {
syn::Data::Enum(ref e) => derive_for_enum(&decl, e),
_ => panic!("The `ForEachVariant` derive macro only works on enums."),
};
proc_macro::TokenStream::from(ret)
}

fn derive_for_enum(decl: &syn::DeriveInput, data: &syn::DataEnum) -> TokenStream {
let enum_name = &decl.ident;
let enum_snake_name = to_snake_case(&enum_name.to_string());
let macro_name = quote::format_ident!("for_each_{}_variant", enum_snake_name);
let variant_names: Punctuated<_, Token![,]> = data.variants.iter().map(|v| &v.ident).collect();
quote! {
/// Calls `f!` passing to it a comma-separated list of names of variants of [`#enum_name`]
/// enclosed in square brackets. The extra `args` are passed to `f!` verbatim after the
/// closing square bracket. For more details, see the documentation of the
/// [`ForEachVariant`] derive macro.
#[macro_export]
macro_rules! #macro_name {
( $f:ident($( $args:tt )*) ) => { $f!([ #variant_names ] $($args)*) }
}

pub(crate) use #macro_name;
}
}
33 changes: 33 additions & 0 deletions lib/rust/shapely/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern crate proc_macro;

mod derive_clone_ref;
mod derive_entry_point;
mod derive_for_each_variant;
mod derive_iterator;
mod derive_no_clone;
mod overlappable;
Expand Down Expand Up @@ -114,6 +115,38 @@ pub fn derive_no_clone(input: proc_macro::TokenStream) -> proc_macro::TokenStrea
derive_no_clone::derive(input)
}

/// Implements the `ForEachVariant` derive macro which creates a helper for iterating over each
/// variant of an enum at compile time. The derive panics if used on non-enum types.
///
/// The derive creates a macro (hereafter called loop-macro) named `for_each_NAME_variant` where
/// `NAME` is replaced with the name of the enum converted to snake case. The loop-macro takes a
/// name of another macro (hereafter called iterator-macro) as an argument followed by a
/// parenthesized list of extra arguments. The loop-macro expands to a call of the iterator-macro
/// with a list of comma-separated names of the enum variants wrapped in square brackets, followed
/// by the extra arguments defined above.
///
/// For example, the following code:
/// ```no_compile
/// #[derive(ForEachVariant)]
/// pub enum FooBar {
/// Foo,
/// Bar,
/// }
/// ```
/// results in the following macro being defined:
/// ```
/// #[macro_export]
/// macro_rules! for_each_foo_bar_variant {
/// ( $f:ident($( $args:tt )*) ) => { $f!([Foo, Bar] $($args)*) }
/// }
///
/// pub(crate) use for_each_foo_bar_variant;
/// ```
#[proc_macro_derive(ForEachVariant)]
pub fn derive_for_each_variant(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
derive_for_each_variant::derive(input)
}

/// Exposes the function as an application entry point. Entry points are alternative application
/// running modes that you can access by adding `?entry=` to the end of the application URL.
#[proc_macro_attribute]
Expand Down

0 comments on commit 07df7fa

Please sign in to comment.