dataframe-textual 2.8.0__tar.gz → 2.9.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.
Files changed (19) hide show
  1. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/PKG-INFO +10 -11
  2. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/README.md +9 -10
  3. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/pyproject.toml +1 -1
  4. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/data_frame_table.py +37 -38
  5. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/yes_no_screen.py +1 -7
  6. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/uv.lock +1 -1
  7. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/.gitignore +0 -0
  8. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/1811.csv.gz +0 -0
  9. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/LICENSE +0 -0
  10. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/glycosmos_glycans_list.csv.gz +0 -0
  11. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/large_malformed.tsv.gz +0 -0
  12. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/main.py +0 -0
  13. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/__init__.py +0 -0
  14. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/__main__.py +0 -0
  15. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/common.py +0 -0
  16. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/data_frame_help_panel.py +0 -0
  17. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/data_frame_viewer.py +0 -0
  18. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/sql_screen.py +0 -0
  19. {dataframe_textual-2.8.0 → dataframe_textual-2.9.0}/src/dataframe_textual/table_screen.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataframe-textual
3
- Version: 2.8.0
3
+ Version: 2.9.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
@@ -310,7 +310,7 @@ zcat compressed_data.csv.gz | dv -f csv
310
310
  | `h` | Hide current column |
311
311
  | `H` | Show all hidden rows/columns |
312
312
 
313
- #### Data Editing
313
+ #### Editing
314
314
 
315
315
  | Key | Action |
316
316
  |-----|--------|
@@ -362,13 +362,6 @@ zcat compressed_data.csv.gz | dv -f csv
362
362
  | `v` | View selected rows (others hidden) |
363
363
  | `V` | View selected by expression (others hidden) |
364
364
 
365
- #### SQL Interface
366
-
367
- | Key | Action |
368
- |-----|--------|
369
- | `l` | Simple SQL interface (select columns & where clause) |
370
- | `L` | Advanced SQL interface (full SQL query with syntax highlight) |
371
-
372
365
  #### Sorting (supporting multiple columns)
373
366
 
374
367
  | Key | Action |
@@ -402,6 +395,13 @@ zcat compressed_data.csv.gz | dv -f csv
402
395
  | `Ctrl+C` | Copy column to clipboard |
403
396
  | `Ctrl+R` | Copy row to clipboard (tab-separated) |
404
397
 
398
+ #### SQL Interface
399
+
400
+ | Key | Action |
401
+ |-----|--------|
402
+ | `l` | Simple SQL interface (select columns & where clause) |
403
+ | `L` | Advanced SQL interface (full SQL query with syntax highlight) |
404
+
405
405
  ## Features in Detail
406
406
 
407
407
  ### 1. Color-Coded Data Types
@@ -448,7 +448,6 @@ These options work with plain text searches. Use Polars regex patterns in expres
448
448
  **Quick Tips:**
449
449
  - Search results highlight matching rows in **red**
450
450
  - Use expression for advanced selection (e.g., $attack > $defense)
451
- - Multiple searches **accumulate** - each new search adds to the selections or matches
452
451
  - Type-aware matching automatically converts values. Resort to string comparison if conversion fails
453
452
  - Use `u` to undo any search or filter
454
453
 
@@ -627,7 +626,7 @@ This is useful for:
627
626
  - Quick statistical summaries without external tools
628
627
  - Comparing statistics across columns
629
628
 
630
- ### 11. Data Editing
629
+ ### 11. Editing
631
630
 
632
631
  **Edit Cell** (`e` or **Double-click**):
633
632
  - Opens modal for editing current cell
@@ -271,7 +271,7 @@ zcat compressed_data.csv.gz | dv -f csv
271
271
  | `h` | Hide current column |
272
272
  | `H` | Show all hidden rows/columns |
273
273
 
274
- #### Data Editing
274
+ #### Editing
275
275
 
276
276
  | Key | Action |
277
277
  |-----|--------|
@@ -323,13 +323,6 @@ zcat compressed_data.csv.gz | dv -f csv
323
323
  | `v` | View selected rows (others hidden) |
