from visidata import vd, VisiData, BaseSheet, Sheet, Column, AttrColumn, ItemColumn, setitem, asyncthread
[docs]class IndexSheet(Sheet):
'Base class for tabular sheets with rows that are Sheets.'
guide = '''
# Index Sheet
This is a list of sheets from `{sheet.source}`.
- `Enter` to open {sheet.cursorRow}
- `g Enter` to open all selected sheets
'''
rowtype = 'sheets' # rowdef: Sheet
columns = [
Column('name', getter=lambda c,r: r.names[-1], setter=lambda c,r,v: setitem(r.names, -1, v)),
AttrColumn('rows', 'nRows', type=int, width=9),
AttrColumn('cols', 'nCols', type=int),
AttrColumn('keys', 'keyColNames'),
AttrColumn('source'),
]
nKeys = 1
def newRow(self):
return Sheet('', columns=[ItemColumn('', 0)], rows=[])
def openRow(self, row):
return row # rowdef is Sheet
def getSheet(self, k):
for vs in self.rows:
if vs.name == k:
return vs
def addRow(self, sheet, **kwargs):
super().addRow(sheet, **kwargs)
if not self.options.load_lazy and not sheet.options.load_lazy:
sheet.ensureLoaded()
@asyncthread
def reloadSheets(self, sheets):
for vs in vd.Progress(sheets):
vs.reload()
class SheetsSheet(IndexSheet):
columns = [
AttrColumn('name'),
AttrColumn('type', '__class__.__name__'),
AttrColumn('pane', type=int),
Column('shortcut', getter=lambda c,r: getattr(r, 'shortcut'), setter=lambda c,r,v: setattr(r, '_shortcut', v)),
AttrColumn('nRows', type=int),
AttrColumn('nCols', type=int),
AttrColumn('nVisibleCols', type=int),
AttrColumn('cursorDisplay'),
AttrColumn('keyColNames'),
AttrColumn('source'),
AttrColumn('progressPct'),
# AttrColumn('threads', 'currentThreads', type=vlen),
]
precious = False
nKeys = 1
def reload(self):
self.rows = self.source
def sort(self):
self.rows[1:] = sorted(self.rows[1:], key=self.sortkey)
class GlobalSheetsSheet(SheetsSheet): #1620
def sort(self):
IndexSheet.sort(self)
@VisiData.lazy_property
def sheetsSheet(vd):
return SheetsSheet("sheets", source=vd.sheets)
@VisiData.lazy_property
def allSheetsSheet(vd):
return GlobalSheetsSheet("sheets_all", source=vd.allSheets)
@Sheet.api
def nextRow(sheet, n=1):
sheet.cursorRowIndex += n
sheet.checkCursor()
return sheet.rows[sheet.cursorRowIndex] # cursorRow itself might be cached
vd.addCommand('S', 'sheets-stack', 'vd.push(vd.sheetsSheet)', 'open Sheets Stack: join or jump between the active sheets on the current stack')
vd.addCommand('gS', 'sheets-all', 'vd.push(vd.allSheetsSheet)', 'open Sheets Sheet: join or jump between all sheets from current session')
BaseSheet.addCommand('g>', 'open-source-next', 'vd.replace(openSource(source.nextRow())) if isinstance(source, IndexSheet) else fail("parent sheet must be Index Sheet")', 'open next sheet on parent index sheet')
BaseSheet.addCommand('g<', 'open-source-prev', 'vd.replace(openSource(source.nextRow(-1))) if isinstance(source, IndexSheet) else fail("parent sheet must be Index Sheet")', 'open prev sheet on parent index sheet')
IndexSheet.addCommand('g^R', 'reload-selected', 'reloadSheets(selectedRows or rows)', 'reload all selected sheets')
# when diving into a sheet, remove the index unless it is precious
SheetsSheet.addCommand('gC', 'columns-selected', 'vd.push(ColumnsSheet("all_columns", source=selectedRows))', 'open Columns Sheet with all visible columns from selected sheets')
IndexSheet.addCommand('^C', 'cancel-row', 'cancelThread(*cursorRow.currentThreads)', 'abort async thread for current sheet')
IndexSheet.addCommand('gz^C', 'cancel-rows', 'for vs in selectedRows: cancelThread(*vs.currentThreads)', 'abort async threads for selected sheets')
SheetsSheet.addCommand('Enter', 'open-row', 'dest=cursorRow; vd.sheets.remove(sheet) if not sheet.precious else None; vd.push(openRow(dest))', 'open sheet referenced in current row')
vd.addGlobals(IndexSheet=IndexSheet,
SheetsSheet=SheetsSheet,
GlobalSheetsSheet=GlobalSheetsSheet)