dataframe-textual 1.16.2__tar.gz → 2.0.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-1.16.2 → dataframe_textual-2.0.0}/PKG-INFO +10 -10
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/README.md +9 -9
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/pyproject.toml +1 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/__init__.py +27 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/__main__.py +7 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/common.py +15 -9
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/data_frame_help_panel.py +0 -3
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/data_frame_table.py +619 -559
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/data_frame_viewer.py +16 -8
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/sql_screen.py +8 -2
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/table_screen.py +25 -51
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/yes_no_screen.py +9 -18
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/uv.lock +1 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/.gitignore +0 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/LICENSE +0 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dataframe-textual
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.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
|
|
@@ -325,7 +325,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
325
325
|
|
|
326
326
|
| Key | Action |
|
|
327
327
|
|-----|--------|
|
|
328
|
-
| `\` | Select rows
|
|
328
|
+
| `\` | Select rows wth cell matches or those matching cursor value in current column |
|
|
329
329
|
| `\|` (pipe) | Select rows by expression |
|
|
330
330
|
| `{` | Go to previous selected row |
|
|
331
331
|
| `}` | Go to next selected row |
|
|
@@ -349,9 +349,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
349
349
|
#### View & Filter
|
|
350
350
|
| Key | Action |
|
|
351
351
|
|-----|--------|
|
|
352
|
-
| `"` (quote) | Filter
|
|
353
|
-
| `v` | View rows (
|
|
354
|
-
| `V` | View
|
|
352
|
+
| `"` (quote) | Filter selected rows (others removed) |
|
|
353
|
+
| `v` | View selected rows (others hidden) |
|
|
354
|
+
| `V` | View selected by expression (others hidden) |
|
|
355
355
|
|
|
356
356
|
#### SQL Interface
|
|
357
357
|
|
|
@@ -411,8 +411,8 @@ Press `Enter` on any row to open a modal showing all column values for that row.
|
|
|
411
411
|
Useful for examining wide datasets where columns don't fit well on screen.
|
|
412
412
|
|
|
413
413
|
**In the Row Detail Modal**:
|
|
414
|
-
- Press `v` to **view** all rows containing the selected column value (
|
|
415
|
-
- Press `"` to **filter** all rows containing the selected column value (
|
|
414
|
+
- Press `v` to **view** all rows containing the selected column value (others hidden but preserved)
|
|
415
|
+
- Press `"` to **filter** all rows containing the selected column value (others removed)
|
|
416
416
|
- Press `{` to move to the **previous row** (respects hidden rows)
|
|
417
417
|
- Press `}` to move to the **next row** (respects hidden rows)
|
|
418
418
|
- Press `q` or `Escape` to close the modal
|
|
@@ -421,7 +421,7 @@ Useful for examining wide datasets where columns don't fit well on screen.
|
|
|
421
421
|
|
|
422
422
|
The application provides multiple modes for selecting rows (marks it for filtering or viewing):
|
|
423
423
|
|
|
424
|
-
- `\` - Select rows
|
|
424
|
+
- `\` - Select rows with cell matches or those matching cursor value in current column (respects data type)
|
|
425
425
|
- `|` - Opens dialog to select rows with custom expression
|
|
426
426
|
- `'` - Select/deselect current row
|
|
427
427
|
- `t` - Flip selections of all rows
|
|
@@ -591,8 +591,8 @@ Press `F` to see value distributions of the current column. The modal shows:
|
|
|
591
591
|
|
|
592
592
|
**In the Frequency Table**:
|
|
593
593
|
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
594
|
-
- Press `v` to **
|
|
595
|
-
- Press `"` to **
|
|
594
|
+
- Press `v` to **view** all rows containing the selected value (others hidden but preserved)
|
|
595
|
+
- Press `"` to **filter** all rows containing the selected value (others removed)
|
|
596
596
|
- Press `q` or `Escape` to close the frequency table
|
|
597
597
|
|
|
598
598
|
This is useful for:
|
|
@@ -286,7 +286,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
286
286
|
|
|
287
287
|
| Key | Action |
|
|
288
288
|
|-----|--------|
|
|
289
|
-
| `\` | Select rows
|
|
289
|
+
| `\` | Select rows wth cell matches or those matching cursor value in current column |
|
|
290
290
|
| `\|` (pipe) | Select rows by expression |
|
|
291
291
|
| `{` | Go to previous selected row |
|
|
292
292
|
| `}` | Go to next selected row |
|
|
@@ -310,9 +310,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
310
310
|
#### View & Filter
|
|
311
311
|
| Key | Action |
|
|
312
312
|
|-----|--------|
|
|
313
|
-
| `"` (quote) | Filter
|
|
314
|
-
| `v` | View rows (
|
|
315
|
-
| `V` | View
|
|
313
|
+
| `"` (quote) | Filter selected rows (others removed) |
|
|
314
|
+
| `v` | View selected rows (others hidden) |
|
|
315
|
+
| `V` | View selected by expression (others hidden) |
|
|
316
316
|
|
|
317
317
|
#### SQL Interface
|
|
318
318
|
|
|
@@ -372,8 +372,8 @@ Press `Enter` on any row to open a modal showing all column values for that row.
|
|
|
372
372
|
Useful for examining wide datasets where columns don't fit well on screen.
|
|
373
373
|
|
|
374
374
|
**In the Row Detail Modal**:
|
|
375
|
-
- Press `v` to **view** all rows containing the selected column value (
|
|
376
|
-
- Press `"` to **filter** all rows containing the selected column value (
|
|
375
|
+
- Press `v` to **view** all rows containing the selected column value (others hidden but preserved)
|
|
376
|
+
- Press `"` to **filter** all rows containing the selected column value (others removed)
|
|
377
377
|
- Press `{` to move to the **previous row** (respects hidden rows)
|
|
378
378
|
- Press `}` to move to the **next row** (respects hidden rows)
|
|
379
379
|
- Press `q` or `Escape` to close the modal
|
|
@@ -382,7 +382,7 @@ Useful for examining wide datasets where columns don't fit well on screen.
|
|
|
382
382
|
|
|
383
383
|
The application provides multiple modes for selecting rows (marks it for filtering or viewing):
|
|
384
384
|
|
|
385
|
-
- `\` - Select rows
|
|
385
|
+
- `\` - Select rows with cell matches or those matching cursor value in current column (respects data type)
|
|
386
386
|
- `|` - Opens dialog to select rows with custom expression
|
|
387
387
|
- `'` - Select/deselect current row
|
|
388
388
|
- `t` - Flip selections of all rows
|
|
@@ -552,8 +552,8 @@ Press `F` to see value distributions of the current column. The modal shows:
|
|
|
552
552
|
|
|
553
553
|
**In the Frequency Table**:
|
|
554
554
|
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
555
|
-
- Press `v` to **
|
|
556
|
-
- Press `"` to **
|
|
555
|
+
- Press `v` to **view** all rows containing the selected value (others hidden but preserved)
|
|
556
|
+
- Press `"` to **filter** all rows containing the selected value (others removed)
|
|
557
557
|
- Press `q` or `Escape` to close the frequency table
|
|
558
558
|
|
|
559
559
|
This is useful for:
|
|
@@ -1,15 +1,32 @@
|
|
|
1
1
|
"""DataFrame Viewer - Interactive CSV/Excel viewer for the terminal."""
|
|
2
2
|
|
|
3
|
+
from importlib.metadata import version
|
|
4
|
+
|
|
5
|
+
__version__ = version("dataframe-textual")
|
|
6
|
+
|
|
3
7
|
from .data_frame_help_panel import DataFrameHelpPanel
|
|
4
8
|
from .data_frame_table import DataFrameTable, History
|
|
5
9
|
from .data_frame_viewer import DataFrameViewer
|
|
6
|
-
from .table_screen import
|
|
10
|
+
from .table_screen import (
|
|
11
|
+
FrequencyScreen,
|
|
12
|
+
MetaColumnScreen,
|
|
13
|
+
MetaShape,
|
|
14
|
+
RowDetailScreen,
|
|
15
|
+
StatisticsScreen,
|
|
16
|
+
TableScreen,
|
|
17
|
+
)
|
|
7
18
|
from .yes_no_screen import (
|
|
19
|
+
AddColumnScreen,
|
|
20
|
+
AddLinkScreen,
|
|
8
21
|
ConfirmScreen,
|
|
9
22
|
EditCellScreen,
|
|
23
|
+
EditColumnScreen,
|
|
10
24
|
FilterScreen,
|
|
25
|
+
FindReplaceScreen,
|
|
11
26
|
FreezeScreen,
|
|
12
27
|
OpenFileScreen,
|
|
28
|
+
RenameColumnScreen,
|
|
29
|
+
RenameTabScreen,
|
|
13
30
|
SaveFileScreen,
|
|
14
31
|
SearchScreen,
|
|
15
32
|
YesNoScreen,
|
|
@@ -23,6 +40,9 @@ __all__ = [
|
|
|
23
40
|
"TableScreen",
|
|
24
41
|
"RowDetailScreen",
|
|
25
42
|
"FrequencyScreen",
|
|
43
|
+
"StatisticsScreen",
|
|
44
|
+
"MetaShape",
|
|
45
|
+
"MetaColumnScreen",
|
|
26
46
|
"YesNoScreen",
|
|
27
47
|
"SaveFileScreen",
|
|
28
48
|
"ConfirmScreen",
|
|
@@ -31,4 +51,10 @@ __all__ = [
|
|
|
31
51
|
"FilterScreen",
|
|
32
52
|
"FreezeScreen",
|
|
33
53
|
"OpenFileScreen",
|
|
54
|
+
"RenameColumnScreen",
|
|
55
|
+
"EditColumnScreen",
|
|
56
|
+
"AddColumnScreen",
|
|
57
|
+
"AddLinkScreen",
|
|
58
|
+
"FindReplaceScreen",
|
|
59
|
+
"RenameTabScreen",
|
|
34
60
|
]
|
|
@@ -4,6 +4,7 @@ import argparse
|
|
|
4
4
|
import sys
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
+
from . import __version__
|
|
7
8
|
from .common import SUPPORTED_FORMATS, load_dataframe
|
|
8
9
|
from .data_frame_viewer import DataFrameViewer
|
|
9
10
|
|
|
@@ -24,6 +25,12 @@ def cli() -> argparse.Namespace:
|
|
|
24
25
|
" cat data.csv | %(prog)s --format csv\n",
|
|
25
26
|
)
|
|
26
27
|
parser.add_argument("files", nargs="*", help="Files to view (or read from stdin)")
|
|
28
|
+
parser.add_argument(
|
|
29
|
+
"-V",
|
|
30
|
+
"--version",
|
|
31
|
+
action="version",
|
|
32
|
+
version=f"%(prog)s {__version__}",
|
|
33
|
+
)
|
|
27
34
|
parser.add_argument(
|
|
28
35
|
"-f",
|
|
29
36
|
"--format",
|
|
@@ -152,8 +152,8 @@ SUBSCRIPT_DIGITS = {
|
|
|
152
152
|
# Cursor types ("none" removed)
|
|
153
153
|
CURSOR_TYPES = ["row", "column", "cell"]
|
|
154
154
|
|
|
155
|
-
#
|
|
156
|
-
|
|
155
|
+
# Row index mapping between filtered and original dataframe
|
|
156
|
+
RID = "^_RID_^"
|
|
157
157
|
|
|
158
158
|
|
|
159
159
|
@dataclass
|
|
@@ -224,7 +224,7 @@ def format_row(vals, dtypes, styles: list[str | None] | None = None, thousand_se
|
|
|
224
224
|
return formatted_row
|
|
225
225
|
|
|
226
226
|
|
|
227
|
-
def rindex(lst: list, value) -> int:
|
|
227
|
+
def rindex(lst: list, value, pos: int | None = None) -> int:
|
|
228
228
|
"""Return the last index of value in a list. Return -1 if not found.
|
|
229
229
|
|
|
230
230
|
Searches through the list in reverse order to find the last occurrence
|
|
@@ -237,9 +237,12 @@ def rindex(lst: list, value) -> int:
|
|
|
237
237
|
Returns:
|
|
238
238
|
The index (0-based) of the last occurrence, or -1 if not found.
|
|
239
239
|
"""
|
|
240
|
+
n = len(lst)
|
|
240
241
|
for i, item in enumerate(reversed(lst)):
|
|
242
|
+
if pos is not None and (n - 1 - i) > pos:
|
|
243
|
+
continue
|
|
241
244
|
if item == value:
|
|
242
|
-
return
|
|
245
|
+
return n - 1 - i
|
|
243
246
|
return -1
|
|
244
247
|
|
|
245
248
|
|
|
@@ -272,7 +275,7 @@ def parse_placeholders(template: str, columns: list[str], current_cidx: int) ->
|
|
|
272
275
|
|
|
273
276
|
Supports multiple placeholder types:
|
|
274
277
|
- `$_` - Current column (based on current_cidx parameter)
|
|
275
|
-
- `$#` - Row index (1-based
|
|
278
|
+
- `$#` - Row index (1-based)
|
|
276
279
|
- `$1`, `$2`, etc. - Column index (1-based)
|
|
277
280
|
- `$name` - Column name (e.g., `$product_id`)
|
|
278
281
|
- `` $`col name` `` - Column name with spaces (e.g., `` $`product id` ``)
|
|
@@ -323,7 +326,7 @@ def parse_placeholders(template: str, columns: list[str], current_cidx: int) ->
|
|
|
323
326
|
parts.append(pl.col(col_name))
|
|
324
327
|
elif placeholder == "#":
|
|
325
328
|
# $# refers to row index (1-based)
|
|
326
|
-
parts.append(
|
|
329
|
+
parts.append(pl.col(RID))
|
|
327
330
|
elif placeholder.isdigit():
|
|
328
331
|
# $1, $2, etc. refer to columns by 1-based position index
|
|
329
332
|
col_idx = int(placeholder) - 1 # Convert to 0-based
|
|
@@ -364,14 +367,14 @@ def parse_polars_expression(expression: str, columns: list[str], current_cidx: i
|
|
|
364
367
|
|
|
365
368
|
Replaces column references with Polars col() expressions:
|
|
366
369
|
- $_ - Current selected column
|
|
367
|
-
- $# - Row index (1-based
|
|
370
|
+
- $# - Row index (1-based)
|
|
368
371
|
- $1, $2, etc. - Column index (1-based)
|
|
369
372
|
- $col_name - Column name (valid identifier starting with _ or letter)
|
|
370
373
|
- $`col name` - Column name with spaces (backtick quoted)
|
|
371
374
|
|
|
372
375
|
Examples:
|
|
373
376
|
- "$_ > 50" -> "pl.col('current_col') > 50"
|
|
374
|
-
- "$# > 10" -> "pl.col('^
|
|
377
|
+
- "$# > 10" -> "pl.col('^_RID_^') > 10"
|
|
375
378
|
- "$1 > 50" -> "pl.col('col0') > 50"
|
|
376
379
|
- "$name == 'Alex'" -> "pl.col('name') == 'Alex'"
|
|
377
380
|
- "$age < $salary" -> "pl.col('age') < pl.col('salary')"
|
|
@@ -404,7 +407,10 @@ def parse_polars_expression(expression: str, columns: list[str], current_cidx: i
|
|
|
404
407
|
if isinstance(part, pl.Expr):
|
|
405
408
|
col = part.meta.output_name()
|
|
406
409
|
|
|
407
|
-
|
|
410
|
+
if col == RID: # Convert to 1-based
|
|
411
|
+
result.append(f"(pl.col('{col}') + 1)")
|
|
412
|
+
else:
|
|
413
|
+
result.append(f"pl.col('{col}')")
|
|
408
414
|
else:
|
|
409
415
|
result.append(part)
|
|
410
416
|
|
{dataframe_textual-1.16.2 → dataframe_textual-2.0.0}/src/dataframe_textual/data_frame_help_panel.py
RENAMED
|
@@ -74,9 +74,6 @@ class DataFrameHelpPanel(Widget):
|
|
|
74
74
|
|
|
75
75
|
Initializes the help panel by setting up a watcher for focused widget changes
|
|
76
76
|
to dynamically update help text based on which widget has focus.
|
|
77
|
-
|
|
78
|
-
Returns:
|
|
79
|
-
None
|
|
80
77
|
"""
|
|
81
78
|
|
|
82
79
|
# def update_help(focused_widget: Widget | None):
|