dataframe-textual 2.10.1__tar.gz → 2.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/PKG-INFO +11 -7
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/README.md +10 -6
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/pyproject.toml +1 -1
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/__main__.py +19 -1
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_table.py +11 -16
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_viewer.py +33 -14
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/table_screen.py +4 -2
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/uv.lock +1 -1
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/.gitignore +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/LICENSE +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/main.py +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/__init__.py +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/common.py +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_help_panel.py +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/sql_screen.py +0 -0
- {dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/yes_no_screen.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataframe-textual
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.12.0
|
|
4
4
|
Summary: Interactive terminal viewer/editor for tabular data
|
|
5
5
|
Project-URL: Homepage, https://github.com/need47/dataframe-textual
|
|
6
6
|
Project-URL: Repository, https://github.com/need47/dataframe-textual.git
|
|
@@ -195,6 +195,7 @@ options:
|
|
|
195
195
|
-N, --n-rows N Stop after reading N rows from CSV/TSV
|
|
196
196
|
-n, --null NULL [NULL ...]
|
|
197
197
|
Values to interpret as null values when reading CSV/TSV
|
|
198
|
+
--theme [THEME] Set the theme for the application (use 'list' to see available themes)
|
|
198
199
|
```
|
|
199
200
|
|
|
200
201
|
### CLI Examples
|
|
@@ -233,6 +234,9 @@ dv -l 3 -a 1 -I messy_scientific_data.csv
|
|
|
233
234
|
# Process compressed data
|
|
234
235
|
dv data.csv.gz
|
|
235
236
|
zcat compressed_data.csv.gz | dv -f csv
|
|
237
|
+
|
|
238
|
+
# Choose the `monokai` theme
|
|
239
|
+
dv --theme monokai data.csv
|
|
236
240
|
```
|
|
237
241
|
|
|
238
242
|
## Keyboard Shortcuts
|
|
@@ -247,8 +251,8 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
247
251
|
| `<` | Move to previous tab |
|
|
248
252
|
| `b` | Cycle through tabs |
|
|
249
253
|
| `B` | Toggle tab bar visibility |
|
|
250
|
-
| `q` |
|
|
251
|
-
| `Q` |
|
|
254
|
+
| `q` | Quit current tab (prompts to save unsaved changes) |
|
|
255
|
+
| `Q` | Quit all tabs and app (prompts to save unsaved changes) |
|
|
252
256
|
| `Ctrl+Q` | Force to quit app (regardless of unsaved changes) |
|
|
253
257
|
| `Ctrl+T` | Save current tab to file |
|
|
254
258
|
| `Ctrl+S` | Save all tabs to file |
|
|
@@ -306,9 +310,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
306
310
|
| `_` (underscore) | Toggle column full width |
|
|
307
311
|
| `z` | Freeze rows and columns |
|
|
308
312
|
| `,` | Toggle thousand separator for numeric display |
|
|
309
|
-
| `&` | Set current row as the new header row |
|
|
313
|
+
| `&` | Set current row as the new header row |
|
|
310
314
|
| `h` | Hide current column |
|
|
311
|
-
| `H` | Show all hidden
|
|
315
|
+
| `H` | Show all hidden columns |
|
|
312
316
|
|
|
313
317
|
#### Editing
|
|
314
318
|
|
|
@@ -499,7 +503,7 @@ Both operations show selected rows but with fundamentally different effects:
|
|
|
499
503
|
**When to use View** (`v` or `V`):
|
|
500
504
|
- Exploring or analyzing data safely
|
|
501
505
|
- Switching between different perspectives
|
|
502
|
-
- Press `
|
|
506
|
+
- Press `q` to return to main table
|
|
503
507
|
|
|
504
508
|
**When to use Filter** (`"`):
|
|
505
509
|
- Cleaning data (removing unwanted rows)
|
|
@@ -678,7 +682,7 @@ This is useful for:
|
|
|
678
682
|
|
|
679
683
|
**Hide/Show Columns** (`h` / `H`):
|
|
680
684
|
- `h` - Temporarily hide current column (data preserved)
|
|
681
|
-
- `H` - Restore all hidden columns
|
|
685
|
+
- `H` - Restore all hidden columns
|
|
682
686
|
|
|
683
687
|
### 12. Column & Row Reordering
|
|
684
688
|
|
|
@@ -156,6 +156,7 @@ options:
|
|
|
156
156
|
-N, --n-rows N Stop after reading N rows from CSV/TSV
|
|
157
157
|
-n, --null NULL [NULL ...]
|
|
158
158
|
Values to interpret as null values when reading CSV/TSV
|
|
159
|
+
--theme [THEME] Set the theme for the application (use 'list' to see available themes)
|
|
159
160
|
```
|
|
160
161
|
|
|
161
162
|
### CLI Examples
|
|
@@ -194,6 +195,9 @@ dv -l 3 -a 1 -I messy_scientific_data.csv
|
|
|
194
195
|
# Process compressed data
|
|
195
196
|
dv data.csv.gz
|
|
196
197
|
zcat compressed_data.csv.gz | dv -f csv
|
|
198
|
+
|
|
199
|
+
# Choose the `monokai` theme
|
|
200
|
+
dv --theme monokai data.csv
|
|
197
201
|
```
|
|
198
202
|
|
|
199
203
|
## Keyboard Shortcuts
|
|
@@ -208,8 +212,8 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
208
212
|
| `<` | Move to previous tab |
|
|
209
213
|
| `b` | Cycle through tabs |
|
|
210
214
|
| `B` | Toggle tab bar visibility |
|
|
211
|
-
| `q` |
|
|
212
|
-
| `Q` |
|
|
215
|
+
| `q` | Quit current tab (prompts to save unsaved changes) |
|
|
216
|
+
| `Q` | Quit all tabs and app (prompts to save unsaved changes) |
|
|
213
217
|
| `Ctrl+Q` | Force to quit app (regardless of unsaved changes) |
|
|
214
218
|
| `Ctrl+T` | Save current tab to file |
|
|
215
219
|
| `Ctrl+S` | Save all tabs to file |
|
|
@@ -267,9 +271,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
267
271
|
| `_` (underscore) | Toggle column full width |
|
|
268
272
|
| `z` | Freeze rows and columns |
|
|
269
273
|
| `,` | Toggle thousand separator for numeric display |
|
|
270
|
-
| `&` | Set current row as the new header row |
|
|
274
|
+
| `&` | Set current row as the new header row |
|
|
271
275
|
| `h` | Hide current column |
|
|
272
|
-
| `H` | Show all hidden
|
|
276
|
+
| `H` | Show all hidden columns |
|
|
273
277
|
|
|
274
278
|
#### Editing
|
|
275
279
|
|
|
@@ -460,7 +464,7 @@ Both operations show selected rows but with fundamentally different effects:
|
|
|
460
464
|
**When to use View** (`v` or `V`):
|
|
461
465
|
- Exploring or analyzing data safely
|
|
462
466
|
- Switching between different perspectives
|
|
463
|
-
- Press `
|
|
467
|
+
- Press `q` to return to main table
|
|
464
468
|
|
|
465
469
|
**When to use Filter** (`"`):
|
|
466
470
|
- Cleaning data (removing unwanted rows)
|
|
@@ -639,7 +643,7 @@ This is useful for:
|
|
|
639
643
|
|
|
640
644
|
**Hide/Show Columns** (`h` / `H`):
|
|
641
645
|
- `h` - Temporarily hide current column (data preserved)
|
|
642
|
-
- `H` - Restore all hidden columns
|
|
646
|
+
- `H` - Restore all hidden columns
|
|
643
647
|
|
|
644
648
|
### 12. Column & Row Reordering
|
|
645
649
|
|
|
@@ -4,6 +4,8 @@ import argparse
|
|
|
4
4
|
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from textual.theme import BUILTIN_THEMES
|
|
8
|
+
|
|
7
9
|
from . import __version__
|
|
8
10
|
from .common import SUPPORTED_FORMATS, load_dataframe
|
|
9
11
|
from .data_frame_viewer import DataFrameViewer
|
|
@@ -81,7 +83,23 @@ def cli() -> argparse.Namespace:
|
|
|
81
83
|
parser.add_argument("-N", "--n-rows", metavar="N", type=int, help="Stop after reading N rows from CSV/TSV")
|
|
82
84
|
parser.add_argument("-n", "--null", nargs="+", help="Values to interpret as null values when reading CSV/TSV")
|
|
83
85
|
|
|
86
|
+
parser.add_argument(
|
|
87
|
+
"--theme",
|
|
88
|
+
nargs="?",
|
|
89
|
+
const="list",
|
|
90
|
+
help="Set the theme for the application (use 'list' to see available themes)",
|
|
91
|
+
)
|
|
92
|
+
|
|
84
93
|
args = parser.parse_args()
|
|
94
|
+
|
|
95
|
+
# List available themes and exit
|
|
96
|
+
if args.theme == "list":
|
|
97
|
+
print("Available themes:")
|
|
98
|
+
for theme in BUILTIN_THEMES:
|
|
99
|
+
print(f" - {theme}")
|
|
100
|
+
sys.exit(0)
|
|
101
|
+
|
|
102
|
+
# Handle files
|
|
85
103
|
if args.files is None:
|
|
86
104
|
args.files = []
|
|
87
105
|
|
|
@@ -119,7 +137,7 @@ def main() -> None:
|
|
|
119
137
|
truncate_ragged_lines=args.truncate_ragged_lines,
|
|
120
138
|
n_rows=args.n_rows,
|
|
121
139
|
)
|
|
122
|
-
app = DataFrameViewer(*sources)
|
|
140
|
+
app = DataFrameViewer(*sources, theme=args.theme)
|
|
123
141
|
app.run()
|
|
124
142
|
|
|
125
143
|
|
{dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_table.py
RENAMED
|
@@ -242,7 +242,7 @@ class DataFrameTable(DataTable):
|
|
|
242
242
|
("ctrl+u", "reset", "Reset to initial state"),
|
|
243
243
|
# Display
|
|
244
244
|
("h", "hide_column", "Hide column"),
|
|
245
|
-
("H", "
|
|
245
|
+
("H", "show_hidden_columns", "Show hidden column(s)"),
|
|
246
246
|
("tilde", "toggle_row_labels", "Toggle row labels"), # `~`
|
|
247
247
|
("K", "cycle_cursor_type", "Cycle cursor mode"), # `K`
|
|
248
248
|
("z", "freeze_row_column", "Freeze rows/columns"),
|
|
@@ -731,9 +731,9 @@ class DataFrameTable(DataTable):
|
|
|
731
731
|
"""Set cursor row as the new header row."""
|
|
732
732
|
self.do_set_cursor_row_as_header()
|
|
733
733
|
|
|
734
|
-
def
|
|
735
|
-
"""Show all hidden
|
|
736
|
-
self.
|
|
734
|
+
def action_show_hidden_columns(self) -> None:
|
|
735
|
+
"""Show all hidden columns."""
|
|
736
|
+
self.do_show_hidden_columns()
|
|
737
737
|
|
|
738
738
|
def action_sort_ascending(self) -> None:
|
|
739
739
|
"""Sort by current column in ascending order."""
|
|
@@ -1847,27 +1847,22 @@ class DataFrameTable(DataTable):
|
|
|
1847
1847
|
|
|
1848
1848
|
# self.notify(f"Set row [$success]{ridx + 1}[/] as header", title="Set Row as Header")
|
|
1849
1849
|
|
|
1850
|
-
def
|
|
1851
|
-
"""Show all hidden
|
|
1852
|
-
if not self.hidden_columns
|
|
1853
|
-
# self.notify("No hidden
|
|
1850
|
+
def do_show_hidden_columns(self) -> None:
|
|
1851
|
+
"""Show all hidden columns by recreating the table."""
|
|
1852
|
+
if not self.hidden_columns:
|
|
1853
|
+
# self.notify("No hidden columns to show", title="Show Hidden Column(s)", severity="warning")
|
|
1854
1854
|
return
|
|
1855
1855
|
|
|
1856
1856
|
# Add to history
|
|
1857
|
-
self.add_history("Showed hidden
|
|
1857
|
+
self.add_history("Showed hidden column(s)")
|
|
1858
1858
|
|
|
1859
|
-
#
|
|
1860
|
-
if self.df_view is not None:
|
|
1861
|
-
self.df = self.df_view
|
|
1862
|
-
self.df_view = None
|
|
1863
|
-
|
|
1864
|
-
# Clear hidden rows/columns tracking
|
|
1859
|
+
# Clear hidden columns tracking
|
|
1865
1860
|
self.hidden_columns.clear()
|
|
1866
1861
|
|
|
1867
1862
|
# Recreate table for display
|
|
1868
1863
|
self.setup_table()
|
|
1869
1864
|
|
|
1870
|
-
# self.notify("Showed hidden
|
|
1865
|
+
# self.notify("Showed hidden column(s)", title="Show Hidden Column(s)")
|
|
1871
1866
|
|
|
1872
1867
|
# Sort
|
|
1873
1868
|
def do_sort_by_column(self, descending: bool = False) -> None:
|
{dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_viewer.py
RENAMED
|
@@ -58,8 +58,8 @@ class DataFrameViewer(App):
|
|
|
58
58
|
""").strip()
|
|
59
59
|
|
|
60
60
|
BINDINGS = [
|
|
61
|
-
("q", "
|
|
62
|
-
("Q", "
|
|
61
|
+
("q", "quit", "Quit from view or close current tab"),
|
|
62
|
+
("Q", "quit_all", "Quit app after closing all tabs"),
|
|
63
63
|
("B", "toggle_tab_bar", "Toggle Tab Bar"),
|
|
64
64
|
("f1", "toggle_help_panel", "Help"),
|
|
65
65
|
("ctrl+o", "open_file", "Open File"),
|
|
@@ -88,7 +88,7 @@ class DataFrameViewer(App):
|
|
|
88
88
|
}
|
|
89
89
|
"""
|
|
90
90
|
|
|
91
|
-
def __init__(self, *sources: Source) -> None:
|
|
91
|
+
def __init__(self, *sources: Source, theme: str | None = None) -> None:
|
|
92
92
|
"""Initialize the DataFrame Viewer application.
|
|
93
93
|
|
|
94
94
|
Loads data from provided sources and prepares the tabbed interface.
|
|
@@ -96,9 +96,11 @@ class DataFrameViewer(App):
|
|
|
96
96
|
Args:
|
|
97
97
|
sources: sources to load dataframes from, each as a tuple of
|
|
98
98
|
(DataFrame, filename, tabname).
|
|
99
|
+
theme: Optional; The theme to use for the application.
|
|
99
100
|
"""
|
|
100
101
|
super().__init__()
|
|
101
102
|
self.sources = sources
|
|
103
|
+
self.theme = theme
|
|
102
104
|
self.tabs: dict[TabPane, DataFrameTable] = {}
|
|
103
105
|
self.help_panel = None
|
|
104
106
|
|
|
@@ -242,21 +244,21 @@ class DataFrameViewer(App):
|
|
|
242
244
|
"""
|
|
243
245
|
self.push_screen(OpenFileScreen(), self.do_open_file)
|
|
244
246
|
|
|
245
|
-
def
|
|
246
|
-
"""
|
|
247
|
+
def action_quit(self) -> None:
|
|
248
|
+
"""Quit from the view or the current tab.
|
|
247
249
|
|
|
248
250
|
Checks for unsaved changes and prompts the user to save if needed.
|
|
249
251
|
If this is the last tab, exits the app.
|
|
250
252
|
"""
|
|
251
|
-
self.
|
|
253
|
+
self.do_quit()
|
|
252
254
|
|
|
253
|
-
def
|
|
254
|
-
"""
|
|
255
|
+
def action_quit_all(self) -> None:
|
|
256
|
+
"""Quit app after closing all tabs.
|
|
255
257
|
|
|
256
258
|
Checks if any tabs have unsaved changes. If yes, opens a confirmation dialog.
|
|
257
259
|
Otherwise, quits immediately.
|
|
258
260
|
"""
|
|
259
|
-
self.
|
|
261
|
+
self.do_quit_all()
|
|
260
262
|
|
|
261
263
|
def action_save_current_tab(self) -> None:
|
|
262
264
|
"""Open a save dialog to save current tab to file."""
|
|
@@ -486,16 +488,33 @@ class DataFrameViewer(App):
|
|
|
486
488
|
self.tabbed.active = tab.id
|
|
487
489
|
table.focus()
|
|
488
490
|
|
|
489
|
-
def
|
|
490
|
-
"""
|
|
491
|
+
def do_quit(self) -> None:
|
|
492
|
+
"""Quit from the view or the current tab.
|
|
491
493
|
|
|
492
|
-
|
|
493
|
-
can be closed, the application
|
|
494
|
+
When in a view, return to main table. Otherwise, close the active tab.
|
|
495
|
+
If only one tab remains and no more tabs can be closed, exits the application.
|
|
494
496
|
"""
|
|
495
497
|
try:
|
|
496
498
|
if not (table := self.active_table):
|
|
497
499
|
return
|
|
498
500
|
|
|
501
|
+
# In a view - return to main table
|
|
502
|
+
if table.df_view is not None:
|
|
503
|
+
# Remove from history
|
|
504
|
+
while table.histories_undo:
|
|
505
|
+
h = table.histories_undo[-1]
|
|
506
|
+
if h.description.startswith("Viewed rows by expression"):
|
|
507
|
+
table.histories_undo.pop()
|
|
508
|
+
else:
|
|
509
|
+
break
|
|
510
|
+
|
|
511
|
+
table.add_history("Return to main table")
|
|
512
|
+
table.df = table.df_view
|
|
513
|
+
table.df_view = None
|
|
514
|
+
table.setup_table()
|
|
515
|
+
|
|
516
|
+
return
|
|
517
|
+
|
|
499
518
|
def _on_save_confirm(result: bool) -> None:
|
|
500
519
|
"""Handle the "save before closing?" confirmation."""
|
|
501
520
|
if result:
|
|
@@ -540,7 +559,7 @@ class DataFrameViewer(App):
|
|
|
540
559
|
except Exception:
|
|
541
560
|
pass
|
|
542
561
|
|
|
543
|
-
def
|
|
562
|
+
def do_quit_all(self) -> None:
|
|
544
563
|
"""Close all tabs and quit the app.
|
|
545
564
|
|
|
546
565
|
Checks if any tabs have unsaved changes. If yes, opens a confirmation dialog.
|
|
@@ -134,8 +134,10 @@ class TableScreen(ModalScreen):
|
|
|
134
134
|
else:
|
|
135
135
|
self.dftable.view_rows((expr, cidx, False, True))
|
|
136
136
|
|
|
137
|
-
# Dismiss
|
|
138
|
-
self.app.
|
|
137
|
+
# Dismiss modal screen(s) to return to main table
|
|
138
|
+
while len(self.app._screen_stack) > 1:
|
|
139
|
+
self.app.pop_screen()
|
|
140
|
+
break
|
|
139
141
|
|
|
140
142
|
def show_frequency(self, cidx_name_value: tuple[int, str, Any] | None) -> None:
|
|
141
143
|
"""Show frequency by the selected value.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/data_frame_help_panel.py
RENAMED
|
File without changes
|
|
File without changes
|
{dataframe_textual-2.10.1 → dataframe_textual-2.12.0}/src/dataframe_textual/yes_no_screen.py
RENAMED
|
File without changes
|