visidata 2.11.dev0__py3-none-any.whl → 3.0__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 +263 -44
- visidata/_open.py +84 -29
- visidata/_types.py +22 -4
- visidata/_urlcache.py +17 -4
- visidata/aggregators.py +65 -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
- visidata/apps/vgit/__main__.py +3 -0
- visidata/apps/vgit/abort.py +23 -0
- visidata/apps/vgit/blame.py +76 -0
- visidata/apps/vgit/branch.py +153 -0
- visidata/apps/vgit/config.py +95 -0
- visidata/apps/vgit/diff.py +169 -0
- visidata/apps/vgit/gitsheet.py +161 -0
- visidata/apps/vgit/grep.py +37 -0
- visidata/apps/vgit/log.py +81 -0
- visidata/apps/vgit/main.py +55 -0
- visidata/apps/vgit/remote.py +57 -0
- visidata/apps/vgit/repos.py +71 -0
- visidata/apps/vgit/setup.py +37 -0
- visidata/apps/vgit/stash.py +69 -0
- visidata/apps/vgit/status.py +204 -0
- visidata/apps/vgit/statusbar.py +34 -0
- visidata/basesheet.py +59 -50
- visidata/canvas.py +251 -99
- visidata/choose.py +15 -11
- visidata/clean_names.py +29 -0
- visidata/clipboard.py +84 -18
- visidata/cliptext.py +220 -46
- visidata/cmdlog.py +89 -114
- visidata/color.py +142 -56
- visidata/column.py +134 -131
- 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 +5 -1
- 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 +32 -6
- 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 +163 -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} +4 -2
- 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} +33 -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} +75 -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 +180 -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 +17 -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 +3 -5
- 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 +48 -10
- 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/macos.py +1 -1
- visidata/macros.py +130 -41
- visidata/main.py +119 -94
- visidata/mainloop.py +101 -154
- visidata/man/parse_options.py +2 -2
- visidata/man/vd.1 +302 -147
- visidata/man/vd.txt +291 -151
- visidata/memory.py +3 -3
- visidata/menu.py +104 -423
- visidata/metasheets.py +59 -141
- visidata/modify.py +79 -23
- visidata/motd.py +3 -3
- visidata/mouse.py +137 -0
- visidata/movement.py +43 -35
- visidata/optionssheet.py +99 -0
- visidata/path.py +131 -43
- visidata/pivot.py +74 -47
- visidata/plugins.py +65 -192
- visidata/pyobj.py +50 -201
- visidata/rename_col.py +20 -0
- visidata/save.py +42 -20
- visidata/search.py +54 -10
- visidata/selection.py +84 -5
- visidata/settings.py +162 -24
- visidata/sheets.py +229 -257
- visidata/shell.py +51 -21
- visidata/sidebar.py +162 -0
- visidata/sort.py +11 -4
- visidata/statusbar.py +113 -104
- visidata/stored_list.py +43 -0
- visidata/stored_prop.py +38 -0
- visidata/tests/conftest.py +3 -3
- visidata/tests/test_cliptext.py +39 -0
- visidata/tests/test_commands.py +62 -7
- visidata/tests/test_edittext.py +2 -2
- visidata/tests/test_features.py +17 -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 +87 -39
- 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 +18 -6
- visidata/utils.py +106 -23
- visidata/vdobj.py +28 -17
- visidata/windows.py +10 -0
- visidata/wrappers.py +9 -3
- visidata-3.0.data/data/share/applications/visidata.desktop +7 -0
- {visidata-2.11.dev0.data → visidata-3.0.data}/data/share/man/man1/vd.1 +302 -147
- {visidata-2.11.dev0.data → visidata-3.0.data}/data/share/man/man1/visidata.1 +302 -147
- visidata-3.0.data/scripts/vd2to3.vdx +9 -0
- {visidata-2.11.dev0.dist-info → visidata-3.0.dist-info}/METADATA +13 -11
- visidata-3.0.dist-info/RECORD +257 -0
- {visidata-2.11.dev0.dist-info → visidata-3.0.dist-info}/WHEEL +1 -1
- {visidata-2.11.dev0.dist-info → visidata-3.0.dist-info}/entry_points.txt +0 -1
- visidata/layout.py +0 -44
- visidata/misc.py +0 -5
- visidata-2.11.dev0.dist-info/RECORD +0 -142
- /visidata/{repeat.py → features/repeat.py} +0 -0
- {visidata-2.11.dev0.data → visidata-3.0.data}/scripts/vd +0 -0
- {visidata-2.11.dev0.dist-info → visidata-3.0.dist-info}/LICENSE.gpl3 +0 -0
- {visidata-2.11.dev0.dist-info → visidata-3.0.dist-info}/top_level.txt +0 -0
visidata/ddw/input.ddw
CHANGED
@@ -1,79 +1,67 @@
|
|
1
|
-
{"x":
|
2
|
-
{"x":
|
3
|
-
{"x":
|
4
|
-
{"x": 11, "y":
|
5
|
-
{"x":
|
6
|
-
{"x":
|
7
|
-
{"x":
|
8
|
-
{"x":
|
9
|
-
{"x":
|
10
|
-
{"x":
|
11
|
-
{"x":
|
12
|
-
{"x":
|
13
|
-
{"x": 45, "y":
|
14
|
-
{"x":
|
15
|
-
{"x": 45, "y":
|
16
|
-
{"x":
|
17
|
-
{"x": 45, "y":
|
18
|
-
{"x":
|
19
|
-
{"x":
|
20
|
-
{"x":
|
21
|
-
{"x":
|
22
|
-
{"x":
|
23
|
-
{"x":
|
24
|
-
{"x":
|
25
|
-
{"x":
|
26
|
-
{"x":
|
27
|
-
{"x":
|
28
|
-
{"x":
|
29
|
-
{"x":
|
30
|
-
{"x":
|
31
|
-
{"x":
|
32
|
-
{"x":
|
33
|
-
{"x":
|
34
|
-
{"x":
|
35
|
-
{"x":
|
36
|
-
{"x":
|
37
|
-
{"x":
|
38
|
-
{"x":
|
39
|
-
{"x":
|
40
|
-
{"x":
|
41
|
-
{"x":
|
42
|
-
{"x":
|
43
|
-
{"x":
|
44
|
-
{"x":
|
45
|
-
{"x":
|
46
|
-
{"x":
|
47
|
-
{"x":
|
48
|
-
{"x":
|
49
|
-
{"x":
|
50
|
-
{"x":
|
51
|
-
{"x":
|
52
|
-
{"x":
|
53
|
-
{"x":
|
54
|
-
{"x":
|
55
|
-
{"x":
|
56
|
-
{"x":
|
57
|
-
{"x":
|
58
|
-
{"x":
|
59
|
-
{"x":
|
60
|
-
{"x":
|
61
|
-
{"x":
|
62
|
-
{"x":
|
63
|
-
{"x":
|
64
|
-
{"x":
|
65
|
-
{"x": 5, "y": 11, "text": "\u2192", "color": "bold white on 237", "tags": [], "group": ""}
|
66
|
-
{"x": 11, "y": 11, "text": "go to next word", "color": "", "tags": [], "group": ""}
|
67
|
-
{"x": 11, "y": 9, "text": "go to end of input", "color": "", "tags": [], "group": ""}
|
68
|
-
{"x": 11, "y": 7, "text": "go to next char", "color": "", "tags": [], "group": ""}
|
69
|
-
{"x": 11, "y": 13, "text": "next input history", "color": "", "tags": [], "group": ""}
|
70
|
-
{"x": 11, "y": 14, "text": "prev input history", "color": "", "tags": [], "group": ""}
|
71
|
-
{"x": 11, "y": 15, "text": "next autocomplete", "color": "", "tags": [], "group": ""}
|
72
|
-
{"x": 11, "y": 16, "text": "prev autocomplete", "color": "", "tags": [], "group": ""}
|
73
|
-
{"x": 4, "y": 4, "text": "+", "color": "", "tags": [], "group": ""}
|
74
|
-
{"x": 5, "y": 4, "text": "C", "color": "bold white on 237", "tags": [], "group": ""}
|
75
|
-
{"x": 5, "y": 16, "text": "+", "color": "", "tags": [], "group": ""}
|
76
|
-
{"x": 6, "y": 16, "text": "Tab", "color": "bold white on 237", "tags": [], "group": ""}
|
1
|
+
{"id": null, "type": null, "x": 6, "y": 7, "text": "\u2190", "color": "keystrokes", "tags": [], "group": "", "frame": null, "rows": null, "duration_ms": null, "ref": null, "onclick": null}
|
2
|
+
{"x": 11, "y": 7, "text": "go to prev/next char", "color": "", "tags": [], "group": ""}
|
3
|
+
{"x": 3, "y": 4, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
4
|
+
{"x": 11, "y": 4, "text": "cancel input (abort)", "color": "", "tags": [], "group": ""}
|
5
|
+
{"x": 45, "y": 4, "text": "delete one char at cursor", "color": "", "tags": [], "group": ""}
|
6
|
+
{"x": 45, "y": 5, "text": "delete one char before cursor", "color": "", "tags": [], "group": ""}
|
7
|
+
{"x": 0, "y": 13, "text": "Shift", "color": "keystrokes", "tags": [], "group": ""}
|
8
|
+
{"x": 4, "y": 3, "text": "Enter", "color": "keystrokes", "tags": [], "group": ""}
|
9
|
+
{"x": 11, "y": 3, "text": "accept input", "color": "", "tags": [], "group": ""}
|
10
|
+
{"x": 42, "y": 6, "text": "K", "color": "keystrokes", "tags": [], "group": ""}
|
11
|
+
{"x": 45, "y": 6, "text": "delete all before/after cursor", "color": "", "tags": [], "group": ""}
|
12
|
+
{"x": 42, "y": 12, "text": "O", "color": "keystrokes", "tags": [], "group": ""}
|
13
|
+
{"x": 45, "y": 12, "text": "open input in external editor", "color": "", "tags": [], "group": ""}
|
14
|
+
{"x": 42, "y": 13, "text": "R", "color": "keystrokes", "tags": [], "group": ""}
|
15
|
+
{"x": 45, "y": 13, "text": "restore starting value", "color": "", "tags": [], "group": ""}
|
16
|
+
{"x": 42, "y": 8, "text": "T", "color": "keystrokes", "tags": [], "group": ""}
|
17
|
+
{"x": 45, "y": 8, "text": "swap last two chars", "color": "", "tags": [], "group": ""}
|
18
|
+
{"x": 40, "y": 6, "text": "U", "color": "keystrokes", "tags": [], "group": ""}
|
19
|
+
{"x": 42, "y": 9, "text": "V", "color": "keystrokes", "tags": [], "group": ""}
|
20
|
+
{"x": 45, "y": 9, "text": "insert literal char", "color": "", "tags": [], "group": ""}
|
21
|
+
{"x": 42, "y": 7, "text": "W", "color": "keystrokes", "tags": [], "group": ""}
|
22
|
+
{"x": 45, "y": 7, "text": "delete one word before cursor", "color": "", "tags": [], "group": ""}
|
23
|
+
{"x": 42, "y": 11, "text": "Y", "color": "keystrokes", "tags": [], "group": ""}
|
24
|
+
{"x": 45, "y": 11, "text": "insert clipboard text at cursor", "color": "", "tags": [], "group": ""}
|
25
|
+
{"x": 6, "y": 8, "text": "\u2190", "color": "keystrokes", "tags": [], "group": ""}
|
26
|
+
{"x": 11, "y": 8, "text": "go to prev/next word", "color": "", "tags": [], "group": ""}
|
27
|
+
{"x": 0, "y": 0, "text": "Begin typing to overwrite the starting value.", "color": "", "tags": [], "group": ""}
|
28
|
+
{"x": 0, "y": 1, "text": "(To edit the starting value, press a movement key first.)", "color": "", "tags": [], "group": ""}
|
29
|
+
{"x": 6, "y": 11, "text": "\u2191", "color": "keystrokes", "tags": [], "group": ""}
|
30
|
+
{"x": 1, "y": 9, "text": "Home", "color": "keystrokes", "tags": [], "group": ""}
|
31
|
+
{"x": 11, "y": 9, "text": "go to start/end", "color": "", "tags": [], "group": ""}
|
32
|
+
{"x": 6, "y": 9, "text": "End", "color": "keystrokes", "tags": [], "group": ""}
|
33
|
+
{"x": 8, "y": 7, "text": "\u2192", "color": "keystrokes", "tags": [], "group": ""}
|
34
|
+
{"x": 37, "y": 4, "text": "Delete", "color": "keystrokes", "tags": [], "group": ""}
|
35
|
+
{"x": 34, "y": 5, "text": "Backspace", "color": "keystrokes", "tags": [], "group": ""}
|
36
|
+
{"x": 37, "y": 3, "text": "Insert", "color": "keystrokes", "tags": [], "group": ""}
|
37
|
+
{"x": 45, "y": 3, "text": "toggle insert mode", "color": "", "tags": [], "group": ""}
|
38
|
+
{"x": 6, "y": 12, "text": "Tab", "color": "keystrokes", "tags": [], "group": ""}
|
39
|
+
{"x": 1, "y": 8, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
40
|
+
{"x": 35, "y": 6, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
41
|
+
{"x": 37, "y": 8, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
42
|
+
{"x": 37, "y": 7, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
43
|
+
{"x": 37, "y": 9, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
44
|
+
{"x": 37, "y": 11, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
45
|
+
{"x": 37, "y": 12, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
46
|
+
{"x": 37, "y": 13, "text": "Ctrl", "color": "keystrokes", "tags": [], "group": ""}
|
47
|
+
{"x": 5, "y": 8, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
48
|
+
{"x": 39, "y": 6, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
49
|
+
{"x": 41, "y": 7, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
50
|
+
{"x": 41, "y": 8, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
51
|
+
{"x": 41, "y": 9, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
52
|
+
{"x": 41, "y": 11, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
53
|
+
{"x": 41, "y": 12, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
54
|
+
{"x": 41, "y": 13, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
55
|
+
{"x": 11, "y": 11, "text": "prev/next in history", "color": "", "tags": [], "group": ""}
|
56
|
+
{"x": 11, "y": 12, "text": "next autocomplete", "color": "", "tags": [], "group": ""}
|
57
|
+
{"x": 11, "y": 13, "text": "prev autocomplete", "color": "", "tags": [], "group": ""}
|
58
|
+
{"x": 7, "y": 4, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
59
|
+
{"x": 8, "y": 4, "text": "C", "color": "keystrokes", "tags": [], "group": ""}
|
60
|
+
{"x": 5, "y": 13, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
61
|
+
{"x": 6, "y": 13, "text": "Tab", "color": "keystrokes", "tags": [], "group": ""}
|
62
|
+
{"x": 32, "y": 3, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
63
|
+
{"x": 32, "y": 4, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
64
|
+
{"x": 32, "y": 5, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
77
65
|
{"x": 32, "y": 6, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
78
66
|
{"x": 32, "y": 7, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
79
67
|
{"x": 32, "y": 8, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
@@ -82,6 +70,13 @@
|
|
82
70
|
{"x": 32, "y": 11, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
83
71
|
{"x": 32, "y": 12, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
84
72
|
{"x": 32, "y": 13, "text": "\u2502", "color": "", "tags": [], "group": ""}
|
85
|
-
{"x":
|
86
|
-
{"x":
|
87
|
-
{"x":
|
73
|
+
{"x": 7, "y": 7, "text": "/", "color": "", "tags": [], "group": ""}
|
74
|
+
{"x": 5, "y": 9, "text": "/", "color": "", "tags": [], "group": ""}
|
75
|
+
{"x": 8, "y": 8, "text": "\u2192", "color": "keystrokes", "tags": [], "group": ""}
|
76
|
+
{"x": 8, "y": 11, "text": "\u2193", "color": "keystrokes", "tags": [], "group": ""}
|
77
|
+
{"x": 41, "y": 6, "text": "/", "color": "", "tags": [], "group": ""}
|
78
|
+
{"x": 7, "y": 11, "text": "/", "color": "", "tags": [], "group": ""}
|
79
|
+
{"x": 7, "y": 8, "text": "/", "color": "", "tags": [], "group": ""}
|
80
|
+
{"x": 75, "y": 0, "text": "?", "color": "bold 117 cyan", "tags": [], "group": "", "onclick": "https://visidata.org/input"}
|
81
|
+
{"x": 3, "y": 5, "text": "Ctrl+G", "color": "keystrokes", "tags": [], "group": ""}
|
82
|
+
{"x": 11, "y": 5, "text": "cycle help sidebar", "color": "", "tags": [], "group": ""}
|
visidata/ddw/regex.ddw
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
{"id": null, "type": null, "x": 5, "y": 1, "text": ".", "color": "keystrokes", "tags": [], "group": "", "frame": null, "rows": null, "duration_ms": null, "ref": null, "href": null}
|
2
|
+
{"x": 5, "y": 2, "text": "^", "color": "keystrokes", "tags": [], "group": ""}
|
3
|
+
{"x": 5, "y": 3, "text": "$", "color": "keystrokes", "tags": [], "group": ""}
|
4
|
+
{"x": 38, "y": 1, "text": "*", "color": "keystrokes", "tags": [], "group": ""}
|
5
|
+
{"x": 38, "y": 2, "text": "+", "color": "keystrokes", "tags": [], "group": ""}
|
6
|
+
{"x": 38, "y": 3, "text": "?", "color": "keystrokes", "tags": [], "group": ""}
|
7
|
+
{"x": 34, "y": 5, "text": "{m,n}", "color": "keystrokes", "tags": [], "group": ""}
|
8
|
+
{"x": 8, "y": 1, "text": "any char except newline", "color": "", "tags": [], "group": ""}
|
9
|
+
{"x": 8, "y": 2, "text": "start of string", "color": "", "tags": [], "group": ""}
|
10
|
+
{"x": 8, "y": 3, "text": "end of string", "color": "", "tags": [], "group": ""}
|
11
|
+
{"x": 42, "y": 1, "text": "0 or more", "color": "", "tags": [], "group": ""}
|
12
|
+
{"x": 42, "y": 2, "text": "1 or more", "color": "", "tags": [], "group": ""}
|
13
|
+
{"x": 42, "y": 3, "text": "0 or 1", "color": "", "tags": [], "group": ""}
|
14
|
+
{"x": 42, "y": 5, "text": "between m and n", "color": "", "tags": [], "group": ""}
|
15
|
+
{"x": 1, "y": 11, "text": "[abc]", "color": "keystrokes", "tags": [], "group": ""}
|
16
|
+
{"x": 0, "y": 12, "text": "[^abc]", "color": "keystrokes", "tags": [], "group": ""}
|
17
|
+
{"x": 4, "y": 4, "text": "\\d", "color": "keystrokes", "tags": [], "group": ""}
|
18
|
+
{"x": 4, "y": 6, "text": "\\s", "color": "keystrokes", "tags": [], "group": ""}
|
19
|
+
{"x": 4, "y": 8, "text": "\\w", "color": "keystrokes", "tags": [], "group": ""}
|
20
|
+
{"x": 8, "y": 4, "text": "digit char", "color": "", "tags": [], "group": ""}
|
21
|
+
{"x": 8, "y": 6, "text": "whitespace char", "color": "", "tags": [], "group": ""}
|
22
|
+
{"x": 4, "y": 10, "text": "\\b", "color": "keystrokes", "tags": [], "group": ""}
|
23
|
+
{"x": 8, "y": 10, "text": "word boundary", "color": "", "tags": [], "group": ""}
|
24
|
+
{"x": 8, "y": 8, "text": "word char", "color": "", "tags": [], "group": ""}
|
25
|
+
{"x": 18, "y": 8, "text": "[a-zA-Z0-9_]", "color": "keystrokes", "tags": [], "group": ""}
|
26
|
+
{"x": 36, "y": 7, "text": "(\u2026)", "color": "keystrokes", "tags": [], "group": ""}
|
27
|
+
{"x": 34, "y": 8, "text": "(?:\u2026)", "color": "keystrokes", "tags": [], "group": ""}
|
28
|
+
{"x": 8, "y": 11, "text": "any of", "color": "", "tags": [], "group": ""}
|
29
|
+
{"x": 15, "y": 11, "text": "a", "color": "keystrokes", "tags": [], "group": ""}
|
30
|
+
{"x": 17, "y": 11, "text": "or", "color": "", "tags": [], "group": ""}
|
31
|
+
{"x": 20, "y": 11, "text": "b", "color": "keystrokes", "tags": [], "group": ""}
|
32
|
+
{"x": 22, "y": 11, "text": "or", "color": "", "tags": [], "group": ""}
|
33
|
+
{"x": 25, "y": 11, "text": "c", "color": "keystrokes", "tags": [], "group": ""}
|
34
|
+
{"x": 19, "y": 4, "text": "[0-9]", "color": "keystrokes", "tags": [], "group": ""}
|
35
|
+
{"x": 42, "y": 7, "text": "capturing group", "color": "", "tags": [], "group": ""}
|
36
|
+
{"x": 42, "y": 8, "text": "non-capturing group", "color": "", "tags": [], "group": ""}
|
37
|
+
{"x": 9, "y": 12, "text": "", "color": "", "tags": [], "group": ""}
|
38
|
+
{"x": 8, "y": 12, "text": "not", "color": "", "tags": [], "group": ""}
|
39
|
+
{"x": 12, "y": 12, "text": "a", "color": "keystrokes", "tags": [], "group": ""}
|
40
|
+
{"x": 14, "y": 12, "text": "or", "color": "", "tags": [], "group": ""}
|
41
|
+
{"x": 17, "y": 12, "text": "b", "color": "keystrokes", "tags": [], "group": ""}
|
42
|
+
{"x": 19, "y": 12, "text": "or", "color": "", "tags": [], "group": ""}
|
43
|
+
{"x": 22, "y": 12, "text": "c", "color": "keystrokes", "tags": [], "group": ""}
|
44
|
+
{"x": 38, "y": 10, "text": "|", "color": "keystrokes", "tags": [], "group": ""}
|
45
|
+
{"x": 42, "y": 10, "text": "logical OR", "color": "", "tags": [], "group": ""}
|
46
|
+
{"x": 4, "y": 5, "text": "\\D", "color": "keystrokes", "tags": [], "group": ""}
|
47
|
+
{"x": 4, "y": 7, "text": "\\S", "color": "keystrokes", "tags": [], "group": ""}
|
48
|
+
{"x": 4, "y": 9, "text": "\\W", "color": "keystrokes", "tags": [], "group": ""}
|
49
|
+
{"x": 8, "y": 5, "text": "non-digit char", "color": "", "tags": [], "group": ""}
|
50
|
+
{"x": 8, "y": 7, "text": "non-whitespace char", "color": "", "tags": [], "group": ""}
|
51
|
+
{"x": 8, "y": 9, "text": "non-word char", "color": "", "tags": [], "group": ""}
|
52
|
+
{"x": 36, "y": 4, "text": "{m}", "color": "keystrokes", "tags": [], "group": ""}
|
53
|
+
{"x": 42, "y": 4, "text": "exactly m", "color": "", "tags": [], "group": ""}
|
54
|
+
{"x": 4, "y": 0, "text": "Character classes", "color": "bold underline", "tags": [], "group": ""}
|
55
|
+
{"x": 35, "y": 0, "text": "Repetition", "color": "bold underline", "tags": [], "group": ""}
|
56
|
+
{"x": 2, "y": 14, "text": "For full documentation on Python regular expressions, see", "color": "", "tags": [], "group": ""}
|
57
|
+
{"x": 6, "y": 15, "text": "https://docs.python.org/3/library/re.html", "color": "underline", "tags": [], "group": "", "href": "https://docs.python.org/3/library/re.html"}
|
visidata/ddwplay.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from collections import defaultdict
|
2
2
|
import json
|
3
3
|
import time
|
4
|
-
from visidata import colors, vd
|
4
|
+
from visidata import colors, vd, clipdraw, ColorAttr
|
5
5
|
|
6
6
|
__all__ = ['Animation', 'AnimationMgr']
|
7
7
|
|
@@ -31,24 +31,38 @@ class Animation:
|
|
31
31
|
self.width = 0
|
32
32
|
self.load_from(fp)
|
33
33
|
|
34
|
-
def iterdeep(self, rows, x=0, y=0, parents=None):
|
35
|
-
'Walk rows deeply and generate (row, x, y, [ancestors]) for each row.'
|
34
|
+
def iterdeep(self, rows, x=0, y=0, parents=None, **kwargs):
|
35
|
+
'Walk rows deeply and generate (row, x, y, [ancestors]) for each row, filtering on kwargs.'
|
36
36
|
for r in rows:
|
37
37
|
newparents = (parents or []) + [r]
|
38
38
|
if r.type == 'frame': continue
|
39
39
|
if r.ref:
|
40
40
|
assert r.type == 'ref'
|
41
41
|
g = self.groups[r.ref]
|
42
|
-
|
42
|
+
if self.matches(r, kwargs):
|
43
|
+
yield from self.iterdeep(map(AttrDict, g.rows or []), x+r.x, y+r.y, newparents)
|
43
44
|
else:
|
44
|
-
|
45
|
-
|
45
|
+
if self.matches(r, kwargs):
|
46
|
+
yield r, x+r.x, y+r.y, newparents
|
47
|
+
yield from self.iterdeep(map(AttrDict, r.rows or []), x+r.x, x+r.y, newparents)
|
48
|
+
|
49
|
+
def matches(self, row, values):
|
50
|
+
for k, v in values.items():
|
51
|
+
actualv = getattr(row, k, None)
|
52
|
+
if isinstance(actualv, (list, tuple)) and isinstance(v, (list, tuple)):
|
53
|
+
if not any(x in actualv for x in v):
|
54
|
+
return False
|
55
|
+
elif v != actualv:
|
56
|
+
return False
|
57
|
+
return True
|
46
58
|
|
47
59
|
def load_from(self, fp):
|
48
60
|
for line in fp.readlines():
|
49
61
|
r = AttrDict(json.loads(line))
|
50
62
|
if r.type == 'frame':
|
51
|
-
self.frames[r.id]
|
63
|
+
f = self.frames[r.id]
|
64
|
+
f.update(r)
|
65
|
+
f.rows = []
|
52
66
|
elif r.type == 'group':
|
53
67
|
self.groups[r.id].update(r)
|
54
68
|
|
@@ -66,9 +80,12 @@ class Animation:
|
|
66
80
|
self.width = max(self.width, x+len(r.text))
|
67
81
|
self.height = max(self.height, y)
|
68
82
|
|
69
|
-
def draw(self, scr, *, t=0, x=0, y=0, loop=False, **kwargs):
|
70
|
-
|
71
|
-
|
83
|
+
def draw(self, scr, *, t=0, x=0, y=0, loop=False, attr=ColorAttr(), **kwargs):
|
84
|
+
windowHeight, windowWidth = scr.getmaxyx()
|
85
|
+
for r, dx, dy, _ in self.iterdeep(self.frames[''].rows, **kwargs):
|
86
|
+
text = f'[:onclick {r.href}]{r.text}[/]' if r.href else r.text
|
87
|
+
if y+dy < windowHeight:
|
88
|
+
clipdraw(scr, y+dy, x+dx, text, attr.update(colors[r.color], 2))
|
72
89
|
|
73
90
|
if not self.total_ms:
|
74
91
|
return None
|
@@ -77,8 +94,10 @@ class Animation:
|
|
77
94
|
for f in self.frames.values():
|
78
95
|
ms -= int(f.duration_ms or 0)
|
79
96
|
if ms < 0:
|
80
|
-
for r, dx, dy, _ in self.iterdeep(f.rows):
|
81
|
-
|
97
|
+
for r, dx, dy, _ in self.iterdeep(f.rows, **kwargs):
|
98
|
+
text = f'[:onclick {r.href}]{r.text}[/]' if r.href else r.text
|
99
|
+
if y+dy < windowHeight:
|
100
|
+
clipdraw(scr, y+dy, x+dx, text, colors[r.color])
|
82
101
|
|
83
102
|
return -ms/1000
|
84
103
|
|
@@ -117,9 +136,9 @@ class AnimationMgr:
|
|
117
136
|
for row in self.active:
|
118
137
|
startt, anim, akwargs = row
|
119
138
|
kwargs.update(akwargs)
|
120
|
-
nextt = anim.draw(scr, t=t
|
139
|
+
nextt = anim.draw(scr, t=t+startt, **kwargs)
|
121
140
|
if nextt is None:
|
122
|
-
if not akwargs.get('loop'):
|
141
|
+
if not akwargs.get('loop', True):
|
123
142
|
done.append(row)
|
124
143
|
else:
|
125
144
|
times.append(t+nextt)
|
visidata/deprecated.py
CHANGED
@@ -73,7 +73,7 @@ visidata.Sheet.exec_command = deprecated('2.0')(visidata.Sheet.execCommand)
|
|
73
73
|
@VisiData.api
|
74
74
|
def filetype(vd, ext, constructor):
|
75
75
|
'Add constructor to handle the given file type/extension.'
|
76
|
-
globals().setdefault('open_'+ext, lambda p,ext=ext: constructor(p.
|
76
|
+
globals().setdefault('open_'+ext, lambda p,ext=ext: constructor(p.base_stem, source=p, filetype=ext))
|
77
77
|
|
78
78
|
@deprecated('2.0', 'Sheet(namepart1, namepart2, ...)')
|
79
79
|
@VisiData.global_api
|
@@ -135,11 +135,12 @@ alias('show-aggregate', 'memo-aggregate')
|
|
135
135
|
|
136
136
|
# 2.6
|
137
137
|
|
138
|
-
clean_name
|
138
|
+
def clean_name(s):
|
139
|
+
return visidata.vd.cleanName(s)
|
139
140
|
|
140
141
|
def maybe_clean(s, vs):
|
141
142
|
if (vs or visidata.vd).options.clean_names:
|
142
|
-
s = visidata.cleanName(s)
|
143
|
+
s = visidata.vd.cleanName(s)
|
143
144
|
return s
|
144
145
|
|
145
146
|
def load_tsv(fn):
|
@@ -164,3 +165,76 @@ exceptionCaught = deprecated('2.6', 'vd.exceptionCaught')(vd.exceptionCaught)
|
|
164
165
|
openSource = deprecated('2.6', 'vd.openSource')(vd.openSource)
|
165
166
|
globalCommand = visidata.BaseSheet.addCommand
|
166
167
|
visidata.Sheet.StaticColumn = deprecated('2.11', 'Sheet.freeze_col')(visidata.Sheet.freeze_col)
|
168
|
+
visidata.Path.open_text = deprecated('3.0', 'visidata.Path.open')(visidata.Path.open)
|
169
|
+
|
170
|
+
vd.sysclip_value = deprecated('3.0', 'vd.sysclipValue')(vd.sysclipValue)
|
171
|
+
|
172
|
+
def itemsetter(i):
|
173
|
+
def g(obj, v):
|
174
|
+
obj[i] = v
|
175
|
+
return g
|
176
|
+
|
177
|
+
|
178
|
+
vd.optalias('force_valid_colnames', 'clean_names')
|
179
|
+
vd.optalias('dir_recurse', 'dir_depth', 100000)
|
180
|
+
vd.optalias('confirm_overwrite', 'overwrite', 'confirm')
|
181
|
+
vd.optalias('show_graph_labels', 'disp_graph_labels')
|
182
|
+
vd.optalias('zoom_incr', 'disp_zoom_incr')
|
183
|
+
|
184
|
+
alias('visibility-sheet', 'toggle-multiline')
|
185
|
+
alias('visibility-col', 'toggle-multiline')
|
186
|
+
|
187
|
+
def clean_to_id(s):
|
188
|
+
return visidata.vd.cleanName(s)
|
189
|
+
|
190
|
+
@deprecated('3.0', 'use try/finally')
|
191
|
+
class OnExit:
|
192
|
+
'"with OnExit(func, ...):" calls func(...) when the context is exited'
|
193
|
+
def __init__(self, func, *args, **kwargs):
|
194
|
+
self.func = func
|
195
|
+
self.args = args
|
196
|
+
self.kwargs = kwargs
|
197
|
+
|
198
|
+
def __enter__(self):
|
199
|
+
return self
|
200
|
+
|
201
|
+
def __exit__(self, exc_type, exc_value, exc_traceback):
|
202
|
+
try:
|
203
|
+
self.func(*self.args, **self.kwargs)
|
204
|
+
except Exception as e:
|
205
|
+
vd.exceptionCaught(e)
|
206
|
+
|
207
|
+
alias('open-inputs', 'open-input-history')
|
208
|
+
|
209
|
+
#vd.option('plugins_url', 'https://visidata.org/plugins/plugins.jsonl', 'source of plugins sheet')
|
210
|
+
|
211
|
+
@visidata.VisiData.api
|
212
|
+
def inputRegexSubstOld(vd, prompt):
|
213
|
+
'Input regex transform via oneliner (separated with `/`). Return parsed transformer as dict(before=, after=).'
|
214
|
+
rex = vd.inputRegex(prompt, type='regex-subst')
|
215
|
+
before, after = vd.parse_sed_transform(rex)
|
216
|
+
return dict(before=before, after=after)
|
217
|
+
|
218
|
+
|
219
|
+
visidata.Sheet.addCommand('', 'addcol-subst', 'addColumnAtCursor(Column(cursorCol.name + "_re", getter=regexTransform(cursorCol, **inputRegexSubstOld("transform column by regex: "))))', 'add column derived from current column, replacing regex with subst (may include \1 backrefs)', deprecated=True)
|
220
|
+
visidata.Sheet.addCommand('', 'setcol-subst', 'setValuesFromRegex([cursorCol], someSelectedRows, **inputRegexSubstOld("transform column by regex: "))', 'regex/subst - modify selected rows in current column, replacing regex with subst, (may include backreferences \\1 etc)', deprecated=True)
|
221
|
+
visidata.Sheet.addCommand('', 'setcol-subst-all', 'setValuesFromRegex(visibleCols, someSelectedRows, **inputRegexSubstOld(f"transform {nVisibleCols} columns by regex: "))', 'modify selected rows in all visible columns, replacing regex with subst (may include \\1 backrefs)', deprecated=True)
|
222
|
+
|
223
|
+
visidata.Sheet.addCommand('', 'split-col', 'addRegexColumns(makeRegexSplitter, cursorCol, inputRegex("split regex: ", type="regex-split"))', 'Add new columns from regex split', deprecated=True)
|
224
|
+
visidata.Sheet.addCommand('', 'capture-col', 'addRegexColumns(makeRegexMatcher, cursorCol, inputRegex("capture regex: ", type="regex-capture"))', 'add new column from capture groups of regex; requires example row', deprecated=True)
|
225
|
+
|
226
|
+
#vd.option('cmdlog_histfile', '', 'file to autorecord each cmdlog action to', sheettype=None)
|
227
|
+
#BaseSheet.bindkey('KEY_BACKSPACE', 'menu-help')
|
228
|
+
|
229
|
+
@deprecated('3.0', 'vd.callNoExceptions(col.setValue, row, value)')
|
230
|
+
@visidata.Column.api
|
231
|
+
def setValueSafe(self, row, value):
|
232
|
+
'setValue and ignore exceptions.'
|
233
|
+
return vd.callNoExceptions(self.setValue, row, value)
|
234
|
+
|
235
|
+
@deprecated('3.0', 'vd.callNoExceptions(sheet.checkCursor)')
|
236
|
+
@visidata.BaseSheet.api
|
237
|
+
def checkCursorNoExceptions(sheet):
|
238
|
+
return vd.callNoExceptions(sheet.checkCursor)
|
239
|
+
|
240
|
+
vd.addGlobals(globals())
|
visidata/editor.py
CHANGED
@@ -12,14 +12,16 @@ visidata.vd.tstp_signal = None
|
|
12
12
|
class SuspendCurses:
|
13
13
|
'Context manager to leave windowed mode on enter and restore it on exit.'
|
14
14
|
def __enter__(self):
|
15
|
-
|
15
|
+
if visidata.vd.scrFull:
|
16
|
+
curses.endwin()
|
16
17
|
if visidata.vd.tstp_signal:
|
17
18
|
signal.signal(signal.SIGTSTP, visidata.vd.tstp_signal)
|
18
19
|
|
19
20
|
def __exit__(self, exc_type, exc_val, tb):
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
if visidata.vd.scrFull:
|
22
|
+
curses.reset_prog_mode()
|
23
|
+
visidata.vd.scrFull.refresh()
|
24
|
+
curses.doupdate()
|
23
25
|
|
24
26
|
|
25
27
|
@visidata.VisiData.api
|
@@ -34,7 +36,7 @@ def launchEditor(vd, *args):
|
|
34
36
|
@visidata.VisiData.api
|
35
37
|
def launchBrowser(vd, *args):
|
36
38
|
'Launch $BROWSER with *args* as arguments.'
|
37
|
-
browser = os.environ.get('BROWSER') or vd.fail('
|
39
|
+
browser = os.environ.get('BROWSER') or vd.fail('no $BROWSER for %s' % args[0])
|
38
40
|
args = [browser] + list(args)
|
39
41
|
subprocess.call(args)
|
40
42
|
|
@@ -44,6 +46,7 @@ def launchExternalEditor(vd, v, linenum=0):
|
|
44
46
|
'Launch $EDITOR to edit string *v* starting on line *linenum*.'
|
45
47
|
import tempfile
|
46
48
|
with tempfile.NamedTemporaryFile() as temp:
|
49
|
+
temp.close() #2118 must close before re-opening on windows
|
47
50
|
with open(temp.name, 'w') as fp:
|
48
51
|
fp.write(v)
|
49
52
|
return vd.launchExternalEditorPath(visidata.Path(temp.name), linenum)
|
@@ -65,7 +68,8 @@ def launchExternalEditorPath(vd, path, linenum=0):
|
|
65
68
|
return ''
|
66
69
|
|
67
70
|
|
68
|
-
|
71
|
+
@visidata.VisiData.api
|
72
|
+
def suspend(vd):
|
69
73
|
import signal
|
70
74
|
with SuspendCurses():
|
71
75
|
os.kill(os.getpid(), signal.SIGSTOP)
|
@@ -94,3 +98,5 @@ sys.breakpointhook = _breakpoint
|
|
94
98
|
|
95
99
|
visidata.BaseSheet.addCommand('^Z', 'suspend', 'suspend()', 'suspend VisiData process')
|
96
100
|
visidata.BaseSheet.addCommand('', 'breakpoint', 'breakpoint()', 'drop into pdb REPL')
|
101
|
+
|
102
|
+
visidata.vd.addGlobals(SuspendCurses=SuspendCurses)
|
visidata/errors.py
CHANGED
@@ -2,7 +2,8 @@ import traceback
|
|
2
2
|
|
3
3
|
from visidata import vd, VisiData, options
|
4
4
|
|
5
|
-
|
5
|
+
vd.option('debug', False, 'exit on error and display stacktrace', max_help=0)
|
6
|
+
|
6
7
|
|
7
8
|
class ExpectedException(Exception):
|
8
9
|
'Controlled Exception from fail() or confirm(). Status or other interface update is done by raiser.'
|
@@ -28,4 +29,7 @@ def exceptionCaught(vd, exc=None, status=True, **kwargs):
|
|
28
29
|
if vd.options.debug:
|
29
30
|
raise
|
30
31
|
|
32
|
+
|
33
|
+
vd.addGlobals(stacktrace=stacktrace, ExpectedException=ExpectedException)
|
34
|
+
|
31
35
|
# see textsheet.py for ErrorSheet and associated commands
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# command setdiff-sheet adds a diff colorizer for all sheets against current sheet
|
2
|
+
|
3
|
+
from visidata import Sheet, CellColorizer, vd
|
4
|
+
|
5
|
+
vd.theme_option('color_diff', 'red', 'color of values different from --diff source')
|
6
|
+
vd.theme_option('color_diff_add', 'yellow', 'color of rows/columns added to --diff source')
|
7
|
+
|
8
|
+
|
9
|
+
def makeDiffColorizer(othersheet):
|
10
|
+
def colorizeDiffs(sheet, col, row, cellval):
|
11
|
+
if row is None or col is None:
|
12
|
+
return None
|
13
|
+
vcolidx = sheet.visibleCols.index(col)
|
14
|
+
rowidx = sheet.rows.index(row)
|
15
|
+
if vcolidx < len(othersheet.visibleCols) and rowidx < len(othersheet.rows):
|
16
|
+
otherval = othersheet.visibleCols[vcolidx].getDisplayValue(othersheet.rows[rowidx])
|
17
|
+
if cellval.display != otherval:
|
18
|
+
return 'color_diff'
|
19
|
+
else:
|
20
|
+
return 'color_diff_add'
|
21
|
+
return colorizeDiffs
|
22
|
+
|
23
|
+
|
24
|
+
@Sheet.api
|
25
|
+
def setDiffSheet(vs):
|
26
|
+
Sheet.colorizers.append(CellColorizer(8, None, makeDiffColorizer(vs)))
|
27
|
+
|
28
|
+
|
29
|
+
Sheet.addCommand(None, 'setdiff-sheet', 'setDiffSheet()', 'set this sheet as diff sheet for all new sheets')
|
@@ -0,0 +1,6 @@
|
|
1
|
+
'Enter edit mode automatically when typing numeric digits.'
|
2
|
+
|
3
|
+
from visidata import Sheet
|
4
|
+
|
5
|
+
for i in range(0, 10):
|
6
|
+
Sheet.addCommand(str(i), 'autoedit-%s' % i, 'cursorCol.setValues([cursorRow], editCell(cursorVisibleColIndex, value="%s", i=1))' % i, 'replace cell value with input starting with %s' % i)
|