diff --git a/CHANGELOG.md b/CHANGELOG.md
index e19c173be3ec..65a682cc3655 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -219,6 +219,8 @@
enter][7527]
- [Connections to lamdas are displayed correctly][7550]. It is possible to drag
a connection to any expression inside the lambda body.
+- [Atom types in dropdowns do not produce redundant imports][#7670]. The
+ possibility of imports conflicts is reduced.
- [Copying and pasting a single node][7618]. Using the common
cmd+C and cmd+V shortcuts, it is
now possible to copy a single selected node and paste its code to the graph or
@@ -249,6 +251,7 @@
[7311]: https://github.com/enso-org/enso/pull/7311
[7527]: https://github.com/enso-org/enso/pull/7527
[7550]: https://github.com/enso-org/enso/pull/7550
+[7670]: https://github.com/enso-org/enso/pull/7670
[7618]: https://github.com/enso-org/enso/pull/7618
#### EnsoGL (rendering engine)
diff --git a/Cargo.lock b/Cargo.lock
index d11987e83483..0a098b59d914 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2116,6 +2116,7 @@ dependencies = [
"enso-reflect",
"lexpr",
"pretty_assertions",
+ "serde",
]
[[package]]
@@ -2588,6 +2589,8 @@ dependencies = [
"flo_stream",
"futures",
"parser",
+ "serde",
+ "serde_json",
"span-tree",
"wasm-bindgen-test",
]
diff --git a/app/gui/docs/product/shortcuts.md b/app/gui/docs/product/shortcuts.md
index 95bc3e8e5a9d..3b4e2d26d096 100644
--- a/app/gui/docs/product/shortcuts.md
+++ b/app/gui/docs/product/shortcuts.md
@@ -141,3 +141,4 @@ broken and require further investigation.
| ctrl + shift + arrow up | Pop a breadcrumb without navigating. |
| cmd + i | Reload visualizations. To see the effect in the currently shown visualizations, you need to switch to another and switch back. |
| ctrl + shift + b | Toggle read-only mode. |
+| ctrl + shift + u | Dump the suggestion database as JSON to the console. Available only in debug mode, and only if the component browser is open. |
diff --git a/app/gui/src/controller/searcher.rs b/app/gui/src/controller/searcher.rs
index 6f8cc3c36b8b..f340bee3ab33 100644
--- a/app/gui/src/controller/searcher.rs
+++ b/app/gui/src/controller/searcher.rs
@@ -313,6 +313,11 @@ impl Searcher {
self
}
+ /// Dump the suggestion database to the console in JSON format.
+ pub fn dump_database_as_json(&self) {
+ console_log!("{}", self.database.dump_as_json());
+ }
+
/// Abort editing and perform cleanup.
pub fn abort_editing(&self) {
self.clear_temporary_imports();
diff --git a/app/gui/src/presenter/project.rs b/app/gui/src/presenter/project.rs
index bfc9d54995ee..5db85e3f86e0 100644
--- a/app/gui/src/presenter/project.rs
+++ b/app/gui/src/presenter/project.rs
@@ -336,16 +336,6 @@ impl Model {
}
});
}
-
- fn show_dashboard(&self) {
- match enso_web::Event::new("show-dashboard") {
- Ok(event) =>
- if let Err(error) = enso_web::document.dispatch_event(&event) {
- error!("Failed to dispatch event to show the dashboard. {error:?}");
- },
- Err(error) => error!("Failed to create event to show the dashboard. {error:?}"),
- }
- }
}
@@ -441,7 +431,6 @@ impl Project {
eval graph_view.execution_environment((env) model.execution_environment_changed(*env));
eval_ graph_view.execution_environment_play_button_pressed( model.trigger_clean_live_execution());
- eval_ view.go_to_dashboard_button_pressed (model.show_dashboard());
eval view.current_shortcut ((shortcut) model.handled_shortcut_changed(shortcut));
}
diff --git a/app/gui/src/presenter/searcher/component_browser.rs b/app/gui/src/presenter/searcher/component_browser.rs
index da1ff878c501..b9c2648d2d9b 100644
--- a/app/gui/src/presenter/searcher/component_browser.rs
+++ b/app/gui/src/presenter/searcher/component_browser.rs
@@ -255,6 +255,7 @@ impl ComponentBrowserSearcher {
// must be up-to-date.
action_list_changed <+ model.project.searcher_input_changed.constant(());
+ eval_ model.project.request_dump_suggestion_database(model.controller.dump_database_as_json());
eval_ model.project.toggle_component_browser_private_entries_visibility (
model.controller.reload_list());
}
diff --git a/app/gui/suggestion-database/Cargo.toml b/app/gui/suggestion-database/Cargo.toml
index f6c75b8b9ee3..620e44ecb90d 100644
--- a/app/gui/suggestion-database/Cargo.toml
+++ b/app/gui/suggestion-database/Cargo.toml
@@ -23,6 +23,8 @@ ensogl-icons = { path = "../../../lib/rust/ensogl/component/icons" }
flo_stream = { version = "0.4.0" }
failure = { workspace = true }
enso-notification = { path = "../../../lib/rust/notification" }
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
[dev-dependencies]
futures = { workspace = true }
diff --git a/app/gui/suggestion-database/src/entry.rs b/app/gui/suggestion-database/src/entry.rs
index 5358bc3daa88..71cd66c13b0b 100644
--- a/app/gui/suggestion-database/src/entry.rs
+++ b/app/gui/suggestion-database/src/entry.rs
@@ -88,7 +88,7 @@ pub struct ModuleSpan {
/// In order to make icon definitions more readable for non-programmer users, the builtin icon name
/// is allowed to be formatted in arbitrary casing. Either `SNAKE_case`,`camelCase`, `Pascal_Case`
/// etc. is allowed.
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
pub struct IconName {
/// The name is kept in `PascalCase` to allow easy conversion into builtin icon ID.
pascal_cased: ImString,
@@ -176,7 +176,7 @@ impl From for import::Info {
// === Kind ===
/// A type of suggestion entry.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, ForEachVariant)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, ForEachVariant, serde::Serialize)]
#[allow(missing_docs)]
pub enum Kind {
Type,
@@ -195,7 +195,7 @@ pub enum Kind {
/// Methods are visible "Everywhere", as they are imported on a module level, so they are not
/// specific to any particular span in the module file.
/// However local variables and local function have limited visibility.
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub enum Scope {
/// The entry is visible in the whole module where it was defined. It can be also brought to
/// other modules by import declarations.
@@ -214,7 +214,7 @@ pub enum Scope {
// === Entry ===
/// The Suggestion Database Entry.
-#[derive(Clone, Debug, Eq, PartialEq)]
+#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub struct Entry {
/// A type of suggestion.
pub kind: Kind,
@@ -972,18 +972,16 @@ where
TagValueResolution::Resolved(entry, chain) => {
let label = chain_to_label(&chain);
let qualified_name = entry.qualified_name();
- let parent_module = qualified_name.parent();
- let required_import = parent_module.as_ref().map(|n| n.to_string());
-
- let expression = if let Some(parent) = parent_module {
- let in_module_name = qualified_name.name();
- let parent_name = parent.name();
- [parent_name, in_module_name].join(opr::predefined::ACCESS)
+ let required_import = Some(qualified_name.to_string());
+ // As we don't generate `this`, we will never follow the code path where
+ // `in_module` is used. That's why passing `default()` is valid.
+ let in_module = default();
+ let expression = entry.code_to_insert(false, in_module);
+ let expression = if entry.arguments.is_empty() {
+ expression.to_string()
} else {
- qualified_name.to_string()
+ format!("({expression})")
};
- let expression =
- if entry.arguments.is_empty() { expression } else { format!("({expression})") };
span_tree::TagValue { required_import, expression, label: Some(label) }
}
diff --git a/app/gui/suggestion-database/src/lib.rs b/app/gui/suggestion-database/src/lib.rs
index e202b36e4085..1d2a58ab2197 100644
--- a/app/gui/suggestion-database/src/lib.rs
+++ b/app/gui/suggestion-database/src/lib.rs
@@ -338,6 +338,13 @@ impl SuggestionDatabase {
default()
}
+ /// Dump all entries in JSON.
+ pub fn dump_as_json(&self) -> String {
+ let all_entries: Vec =
+ self.entries.borrow().values().map(|e| e.deref().clone()).collect_vec();
+ serde_json::to_string(&all_entries).unwrap()
+ }
+
/// Create a database filled with entries provided by the given iterator.
pub fn new_from_entries<'a>(
entries: impl IntoIterator- ,
diff --git a/app/gui/view/src/project.rs b/app/gui/view/src/project.rs
index 8461db6d2068..47f46bbc69a0 100644
--- a/app/gui/view/src/project.rs
+++ b/app/gui/view/src/project.rs
@@ -149,6 +149,8 @@ ensogl::define_endpoints! {
start_node_creation_with_component_browser(),
/// Accepts the currently selected input of the searcher.
accept_searcher_input(),
+ /// Dump the suggestion database in JSON to the console.
+ dump_suggestion_database(),
}
Output {
@@ -174,9 +176,10 @@ ensogl::define_endpoints! {
fullscreen_visualization_shown (bool),
drop_files_enabled (bool),
debug_mode (bool),
- go_to_dashboard_button_pressed (),
/// The name of the command currently being handled due to shortcut being pressed.
current_shortcut (Option),
+ /// Request the controller to dump the suggestion database in JSON to the console.
+ request_dump_suggestion_database(),
}
}
@@ -700,6 +703,7 @@ impl View {
debug_mode <- bool(&frp.disable_debug_mode, &frp.enable_debug_mode);
frp.source.debug_mode <+ debug_mode;
popup.is_enabled <+ debug_mode;
+ frp.source.request_dump_suggestion_database <+ frp.dump_suggestion_database;
}
self
}
@@ -803,6 +807,7 @@ impl application::View for View {
(Press, "is_searcher_opened", "enter", "accept_searcher_input"),
(Press, "debug_mode", "ctrl shift enter", "debug_push_breadcrumb"),
(Press, "debug_mode", "ctrl shift b", "debug_pop_breadcrumb"),
+ (Press, "debug_mode", "ctrl shift u", "dump_suggestion_database"),
]
.iter()
.map(|(a, b, c, d)| Self::self_shortcut_when(*a, *c, *d, *b))
diff --git a/lib/rust/font/src/lib.rs b/lib/rust/font/src/lib.rs
index 41267a1f1386..2f6e0db2fc6c 100644
--- a/lib/rust/font/src/lib.rs
+++ b/lib/rust/font/src/lib.rs
@@ -29,7 +29,6 @@ use derive_more::Deref;
use derive_more::Display;
-
// ==============
// === Export ===
// ==============
diff --git a/lib/rust/parser/doc-parser/Cargo.toml b/lib/rust/parser/doc-parser/Cargo.toml
index 2813e61cc5e8..8c5b1168fe70 100644
--- a/lib/rust/parser/doc-parser/Cargo.toml
+++ b/lib/rust/parser/doc-parser/Cargo.toml
@@ -14,6 +14,7 @@ enso-parser = { path = ".." }
enso-prelude = { path = "../../prelude" }
enso-profiler = { path = "../../profiler" }
enso-reflect = { path = "../../reflect" }
+serde = { version = "1.0", features = ["derive"] }
[dev-dependencies]
enso-metamodel = { path = "../../metamodel", features = ["rust"] }
diff --git a/lib/rust/parser/doc-parser/src/doc_sections.rs b/lib/rust/parser/doc-parser/src/doc_sections.rs
index 99085d4f1a01..777db8b3d000 100644
--- a/lib/rust/parser/doc-parser/src/doc_sections.rs
+++ b/lib/rust/parser/doc-parser/src/doc_sections.rs
@@ -64,7 +64,7 @@ pub type HtmlString = String;
/// A description of a single argument in the documentation. The name is delimited from the
/// description using a colon.
-#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize)]
pub struct Argument {
/// Name of the argument.
pub name: String,
@@ -87,7 +87,7 @@ impl Argument {
}
/// A single section of the documentation.
-#[derive(Hash, Debug, Clone, PartialEq, Eq)]
+#[derive(Hash, Debug, Clone, PartialEq, Eq, serde::Serialize)]
#[allow(missing_docs)]
pub enum DocSection {
/// The documentation tag.
diff --git a/lib/rust/parser/doc-parser/src/lib.rs b/lib/rust/parser/doc-parser/src/lib.rs
index 532ed283a4f2..44dee4476e29 100644
--- a/lib/rust/parser/doc-parser/src/lib.rs
+++ b/lib/rust/parser/doc-parser/src/lib.rs
@@ -56,7 +56,7 @@ pub struct TagWithDescription<'a, L> {
}
/// Indicator placed at the beginning of a documentation section, e.g. `PRIVATE`.
-#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq, serde::Serialize)]
#[allow(missing_docs)]
pub enum Tag {
Added,
@@ -138,7 +138,7 @@ pub struct Marked<'a, L> {
}
/// Documentation section mark.
-#[derive(Hash, Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Hash, Debug, Copy, Clone, PartialEq, Eq, serde::Serialize)]
#[allow(missing_docs)]
pub enum Mark {
Important,
diff --git a/lib/rust/text/Cargo.toml b/lib/rust/text/Cargo.toml
index 1d31041338a9..08fbdc8edc46 100644
--- a/lib/rust/text/Cargo.toml
+++ b/lib/rust/text/Cargo.toml
@@ -11,4 +11,4 @@ crate-type = ["rlib", "cdylib"]
enso-prelude = { path = "../prelude" }
enso-types = { path = "../types" }
xi-rope = { version = "0.3.0" }
-serde = "1"
+serde = { version = "1", features = ["derive"] }
diff --git a/lib/rust/text/src/index.rs b/lib/rust/text/src/index.rs
index 95b81bb20976..c8572eabae65 100644
--- a/lib/rust/text/src/index.rs
+++ b/lib/rust/text/src/index.rs
@@ -180,6 +180,7 @@ macro_rules! define_line_unit {
#[derive(
Clone, Copy, Debug, Display, Default, Eq, Hash, Ord, PartialEq, PartialOrd, From, Into
)]
+ #[derive(serde::Serialize, serde::Deserialize)]
pub struct $name {
#[allow(missing_docs)]
pub value: usize,
diff --git a/lib/rust/text/src/unit.rs b/lib/rust/text/src/unit.rs
index 5114239a7922..2adeb40c6021 100644
--- a/lib/rust/text/src/unit.rs
+++ b/lib/rust/text/src/unit.rs
@@ -198,6 +198,7 @@ impl AddAssign for Column {
unit! {
/// An offset in the text measured in number of code units in text in UTF-16 representation.
+ #[derive(serde::Serialize, serde::Deserialize)]
Utf16CodeUnit::utf16_code_unit(usize)
}
@@ -213,6 +214,7 @@ mod location {
use super::*;
#[doc = " A type representing 2d measurements."]
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ #[derive(serde::Serialize, serde::Deserialize)]
#[allow(missing_docs)]
pub struct Location {
pub line: LineType,
diff --git a/lib/rust/types/src/unit.rs b/lib/rust/types/src/unit.rs
index fcdfb128712d..cb67a3237a84 100644
--- a/lib/rust/types/src/unit.rs
+++ b/lib/rust/types/src/unit.rs
@@ -401,7 +401,7 @@ macro_rules! newtype_no_sub {
macro_rules! newtype_struct {
($(#$meta:tt)* $name:ident { $($field:ident : $field_type:ty),* $(,)? }) => {
$crate::newtype_struct_def! {$(#$meta)* $name { $($field : $field_type),*}}
- $crate::newtype_struct_impls! {$(#$meta)* $name { $($field : $field_type),*}}
+ $crate::newtype_struct_impls! {$name { $($field : $field_type),*}}
}
}
@@ -410,7 +410,7 @@ macro_rules! newtype_struct {
macro_rules! newtype_struct_float_like {
($(#$meta:tt)* $name:ident { $($field:ident : $field_type:ty),* $(,)? }) => {
$crate::newtype_struct_def_float_like! {$(#$meta)* $name { $($field : $field_type),*}}
- $crate::newtype_struct_impls! {$(#$meta)* $name { $($field : $field_type),*}}
+ $crate::newtype_struct_impls! {$name { $($field : $field_type),*}}
}
}
@@ -441,9 +441,8 @@ macro_rules! newtype_struct_def_float_like {
/// Unit definition macro. See module docs to learn more.
#[macro_export]
macro_rules! newtype_struct_impls {
- ($(#$meta:tt)* $name:ident { $field:ident : $field_type:ty $(,)? }) => {
+ ($name:ident { $field:ident : $field_type:ty $(,)? }) => {
/// Smart constructor.
- $(#$meta)*
#[allow(non_snake_case)]
pub const fn $name($field:$field_type) -> $name { $name {$field} }