Esempio n. 1
0
def cursesMain(_scr, sheetlist):
    'Populate VisiData object with sheets from a given list.'

    colors.setup()

    for vs in sheetlist:
        vd.push(vs)

    vd.status('Ctrl+H opens help')
    return vd.mainloop(_scr)
Esempio n. 2
0
def eval_vd(logpath, *args, **kwargs):
    'Instantiate logpath with args/kwargs replaced and replay all commands.'
    log = logpath.read_text()
    if args or kwargs:
        log = log.format(*args, **kwargs)

    src = Path(logpath.given, fp=io.StringIO(log), filesize=len(log))
    vs = openSource(src, filetype=src.ext)
    vs.name += '_vd'
    vd.push(vs)
    vs.vd = vd
    return vs
Esempio n. 3
0
def dedupe_rows(sheet):
    """
    Given a sheet, pushes a new sheet in which only non-duplicate rows are
    included.
    """
    vs = copy(sheet)
    vs.name += "_deduped"
    vd.push(vs)

    for row, is_dupe in gen_identify_duplicates(sheet):
        if is_dupe == False:
            vs.addRow(row)
Esempio n. 4
0
    def join_rows(self, rows):
        """Open new sheets for the target rows and concatenate their contents."""
        sheets = list(self.open_rows(rows))
        for sheet in vd.Progress(sheets):
            sheet.reload()

        # Wait for all sheets to fully load before joining them.
        # 'append' is the only join type that makes sense here,
        # since we're joining freshly opened sheets with no key
        # columns.
        vd.sync()
        vd.push(vd.createJoinedSheet(sheets, jointype="append"))
Esempio n. 5
0
def _replaceDetailSheet(parentRowIdx, openCommand, placeholder):
    '''
    Try to refresh a child window with data from the given parent
    row.
    '''
    if vd.sheet is placeholder or openCommand in (
            cmd.longname for cmd in vd.sheet.cmdlog_sheet.rows):
        parent = vd.sheets[1]
        vd.remove(vd.sheet)
        parent.cursorRowIndex = parentRowIdx
        parent.execCommand(openCommand)
        if vd.sheet is parent and _noContent():
            vd.push(NoContentPlaceholder.emptyCellSheet)
        return vd.sheet
def _replaceDetailSheet(parentRowIdx, entityType):
    """
    Try to refresh a child window with data from a given parent
    entity (row or cell).
    """
    placeholder = _placeholderSheet(entityType)
    openCommand = f"open-{entityType}"

    if vd.sheet is placeholder or openCommand in (
            cmd.longname for cmd in vd.sheet.cmdlog_sheet.rows):
        parent = vd.sheets[1]
        vd.remove(vd.sheet)
        parent.cursorRowIndex = parentRowIdx
        parent.execCommand(openCommand)
        if vd.sheet is parent and _noContentStatus():
            vd.push(placeholder)
        return vd.sheet
Esempio n. 7
0
def dedupe_rows(sheet):
    """
    Given a sheet, pushes a new sheet in which only non-duplicate rows are
    included.
    """
    vs = copy(sheet)
    vs.name += "_deduped"

    @asyncthread
    def _reload(self=vs):
        self.rows = []
        gen = gen_identify_duplicates(sheet)
        prog = Progress(gen, gerund="deduplicating", total=sheet.nRows)
        for row, is_dupe in prog:
            if not is_dupe:
                self.addRow(row)

    vs.reload = _reload
    vd.push(vs)
Esempio n. 8
0
    def dive(self):
        if self.is_keyvalue:
            cell = self.cursorRow["value"]
            name = joinSheetnames(self.name, self.cursorRow["key"])

            if isinstance(cell, (list, dict)):
                vs = self.__class__(name, source=cell)
            else:
                warning("Nothing to dive into.")
                return
        else:
            name = joinSheetnames(self.name, "row")
            vs = self.__class__(name, source=self.cursorRow)

        success = vs.reload()
        if success == False:
            return

        vd.push(vs)
