Repository: saulpw/visidata

Issue:
[macros] Recording a macros fails
**Small description**
Recording a macro fails.

**Expected result**
Macro is saved.

**Actual result with screenshot**
https://asciinema.org/a/7T0YgyrSQFhHyWfdok17oi6Qj

```
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/visidata/basesheet.py", line 136, in execCommand
    exec(code, vdglobals, LazyChainMap(vd, self))
  File "macro-record", line 1, in <module>
  File "/usr/lib/python3.9/site-packages/visidata/macros.py", line 52, in startMacro
    vd.cmdlog.saveMacro(vd.macroMode.rows, ks)
  File "/usr/lib/python3.9/site-packages/visidata/macros.py", line 37, in saveMacro
    append_tsv_row(vd.macrosheet, (ks, macropath))
  File "/usr/lib/python3.9/site-packages/visidata/loaders/tsv.py", line 81, in append_tsv_row
    if not vs.source.exists():
AttributeError: 'NoneType' object has no attribute 'exists'
```

**Steps to reproduce with sample data and a .vd**
Record a macro, provide a filename when asked, and vd throws an exception.

**Additional context**
Please include the version of VisiData. Latest develop version.



Discussion:
This should now be fixed on `develop`!
Hi @anjakefala! I was trying to confirm the fix.  But I'm not sure how to run a macro.  It looks like the macro name becomes the name of a new command, but when I try to run it, I get a KeyError: ' '  It is getting late, I don't have time now to look further.  Will have to take a look when I have time.
Hi @anjakefala I think I understand my issue.  

When it is time to save the macro, I wasn't giving a keystroke, but giving it longer name, `delete-ten-rows` rather than `zx`.  If I then try to do a long-command: `delete-ten-rows`, I get the KeyError.

https://asciinema.org/a/mUuTYelsvQ6gduB4qMKQpaWmM

```
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/visidata/basesheet.py", line 136, in execCommand
    exec(code, vdglobals, LazyChainMap(vd, self))
  File "cmdlog", line 1, in <module>
KeyError: ' '
```

@saulpw, should we allow longnames, as well as keystrokes? Hmmmmm.
Yes, allowing longnames is a good idea.  I think it should work already, though, so this may be just a small bug (hopefully it doesn't unravel into something bigger).

Resolving patch:
diff --git a/visidata/basesheet.py b/visidata/basesheet.py
--- a/visidata/basesheet.py
+++ b/visidata/basesheet.py
@@ -226,6 +226,11 @@ def sheet(self):
     'the top sheet on the stack'
     return self.sheets[0] if self.sheets else None
 
+@VisiData.api
+def isLongname(self, ks):
+    'Return True if *ks* is a longname.'
+    return ('-' in ks) and (ks[-1] != '-')
+
 
 @VisiData.api
 def getSheet(vd, sheetname):
diff --git a/visidata/help.py b/visidata/help.py
--- a/visidata/help.py
+++ b/visidata/help.py
@@ -36,7 +36,7 @@ def iterload(self):
         self.revbinds = {}  # [longname] -> keystrokes
         itbindings = vd.bindkeys.iterall()
         for (keystrokes, _), longname in itbindings:
-            if (keystrokes not in self.revbinds) and ('-' not in keystrokes or keystrokes[-1] == '-'):
+            if (keystrokes not in self.revbinds) and not vd.isLongname(keystrokes):
                 self.revbinds[longname] = keystrokes
 
 
diff --git a/visidata/macros.py b/visidata/macros.py
--- a/visidata/macros.py
+++ b/visidata/macros.py
@@ -24,7 +24,10 @@ def runMacro(vd, macro):
 
 def setMacro(ks, vs):
     vd.macrobindings[ks] = vs
-    BaseSheet.addCommand(ks, vs.name, 'runMacro(vd.macrobindings[keystrokes])')
+    if vd.isLongname(ks):
+        BaseSheet.addCommand('', ks, 'runMacro(vd.macrobindings[longname])')
+    else:
+        BaseSheet.addCommand(ks, vs.name, 'runMacro(vd.macrobindings[keystrokes])')
 
 
 @CommandLog.api


Test patch: