visidata 2.11.1__py3-none-any.whl → 3.0.1__py3-none-any.whl
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.
- visidata/__init__.py +72 -91
- visidata/_input.py +259 -42
- visidata/_open.py +84 -29
- visidata/_types.py +21 -3
- visidata/_urlcache.py +17 -4
- visidata/aggregators.py +78 -25
- visidata/apps/__init__.py +0 -0
- visidata/apps/vdsql/__about__.py +8 -0
- visidata/apps/vdsql/__init__.py +5 -0
- visidata/apps/vdsql/__main__.py +27 -0
- visidata/apps/vdsql/_ibis.py +748 -0
- visidata/apps/vdsql/bigquery.py +61 -0
- visidata/apps/vdsql/clickhouse.py +53 -0
- visidata/apps/vdsql/setup.py +40 -0
- visidata/apps/vdsql/snowflake.py +67 -0
- visidata/apps/vgit/__init__.py +13 -0
- {vgit → visidata/apps/vgit}/blame.py +5 -2
- {vgit → visidata/apps/vgit}/branch.py +31 -16
- {vgit → visidata/apps/vgit}/config.py +3 -3
- visidata/apps/vgit/diff.py +169 -0
- visidata/apps/vgit/gitsheet.py +161 -0
- {vgit → visidata/apps/vgit}/grep.py +6 -5
- visidata/apps/vgit/log.py +81 -0
- {vgit → visidata/apps/vgit}/main.py +18 -5
- {vgit → visidata/apps/vgit}/remote.py +8 -4
- visidata/apps/vgit/repos.py +71 -0
- {vgit → visidata/apps/vgit}/setup.py +6 -4
- visidata/apps/vgit/stash.py +69 -0
- visidata/apps/vgit/status.py +204 -0
- {vgit → visidata/apps/vgit}/statusbar.py +2 -0
- visidata/basesheet.py +63 -51
- visidata/canvas.py +208 -93
- visidata/choose.py +6 -6
- visidata/clean_names.py +29 -0
- visidata/clipboard.py +73 -17
- visidata/cliptext.py +220 -46
- visidata/cmdlog.py +88 -114
- visidata/color.py +142 -56
- visidata/column.py +121 -129
- visidata/ddw/input.ddw +74 -79
- visidata/ddw/regex.ddw +57 -0
- visidata/ddwplay.py +33 -14
- visidata/deprecated.py +77 -3
- visidata/desktop/visidata.desktop +7 -0
- visidata/editor.py +12 -6
- visidata/errors.py +6 -2
- visidata/experimental/__init__.py +0 -0
- visidata/experimental/diff_sheet.py +29 -0
- visidata/experimental/digit_autoedit.py +6 -0
- visidata/experimental/gdrive.py +89 -0
- visidata/experimental/google.py +37 -0
- visidata/experimental/gsheets.py +79 -0
- visidata/experimental/live_search.py +37 -0
- visidata/experimental/liveupdate.py +45 -0
- visidata/experimental/mark.py +133 -0
- visidata/experimental/noahs_tapestry/__init__.py +1 -0
- visidata/experimental/noahs_tapestry/tapestry.py +147 -0
- visidata/experimental/rownum.py +73 -0
- visidata/experimental/slide_cells.py +26 -0
- visidata/expr.py +8 -4
- visidata/extensible.py +22 -4
- visidata/features/__init__.py +0 -0
- visidata/features/addcol_audiometadata.py +42 -0
- visidata/features/addcol_histogram.py +34 -0
- visidata/features/canvas_save_svg.py +69 -0
- visidata/features/change_precision.py +46 -0
- visidata/features/cmdpalette.py +197 -0
- visidata/features/colorbrewer.py +363 -0
- visidata/{colorsheet.py → features/colorsheet.py} +17 -16
- visidata/features/command_server.py +105 -0
- visidata/features/currency_to_usd.py +70 -0
- visidata/{customdate.py → features/customdate.py} +2 -0
- visidata/features/dedupe.py +132 -0
- visidata/{describe.py → features/describe.py} +17 -15
- visidata/features/errors_guide.py +26 -0
- visidata/features/expand_cols.py +202 -0
- visidata/{fill.py → features/fill.py} +3 -1
- visidata/{freeze.py → features/freeze.py} +11 -6
- visidata/features/graph_seaborn.py +79 -0
- visidata/features/helloworld.py +10 -0
- visidata/features/hint_types.py +17 -0
- visidata/{incr.py → features/incr.py} +5 -0
- visidata/{join.py → features/join.py} +107 -53
- visidata/features/known_cols.py +21 -0
- visidata/features/layout.py +62 -0
- visidata/{melt.py → features/melt.py} +32 -21
- visidata/features/normcol.py +118 -0
- visidata/features/open_config.py +7 -0
- visidata/features/open_syspaste.py +18 -0
- visidata/features/ping.py +157 -0
- visidata/features/procmgr.py +208 -0
- visidata/features/random_sample.py +6 -0
- visidata/{regex.py → features/regex.py} +47 -31
- visidata/features/reload_every.py +55 -0
- visidata/features/rename_col_cascade.py +30 -0
- visidata/features/scroll_context.py +60 -0
- visidata/features/select_equal_selected.py +11 -0
- visidata/features/setcol_fake.py +65 -0
- visidata/{slide.py → features/slide.py} +77 -21
- visidata/features/sparkline.py +48 -0
- visidata/features/status_source.py +20 -0
- visidata/{sysedit.py → features/sysedit.py} +2 -1
- visidata/features/sysopen_mailcap.py +46 -0
- visidata/features/term_extras.py +13 -0
- visidata/{transpose.py → features/transpose.py} +5 -4
- visidata/features/type_ipaddr.py +73 -0
- visidata/features/type_url.py +11 -0
- visidata/{unfurl.py → features/unfurl.py} +9 -9
- visidata/{window.py → features/window.py} +2 -2
- visidata/form.py +50 -21
- visidata/freqtbl.py +81 -33
- visidata/fuzzymatch.py +414 -0
- visidata/graph.py +105 -33
- visidata/guide.py +200 -0
- visidata/help.py +75 -44
- visidata/hint.py +39 -0
- visidata/indexsheet.py +109 -0
- visidata/input_history.py +55 -0
- visidata/interface.py +58 -0
- visidata/keys.py +20 -16
- visidata/loaders/__init__.py +9 -0
- visidata/loaders/_pandas.py +61 -21
- visidata/loaders/api_airtable.py +70 -0
- visidata/loaders/api_bitio.py +102 -0
- visidata/loaders/api_matrix.py +148 -0
- visidata/loaders/api_reddit.py +306 -0
- visidata/loaders/api_zulip.py +249 -0
- visidata/loaders/archive.py +41 -7
- visidata/loaders/arrow.py +7 -7
- visidata/loaders/conll.py +49 -0
- visidata/loaders/csv.py +25 -7
- visidata/loaders/eml.py +3 -4
- visidata/loaders/f5log.py +1204 -0
- visidata/loaders/fec.py +325 -0
- visidata/loaders/fixed_width.py +2 -4
- visidata/loaders/frictionless.py +3 -3
- visidata/loaders/geojson.py +8 -5
- visidata/loaders/google.py +48 -0
- visidata/loaders/graphviz.py +4 -4
- visidata/loaders/hdf5.py +4 -4
- visidata/loaders/html.py +54 -12
- visidata/loaders/http.py +84 -30
- visidata/loaders/imap.py +20 -10
- visidata/loaders/jrnl.py +52 -0
- visidata/loaders/json.py +83 -29
- visidata/loaders/jsonla.py +74 -0
- visidata/loaders/lsv.py +15 -11
- visidata/loaders/mailbox.py +40 -0
- visidata/loaders/markdown.py +1 -3
- visidata/loaders/mbtiles.py +4 -5
- visidata/loaders/mysql.py +11 -13
- visidata/loaders/npy.py +7 -7
- visidata/loaders/odf.py +4 -1
- visidata/loaders/orgmode.py +428 -0
- visidata/loaders/pandas_freqtbl.py +14 -20
- visidata/loaders/parquet.py +62 -6
- visidata/loaders/pcap.py +3 -3
- visidata/loaders/pdf.py +4 -3
- visidata/loaders/png.py +19 -13
- visidata/loaders/postgres.py +9 -8
- visidata/loaders/rec.py +7 -3
- visidata/loaders/s3.py +342 -0
- visidata/loaders/sas.py +5 -5
- visidata/loaders/scrape.py +186 -0
- visidata/loaders/shp.py +6 -5
- visidata/loaders/spss.py +5 -6
- visidata/loaders/sqlite.py +68 -28
- visidata/loaders/texttables.py +1 -1
- visidata/loaders/toml.py +60 -0
- visidata/loaders/tsv.py +61 -19
- visidata/loaders/ttf.py +19 -7
- visidata/loaders/unzip_http.py +6 -5
- visidata/loaders/usv.py +1 -1
- visidata/loaders/vcf.py +16 -16
- visidata/loaders/vds.py +10 -7
- visidata/loaders/vdx.py +30 -5
- visidata/loaders/xlsb.py +8 -1
- visidata/loaders/xlsx.py +145 -25
- visidata/loaders/xml.py +6 -3
- visidata/loaders/xword.py +4 -4
- visidata/loaders/yaml.py +15 -5
- visidata/macros.py +129 -42
- visidata/main.py +119 -94
- visidata/mainloop.py +101 -155
- visidata/man/parse_options.py +2 -2
- visidata/man/vd.1 +302 -149
- visidata/man/vd.txt +291 -154
- visidata/memory.py +3 -3
- visidata/menu.py +104 -423
- visidata/metasheets.py +59 -141
- visidata/modify.py +78 -23
- visidata/motd.py +3 -3
- visidata/mouse.py +137 -0
- visidata/movement.py +43 -35
- visidata/optionssheet.py +99 -0
- visidata/path.py +113 -32
- visidata/pivot.py +73 -47
- visidata/plugins.py +65 -192
- visidata/pyobj.py +55 -205
- visidata/rename_col.py +20 -0
- visidata/save.py +37 -20
- visidata/search.py +54 -10
- visidata/selection.py +84 -5
- visidata/settings.py +162 -25
- visidata/sheets.py +239 -260
- visidata/shell.py +51 -21
- visidata/sidebar.py +162 -0
- visidata/sort.py +11 -4
- visidata/statusbar.py +114 -104
- visidata/stored_list.py +43 -0
- visidata/stored_prop.py +38 -0
- visidata/tests/benchmark.csv +52 -0
- visidata/tests/conftest.py +3 -3
- visidata/tests/test_cliptext.py +39 -0
- visidata/tests/test_commands.py +65 -7
- visidata/tests/test_edittext.py +2 -2
- visidata/tests/test_features.py +28 -0
- visidata/tests/test_menu.py +14 -0
- visidata/tests/test_path.py +13 -4
- visidata/text_source.py +53 -0
- visidata/textsheet.py +10 -3
- visidata/theme.py +44 -0
- visidata/themes/__init__.py +0 -0
- visidata/themes/ascii8.py +84 -0
- visidata/themes/asciimono.py +84 -0
- visidata/themes/light.py +17 -0
- visidata/threads.py +89 -40
- visidata/tuiwin.py +22 -0
- visidata/type_currency.py +22 -3
- visidata/type_date.py +31 -9
- visidata/type_floatsi.py +5 -1
- visidata/undo.py +17 -5
- visidata/utils.py +106 -23
- visidata/vdobj.py +28 -17
- visidata/windows.py +10 -0
- visidata/wrappers.py +9 -3
- visidata-3.0.1.data/data/share/applications/visidata.desktop +7 -0
- {visidata-2.11.1.data → visidata-3.0.1.data}/data/share/man/man1/vd.1 +302 -149
- {visidata-2.11.1.data → visidata-3.0.1.data}/data/share/man/man1/visidata.1 +302 -149
- visidata-3.0.1.data/scripts/vd2to3.vdx +9 -0
- {visidata-2.11.1.dist-info → visidata-3.0.1.dist-info}/METADATA +12 -8
- visidata-3.0.1.dist-info/RECORD +258 -0
- {visidata-2.11.1.dist-info → visidata-3.0.1.dist-info}/WHEEL +1 -1
- vgit/__init__.py +0 -1
- vgit/gitsheet.py +0 -164
- visidata/layout.py +0 -44
- visidata/misc.py +0 -5
- visidata-2.11.1.data/scripts/vgit +0 -9
- visidata-2.11.1.dist-info/RECORD +0 -155
- {vgit → visidata/apps/vgit}/__main__.py +0 -0
- {vgit → visidata/apps/vgit}/abort.py +0 -0
- /visidata/{repeat.py → features/repeat.py} +0 -0
- {visidata-2.11.1.data → visidata-3.0.1.data}/scripts/vd +0 -0
- {visidata-2.11.1.dist-info → visidata-3.0.1.dist-info}/LICENSE.gpl3 +0 -0
- {visidata-2.11.1.dist-info → visidata-3.0.1.dist-info}/entry_points.txt +0 -0
- {visidata-2.11.1.dist-info → visidata-3.0.1.dist-info}/top_level.txt +0 -0
visidata/utils.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
from contextlib import contextmanager
|
1
2
|
import operator
|
2
3
|
import string
|
3
4
|
import re
|
4
5
|
|
5
6
|
'Various helper classes and functions.'
|
6
7
|
|
7
|
-
__all__ = ['AlwaysDict', 'AttrDict', 'moveListItem', 'namedlist', 'classproperty', '
|
8
|
+
__all__ = ['AlwaysDict', 'AttrDict', 'DefaultAttrDict', 'moveListItem', 'namedlist', 'classproperty', 'MissingAttrFormatter', 'getitem', 'setitem', 'getitemdef', 'getitemdeep', 'setitemdeep', 'getattrdeep', 'setattrdeep', 'ExplodingMock', 'ScopedSetattr']
|
8
9
|
|
9
10
|
|
10
11
|
class AlwaysDict(dict):
|
@@ -36,6 +37,24 @@ class AttrDict(dict):
|
|
36
37
|
return self.keys()
|
37
38
|
|
38
39
|
|
40
|
+
class DefaultAttrDict(dict):
|
41
|
+
'Augment a dict with more convenient .attr syntax. not-present keys store new DefaultAttrDict. like a recursive defaultdict.'
|
42
|
+
def __getattr__(self, k):
|
43
|
+
if k not in self:
|
44
|
+
if k.startswith("__"):
|
45
|
+
raise AttributeError from e
|
46
|
+
self[k] = DefaultAttrDict()
|
47
|
+
return self[k]
|
48
|
+
|
49
|
+
def __setattr__(self, k, v):
|
50
|
+
self[k] = v
|
51
|
+
|
52
|
+
def __dir__(self):
|
53
|
+
return self.keys()
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
|
39
58
|
class classproperty(property):
|
40
59
|
def __get__(self, cls, obj):
|
41
60
|
return classmethod(self.fget).__get__(None, obj or cls)()
|
@@ -50,34 +69,75 @@ def moveListItem(L, fromidx, toidx):
|
|
50
69
|
return toidx
|
51
70
|
|
52
71
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
72
|
+
def setitem(r, i, v): # function needed for use in lambda
|
73
|
+
r[i] = v
|
74
|
+
return True
|
75
|
+
|
76
|
+
def getitem(o, k, default=None):
|
77
|
+
return default if o is None else o[k]
|
78
|
+
|
79
|
+
def getitemdef(o, k, default=None):
|
80
|
+
try:
|
81
|
+
return default if o is None else o[k]
|
82
|
+
except Exception:
|
83
|
+
return default
|
84
|
+
|
58
85
|
|
86
|
+
def getattrdeep(obj, attr, *default, getter=getattr):
|
87
|
+
try:
|
88
|
+
'Return dotted attr (like "a.b.c") from obj, or default if any of the components are missing.'
|
89
|
+
if not isinstance(attr, str):
|
90
|
+
return getter(obj, attr, *default)
|
91
|
+
|
92
|
+
try: # if attribute exists, return toplevel value, even if dotted
|
93
|
+
if attr in obj:
|
94
|
+
return getter(obj, attr)
|
95
|
+
except RecursionError: #1696
|
96
|
+
raise
|
97
|
+
except Exception as e:
|
98
|
+
pass
|
99
|
+
|
100
|
+
attrs = attr.split('.')
|
101
|
+
for a in attrs[:-1]:
|
102
|
+
obj = getter(obj, a)
|
103
|
+
|
104
|
+
return getter(obj, attrs[-1])
|
105
|
+
except Exception as e:
|
106
|
+
if not default: raise
|
107
|
+
return default[0]
|
59
108
|
|
60
|
-
class OnExit:
|
61
|
-
'"with OnExit(func, ...):" calls func(...) when the context is exited'
|
62
|
-
def __init__(self, func, *args, **kwargs):
|
63
|
-
self.func = func
|
64
|
-
self.args = args
|
65
|
-
self.kwargs = kwargs
|
66
109
|
|
67
|
-
|
68
|
-
|
110
|
+
def setattrdeep(obj, attr, val, getter=getattr, setter=setattr):
|
111
|
+
'Set dotted attr (like "a.b.c") on obj to val.'
|
112
|
+
if not isinstance(attr, str):
|
113
|
+
return setter(obj, attr, val)
|
69
114
|
|
70
|
-
|
115
|
+
try: # if attribute exists, overwrite toplevel value, even if dotted
|
116
|
+
getter(obj, attr)
|
117
|
+
return setter(obj, attr, val)
|
118
|
+
except Exception as e:
|
119
|
+
pass
|
120
|
+
|
121
|
+
attrs = attr.split('.')
|
122
|
+
for a in attrs[:-1]:
|
71
123
|
try:
|
72
|
-
|
124
|
+
obj = getter(obj, a)
|
73
125
|
except Exception as e:
|
74
|
-
|
126
|
+
obj = obj[a] = type(obj)() # assume homogeneous nesting
|
127
|
+
|
128
|
+
setter(obj, attrs[-1], val)
|
75
129
|
|
76
130
|
|
77
|
-
def
|
78
|
-
|
79
|
-
|
80
|
-
|
131
|
+
def getitemdeep(obj, k, *default):
|
132
|
+
if not isinstance(k, str):
|
133
|
+
try:
|
134
|
+
return obj[k]
|
135
|
+
except IndexError:
|
136
|
+
pass
|
137
|
+
return getattrdeep(obj, k, *default, getter=getitem)
|
138
|
+
|
139
|
+
def setitemdeep(obj, k, val):
|
140
|
+
return setattrdeep(obj, k, val, getter=getitemdef, setter=setitem)
|
81
141
|
|
82
142
|
|
83
143
|
def namedlist(objname, fieldnames):
|
@@ -111,11 +171,24 @@ def namedlist(objname, fieldnames):
|
|
111
171
|
|
112
172
|
return NamedListTemplate
|
113
173
|
|
174
|
+
|
175
|
+
class ExplodingMock:
|
176
|
+
'A mock object that raises an exception for everything except conversion to True/False.'
|
177
|
+
def __init__(self, msg):
|
178
|
+
self.__msg = msg
|
179
|
+
|
180
|
+
def __getattr__(self, k):
|
181
|
+
raise Exception(self.__msg)
|
182
|
+
|
183
|
+
def __bool__(self):
|
184
|
+
return False
|
185
|
+
|
186
|
+
|
114
187
|
class MissingAttrFormatter(string.Formatter):
|
115
188
|
"formats {} fields with `''`, that would normally result in a raised KeyError or AttributeError; intended for user customisable format strings."
|
116
|
-
def get_field(self, field_name,
|
189
|
+
def get_field(self, field_name, args, kwargs):
|
117
190
|
try:
|
118
|
-
return super().get_field(field_name,
|
191
|
+
return super().get_field(field_name, args, kwargs)
|
119
192
|
except (KeyError, AttributeError):
|
120
193
|
return (None, field_name)
|
121
194
|
|
@@ -126,3 +199,13 @@ class MissingAttrFormatter(string.Formatter):
|
|
126
199
|
elif not value:
|
127
200
|
return str(value)
|
128
201
|
return super().format_field(value, format_spec)
|
202
|
+
|
203
|
+
|
204
|
+
@contextmanager
|
205
|
+
def ScopedSetattr(obj, attrname, val):
|
206
|
+
oldval = getattr(obj, attrname)
|
207
|
+
try:
|
208
|
+
setattr(obj, attrname, val)
|
209
|
+
yield
|
210
|
+
finally:
|
211
|
+
setattr(obj, attrname, oldval)
|
visidata/vdobj.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
from functools import wraps
|
2
|
-
from unittest import mock
|
3
2
|
import curses
|
4
3
|
|
5
4
|
import visidata
|
@@ -25,7 +24,7 @@ def asyncthread(func):
|
|
25
24
|
|
26
25
|
|
27
26
|
class VisiData(visidata.Extensible):
|
28
|
-
allPrefixes = ['g', 'z',
|
27
|
+
allPrefixes = ['g', 'z', 'Alt+'] # embig'g'en, 'z'mallify, Alt/Esc=User
|
29
28
|
|
30
29
|
@classmethod
|
31
30
|
def global_api(cls, func):
|
@@ -42,9 +41,16 @@ class VisiData(visidata.Extensible):
|
|
42
41
|
self.lastErrors = []
|
43
42
|
self.pendingKeys = []
|
44
43
|
self.keystrokes = ''
|
45
|
-
self.scrFull =
|
44
|
+
self.scrFull = None
|
46
45
|
self._cmdlog = None
|
46
|
+
self.currentReplay = None
|
47
47
|
self.contexts = [self] # objects whose attributes are in the fallback context for eval/exec.
|
48
|
+
self.importingModule = None
|
49
|
+
self.importedModules = []
|
50
|
+
|
51
|
+
@property
|
52
|
+
def cursesEnabled(self):
|
53
|
+
return bool(self.scrFull)
|
48
54
|
|
49
55
|
def sheetstack(self, pane=0):
|
50
56
|
'Return list of sheets in given *pane*. pane=0 is the active pane. pane=-1 is the inactive pane.'
|
@@ -74,10 +80,6 @@ class VisiData(visidata.Extensible):
|
|
74
80
|
def activeStack(self):
|
75
81
|
return self.sheetstack() or self.sheetstack(-1)
|
76
82
|
|
77
|
-
@visidata.drawcache_property
|
78
|
-
def mousereg(self):
|
79
|
-
return []
|
80
|
-
|
81
83
|
def __copy__(self):
|
82
84
|
'Dummy method for Extensible.init()'
|
83
85
|
pass
|
@@ -100,12 +102,29 @@ class VisiData(visidata.Extensible):
|
|
100
102
|
'Invalidate internal caches between command inputs.'
|
101
103
|
visidata.Extensible.clear_all_caches()
|
102
104
|
|
105
|
+
def resetVisiData(self):
|
106
|
+
self.clearCaches() # we want vd to return a new VisiData object for each command
|
107
|
+
vd = visidata.vd # get the new vd
|
108
|
+
vd.cmdlog.rows = []
|
109
|
+
vd.sheets = []
|
110
|
+
vd.allSheets = []
|
111
|
+
return vd
|
112
|
+
|
113
|
+
def get_wch(self, scr):
|
114
|
+
try:
|
115
|
+
return scr.get_wch()
|
116
|
+
except AttributeError: #192 some packages don't have wide chars
|
117
|
+
k = scr.getch()
|
118
|
+
if k == -1: # mimic get_wch behavior
|
119
|
+
raise curses.error('no char ready')
|
120
|
+
return k
|
121
|
+
|
103
122
|
def drainPendingKeys(self, scr):
|
104
123
|
'''Call scr.get_wch() until no more keypresses are available. Return True if any keypresses are pending.'''
|
105
124
|
scr.timeout(0)
|
106
125
|
try:
|
107
126
|
while True:
|
108
|
-
k =
|
127
|
+
k = self.get_wch(scr)
|
109
128
|
if k:
|
110
129
|
self.pendingKeys.append(k)
|
111
130
|
else:
|
@@ -127,7 +146,7 @@ class VisiData(visidata.Extensible):
|
|
127
146
|
curses.reset_prog_mode() #1347
|
128
147
|
try:
|
129
148
|
scr.refresh()
|
130
|
-
k =
|
149
|
+
k = self.get_wch(scr)
|
131
150
|
vs = vs or self.activeSheet
|
132
151
|
if vs:
|
133
152
|
self.drawRightStatus(vs._scr, vs) # continue to display progress %
|
@@ -140,14 +159,6 @@ class VisiData(visidata.Extensible):
|
|
140
159
|
k = ord(k)
|
141
160
|
return curses.keyname(k).decode('utf-8')
|
142
161
|
|
143
|
-
def onMouse(self, scr, y, x, h, w, **kwargs):
|
144
|
-
self.mousereg.append((scr, y, x, h, w, kwargs))
|
145
|
-
|
146
|
-
def getMouse(self, _scr, _x, _y, button):
|
147
|
-
for scr, y, x, h, w, kwargs in self.mousereg[::-1]:
|
148
|
-
if scr is _scr and x <= _x < x+w and y <= _y < y+h and button in kwargs:
|
149
|
-
return kwargs[button]
|
150
|
-
|
151
162
|
@property
|
152
163
|
def screenHeight(self):
|
153
164
|
return self.scrFull.getmaxyx()[0] if self.scrFull else 25
|
visidata/windows.py
ADDED
visidata/wrappers.py
CHANGED
@@ -5,9 +5,6 @@ import functools
|
|
5
5
|
|
6
6
|
from visidata import options, stacktrace, BaseSheet, vd
|
7
7
|
|
8
|
-
__all__ = ['forward', 'wrmap', 'wrapply', 'TypedWrapper', 'TypedExceptionWrapper']
|
9
|
-
|
10
|
-
vd.option('null_value', None, 'a value to be counted as null', replay=True)
|
11
8
|
|
12
9
|
@BaseSheet.api
|
13
10
|
def isNullFunc(sheet):
|
@@ -109,3 +106,12 @@ def wrapply(func, *args, **kwargs):
|
|
109
106
|
except Exception as e:
|
110
107
|
e.stacktrace = stacktrace()
|
111
108
|
return TypedExceptionWrapper(func, *args, exception=e)
|
109
|
+
|
110
|
+
|
111
|
+
vd.addGlobals(
|
112
|
+
forward=forward,
|
113
|
+
wrmap=wrmap,
|
114
|
+
wrapply=wrapply,
|
115
|
+
TypedWrapper=TypedWrapper,
|
116
|
+
TypedExceptionWrapper=TypedExceptionWrapper
|
117
|
+
)
|