gpui: Add 'Nearest' scrolling strategy to 'UniformList' (#41844)
This PR introduces `Nearest` scrolling strategy to `UniformList`. This is now used in completions menu and the picker to choose the appropriate scrolling strategy depending on movement direction. Previously, selecting the next element after the last visible item caused the menu to scroll with `ScrollStrategy::Top`, which scrolled the whole page and placed the next element at the top. This behavior is inconsistent, because using `ScrollStrategy::Top` when moving up only scrolls one element, not the whole page. https://github.com/user-attachments/assets/ccfb238f-8f76-4a18-a18d-bbcb63340c5a The solution is to introduce the `Nearest` scrolling strategy which will internally choose the scrolling strategy depending on whether the new selected item is below or above currently visible items. This ensures a single-item scroll regardless of movement direction. https://github.com/user-attachments/assets/8502efb8-e2c0-4ab1-bd8d-93103841a9c4 I also noticed that some functions in the file have different logic depending on `y_flipped`. This appears related to reversing the order of elements in the list when the completion menu appears above the cursor. This was a feature suggested in #11200 and implemented in #23446. It looks like this feature was reverted in #27765 and there currently seem to be no way to have `y_flipped` to be set to `true`. My understanding is that the opposite scroll strategy should be used if `y_flipped`, but since there is no way to enable this feature to test it and I don't know if the feature is ever going to be reintroduced I decided not to include it in this PR. Release Notes: - gpui: Add 'Nearest' scrolling strategy to 'UniformList'
This commit is contained in:
@@ -506,7 +506,7 @@ impl CompletionsMenu {
|
||||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
self.scroll_handle
|
||||
.scroll_to_item(self.selected_item, ScrollStrategy::Top);
|
||||
.scroll_to_item(self.selected_item, ScrollStrategy::Nearest);
|
||||
if let Some(provider) = provider {
|
||||
let entries = self.entries.borrow();
|
||||
let entry = if self.selected_item < entries.len() {
|
||||
|
||||
Reference in New Issue
Block a user