Skip to content

Commit 84cbfa1

Browse files
authored
Merge pull request #223 from PeterAdams-ecitsolutions/fix-empty-state-footer-bindings
Show label-only footer bindings, gate Visual on a tree selection
2 parents a55e795 + 6469a1b commit 84cbfa1

3 files changed

Lines changed: 46 additions & 2 deletions

File tree

‎sqlit/core/state_base.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ def allows(
130130
help_key=help_key or key,
131131
help_description=help,
132132
)
133-
if key and label:
133+
# A label means the author wants this in the footer. The display
134+
# key can be omitted here and resolved at render time via the
135+
# global keymap (see ActionSpec.get_display_binding).
136+
if label:
134137
if right:
135138
self._right_bindings.append(action_name)
136139
else:

‎sqlit/domains/explorer/state/tree_focused.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ def _setup_actions(self) -> None:
1818
self.allows("tree_cursor_down") # vim j
1919
self.allows("tree_cursor_up") # vim k
2020
self.allows("tree_filter", help="Filter items")
21-
self.allows("enter_tree_visual_mode", label="Visual", help="Enter visual selection mode")
21+
self.allows(
22+
"enter_tree_visual_mode",
23+
lambda app: app.tree_node_kind is not None,
24+
label="Visual",
25+
help="Enter visual selection mode",
26+
)
2227

2328
def is_active(self, app: InputContext) -> bool:
2429
return app.focus == "explorer" and not app.tree_filter_active

‎tests/ui/keybindings/test_state_machine.py‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,39 @@ def test_collapse_all_only_in_tree_mode(self):
177177
value_view_tree_mode=False,
178178
)
179179
assert sm.check_action(ctx, "collapse_all_json_nodes") is False
180+
181+
182+
class TestEmptyExplorerFooter:
183+
"""Empty-state footer must guide a first-time user toward `n` for New."""
184+
185+
def test_new_connection_in_footer_when_explorer_focused_empty(self):
186+
sm = UIStateMachine()
187+
ctx = make_context(focus="explorer", tree_node_kind=None)
188+
left, _right = sm.get_display_bindings(ctx)
189+
actions = [b.action for b in left]
190+
assert "new_connection" in actions, (
191+
"First-time users with no connections must see `n` for New "
192+
"in the footer when the explorer is focused."
193+
)
194+
195+
def test_refresh_tree_in_footer_when_explorer_focused_empty(self):
196+
sm = UIStateMachine()
197+
ctx = make_context(focus="explorer", tree_node_kind=None)
198+
left, _right = sm.get_display_bindings(ctx)
199+
actions = [b.action for b in left]
200+
assert "refresh_tree" in actions
201+
202+
def test_visual_mode_hidden_from_footer_when_tree_empty(self):
203+
"""Visual selection mode only makes sense when there's something to select."""
204+
sm = UIStateMachine()
205+
ctx = make_context(focus="explorer", tree_node_kind=None)
206+
left, _right = sm.get_display_bindings(ctx)
207+
actions = [b.action for b in left]
208+
assert "enter_tree_visual_mode" not in actions
209+
210+
def test_visual_mode_shown_in_footer_when_node_highlighted(self):
211+
sm = UIStateMachine()
212+
ctx = make_context(focus="explorer", tree_node_kind="connection")
213+
left, _right = sm.get_display_bindings(ctx)
214+
actions = [b.action for b in left]
215+
assert "enter_tree_visual_mode" in actions

0 commit comments

Comments
 (0)