Skip to content

Commit 095e8e7

Browse files
committed
Preview and view tooltip
1 parent 63eb012 commit 095e8e7

File tree

5 files changed

+77
-4
lines changed

5 files changed

+77
-4
lines changed

sqlit/app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ class SSMSTUI(
285285
Binding("j", "tree_cursor_down", "Down", show=False),
286286
Binding("k", "tree_cursor_up", "Up", show=False),
287287
Binding("v", "view_cell", "View cell", show=False),
288+
Binding("V", "view_cell_full", "View cell full", show=False),
288289
Binding("u", "edit_cell", "Update cell", show=False),
289290
Binding("h", "results_cursor_left", "Left", show=False),
290291
Binding("j", "results_cursor_down", "Down", show=False),

sqlit/keymap.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def get_action_keys(self) -> list[ActionKeyDef]:
126126
ActionKeyDef("y", "copy_context", "query_normal"),
127127
# Results
128128
ActionKeyDef("v", "view_cell", "results"),
129+
ActionKeyDef("V", "view_cell_full", "results"),
129130
ActionKeyDef("y", "copy_context", "results"),
130131
ActionKeyDef("Y", "copy_row", "results"),
131132
ActionKeyDef("a", "copy_results", "results"),

sqlit/state_machine.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,8 @@ class ResultsFocusedState(State):
899899
help_category = "Results"
900900

901901
def _setup_actions(self) -> None:
902-
self.allows("view_cell", key="v", label="View cell", help="View selected cell")
902+
self.allows("view_cell", key="v", label="View cell", help="Preview cell (tooltip)")
903+
self.allows("view_cell_full", key="V", label="View full", help="View full cell value")
903904
self.allows("edit_cell", key="u", label="Update cell", help="Update cell (generate UPDATE)")
904905
self.allows("copy_context", key="y", label="Copy cell", help="Copy selected cell")
905906
self.allows("copy_row", key="Y", label="Copy row", help="Copy selected row")
@@ -921,15 +922,16 @@ def get_display_bindings(self, app: SSMSTUI) -> tuple[list[DisplayBinding], list
921922
left.append(DisplayBinding(key="v", label="View error", action="view_cell"))
922923
left.append(DisplayBinding(key="y", label="Copy error", action="copy_context"))
923924
else:
924-
left.append(DisplayBinding(key="v", label="View cell", action="view_cell"))
925+
left.append(DisplayBinding(key="v", label="Preview", action="view_cell"))
926+
left.append(DisplayBinding(key="V", label="View", action="view_cell_full"))
925927
left.append(DisplayBinding(key="u", label="Update", action="edit_cell"))
926928
left.append(DisplayBinding(key="y", label="Copy cell", action="copy_context"))
927929
left.append(DisplayBinding(key="Y", label="Copy row", action="copy_row"))
928930
left.append(DisplayBinding(key="a", label="Copy all", action="copy_results"))
929931
left.append(DisplayBinding(key="x", label="Clear", action="clear_results"))
930932
left.append(DisplayBinding(key="/", label="Filter", action="results_filter"))
931933

932-
seen.update(["view_cell", "copy_context", "copy_row", "copy_results", "clear_results", "results_filter"])
934+
seen.update(["view_cell", "view_cell_full", "copy_context", "copy_row", "copy_results", "clear_results", "results_filter"])
933935

934936
right: list[DisplayBinding] = []
935937
if self.parent:

sqlit/ui/mixins/results.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,64 @@ def fmt(value: object) -> str:
7474
return "\n".join(lines)
7575

7676
def action_view_cell(self: AppProtocol) -> None:
77+
"""Show/hide tooltip preview of the selected cell at the cell position."""
78+
from textual.geometry import Offset
79+
from textual.widgets._tooltip import Tooltip
80+
81+
table = self.results_table
82+
if table.row_count <= 0:
83+
self.notify("No results", severity="warning")
84+
return
85+
try:
86+
# Get the tooltip widget from the screen
87+
screen = self.screen
88+
try:
89+
tooltip_widget = screen.get_child_by_type(Tooltip)
90+
except Exception:
91+
return
92+
93+
current_coord = table.cursor_coordinate
94+
95+
# Check if tooltip is already showing for this cell - toggle it off
96+
tooltip_coord = getattr(self, "_tooltip_cell_coord", None)
97+
tooltip_showing = getattr(self, "_tooltip_showing", False)
98+
if tooltip_showing and tooltip_coord == current_coord:
99+
tooltip_widget.display = False
100+
self._tooltip_cell_coord = None
101+
self._tooltip_showing = False
102+
return
103+
104+
# Get cell value directly (always show, regardless of truncation)
105+
value = table.get_cell_at(current_coord)
106+
if value is None:
107+
value = "NULL"
108+
tooltip_content = str(value)
109+
110+
# Position at bottom-right of table content area
111+
scrollbar_h = table.scrollbar_size_horizontal
112+
scrollbar_v = table.scrollbar_size_vertical
113+
screen_x = table.region.x + table.region.width - scrollbar_v
114+
screen_y = table.region.y + table.region.height - scrollbar_h - 1
115+
116+
# Update and position the tooltip
117+
tooltip_widget.display = True
118+
tooltip_widget.absolute_offset = Offset(screen_x, screen_y)
119+
tooltip_widget.update(tooltip_content)
120+
121+
# Apply CSS offsets to make tooltip expand left and up from anchor
122+
tooltip_widget.styles.offset = ("-100%", "-100%")
123+
124+
# Track which cell the tooltip is showing for
125+
self._tooltip_cell_coord = current_coord
126+
self._tooltip_showing = True
127+
128+
# Clear _tooltip_widget so mouse movement won't clear this tooltip
129+
# (the _maybe_clear_tooltip check compares current widget to _tooltip_widget)
130+
screen._tooltip_widget = None
131+
except Exception:
132+
pass
133+
134+
def action_view_cell_full(self: AppProtocol) -> None:
77135
"""View the full value of the selected cell inline."""
78136
from ...widgets import InlineValueView
79137

sqlit/widgets.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,18 @@ def _on_key(self, event: Key) -> None:
3636

3737

3838
class SqlitDataTable(FastDataTable):
39-
"""FastDataTable with correct header behavior when show_header is False."""
39+
"""FastDataTable with correct header behavior when show_header is False.
40+
41+
Disables hover tooltips - use 'v' key to preview cell values instead.
42+
"""
43+
44+
# Track if a manual tooltip is being shown (via 'v' key)
45+
_manual_tooltip_active: bool = False
46+
47+
def _set_tooltip_from_cell_at(self, coordinate: Any) -> None:
48+
"""Override to disable hover tooltips entirely."""
49+
# Don't set tooltip on hover - we handle this manually via 'v' key
50+
pass
4051

4152
def action_copy_selection(self) -> None:
4253
"""Copy selection to clipboard, guarding against empty tables."""

0 commit comments

Comments
 (0)