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

Show Visualisation Preview when Selecting Item on Searcher #3691

Conversation

MichaelMauderer
Copy link
Contributor

@MichaelMauderer MichaelMauderer commented Sep 7, 2022

Pull Request Description

Implements #182634050.

Enables visualization previews for selections in the searcher.

Works for the old Searcher and the new Component Browser, but it was easier to show the examples for the old searcher, as the suggestions seem to be better/faster available currently (this will improve with the new implementation using better strings and the new GridView).

Peek.2022-09-07.12-59.mp4

Aborting an edit now also correctly reverts a node.

Peek.2022-09-07.13-00.mp4

Checklist

Please include the following checklist in your PR:

  • The documentation has been updated if necessary.
  • All code conforms to the
    Scala,
    Java,
    and
    Rust
    style guides.
  • All code has been tested:
    • Unit tests have been written where possible.
    • If GUI codebase was changed: Enso GUI was tested when built using BOTH
      ./run ide build and ./run ide watch.

@MichaelMauderer MichaelMauderer force-pushed the wip/michaelmauderer/Propagate_Component_Browser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050 branch from 2b7e26e to c200c14 Compare September 7, 2022 14:13
@MichaelMauderer MichaelMauderer marked this pull request as ready for review September 7, 2022 14:27
@wdanilo
Copy link
Member

wdanilo commented Sep 8, 2022

Michael, this is amazing. One thing that is to be fixed is that sometimes the result needs to be computed for a longer time. Until its computed, a spinner sohuld be shown. Any spinner - could be any shape animated in GLSL. BTW, if you'll be animating in GLSL (like our. text cursor, the animation will stop when you stop moving mouse - this is a bug I'll fix in my PR).

Copy link
Member

@wdanilo wdanilo left a comment

Choose a reason for hiding this comment

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

Added comment above.

@MichaelMauderer MichaelMauderer self-assigned this Sep 8, 2022
@MichaelMauderer
Copy link
Contributor Author

MichaelMauderer commented Sep 8, 2022

Michael, this is amazing. One thing that is to be fixed is that sometimes the result needs to be computed for a longer time. Until its computed, a spinner sohuld be shown. Any spinner - could be any shape animated in GLSL. BTW, if you'll be animating in GLSL (like our. text cursor, the animation will stop when you stop moving mouse - this is a bug I'll fix in my PR).