Esempio n. 9
0
def main_vd():
    '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=None, 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('-P', dest='preplay', action='append', default=[], help='VisiData command to preplay before cmdlog replay')
    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 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/usv 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_info__)

    args = vd.parseArgs(parser)

    # fetch motd and plugins *after* options parsing/setting
    visidata.PluginsSheet().reload()
    domotd()

    locale.setlocale(locale.LC_ALL, '')

    flPipedInput = not sys.stdin.isatty()
    flPipedOutput = not sys.stdout.isatty()

    vd._stdin, vd._stdout = duptty()  # always dup stdin/stdout

    stdinSource = Path('-', fp=vd._stdin)

    # parse args, including +sheetname:subsheet:4:3 starting at row:col on sheetname:subsheet[:...]
    start_positions = []  # (list_of_sheetstr, str, str)  # empty sheetstr means all sheets
    startsheets, startrow, startcol = [], None, None
    fmtargs = []
    fmtkwargs = {}
    inputs = []
    for arg in args.inputs:
        if arg.startswith('+'):  # position cursor at start
            if ':' in arg:
                pos = arg[1:].split(':')
                if len(pos) == 1:
                    startsheet = [Path(inputs[-1]).name] if inputs else None
                    start_positions.append((startsheet, pos[0], None))
                elif len(pos) == 2:
                    startsheet = [Path(inputs[-1]).name] if inputs else None
                    startrow, startcol = pos
                    start_positions.append((None, startrow, startcol))
                elif len(pos) >= 3:
                    startsheets = pos[:-2]
                    startrow, startcol = pos[-2:]
                    start_positions.append((startsheets, startrow, startcol))
            else:
                start_positions.append((None, arg[1:], None))

        elif args.play and '=' 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 args.diff:
        vs = openSource(args.diff)
        vd.push(vs)
        vs.reload()
        setDiffSheet(vs)

    if args.batch:
        options.undo = False
        vd.status = lambda *args, **kwargs: print(*args, file=sys.stderr)  # ignore kwargs (like priority)
        vd.editline = lambda *args, **kwargs: ''
        vd.execAsync = lambda func, *args, **kwargs: func(*args, **kwargs) # disable async

    for cmd in args.preplay:
        Sheet('').exec_keystrokes(cmd)

    if not args.play:
        if flPipedInput and not inputs:  # '|vd' without explicit '-'
            inputs.append(stdinSource)

    sources = []
    for src in inputs:
        vs = openSource(src)
        vd.cmdlog.openHook(vs, src)
        sources.append(vs)

    vd.sheets.extend(sources)  # purposefully do not load everything

    if not vd.sheets and not args.play and not args.batch:
        vd.push(vd.vdmenu)

    if not args.play:
        if args.batch:
            vd.push(sources[0])
            sources[0].reload()

        for startsheets, startrow, startcol in start_positions:
            sheets = []  # sheets to apply startrow:startcol to
            if not startsheets:
                sheets = sources  # apply row/col to all sheets
            else:
                vs = vd.getSheet(startsheets[0]) or sources[-1]
                vd.sync(vs.ensureLoaded())
                vd.clearCaches()
                for startsheet in startsheets[1:]:
                    rowidx = vs.getRowIndexFromStr(startsheet)
                    if rowidx is None:
                        vs = None
                        vd.warning(f'no sheet "{startsheet}"')
                        break
                    vs = vs.rows[rowidx]
                    vd.sync(vs.ensureLoaded())
                    vd.clearCaches()
                if vs:
                    vd.push(vs)
                    sheets = [vs]

            if startrow:
                for vs in sheets:
                    if vs:
                        vs.moveToRow(startrow) or vd.warning(f'{vs} has no row "{startrow}"')

            if startcol:
                for vs in sheets:
                    if vs:
                        vs.moveToCol(startcol) or vd.warning(f'{vs} has no column "{startcol}"')

        if not args.batch:
            run(vd.sheets[0])
    else:
        if args.play == '-':
            vdfile = stdinSource
            vdfile.name = 'stdin.vd'
        else:
            vdfile = Path(args.play)

        vs = eval_vd(vdfile, *fmtargs, **fmtkwargs)
        vd.sync(vs.reload())
        if args.batch:
            if vd.replay_sync(vs):  # error
                return 1
        else:
            vd.replay(vs)
            run()

    if vd.sheets and (flPipedOutput or args.output):
        outpath = Path(args.output or '-')
        saveSheets(outpath, vd.sheets[0], confirm_overwrite=False)
        vd.sync()

    vd._stdout.flush()

    return 0
Esempio n. 10
0
 def dive(self):
     vs = DiveSheet(joinSheetnames(self.name, "detail"),
                    source=self.cursorRow)
     vs.reload()
     vd.push(vs)
Esempio n. 11
0
def replace(vd, vs):
    'Replace top sheet with the given sheet `vs`.'
    vd.sheets.pop(0)
    return vd.push(vs)