324
324
  | `V` | View selected by expression (others hidden) |
325
325
 
326
- #### SQL Interface
327
-
328
- | Key | Action |
329
- |-----|--------|
330
- | `l` | Simple SQL interface (select columns & where clause) |
331
- | `L` | Advanced SQL interface (full SQL query with syntax highlight) |
332
-
333
326
  #### Sorting (supporting multiple columns)
334
327
 
335
328
  | Key | Action |
@@ -363,6 +356,13 @@ zcat compressed_data.csv.gz | dv -f csv
363
356
  | `Ctrl+C` | Copy column to clipboard |
364
357
  | `Ctrl+R` | Copy row to clipboard (tab-separated) |
365
358
 
359
+ #### SQL Interface
360
+
361
+ | Key | Action |
362
+ |-----|--------|
363
+ | `l` | Simple SQL interface (select columns & where clause) |
364
+ | `L` | Advanced SQL interface (full SQL query with syntax highlight) |
365
+
366
366
  ## Features in Detail
367
367
 
368
368
  ### 1. Color-Coded Data Types
@@ -409,7 +409,6 @@ These options work with plain text searches. Use Polars regex patterns in expres
409
409
  **Quick Tips:**
410
410
  - Search results highlight matching rows in **red**
411
411
  - Use expression for advanced selection (e.g., $attack > $defense)
412
- - Multiple searches **accumulate** - each new search adds to the selections or matches
413
412
  - Type-aware matching automatically converts values. Resort to string comparison if conversion fails
414
413
  - Use `u` to undo any search or filter
415
414
 
@@ -588,7 +587,7 @@ This is useful for:
588
587
  - Quick statistical summaries without external tools
589
588
  - Comparing statistics across columns
590
589
 
591
- ### 11. Data Editing
590
+ ### 11. Editing
592
591
 
593
592
  **Edit Cell** (`e` or **Double-click**):
594
593
  - Opens modal for editing current cell
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dataframe-textual"
7
- version = "2.8.0"
7
+ version = "2.9.0"
8
8
  description = "Interactive terminal viewer/editor for tabular data"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -161,10 +161,21 @@ class DataFrameTable(DataTable):
161
161
  - **,** - 🔢 Toggle thousand separator for numeric display
162
162
  - **K** - 🔄 Cycle cursor (cell → row → column → cell)
163
163
 
164
- ## ↕️ Sorting
165
- - **[** - 🔼 Sort column ascending
166
- - **]** - 🔽 Sort column descending
167
- - *(Multi-column sort supported)*
164
+ ## ✏️ Editing
165
+ - **Double-click** - ✍️ Edit cell or rename column header
166
+ - **e** - ✍️ Edit current cell
167
+ - **E** - 📊 Edit entire column with expression
168
+ - **a** - ➕ Add empty column after current
169
+ - **A** - ➕ Add column with name and optional expression
170
+ - **@** - 🔗 Add a new link column from template
171
+ - **x** - ❌ Delete current row
172
+ - **X** - ❌ Delete row and those below
173
+ - **Ctrl+X** - ❌ Delete row and those above
174
+ - **delete** - ❌ Clear current cell (set to NULL)
175
+ - **Shift+Delete** - ❌ Clear current column (set matching cells to NULL)
176
+ - **-** - ❌ Delete current column
177
+ - **d** - 📋 Duplicate current column
178
+ - **D** - 📋 Duplicate current row
168
179
 
169
180
  ## ✅ Row Selection
170
181
  - **\\\\** - ✅ Select rows with cell matches or those matching cursor value in current column
@@ -193,25 +204,10 @@ class DataFrameTable(DataTable):
193
204
  - **v** - 👁️ View selected rows (others hidden)
194
205
  - **V** - 🔧 View selected rows matching expression (others hidden)
195
206
 