@wdanilo Should we plan this as a separate task, though? While I agree that this would be a super useful feature, it seems somewhat unrelated to this task, from a planning standpoint. If anything, I would add this feature as part of the "always show the visualization" task, as that actually touches visualization code.

}
Some(mut expression) => {
let new_argument = ast::prefix::Argument {
sast: ast::Shifted::new(pattern_offset.max(1), added_ast),
Copy link
Member

Choose a reason for hiding this comment

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

magic 1

Comment on lines 671 to 675
if displayed.expression != expression {
displayed.expression = expression;
Some(ast_id)
} else {
None
Copy link
Member

Choose a reason for hiding this comment

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

use .as_some on bool instead in such cases.

Comment on lines +666 to +670
tracing::debug!(
"Setting node expression from view: {} -> {}",
displayed.expression,
expression
);
Copy link
Member

Choose a reason for hiding this comment

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

you can make it 2 lines instead of 5 lines by extracting &str to var

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For me, extracting the message makes the debug statement much less readable.

let debug_message = "Setting node expression from view: {} -> {}";
tracing::debug!(debug_message, displayed.expression, expression);

The extra variable does not add any useful contextual information, but now when scanning the debug statement, one has to trace back to the variable to read its content.
Before, one could just read the debug statement linearly top to bottom.

Copy link
Contributor

Choose a reason for hiding this comment

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

you can make it 2 lines instead of 5 lines by extracting &str to var

I'm not sure if it has the same performance: the format macro can adjust allocated space when knows the string on compilation time.

Copy link
Member

Choose a reason for hiding this comment

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

I believe it has the same performance - this is &'static str, it is not allocated, it is build-into the binary, it sohuld be:

let debug_message = "Setting node expression from view:";
tracing::debug!("{debug_message} {} -> {}", displayed.expression, expression);

It's sharter to look at and I think we should optimize the code lengh, otherwise it's hard to read. If we can change it, I'd be thankful.

@@ -129,6 +129,8 @@ impl Model {
fn editing_aborted(&self) {
let searcher = self.searcher.take();
if let Some(searcher) = searcher {
let node = self.graph.ast_node_of_view(searcher.input_view()).unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

unwrap left in the code

Copy link
Contributor

@farmaazon farmaazon left a comment

Choose a reason for hiding this comment

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

You should be awarded with "creator of the branch with the longest name" badge.

Comment on lines 728 to 744
let new_expression = match self.data.borrow_mut().input.expression.clone() {
None => {
let ast = ast::prefix::Chain::from_ast_non_strict(&added_ast);
ast::Shifted::new(pattern_offset, ast)
}
Some(mut expression) => {
let new_argument = ast::prefix::Argument {
sast: ast::Shifted::new(
pattern_offset.max(MINIMUM_PATTERN_OFFSET),
added_ast,
),
prefix_id: default(),
};
expression.args.push(new_argument);
expression
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like duplicated code, doesn't it? Perhaps there should be a function returning new_expression.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored.

Comment on lines 745 to 757
let expr_and_method = || {
let input_chain = Some(new_expression);

let expression = match (self.this_var(), input_chain) {
(Some(this_var), Some(input)) =>
apply_this_argument(this_var, &input.wrapped.into_ast()).repr(),
(None, Some(input)) => input.wrapped.into_ast().repr(),
(_, None) => "".to_owned(),
};
let intended_method = self.intended_method();
(expression, intended_method)
};
let (expression, intended_method) = expr_and_method();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we doing it in lambda? I don't even see need for block...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was taken from the original code in commit_node. But after doing the refactoring into a separate method, it is gone now.


self.graph.graph().module.with_node_metadata(
self.mode.node_id(),
Box::new(|md| md.intended_method = intended_method),
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to make sure: is this restored after editing aborting?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now it is.

Comment on lines +666 to +670
tracing::debug!(
"Setting node expression from view: {} -> {}",
displayed.expression,
expression
);
Copy link
Contributor

Choose a reason for hiding this comment

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

you can make it 2 lines instead of 5 lines by extracting &str to var

I'm not sure if it has the same performance: the format macro can adjust allocated space when knows the string on compilation time.

Comment on lines 858 to 864
let input_chain = self.data.borrow().input.as_prefix_chain(self.ide.parser());
// We add the required imports before we edit its content. This way, we avoid an
// intermediate state where imports would already be in use but not yet available.
self.add_required_imports()?;
let (expression, intended_method) = expr_and_method();
let expression = self.get_expression(input_chain);
let intended_method = self.intended_method();

Copy link
Contributor

Choose a reason for hiding this comment

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

These lines are strangely mixed. I think the add_required_imports should go before variables which are not used by it.

(expression, intended_method)
};
let (expression, intended_method) = expr_and_method();
let expression = self.get_expression(new_expression);
Copy link
Contributor

Choose a reason for hiding this comment

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

The name is unclear. Why, having new_expression we must yet get expression from it?

Additionally, I think new_expression construction is still duplicated.

…rowser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050

# Conflicts:
#	CHANGELOG.md
@@ -49,6 +49,7 @@ pub const ASSIGN_NAMES_FOR_NODES: bool = true;
const ENSO_PROJECT_SPECIAL_MODULE: &str =
concatcp!(project::STANDARD_BASE_LIBRARY_PATH, ".Enso_Project");

const MINIMUM_PATTERN_OFFSET: usize = 1;
Copy link
Member

Choose a reason for hiding this comment

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

No docs, and the name does not explain what it is.

Comment on lines +666 to +668
sast: ast::Shifted::new(
pattern_offset.max(MINIMUM_PATTERN_OFFSET),
added_ast,
Copy link
Member

Choose a reason for hiding this comment

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

export to var to make it shorter.

let id = self.data.borrow().input.next_completion_id();
let picked_completion = FragmentAddedByPickingSuggestion { id, picked_suggestion };
let code_to_insert = self.code_to_insert(&picked_completion).code;
tracing::debug!("Code to insert: \"{}\"", code_to_insert);
Copy link
Member

Choose a reason for hiding this comment

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

missing . at the end.

Comment on lines 733 to 742
Some(mut expression) => {
let new_argument = ast::prefix::Argument {
sast: ast::Shifted::new(
pattern_offset.max(MINIMUM_PATTERN_OFFSET),
added_ast,
),
prefix_id: default(),
};
expression.args.push(new_argument);
Some(expression)
Copy link
Member

Choose a reason for hiding this comment

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

duplicated code - I've seen it above.

self.mode.node_id(),
Box::new(|md| md.intended_method = intended_method),
)?;
tracing::debug!("Previewing expression: {:?}", expression);
Copy link
Member

Choose a reason for hiding this comment

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

  1. Earlier, the code was enclosed in ", here it is not.
  2. Missing dot.

Comment on lines +447 to +450
tracing::debug!(
"Setting node expression from controller: {} -> {}",
displayed.expression,
new_displayed_expr
Copy link
Member

Choose a reason for hiding this comment

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

export msg to var to make it shorter.

Comment on lines +666 to +669
tracing::debug!(
"Setting node expression from view: {} -> {}",
displayed.expression,
expression
Copy link
Member

Choose a reason for hiding this comment

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

export msg to var to make it shorter

@@ -120,7 +120,9 @@ impl Model {
/// Should be called if an entry is selected but not used yet. Only used for the old searcher
/// API.
fn entry_selected_as_suggestion(&self, entry_id: view::searcher::entry::Id) {
self.controller.preview_entry_as_suggestion(entry_id);
if let Err(error) = self.controller.preview_entry_as_suggestion(entry_id) {
tracing::warn!("Failed to preview entry {entry_id:?} because of error: {error:?}");
Copy link
Member

Choose a reason for hiding this comment

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

  1. double space
  2. Does it end with dot?

@@ -151,7 +153,9 @@ impl Model {
/// Should be called if a suggestion is selected but not used yet.
fn suggestion_selected(&self, entry_id: list_panel::EntryId) {
let suggestion = self.suggestion_for_entry_id(entry_id).unwrap();
self.controller.preview_suggestion(suggestion);
if let Err(error) = self.controller.preview_suggestion(suggestion) {
tracing::warn!("Failed to preview suggestion {entry_id:?} because of error: {error:?}");
Copy link
Member

Choose a reason for hiding this comment

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

does it end with. dot?

@MichaelMauderer MichaelMauderer added the CI: Ready to merge This PR is eligible for automatic merge label Sep 16, 2022
…rowser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050
@mergify mergify bot merged commit 545e1d7 into develop Sep 16, 2022
@mergify mergify bot deleted the wip/michaelmauderer/Propagate_Component_Browser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050 branch September 16, 2022 16:05
@MichaelMauderer MichaelMauderer restored the wip/michaelmauderer/Propagate_Component_Browser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050 branch September 20, 2022 09:54
@MichaelMauderer MichaelMauderer deleted the wip/michaelmauderer/Propagate_Component_Browser_Selections_to_Source_and_Disassociate_the_Node_That_Is_Edited_by_the_Searcher_From_any_Changes_Not_Made_by_the_Searcher_#182634050 branch December 9, 2022 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants