Skip to content

Commit aef7c9e

Browse files
authored
Merge pull request #5361 from Textualize/command-palette-highlight
highlight top item
2 parents 2686bba + b609303 commit aef7c9e

10 files changed

+468
-491
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1717

1818
- Change default quit key to `ctrl+q` https://github.com/Textualize/textual/pull/5352
1919
- Changed delete line binding on TextArea to use `ctrl+shift+x` https://github.com/Textualize/textual/pull/5352
20+
- The command palette will now select the top item automatically https://github.com/Textualize/textual/pull/5361
2021

2122
### Fixed
2223

src/textual/command.py

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from dataclasses import dataclass
2121
from functools import total_ordering
2222
from inspect import isclass
23+
from operator import attrgetter
2324
from time import monotonic
2425
from typing import (
2526
TYPE_CHECKING,
@@ -455,9 +456,9 @@ class CommandList(OptionList, can_focus=False):
455456
}
456457
457458
CommandList > .option-list--option-highlighted {
458-
color: $block-cursor-foreground;
459-
background: $block-cursor-background;
460-
text-style: $block-cursor-text-style;
459+
color: $block-cursor-blurred-foreground;
460+
background: $block-cursor-blurred-background;
461+
text-style: $block-cursor-blurred-text-style;
461462
}
462463
463464
CommandList:nocolor > .option-list--option-highlighted {
@@ -1014,26 +1015,12 @@ def _refresh_command_list(
10141015
commands: The commands to show in the widget.
10151016
clear_current: Should the current content of the list be cleared first?
10161017
"""
1017-
# For the moment, this is a fairly naive approach to populating the
1018-
# command list with a list of commands. Every time we add a
1019-
# new one we're nuking the list of options and populating them
1020-
# again. If this turns out to not be a great approach, we may try
1021-
# and get a lot smarter with this (ideally OptionList will grow a
1022-
# method to sort its content in an efficient way; but for now we'll
1023-
# go with "worse is better" wisdom).
1024-
highlighted = (
1025-
command_list.get_option_at_index(command_list.highlighted)
1026-
if command_list.highlighted is not None and not clear_current
1027-
else None
1028-
)
1029-
1030-
def sort_key(command: Command) -> float:
1031-
return -command.hit.score
10321018

1033-
sorted_commands = sorted(commands, key=sort_key)
1019+
sorted_commands = sorted(commands, key=attrgetter("hit.score"), reverse=True)
10341020
command_list.clear_options().add_options(sorted_commands)
1035-
if highlighted is not None and highlighted.id:
1036-
command_list.highlighted = command_list.get_option_index(highlighted.id)
1021+
1022+
if sorted_commands:
1023+
command_list.highlighted = 0
10371024

10381025
self._list_visible = bool(command_list.option_count)
10391026
self._hit_count = command_list.option_count

tests/command_palette/test_interaction.py

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ def on_mount(self) -> None:
1919

2020

2121
async def test_initial_list_no_highlight() -> None:
22-
"""When the list initially appears, nothing will be highlighted."""
22+
"""When the list initially appears, the first item is highlghted."""
2323
async with CommandPaletteApp().run_test() as pilot:
2424
assert CommandPalette.is_open(pilot.app)
2525
assert pilot.app.screen.query_one(CommandList).visible is False
2626
await pilot.press("a")
2727
assert pilot.app.screen.query_one(CommandList).visible is True
28-
assert pilot.app.screen.query_one(CommandList).highlighted is None
28+
assert pilot.app.screen.query_one(CommandList).highlighted == 0
2929

3030

3131
async def test_down_arrow_selects_an_item() -> None:
@@ -35,32 +35,19 @@ async def test_down_arrow_selects_an_item() -> None:
3535
assert pilot.app.screen.query_one(CommandList).visible is False
3636
await pilot.press("a")
3737
assert pilot.app.screen.query_one(CommandList).visible is True
38-
assert pilot.app.screen.query_one(CommandList).highlighted is None
38+
assert pilot.app.screen.query_one(CommandList).highlighted == 0
3939
await pilot.press("down")
40-
assert pilot.app.screen.query_one(CommandList).highlighted is not None
40+
assert pilot.app.screen.query_one(CommandList).highlighted == 1
4141

4242

4343
async def test_enter_selects_an_item() -> None:
44-
"""Typing in a search value then pressing enter should select a command."""
44+
"""Typing in a search value then pressing enter should dismiss the command palette."""
4545
async with CommandPaletteApp().run_test() as pilot:
4646
assert CommandPalette.is_open(pilot.app)
4747
assert pilot.app.screen.query_one(CommandList).visible is False
4848
await pilot.press("a")
4949
assert pilot.app.screen.query_one(CommandList).visible is True
50-
assert pilot.app.screen.query_one(CommandList).highlighted is None
51-
await pilot.press("enter")
52-
assert pilot.app.screen.query_one(CommandList).highlighted is not None
53-
54-
55-
async def test_selection_of_command_closes_command_palette() -> None:
56-
"""Selecting a command from the list should close the list."""
57-
async with CommandPaletteApp().run_test() as pilot:
58-
assert CommandPalette.is_open(pilot.app)
59-
assert pilot.app.screen.query_one(CommandList).visible is False
60-
await pilot.press("a")
61-
assert pilot.app.screen.query_one(CommandList).visible is True
62-
assert pilot.app.screen.query_one(CommandList).highlighted is None
63-
await pilot.press("enter")
64-
assert pilot.app.screen.query_one(CommandList).highlighted is not None
50+
assert pilot.app.screen.query_one(CommandList).highlighted == 0
6551
await pilot.press("enter")
6652
assert not CommandPalette.is_open(pilot.app)
53+
assert not pilot.app.screen.query(CommandList)

tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_command_palette.svg

Lines changed: 68 additions & 67 deletions
Loading

0 commit comments

Comments
 (0)