196
- ## 🔍 SQL Interface
197
- - **l** - 💬 Open simple SQL interface (select columns & where clause)
198
- - **L** - 🔎 Open advanced SQL interface (full SQL queries)
199
-
200
- ## ✏️ Editing
201
- - **Double-click** - ✍️ Edit cell or rename column header
202
- - **e** - ✍️ Edit current cell
203
- - **E** - 📊 Edit entire column with expression
204
- - **a** - ➕ Add empty column after current
205
- - **A** - ➕ Add column with name and optional expression
206
- - **@** - 🔗 Add a new link column from template
207
- - **x** - ❌ Delete current row
208
- - **X** - ❌ Delete row and those below
209
- - **Ctrl+X** - ❌ Delete row and those above
210
- - **delete** - ❌ Clear current cell (set to NULL)
211
- - **Shift+Delete** - ❌ Clear current column (set matching cells to NULL)
212
- - **-** - ❌ Delete current column
213
- - **d** - 📋 Duplicate current column
214
- - **D** - 📋 Duplicate current row
207
+ ## ↕️ Sorting
208
+ - **[** - 🔼 Sort column ascending
209
+ - **]** - 🔽 Sort column descending
210
+ - *(Multi-column sort supported)*
215
211
 
216
212
  ## 🎯 Reorder
217
213
  - **Shift+↑↓** - ⬆️⬇️ Move row up/down
@@ -227,6 +223,10 @@ class DataFrameTable(DataTable):
227
223
  - **c** - 📋 Copy cell to clipboard
228
224
  - **Ctrl+c** - 📊 Copy column to clipboard
229
225
  - **Ctrl+r** - 📝 Copy row to clipboard (tab-separated)
