def draw(self, scr): 'Draw entire screen onto the `scr` curses object.' vd.clearCaches() if not self.columns: if options.debug: self.addColumn(Column()) else: return drawparams = { 'isNull': isNullFunc(), 'topsep': options.disp_rowtop_sep, 'midsep': options.disp_rowmid_sep, 'botsep': options.disp_rowbot_sep, 'endsep': options.disp_rowend_sep, 'keytopsep': options.disp_keytop_sep, 'keymidsep': options.disp_keymid_sep, 'keybotsep': options.disp_keybot_sep, 'endtopsep': options.disp_endtop_sep, 'endmidsep': options.disp_endmid_sep, 'endbotsep': options.disp_endbot_sep, 'colsep': options.disp_column_sep, 'keysep': options.disp_keycol_sep, 'selectednote': options.disp_selected_note, } self._rowLayout = {} # [rowidx] -> (y, height) self.calcColLayout() numHeaderRows = self.nHeaderRows vcolidx = 0 headerRow = 0 for vcolidx, colinfo in sorted(self._visibleColLayout.items()): self.drawColHeader(scr, headerRow, numHeaderRows, vcolidx) y = headerRow + numHeaderRows rows = self.rows[self.topRowIndex:min(self.topRowIndex+self.nScreenRows, self.nRows)] self.checkCursorNoExceptions() for rowidx, row in enumerate(rows): if y >= self.windowHeight-1: break rowcattr = self._colorize(None, row) y += self.drawRow(scr, row, self.topRowIndex+rowidx, y, rowcattr, maxheight=self.windowHeight-y, **drawparams) if vcolidx+1 < self.nVisibleCols: scr.addstr(headerRow, self.windowWidth-2, options.disp_more_right, colors.color_column_sep) scr.refresh()
def getValueRows(self, rows): 'Generate (val, row) for the given `rows` at this Column, excluding errors and nulls.' f = isNullFunc() for r in Progress(rows, 'calculating'): try: v = self.getTypedValue(r) if not f(v): yield v, r except Exception: pass
def _isNullFunc(): """ isNullFunc is available as a sheet property in newer VisiData releases, but was previously a function in the "visidata" module. Try to use the sheet property, but fall back to support earlier versions. """ try: return vd.sheet.isNullFunc() except AttributeError: import visidata return visidata.isNullFunc()
def autofake(cols, rows): ''' Try to guess an appropriate vfake faketype for a given column and row set. If we find a match, run with it. NO REGERTS. ''' isNull = isNullFunc() for col in cols: faketype = None with suppress(StopIteration): next(r for r in rows if not isNull(hint := col.getValue(r))) faketype = next(v for k, v in faketype_mapping.items() if k(str(hint), col.name))
def from_entries(col): ''' Convert values from lists of Key/Value pairs into a dict, similar to the from_entries function in jq. Abort if the specified column's value for any row is _not_ a list of Key/Value pairs. ''' sheet = col.sheet rows = sheet.rows key_keynames = ('key', 'name') NOT_FOUND = object() def _die(): sheet.columns.pop(new_idx) vd.fail(f'Columns {col.name} is not a list of Key/Value pairs') new_idx = sheet.columns.index(col) + 1 new_col = sheet.addColumn(SettableColumn(col.name), index=new_idx) isNull = isNullFunc() for row in rows: val = col.getValue(row) new_val = {} if isNull(val): continue if not isinstance(val, list): _die() for pair in val: col_key = col_value = NOT_FOUND for k, v in pair.items(): if k.lower() in key_keynames: col_key = v elif k.lower() == 'value': col_value = v if col_key is NOT_FOUND or col_value is NOT_FOUND: _die() new_val[col_key] = col_value new_col.setValue(row, new_val) col.hide() return new_col
def to_entries(col): ''' Convert values from a dict into a list of Key/Value pairs, similar to the to_entries function in jq: Abort if the specified column's value for any row is _not_ a dict. ''' sheet = col.sheet rows = sheet.rows new_idx = sheet.columns.index(col) + 1 new_col = sheet.addColumn(SettableColumn(col.name), index=new_idx) isNull = isNullFunc() for r in rows: val = col.getValue(r) if isNull(val): continue if not isinstance(val, dict): sheet.columns.pop(new_idx) vd.fail('Column "{}" is not a dict'.format(col.name)) new_col.setValue(r, [{'Key': k, 'Value': v} for k, v in val.items()]) col.hide() return new_col