Repository: saulpw/visidata

Issue:
[fec] opening rows in FEC files does not seem to work
**Small description**
FEC files can be opened, but rows cannot be browsed.

**Data to reproduce**
Using [a sample file 1326070.fec](https://docquery.fec.gov/dcdev/posted/1326070.fec).

**Steps to reproduce**

**Expected result**
When the user presses `Enter`, rows should open as in [jsvine's demo video at 13 seconds].(https://asciinema.org/a/Xyh2BFsUaOF0AlHTmMUbqQZPC)

**Actual result**
When the user presses `Enter`, `open-rows` runs, for example, opening the itemization row, as:
```
column    | value
------------------------
component | itemization
size      | 56958
```

**Configuration**
- Does this issue reproduce without any plugins or configuration (using the `-N` CLI flag)?
Yes, it reproduces with `-N`.

- Does this issue reproduce with either the [latest release](https://www.visidata.org/releases/), or with the [develop branch](https://www.visidata.org/install/#update-visidata-from-an-existing-installation)?
Yes, the latest develop.

**Additional context**
`fecfile` 0.8.0 installed via pip
Python 3.10.12
Ubuntu 22.04.4


Discussion:

Resolving patch:
diff --git a/visidata/loaders/fec.py b/visidata/loaders/fec.py
--- a/visidata/loaders/fec.py
+++ b/visidata/loaders/fec.py
@@ -37,13 +37,12 @@
 from copy import copy
 from visidata import (
     vd,
+    VisiData,
     Path,
     Sheet,
     TextSheet,
-    Column,
     ColumnAttr,
     ColumnItem,
-    ENTER,
     asyncthread,
     Progress,
     addGlobals,
@@ -111,10 +110,10 @@ def reload(self):
                     vd.warning("Can't dive on lists with heterogenous item types.")
                     return False
 
-    def dive(self):
+    def openRow(self, row):
         if self.is_keyvalue:
-            cell = self.cursorRow["value"]
-            name = vd.joinSheetnames(self.name, self.cursorRow["key"])
+            cell = row["value"]
+            name = vd.joinSheetnames(self.name, row["key"])
 
             if isinstance(cell, (list, dict)):
                 vs = self.__class__(name, source = cell)
@@ -123,19 +122,13 @@ def dive(self):
                 return
         else:
             name = vd.joinSheetnames(self.name, "row")
-            vs = self.__class__(name, source = self.cursorRow)
+            vs = self.__class__(name, source = self.row)
 
         success = vs.reload()
         if success == False:
-            return
-
-        vd.push(vs)
+            vd.fail('could not reload new sheet')
+        return vs
 
-DiveSheet.addCommand(
-    ENTER,
-    'dive-row',
-    'vd.sheet.dive()'
-)
 
 class FECItemizationSheet(Sheet):
     "A sheet to display a list of FEC itemizations from a given form/schedule."
@@ -159,19 +152,9 @@ def set_columns_from_row(self, row):
         self.columns.clear()
         for i, name in enumerate(row.keys()):
             self.addColumn(ColumnItem(name))
-    def dive(self):
-        vs = DiveSheet(
-            vd.joinSheetnames(self.name, "detail"),
-            source = self.cursorRow
-        )
-        vs.reload()
-        vd.push(vs)
-
-FECItemizationSheet.addCommand(
-    ENTER,
-    'dive-row',
-    'vd.sheet.dive()'
-)
+
+    def openRow(self, row):
+        return row
 
 class FECScheduleSheet(Sheet):
     "A sheet to display the list of itemized schedules in a filing."
@@ -199,11 +182,8 @@ def reload(self):
             )
             self.addRow(vs)
 
-FECScheduleSheet.addCommand(
-    ENTER,
-    'dive-row',
-    'vd.push(cursorRow)'
-)
+    def openRow(self, row):
+        return row
 
 COMPONENT_SHEET_CLASSES = {
     "header": DiveSheet,
@@ -230,7 +210,7 @@ class FECFiling(Sheet):
     @asyncthread
     def reload(self):
         from fecfile import fecparser
-        self.rows = []
+        self.rows = []  # rowdef:  Sheet, of a type from COMPONENT_SHEET_CLASSES.values()
 
         row_dict = { }
         itemization_subsheets = {}
@@ -310,16 +290,13 @@ def addSheetRow(component_name):
                 sheet_row.source[form_type].append(item.data)
                 sheet_row.size += 1
 
-FECFiling.addCommand(
-    ENTER,
-    'dive-row',
-    'vd.push(cursorRow)'
-)
+    def openRow(self, row):
+        return row
 
-def open_fec(p):
+@VisiData.api
+def open_fec(vd, p):
     return FECFiling(p.base_stem, source=p)
 
 addGlobals({
-    "open_fec": open_fec,
     "DiveSheet": DiveSheet
 })


Test patch:
diff --git a/tests/golden/load-fec.tsv b/tests/golden/load-fec.tsv
new file mode 100644
--- /dev/null
+++ b/tests/golden/load-fec.tsv
@@ -0,0 +1,9 @@
+key	value
+record_type	HDR
+ef_type	FEC
+fec_version	8.4
+soft_name	Campaign Manager 360
+soft_ver	1.0
+report_id	FEC-1724438
+report_number	6
+comment	
diff --git a/tests/load-fec.vdj b/tests/load-fec.vdj
new file mode 100644
--- /dev/null
+++ b/tests/load-fec.vdj
@@ -0,0 +1,3 @@
+#!vd -p
+{"sheet": null, "col": null, "row": null, "longname": "open-file", "input": "sample_data/1794685.fec", "keystrokes": "o", "comment": null}
+{"sheet": "1794685", "col": "", "row": "\u30adheader", "longname": "open-row", "input": "", "keystrokes": "Enter", "comment": "open current row with sheet-specific dive"}