dataframe-textual 1.16.2__tar.gz → 2.2.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.2.0}/PKG-INFO +28 -27
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/README.md +27 -26
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/pyproject.toml +1 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/__init__.py +27 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/__main__.py +11 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/common.py +19 -9
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/data_frame_help_panel.py +0 -3
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/data_frame_table.py +686 -582
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/data_frame_viewer.py +37 -10
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/sql_screen.py +8 -2
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/table_screen.py +25 -51
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/src/dataframe_textual/yes_no_screen.py +9 -18
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/uv.lock +1 -1
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/.gitignore +0 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.0}/LICENSE +0 -0
- {dataframe_textual-1.16.2 → dataframe_textual-2.2.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.2.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
|
|
@@ -247,8 +247,8 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
247
247
|
| `Q` | Close all tabs and app (prompts to save unsaved changes) |
|
|
248
248
|
| `Ctrl+Q` | Force to quit app (regardless of unsaved changes) |
|
|
249
249
|
| `Ctrl+T` | Save current tab to file |
|
|
250
|
+
| `Ctrl+A` | Save all tabs to a Excel file |
|
|
250
251
|
| `w` | Save current tab to file (overwrite without prompt) |
|
|
251
|
-
| `Ctrl+A` | Save all tabs to file |
|
|
252
252
|
| `W` | Save all tabs to file (overwrite without prompt) |
|
|
253
253
|
| `Ctrl+D` | Duplicate current tab |
|
|
254
254
|
| `Ctrl+O` | Open file in a new tab |
|
|
@@ -271,7 +271,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
271
271
|
| Key | Action |
|
|
272
272
|
|-----|--------|
|
|
273
273
|
| `g` | Jump to first row |
|
|
274
|
-
| `G` | Jump to last row
|
|
274
|
+
| `G` | Jump to last row |
|
|
275
275
|
| `↑` / `↓` | Move up/down one row |
|
|
276
276
|
| `←` / `→` | Move left/right one column |
|
|
277
277
|
| `Home` / `End` | Jump to first/last column |
|
|
@@ -295,9 +295,11 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
295
295
|
| `F` | Show frequency distribution for current column |
|
|
296
296
|
| `s` | Show statistics for current column |
|
|
297
297
|
| `S` | Show statistics for entire dataframe |
|
|
298
|
+
| `m` | Show metadata for row count and column count |
|
|
299
|
+
| `M` | Show metadata for current column |
|
|
298
300
|
| `K` | Cycle cursor types: cell → row → column → cell |
|
|
299
301
|
| `~` | Toggle row labels |
|
|
300
|
-
| `_` (underscore) |
|
|
302
|
+
| `_` (underscore) | Toggle column full width |
|
|
301
303
|
| `z` | Freeze rows and columns |
|
|
302
304
|
| `,` | Toggle thousand separator for numeric display |
|
|
303
305
|
| `h` | Hide current column |
|
|
@@ -318,14 +320,14 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
318
320
|
| `x` | Delete current row |
|
|
319
321
|
| `X` | Delete current row and all those below |
|
|
320
322
|
| `Ctrl+X` | Delete current row and all those above |
|
|
321
|
-
| `d` | Duplicate current column
|
|
323
|
+
| `d` | Duplicate current column |
|
|
322
324
|
| `D` | Duplicate current row |
|
|
323
325
|
|
|
324
326
|
#### Row Selection
|
|
325
327
|
|
|
326
328
|
| Key | Action |
|
|
327
329
|
|-----|--------|
|
|
328
|
-
| `\` | Select rows
|
|
330
|
+
| `\` | Select rows wth cell matches or those matching cursor value in current column |
|
|
329
331
|
| `\|` (pipe) | Select rows by expression |
|
|
330
332
|
| `{` | Go to previous selected row |
|
|
331
333
|
| `}` | Go to next selected row |
|
|
@@ -349,9 +351,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
349
351
|
#### View & Filter
|
|
350
352
|
| Key | Action |
|
|
351
353
|
|-----|--------|
|
|
352
|
-
| `"` (quote) | Filter
|
|
353
|
-
| `v` | View rows (
|
|
354
|
-
| `V` | View
|
|
354
|
+
| `"` (quote) | Filter selected rows (others removed) |
|
|
355
|
+
| `v` | View selected rows (others hidden) |
|
|
356
|
+
| `V` | View selected by expression (others hidden) |
|
|
355
357
|
|
|
356
358
|
#### SQL Interface
|
|
357
359
|
|
|
@@ -392,7 +394,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
392
394
|
| `c` | Copy current cell to clipboard |
|
|
393
395
|
| `Ctrl+C` | Copy column to clipboard |
|
|
394
396
|
| `Ctrl+R` | Copy row to clipboard (tab-separated) |
|
|
395
|
-
| `Ctrl+S` | Save
|
|
397
|
+
| `Ctrl+S` | Save to file |
|
|
396
398
|
|
|
397
399
|
## Features in Detail
|
|
398
400
|
|
|
@@ -411,17 +413,17 @@ Press `Enter` on any row to open a modal showing all column values for that row.
|
|
|
411
413
|
Useful for examining wide datasets where columns don't fit well on screen.
|
|
412
414
|
|
|
413
415
|
**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 (
|
|
416
|
-
- Press `{` to move to the
|
|
417
|
-
- Press `}` to move to the
|
|
416
|
+
- Press `v` to **view** all rows containing the selected column value (others hidden but preserved)
|
|
417
|
+
- Press `"` to **filter** all rows containing the selected column value (others removed)
|
|
418
|
+
- Press `{` to move to the previous row
|
|
419
|
+
- Press `}` to move to the next row
|
|
418
420
|
- Press `q` or `Escape` to close the modal
|
|
419
421
|
|
|
420
422
|
### 3. Row Selection
|
|
421
423
|
|
|
422
424
|
The application provides multiple modes for selecting rows (marks it for filtering or viewing):
|
|
423
425
|
|
|
424
|
-
- `\` - Select rows
|
|
426
|
+
- `\` - Select rows with cell matches or those matching cursor value in current column (respects data type)
|
|
425
427
|
- `|` - Opens dialog to select rows with custom expression
|
|
426
428
|
- `'` - Select/deselect current row
|
|
427
429
|
- `t` - Flip selections of all rows
|
|
@@ -429,7 +431,7 @@ The application provides multiple modes for selecting rows (marks it for filteri
|
|
|
429
431
|
- `{` - Go to previous selected row
|
|
430
432
|
- `}` - Go to next selected row
|
|
431
433
|
|
|
432
|
-
**Advanced
|
|
434
|
+
**Advanced Options**:
|
|
433
435
|
|
|
434
436
|
When searching or finding, you can use checkboxes in the dialog to enable:
|
|
435
437
|
- **Match Nocase**: Ignore case differences
|
|
@@ -445,7 +447,7 @@ These options work with plain text searches. Use Polars regex patterns in expres
|
|
|
445
447
|
- Use `u` to undo any search or filter
|
|
446
448
|
|
|
447
449
|
### 4. Find & Replace
|
|
448
|
-
|
|
450
|
+
Find by value/expression and highlight matching cells:
|
|
449
451
|
- `/` - Find cursor value within current column (respects data type)
|
|
450
452
|
- `?` - Open dialog to search current column with expression
|
|
451
453
|
- `;` - Find cursor value across all columns
|
|
@@ -469,10 +471,10 @@ When you press `r` or `R`, enter:
|
|
|
469
471
|
|
|
470
472
|
**Replace Interactive**:
|
|
471
473
|
- Review each match one at a time (confirm, skip, or cancel)
|
|
472
|
-
- Shows progress
|
|
474
|
+
- Shows progress
|
|
473
475
|
|
|
474
476
|
**Tips:**
|
|
475
|
-
- Search are done by string value (i.e
|
|
477
|
+
- Search are done by string value (i.e., ignoring data type)
|
|
476
478
|
- Type `NULL` to replace null/missing values
|
|
477
479
|
- Use `Match Nocase` for case-insensitive matching
|
|
478
480
|
- Use `Match Whole` to avoid partial replacements
|
|
@@ -480,7 +482,7 @@ When you press `r` or `R`, enter:
|
|
|
480
482
|
|
|
481
483
|
### 5. Filter vs. View
|
|
482
484
|
|
|
483
|
-
Both operations show
|
|
485
|
+
Both operations show selected rows but with fundamentally different effects:
|
|
484
486
|
|
|
485
487
|
| Operation | Keyboard | Effect | Data Preserved |
|
|
486
488
|
|-----------|----------|--------|-----------------|
|
|
@@ -571,8 +573,8 @@ View quick metadata about your dataframe and columns to understand their structu
|
|
|
571
573
|
|
|
572
574
|
**Dataframe Metadata** (`m`):
|
|
573
575
|
- Press `m` to open a modal displaying:
|
|
574
|
-
- **
|
|
575
|
-
- **
|
|
576
|
+
- **Row** - Total number of rows in the dataframe
|
|
577
|
+
- **Column** - Total number of columns in the dataframe
|
|
576
578
|
|
|
577
579
|
**Column Metadata** (`M`):
|
|
578
580
|
- Press `M` to open a modal displaying details for all columns:
|
|
@@ -591,8 +593,8 @@ Press `F` to see value distributions of the current column. The modal shows:
|
|
|
591
593
|
|
|
592
594
|
**In the Frequency Table**:
|
|
593
595
|
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
594
|
-
- Press `v` to **
|
|
595
|
-
- Press `"` to **
|
|
596
|
+
- Press `v` to **view** all rows containing the selected value (others hidden but preserved)
|
|
597
|
+
- Press `"` to **filter** all rows containing the selected value (others removed)
|
|
596
598
|
- Press `q` or `Escape` to close the frequency table
|
|
597
599
|
|
|
598
600
|
This is useful for:
|
|
@@ -751,7 +753,6 @@ SELECT specific columns and apply WHERE conditions without writing full SQL:
|
|
|
751
753
|
#### Advanced SQL Interface (`L`)
|
|
752
754
|
Execute complete SQL queries for advanced data manipulation:
|
|
753
755
|
- Write full SQL queries with standard [SQL syntax](https://docs.pola.rs/api/python/stable/reference/sql/index.html)
|
|
754
|
-
- Support for JOINs, GROUP BY, aggregations, and more
|
|
755
756
|
- Access to all SQL capabilities for complex transformations
|
|
756
757
|
- Always use `self` as the table name
|
|
757
758
|
- Syntax highlighted
|
|
@@ -773,7 +774,7 @@ WHERE `product id` = 7
|
|
|
773
774
|
|
|
774
775
|
Copies value to system clipboard with `pbcopy` on macOS and `xclip` on Linux.
|
|
775
776
|
|
|
776
|
-
**Note
|
|
777
|
+
**Note**: may require a X server to work.
|
|
777
778
|
|
|
778
779
|
- Press `c` to copy cursor value
|
|
779
780
|
- Press `Ctrl+C` to copy column values
|
|
@@ -815,8 +816,8 @@ Manage multiple files and dataframes simultaneously with tabs.
|
|
|
815
816
|
- **`Double-click`** - Rename the tab
|
|
816
817
|
- **`Ctrl+D`** - Duplicate current tab (creates a copy with same data and state)
|
|
817
818
|
- **`Ctrl+T`** - Save current tab to file
|
|
818
|
-
- **`w`** - Save current tab to file (overwrite without prompt)
|
|
819
819
|
- **`Ctrl+A`** - Save all tabs in a single Excel file
|
|
820
|
+
- **`w`** - Save current tab to file (overwrite without prompt)
|
|
820
821
|
- **`W`** - Save all tabs to file (overwrite without prompt)
|
|
821
822
|
- **`q`** - Close current tab (closes tab, prompts to save if unsaved changes)
|
|
822
823
|
- **`Q`** - Close all tabs and exit app (prompts to save tabs with unsaved changes)
|
|
@@ -208,8 +208,8 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
208
208
|
| `Q` | Close all tabs and app (prompts to save unsaved changes) |
|
|
209
209
|
| `Ctrl+Q` | Force to quit app (regardless of unsaved changes) |
|
|
210
210
|
| `Ctrl+T` | Save current tab to file |
|
|
211
|
+
| `Ctrl+A` | Save all tabs to a Excel file |
|
|
211
212
|
| `w` | Save current tab to file (overwrite without prompt) |
|
|
212
|
-
| `Ctrl+A` | Save all tabs to file |
|
|
213
213
|
| `W` | Save all tabs to file (overwrite without prompt) |
|
|
214
214
|
| `Ctrl+D` | Duplicate current tab |
|
|
215
215
|
| `Ctrl+O` | Open file in a new tab |
|
|
@@ -232,7 +232,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
232
232
|
| Key | Action |
|
|
233
233
|
|-----|--------|
|
|
234
234
|
| `g` | Jump to first row |
|
|
235
|
-
| `G` | Jump to last row
|
|
235
|
+
| `G` | Jump to last row |
|
|
236
236
|
| `↑` / `↓` | Move up/down one row |
|
|
237
237
|
| `←` / `→` | Move left/right one column |
|
|
238
238
|
| `Home` / `End` | Jump to first/last column |
|
|
@@ -256,9 +256,11 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
256
256
|
| `F` | Show frequency distribution for current column |
|
|
257
257
|
| `s` | Show statistics for current column |
|
|
258
258
|
| `S` | Show statistics for entire dataframe |
|
|
259
|
+
| `m` | Show metadata for row count and column count |
|
|
260
|
+
| `M` | Show metadata for current column |
|
|
259
261
|
| `K` | Cycle cursor types: cell → row → column → cell |
|
|
260
262
|
| `~` | Toggle row labels |
|
|
261
|
-
| `_` (underscore) |
|
|
263
|
+
| `_` (underscore) | Toggle column full width |
|
|
262
264
|
| `z` | Freeze rows and columns |
|
|
263
265
|
| `,` | Toggle thousand separator for numeric display |
|
|
264
266
|
| `h` | Hide current column |
|
|
@@ -279,14 +281,14 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
279
281
|
| `x` | Delete current row |
|
|
280
282
|
| `X` | Delete current row and all those below |
|
|
281
283
|
| `Ctrl+X` | Delete current row and all those above |
|
|
282
|
-
| `d` | Duplicate current column
|
|
284
|
+
| `d` | Duplicate current column |
|
|
283
285
|
| `D` | Duplicate current row |
|
|
284
286
|
|
|
285
287
|
#### Row Selection
|
|
286
288
|
|
|
287
289
|
| Key | Action |
|
|
288
290
|
|-----|--------|
|
|
289
|
-
| `\` | Select rows
|
|
291
|
+
| `\` | Select rows wth cell matches or those matching cursor value in current column |
|
|
290
292
|
| `\|` (pipe) | Select rows by expression |
|
|
291
293
|
| `{` | Go to previous selected row |
|
|
292
294
|
| `}` | Go to next selected row |
|
|
@@ -310,9 +312,9 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
310
312
|
#### View & Filter
|
|
311
313
|
| Key | Action |
|
|
312
314
|
|-----|--------|
|
|
313
|
-
| `"` (quote) | Filter
|
|
314
|
-
| `v` | View rows (
|
|
315
|
-
| `V` | View
|
|
315
|
+
| `"` (quote) | Filter selected rows (others removed) |
|
|
316
|
+
| `v` | View selected rows (others hidden) |
|
|
317
|
+
| `V` | View selected by expression (others hidden) |
|
|
316
318
|
|
|
317
319
|
#### SQL Interface
|
|
318
320
|
|
|
@@ -353,7 +355,7 @@ zcat compressed_data.csv.gz | dv -f csv
|
|
|
353
355
|
| `c` | Copy current cell to clipboard |
|
|
354
356
|
| `Ctrl+C` | Copy column to clipboard |
|
|
355
357
|
| `Ctrl+R` | Copy row to clipboard (tab-separated) |
|
|
356
|
-
| `Ctrl+S` | Save
|
|
358
|
+
| `Ctrl+S` | Save to file |
|
|
357
359
|
|
|
358
360
|
## Features in Detail
|
|
359
361
|
|
|
@@ -372,17 +374,17 @@ Press `Enter` on any row to open a modal showing all column values for that row.
|
|
|
372
374
|
Useful for examining wide datasets where columns don't fit well on screen.
|
|
373
375
|
|
|
374
376
|
**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 (
|
|
377
|
-
- Press `{` to move to the
|
|
378
|
-
- Press `}` to move to the
|
|
377
|
+
- Press `v` to **view** all rows containing the selected column value (others hidden but preserved)
|
|
378
|
+
- Press `"` to **filter** all rows containing the selected column value (others removed)
|
|
379
|
+
- Press `{` to move to the previous row
|
|
380
|
+
- Press `}` to move to the next row
|
|
379
381
|
- Press `q` or `Escape` to close the modal
|
|
380
382
|
|
|
381
383
|
### 3. Row Selection
|
|
382
384
|
|
|
383
385
|
The application provides multiple modes for selecting rows (marks it for filtering or viewing):
|
|
384
386
|
|
|
385
|
-
- `\` - Select rows
|
|
387
|
+
- `\` - Select rows with cell matches or those matching cursor value in current column (respects data type)
|
|
386
388
|
- `|` - Opens dialog to select rows with custom expression
|
|
387
389
|
- `'` - Select/deselect current row
|
|
388
390
|
- `t` - Flip selections of all rows
|
|
@@ -390,7 +392,7 @@ The application provides multiple modes for selecting rows (marks it for filteri
|
|
|
390
392
|
- `{` - Go to previous selected row
|
|
391
393
|
- `}` - Go to next selected row
|
|
392
394
|
|
|
393
|
-
**Advanced
|
|
395
|
+
**Advanced Options**:
|
|
394
396
|
|
|
395
397
|
When searching or finding, you can use checkboxes in the dialog to enable:
|
|
396
398
|
- **Match Nocase**: Ignore case differences
|
|
@@ -406,7 +408,7 @@ These options work with plain text searches. Use Polars regex patterns in expres
|
|
|
406
408
|
- Use `u` to undo any search or filter
|
|
407
409
|
|
|
408
410
|
### 4. Find & Replace
|
|
409
|
-
|
|
411
|
+
Find by value/expression and highlight matching cells:
|
|
410
412
|
- `/` - Find cursor value within current column (respects data type)
|
|
411
413
|
- `?` - Open dialog to search current column with expression
|
|
412
414
|
- `;` - Find cursor value across all columns
|
|
@@ -430,10 +432,10 @@ When you press `r` or `R`, enter:
|
|
|
430
432
|
|
|
431
433
|
**Replace Interactive**:
|
|
432
434
|
- Review each match one at a time (confirm, skip, or cancel)
|
|
433
|
-
- Shows progress
|
|
435
|
+
- Shows progress
|
|
434
436
|
|
|
435
437
|
**Tips:**
|
|
436
|
-
- Search are done by string value (i.e
|
|
438
|
+
- Search are done by string value (i.e., ignoring data type)
|
|
437
439
|
- Type `NULL` to replace null/missing values
|
|
438
440
|
- Use `Match Nocase` for case-insensitive matching
|
|
439
441
|
- Use `Match Whole` to avoid partial replacements
|
|
@@ -441,7 +443,7 @@ When you press `r` or `R`, enter:
|
|
|
441
443
|
|
|
442
444
|
### 5. Filter vs. View
|
|
443
445
|
|
|
444
|
-
Both operations show
|
|
446
|
+
Both operations show selected rows but with fundamentally different effects:
|
|
445
447
|
|
|
446
448
|
| Operation | Keyboard | Effect | Data Preserved |
|
|
447
449
|
|-----------|----------|--------|-----------------|
|
|
@@ -532,8 +534,8 @@ View quick metadata about your dataframe and columns to understand their structu
|
|
|
532
534
|
|
|
533
535
|
**Dataframe Metadata** (`m`):
|
|
534
536
|
- Press `m` to open a modal displaying:
|
|
535
|
-
- **
|
|
536
|
-
- **
|
|
537
|
+
- **Row** - Total number of rows in the dataframe
|
|
538
|
+
- **Column** - Total number of columns in the dataframe
|
|
537
539
|
|
|
538
540
|
**Column Metadata** (`M`):
|
|
539
541
|
- Press `M` to open a modal displaying details for all columns:
|
|
@@ -552,8 +554,8 @@ Press `F` to see value distributions of the current column. The modal shows:
|
|
|
552
554
|
|
|
553
555
|
**In the Frequency Table**:
|
|
554
556
|
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
555
|
-
- Press `v` to **
|
|
556
|
-
- Press `"` to **
|
|
557
|
+
- Press `v` to **view** all rows containing the selected value (others hidden but preserved)
|
|
558
|
+
- Press `"` to **filter** all rows containing the selected value (others removed)
|
|
557
559
|
- Press `q` or `Escape` to close the frequency table
|
|
558
560
|
|
|
559
561
|
This is useful for:
|
|
@@ -712,7 +714,6 @@ SELECT specific columns and apply WHERE conditions without writing full SQL:
|
|
|
712
714
|
#### Advanced SQL Interface (`L`)
|
|
713
715
|
Execute complete SQL queries for advanced data manipulation:
|
|
714
716
|
- Write full SQL queries with standard [SQL syntax](https://docs.pola.rs/api/python/stable/reference/sql/index.html)
|
|
715
|
-
- Support for JOINs, GROUP BY, aggregations, and more
|
|
716
717
|
- Access to all SQL capabilities for complex transformations
|
|
717
718
|
- Always use `self` as the table name
|
|
718
719
|
- Syntax highlighted
|
|
@@ -734,7 +735,7 @@ WHERE `product id` = 7
|
|
|
734
735
|
|
|
735
736
|
Copies value to system clipboard with `pbcopy` on macOS and `xclip` on Linux.
|
|
736
737
|
|
|
737
|
-
**Note
|
|
738
|
+
**Note**: may require a X server to work.
|
|
738
739
|
|
|
739
740
|
- Press `c` to copy cursor value
|
|
740
741
|
- Press `Ctrl+C` to copy column values
|
|
@@ -776,8 +777,8 @@ Manage multiple files and dataframes simultaneously with tabs.
|
|
|
776
777
|
- **`Double-click`** - Rename the tab
|
|
777
778
|
- **`Ctrl+D`** - Duplicate current tab (creates a copy with same data and state)
|
|
778
779
|
- **`Ctrl+T`** - Save current tab to file
|
|
779
|
-
- **`w`** - Save current tab to file (overwrite without prompt)
|
|
780
780
|
- **`Ctrl+A`** - Save all tabs in a single Excel file
|
|
781
|
+
- **`w`** - Save current tab to file (overwrite without prompt)
|
|
781
782
|
- **`W`** - Save all tabs to file (overwrite without prompt)
|
|
782
783
|
- **`q`** - Close current tab (closes tab, prompts to save if unsaved changes)
|
|
783
784
|
- **`Q`** - Close all tabs and exit app (prompts to save tabs with unsaved changes)
|
|
@@ -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",
|
|
@@ -39,6 +46,9 @@ def cli() -> argparse.Namespace:
|
|
|
39
46
|
parser.add_argument(
|
|
40
47
|
"-I", "--no-inference", action="store_true", help="Do not infer data types when reading CSV/TSV"
|
|
41
48
|
)
|
|
49
|
+
parser.add_argument(
|
|
50
|
+
"-t", "--truncate-ragged-lines", action="store_true", help="Truncate ragged lines when reading CSV/TSV"
|
|
51
|
+
)
|
|
42
52
|
parser.add_argument("-E", "--ignore-errors", action="store_true", help="Ignore errors when reading CSV/TSV")
|
|
43
53
|
parser.add_argument(
|
|
44
54
|
"-c", "--comment-prefix", nargs="?", const="#", help="Comment lines are skipped when reading CSV/TSV"
|
|
@@ -87,6 +97,7 @@ def main() -> None:
|
|
|
87
97
|
skip_rows_after_header=args.skip_rows_after_header,
|
|
88
98
|
null_values=args.null,
|
|
89
99
|
ignore_errors=args.ignore_errors,
|
|
100
|
+
truncate_ragged_lines=args.truncate_ragged_lines,
|
|
90
101
|
)
|
|
91
102
|
app = DataFrameViewer(*sources)
|
|
92
103
|
app.run()
|
|
@@ -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
|
|
|
@@ -478,6 +484,7 @@ def load_dataframe(
|
|
|
478
484
|
skip_rows_after_header: int = 0,
|
|
479
485
|
null_values: list[str] | None = None,
|
|
480
486
|
ignore_errors: bool = False,
|
|
487
|
+
truncate_ragged_lines: bool = False,
|
|
481
488
|
) -> list[Source]:
|
|
482
489
|
"""Load DataFrames from file specifications.
|
|
483
490
|
|
|
@@ -542,6 +549,7 @@ def load_dataframe(
|
|
|
542
549
|
skip_rows_after_header=skip_rows_after_header,
|
|
543
550
|
null_values=null_values,
|
|
544
551
|
ignore_errors=ignore_errors,
|
|
552
|
+
truncate_ragged_lines=truncate_ragged_lines,
|
|
545
553
|
)
|
|
546
554
|
)
|
|
547
555
|
|
|
@@ -618,6 +626,7 @@ def load_file(
|
|
|
618
626
|
schema_overrides: dict[str, pl.DataType] | None = None,
|
|
619
627
|
null_values: list[str] | None = None,
|
|
620
628
|
ignore_errors: bool = False,
|
|
629
|
+
truncate_ragged_lines: bool = False,
|
|
621
630
|
) -> list[Source]:
|
|
622
631
|
"""Load a single file.
|
|
623
632
|
|
|
@@ -672,6 +681,7 @@ def load_file(
|
|
|
672
681
|
schema_overrides=schema_overrides,
|
|
673
682
|
null_values=null_values,
|
|
674
683
|
ignore_errors=ignore_errors,
|
|
684
|
+
truncate_ragged_lines=truncate_ragged_lines,
|
|
675
685
|
)
|
|
676
686
|
data.append(Source(lf, filename, filepath.stem))
|
|
677
687
|
elif file_format in ("xlsx", "xls", "excel"):
|
{dataframe_textual-1.16.2 → dataframe_textual-2.2.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):
|