/usr/bin/vd is in visidata 1.0-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #!/usr/bin/python3
#
# Usage: $0 [<options>] [<input> ...]
# $0 [<options>] --play <cmdlog> [--batch] [-w <waitsecs>] [-o <output>] [field=value ...]
__version__ = 'saul.pw/VisiData v1.0'
import os
from visidata import *
option('color_diff', 'red', 'color of values different from --diff source')
option('color_diff_add', 'yellow', 'color of rows/columns added to --diff source')
# for --play
def eval_vd(logpath, *args, **kwargs):
'Instantiate logpath with args/kwargs replaced and replay all commands.'
log = logpath.read_text().format(*args, **kwargs)
src = PathFd(logpath.fqpn, io.StringIO(log), filesize=len(log))
vs = openSource(src, filetype='vd')
vd().push(vs)
vs.vd = vd()
return vs
# for --diff
def makeDiffColorizer(othersheet):
def colorizeDiffs(sheet, col, row, cellval):
vcolidx = sheet.visibleCols.index(col)
rowidx = sheet.rows.index(row)
if vcolidx < len(othersheet.visibleCols) and rowidx < len(othersheet.rows):
otherval = othersheet.visibleCols[vcolidx].getValue(othersheet.rows[rowidx])
if cellval.value != otherval:
return options.color_diff
else:
return options.color_diff_add
return colorizeDiffs
def main():
'Open the given sources using the VisiData interface.'
import argparse
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('inputs', nargs='*', help='initial sources')
parser.add_argument('-f', dest='filetype', default='', help='uses loader for filetype instead of file extension')
parser.add_argument('-y', dest='confirm_overwrite', default=True, action='store_false', help='overwrites existing files without confirmation')
parser.add_argument('-p', '--play', dest='play', default=None, help='replays a saved .vd file within the interface')
parser.add_argument('-b', '--batch', dest='batch', action='store_true', default=False, help='replays in batch mode (with no interface and all status sent to stdout)')
parser.add_argument('-o', '--output', dest='output', default=None, help='saves the final visible sheet to output (as .tsv) at the end of replay')
parser.add_argument('-w', dest='replay_wait', default=0, help='time to wait between replayed commands, in seconds')
parser.add_argument('-d', dest='delimiter', help='delimiter to use for tsv filetype')
parser.add_argument('--diff', dest='diff', default=None, help='show diffs from all sheets against this source')
parser.add_argument('-v', '--version', action='version', version=__version__)
for optname, v in vdtui.baseOptions.items():
name, optval, defaultval, helpstr = v
if name.startswith('color_') or name.startswith('disp_'):
continue
action = 'store_true' if optval is False else 'store'
parser.add_argument('--' + optname.replace('_', '-'), action=action, dest=optname, default=None, help=helpstr)
args = parser.parse_args()
# user customisations in config file in standard location
fnrc = '~/.visidatarc'
p = Path(fnrc)
if p.exists():
code = compile(open(p.resolve()).read(), p.resolve(), 'exec')
exec(code, globals())
vdtui.addGlobals(globals())
# command-line overrides
for optname, optval in vars(args).items():
if optval is not None and optname not in ['inputs', 'play', 'batch', 'output', 'diff']:
vdtui.options[optname] = optval
stdinSource = None
if not sys.stdin.isatty():
# duplicate stdin for input and reopen tty as stdin
stdinSource = PathFd('stdin', open(os.dup(0)))
f = open('/dev/tty')
os.dup2(f.fileno(), 0)
startrow, startcol = None, None
fmtargs = []
fmtkwargs = {}
inputs = []
for arg in args.inputs:
if arg.startswith('+'): # position cursor at start
if ':' in arg:
startrow, startcol = arg[1:].split(':')
else:
startrow = arg[1:]
elif '=' in arg:
# parse 'key=value' pairs for formatting cmdlog template in replay mode
k, v = arg.split('=')
fmtkwargs[k] = v
elif arg == '-':
inputs.append(stdinSource)
else:
inputs.append(arg)
fmtargs.append(arg)
if stdinSource and stdinSource not in inputs: # '|vd' without explicit '-'
inputs.append(stdinSource)
if args.diff:
vs = openSource(args.diff)
vd().push(vs)
Sheet.colorizers.append(Colorizer("cell", 8, makeDiffColorizer(vs)))
if not args.play:
if not inputs:
inputs = ['.']
sources = []
for src in inputs:
vs = openSource(src)
vdtui.vd().cmdlog.openHook(vs, src)
sources.append(vs)
if startrow is not None:
vs.cursorRowIndex = int(startrow)-1
if startcol is not None:
vs.cursorVisibleColIndex = int(startcol)-1
vdtui.run(*sources)
return
if args.play == '-':
vdfile = stdinSource
assert isinstance(vdfile, PathFd)
vdfile.name = 'stdin.vd'
else:
vdfile = Path(args.play)
vs = eval_vd(vdfile, *fmtargs, **fmtkwargs)
if args.batch:
vd().status = print
vd().execAsync = lambda func, *args, **kwargs: func(*args, **kwargs) # disable async
vs.replay_sync()
if args.output:
saveSheet(vd().sheets[0], args.output, confirm_overwrite=False)
sync()
else:
vs.replay()
run()
if __name__ == '__main__':
vdtui.status(__version__)
main()
os._exit(0) # cleanup can be expensive with large datasets
|