226
+
227
+ ## 🔍 SQL Interface
228
+ - **l** - 💬 Open simple SQL interface (select columns & where clause)
229
+ - **L** - 🔎 Open advanced SQL interface (full SQL queries)
230
230
  """).strip()
231
231
 
232
232
  # fmt: off
@@ -2882,7 +2882,7 @@ class DataFrameTable(DataTable):
2882
2882
  expr = validate_expr(term, self.df.columns, cidx)
2883
2883
  except Exception as e:
2884
2884
  self.notify(
2885
- f"Error validating expression [$error]{term}[/]", title="Search", severity="error", timeout=10
2885
+ f"Error validating expression [$error]{term}[/]", title="Select Row", severity="error", timeout=10
2886
2886
  )
2887
2887
  self.log(f"Error validating expression `{term}`: {str(e)}")
2888
2888
  return
@@ -2908,7 +2908,7 @@ class DataFrameTable(DataTable):
2908
2908
  expr = pl.col(col_name).cast(pl.String).str.contains(term)
2909
2909
  self.notify(
2910
2910
  f"Error converting [$error]{term}[/] to [$accent]{dtype}[/]. Cast to string.",
2911
- title="Search",
2911
+ title="Select Row",
2912
2912
  severity="warning",
2913
2913
  )
2914
2914
 
@@ -2920,7 +2920,7 @@ class DataFrameTable(DataTable):
2920
2920
  ok_rids = set(lf.filter(expr).collect()[RID])
2921
2921
  except Exception as e:
2922
2922
  self.notify(
2923
- f"Error applying search filter `[$error]{term}[/]`", title="Search", severity="error", timeout=10
2923
+ f"Error applying search filter `[$error]{term}[/]`", title="Select Row", severity="error", timeout=10
2924
2924
  )
2925
2925
  self.log(f"Error applying search filter `{term}`: {str(e)}")
2926
2926
  return
@@ -2929,7 +2929,7 @@ class DataFrameTable(DataTable):
2929
2929
  if match_count == 0:
2930
2930
  self.notify(
2931
2931
  f"No matches found for `[$warning]{term}[/]`. Try [$accent](?i)abc[/] for case-insensitive search.",
2932
- title="Search",
2932
+ title="Select Row",
2933
2933
  severity="warning",
2934
2934
  )
2935
2935
  return
@@ -2939,8 +2939,8 @@ class DataFrameTable(DataTable):
2939
2939
  # Add to history
2940
2940
  self.add_history(message)
2941
2941
 
2942
- # Update selected rows to include new selections
2943
- self.selected_rows.update(ok_rids)
2942
+ # Update selected rows
2943
+ self.selected_rows = ok_rids
2944
2944
 
2945
2945
  # Show notification immediately, then start highlighting
2946
2946
  self.notify(message, title="Select Row")
@@ -3048,7 +3048,7 @@ class DataFrameTable(DataTable):
3048
3048
  else:
3049
3049
  columns_to_search = list(enumerate(self.df.columns))
3050
3050
 
3051
- # Search each column consistently
3051
+ # Handle each column consistently
3052
3052
  for col_idx, col_name in columns_to_search:
3053
3053
  # Build expression based on term type
3054
3054
  if term == NULL:
@@ -3108,8 +3108,9 @@ class DataFrameTable(DataTable):
3108
3108
  cidx = self.cursor_col_idx if scope == "column" else None
3109
3109
 
3110
3110
  # Push the search modal screen
3111
+
3111
3112
  self.app.push_screen(
3112
- SearchScreen("Find", term, self.df, cidx),
3113
+ SearchScreen("Find" if scope == "column" else "Global Find", term, self.df, cidx),
3113
3114
  callback=self.find if scope == "column" else self.find_global,
3114
3115
  )
3115
3116
 
@@ -3139,10 +3140,9 @@ class DataFrameTable(DataTable):
3139
3140
  # Add to history
3140
3141
  self.add_history(f"Found `[$success]{term}[/]` in column [$accent]{col_name}[/]")
3141
3142
 
3142
- # Add to matches and count total
3143
+ # Update matches and count total
3143
3144
  match_count = sum(len(cols) for cols in matches.values())
3144
- for rid, cols in matches.items():
3145
- self.matches[rid].update(cols)
3145
+ self.matches = matches
3146
3146
 
3147
3147
  self.notify(f"Found [$success]{match_count}[/] matches for `[$accent]{term}[/]`", title="Find")
3148
3148
 
@@ -3173,10 +3173,9 @@ class DataFrameTable(DataTable):
3173
3173
  # Add to history
3174
3174
  self.add_history(f"Found `[$success]{term}[/]` across all columns")
3175
3175
 
3176
- # Add to matches and count total
3176
+ # Update matches and count total
3177
3177
  match_count = sum(len(cols) for cols in matches.values())
3178
- for rid, cols in matches.items():
3179
- self.matches[rid].update(cols)
3178
+ self.matches = matches
3180
3179
 
3181
3180
  self.notify(
3182
3181
  f"Found [$success]{match_count}[/] matches for `[$accent]{term}[/]` across all columns",
@@ -3284,7 +3283,7 @@ class DataFrameTable(DataTable):
3284
3283
  """Open replace screen for current column."""
3285
3284
  # Push the replace modal screen
3286
3285
  self.app.push_screen(
3287
- FindReplaceScreen(self, title="Find and Replace in Current Column"),
3286
+ FindReplaceScreen(self, title="Find and Replace"),
3288
3287
  callback=self.replace,
3289
3288
  )
3290
3289
 
@@ -449,13 +449,7 @@ class SearchScreen(YesNoScreen):
449
449
  self.cidx = cidx
450
450
 
451
451
  EXPR = f"ABC, (?i)abc, ^abc$, {NULL}, $_ > 50, $1 < $HP, $_.str.contains('sub')"
452
-
453
- if "Search" in title:
454
- col_name = df.columns[cidx]
455
- col_dtype = df.dtypes[cidx]
456
- label = f"{title} in [$success]{col_name}[/] ([$warning]{col_dtype}[/]) with value or Polars expression, e.g., {EXPR}"
457
- else:
458
- label = f"{title} by value or Polars expression, e.g., {EXPR}"
452
+ label = f"By value or Polars expression, e.g., {EXPR}"
459
453
 
460
454
  super().__init__(
461
455
  title=title,
@@ -171,7 +171,7 @@ wheels = [
171
171
 
172
172
  [[package]]
173
173
  name = "dataframe-textual"
174
- version = "2.8.0"
174
+ version = "2.9.0"
175
175
  source = { editable = "." }
176
176
  dependencies = [
177
177
  { name = "polars" },