A terminal spreadsheet multitool for discovering and arranging data
This report summarizes scanner evidence for saulpw/visidata, a Python project with 9,434 GitHub stars. SynthScan examined 61,821 lines of code across 516 source files, recording 941 pattern matches distributed across 12 syntactic categories. The legacy adjusted pattern signal is 33.2 (High pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 281 finding(s).
Are imports declared and package/API names verified? 473 finding(s).
Are wrappers, guards, and repeated structures necessary? 281 finding(s).
Which changes need focused human review? 941 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 941 distinct pattern matches across 12 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | visidata/indexsheet.py | 93 | vd.addCommand('S', 'sheets-stack', 'vd.push(vd.sheetsSheet)', 'open Sheets Stack: join or jump between the active sheets | STRING |
| HIGH⚡ | visidata/indexsheet.py | 94 | vd.addCommand('gS', 'sheets-all', 'vd.allSheetsSheet.reload(); vd.push(vd.allSheetsSheet)', 'open Sheets Sheet: join or | STRING |
| HIGH⚡ | visidata/indexsheet.py | 102 | IndexSheet.addCommand('gC', 'columns-selected', 'vd.push(ColumnsSheet("all_columns", source=selectedRows))', 'open Colum | STRING |
| HIGH⚡ | visidata/indexsheet.py | 105 | SheetsSheet.addCommand('Enter', 'open-row', 'dest=cursorRow; vd.sheets.remove(sheet) if not sheet.precious else None; vd | STRING |
| HIGH | visidata/plugins.py | 96 | BaseSheet.addCommand(None, 'open-plugins', 'vd.push(vd.pluginsSheet)', 'Open Plugins Sheet to manage supported plugins') | CODE |
| HIGH | visidata/sidebar.py | 238 | BaseSheet.addCommand('gb', 'open-sidebar', 'sheet.current_sidebar = "" if not hasattr(sheet, "current_sidebar") else she | STRING |
| HIGH | visidata/guide.py | 238 | BaseSheet.addCommand('', 'open-guide-index', 'vd.push(GuideIndex("VisiData_Guide"))', 'open VisiData guides table of con | STRING |
| HIGH | visidata/statusbar.py | 301 | BaseSheet.addCommand('Ctrl+P', 'open-statuses', 'vd.push(vd.statusHistorySheet)', 'open Status History') | CODE |
| HIGH | visidata/input_history.py | 55 | vd.addCommand(None, 'open-input-history', 'vd.push(inputHistorySheet)', 'open sheet with previous inputs') | CODE |
| HIGH | visidata/choose.py | 35 | vd.push(vs) | CODE |
| HIGH⚡ | visidata/sheets.py | 1323 | Sheet.addCommand('"', 'dup-selected', 'vs=copy(sheet); vs.name += "_selectedref"; vs.reload=lambda vs=vs,rows=selectedRo | CODE |
| HIGH⚡ | visidata/sheets.py | 1324 | Sheet.addCommand('g"', 'dup-rows', 'vs=copy(sheet); vs.name+="_copy"; vs.rows=list(rows); status("copied "+vs.name); vs. | CODE |
| HIGH⚡ | visidata/sheets.py | 1325 | Sheet.addCommand('z"', 'dup-selected-deep', 'vs = copy(sheet); vs.name += "_selecteddeepcopy"; vs.rows = vs.async_deepco | CODE |
| HIGH⚡ | visidata/sheets.py | 1326 | Sheet.addCommand('gz"', 'dup-rows-deep', 'vs = copy(sheet); vs.name += "_deepcopy"; vs.rows = vs.async_deepcopy(rows); v | CODE |
| HIGH | visidata/sheets.py | 1158 | return vd.push(vs) | CODE |
| HIGH | visidata/sheets.py | 1304 | vd.push(vs) | CODE |
| HIGH | visidata/sheets.py | 1347 | BaseSheet.addCommand('A', 'open-new', 'vd.push(vd.newSheet("unnamed", 1))', 'Open new empty sheet') | CODE |
| HIGH | visidata/sheets.py | 1349 | BaseSheet.addCommand('`', 'open-source', 'vd.push(source)', 'open source sheet') | CODE |
| HIGH | visidata/mainloop.py | 361 | vd.push(vs, load=False) | CODE |
| HIGH | visidata/memory.py | 45 | BaseSheet.addCommand('Alt+Shift+M', 'open-memos', 'vd.push(vd.memosSheet)', 'open the Memory Sheet') | CODE |
| HIGH | visidata/pyobj.py | 266 | vd.push(sheet.openRow(r)) | CODE |
| HIGH | visidata/pyobj.py | 274 | vd.push(openCell(col, r)) | CODE |
| HIGH⚡ | visidata/pyobj.py | 301 | BaseSheet.addCommand('Ctrl+X', 'pyobj-expr', 'expr=inputPythonExpr(); vd.push(PyobjSheet(expr, source=sheet.evalExpr(exp | CODE |
| HIGH⚡ | visidata/pyobj.py | 305 | BaseSheet.addCommand('zCtrl+X', 'pyobj-expr-row', 'expr = input("eval over current row: ", "expr", completer=CompleteExp | CODE |
| HIGH⚡ | visidata/pyobj.py | 310 | Sheet.addCommand('Ctrl+Y', 'pyobj-row', 'status(type(cursorRow).__name__); vd.push(openRowPyobj(cursorRowIndex))', 'open | CODE |
| HIGH⚡ | visidata/pyobj.py | 311 | Sheet.addCommand('zCtrl+Y', 'pyobj-cell', 'status(type(cursorValue).__name__); vd.push(openCellPyobj(cursorCol, cursorRo | CODE |
| HIGH⚡ | visidata/pyobj.py | 312 | BaseSheet.addCommand('gCtrl+Y', 'pyobj-sheet', 'status(type(sheet).__name__); vd.push(PyobjSheet(sheet.name+"_sheet", so | CODE |
| HIGH⚡ | visidata/pyobj.py | 314 | Sheet.addCommand('', 'open-row-basic', 'vd.push(TableSheet.openRow(sheet, cursorRow))', 'dive into current row as basic | CODE |
| HIGH⚡ | visidata/pyobj.py | 315 | Sheet.addCommand('Enter', 'open-row', 'vd.push(openRow(cursorRow)) if cursorRow is not None else vd.fail("no row to open | CODE |
| HIGH⚡ | visidata/pyobj.py | 316 | Sheet.addCommand('zEnter', 'open-cell', 'vd.push(openCell(cursorCol, cursorRow))', 'open sheet with copies of rows refer | CODE |
| HIGH | visidata/splitwin.py | 14 | vd.push(undersheet, pane=pane) | CODE |
| HIGH | visidata/_open.py | 218 | BaseSheet.addCommand('o', 'open-file', 'vd.push(openSource(inputPath("open: "), create=True))', 'Open file or URL') | CODE |
| HIGH | visidata/_open.py | 219 | TableSheet.addCommand('zo', 'open-cell-file', 'cd=cursorDisplay; (vd.push(openSource(cd) if cd else fail("no path given" | CODE |
| HIGH⚡ | visidata/textsheet.py | 121 | BaseSheet.addCommand('Ctrl+E', 'error-recent', 'recentErrorsSheet.reload(); vd.push(recentErrorsSheet) if vd.lastErrors | STRING |
| HIGH⚡ | visidata/textsheet.py | 122 | BaseSheet.addCommand('gCtrl+E', 'errors-all', 'vd.push(vd.allErrorsSheet)', 'view traceback for most recent errors') | STRING |
| HIGH⚡ | visidata/textsheet.py | 124 | Sheet.addCommand('zCtrl+E', 'error-cell', 'vd.push(ErrorCellSheet(sheet.name+"_cell_error", sourceSheet=sheet, source=ge | STRING |
| HIGH⚡ | visidata/graph.py | 381 | Sheet.addCommand('.', 'plot-column', 'vd.push(GraphSheet(sheet.name, "graph", source=sheet, sourceRows=rows, xcols=keyCo | CODE |
| HIGH⚡ | visidata/graph.py | 382 | Sheet.addCommand('g.', 'plot-numerics', 'vd.push(GraphSheet(sheet.name, "graph", source=sheet, sourceRows=rows, xcols=ke | CODE |
| HIGH⚡ | visidata/graph.py | 383 | ColumnsSheet.addCommand('g.', 'plot-source-selected', 'vd.push(GraphSheet(sheet.source[0].name, "graph", source=source[0 | CODE |
| HIGH | visidata/deprecated.py | 107 | return vd.push(vs) | CODE |
| HIGH | visidata/shell.py | 65 | vd.push(TextSheet(' '.join(args), source=lines)) | CODE |
| HIGH⚡ | visidata/shell.py | 307 | DirSheet.addCommand('`', 'open-dir-parent', 'vd.push(openSource(source.parent if source.resolve()!=Path(".").resolve() e | STRING |
| HIGH⚡ | visidata/shell.py | 308 | BaseSheet.addCommand('', 'open-dir-current', 'vd.push(vd.currentDirSheet)', 'open Directory Sheet: browse properties of | STRING |
| HIGH⚡ | visidata/shell.py | 312 | DirSheet.addCommand('Enter', 'open-row-file', 'vd.push(openSource(cursorRow or fail("no row"), filetype="dir" if cursorR | STRING |
| HIGH⚡ | visidata/shell.py | 313 | DirSheet.addCommand('gEnter', 'open-rows', 'for r in selectedRows: vd.push(openSource(r))', 'open selected files as new | STRING |
| HIGH⚡ | visidata/shell.py | 320 | DirSheet.addCommand('zEnter', 'open-row-filetype', 'ft = input("filetype: ", type="filetype", value=options.filetype or | STRING |
| HIGH | visidata/shell.py | 342 | vd.push(vs, pane=2) | STRING |
| HIGH | visidata/movement.py | 117 | vd.push(matches[0]) | CODE |
| HIGH | visidata/movement.py | 163 | BaseSheet.addCommand(f'Alt+{str(i)[-1]}', f'jump-sheet-{i}', f'vd.push(*(list(s for s in allSheets if s.shortcut==st | CODE |
| HIGH | visidata/movement.py | 166 | BaseSheet.addCommand('', f'jump-sheet-{i}', f'vd.push(*(list(s for s in allSheets if s.shortcut==str({i})) or fail(" | CODE |
| HIGH | visidata/movement.py | 230 | BaseSheet.addCommand('Ctrl+^', 'jump-prev', 'vd.activeStack[1:] or fail("no previous sheet"); vd.push(vd.activeStack[1]) | CODE |
| HIGH | visidata/movement.py | 231 | BaseSheet.addCommand('gCtrl+^', 'jump-first', 'vd.push(vd.activeStack[-1])', 'jump to first sheet') | CODE |
| HIGH | visidata/threads.py | 535 | BaseSheet.addCommand('Ctrl+T', 'threads-all', 'vd.push(vd.allThreadsSheet)', 'open Threads for all sheets') | STRING |
| HIGH | visidata/threads.py | 536 | BaseSheet.addCommand('zCtrl+T', 'threads-sheet', 'vd.push(ThreadsSheet("threads", source=sheet.currentThreads))', 'open | STRING |
| HIGH | visidata/optionssheet.py | 91 | BaseSheet.addCommand('O', 'options-global', 'vd.push(vd.globalOptionsSheet)', 'open Options Sheet: edit global options ( | CODE |
| HIGH | visidata/optionssheet.py | 93 | BaseSheet.addCommand('zO', 'options-sheet', 'vd.push(sheet.optionsSheet)', 'open Options Sheet: edit sheet options (appl | CODE |
| HIGH | visidata/macros.py | 269 | Sheet.addCommand('gm', 'macro-sheet', 'vd.push(vd.macrosheet)', 'open an index of existing macros') | STRING |
| HIGH⚡ | visidata/freqtbl.py | 202 | FreqTableSheet.addCommand('', 'open-preview', 'vd.push(FreqTablePreviewSheet(sheet.name, "preview", source=sheet, column | STRING |
| HIGH⚡ | visidata/freqtbl.py | 204 | Sheet.addCommand('F', 'freq-col', 'vd.push(makeFreqTable(sheet, cursorCol))', 'open Frequency Table grouped on current c | STRING |
| HIGH⚡ | visidata/freqtbl.py | 205 | Sheet.addCommand('gF', 'freq-keys', 'vd.push(makeFreqTable(sheet, *keyCols)) if keyCols else vd.fail("there are no key c | STRING |
| 161 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/plugins.py | 7 | CODE | |
| LOW | visidata/plugins.py | 8 | CODE | |
| LOW | visidata/plugins.py | 10 | CODE | |
| LOW | visidata/plugins.py | 10 | CODE | |
| LOW | visidata/plugins.py | 10 | CODE | |
| LOW | visidata/plugins.py | 10 | CODE | |
| LOW | visidata/plugins.py | 85 | CODE | |
| LOW | visidata/plugins.py | 86 | CODE | |
| LOW | visidata/sidebar.py | 1 | CODE | |
| LOW | visidata/sidebar.py | 1 | CODE | |
| LOW | visidata/sidebar.py | 6 | CODE | |
| LOW | visidata/guide.py | 10 | CODE | |
| LOW | visidata/_urlcache.py | 42 | CODE | |
| LOW | visidata/statusbar.py | 10 | CODE | |
| LOW | visidata/color.py | 3 | CODE | |
| LOW | visidata/color.py | 4 | CODE | |
| LOW | visidata/color.py | 7 | CODE | |
| LOW | visidata/color.py | 7 | CODE | |
| LOW | visidata/color.py | 8 | CODE | |
| LOW | visidata/sheets.py | 4 | CODE | |
| LOW | visidata/sheets.py | 6 | CODE | |
| LOW | visidata/sheets.py | 6 | CODE | |
| LOW | visidata/sheets.py | 6 | CODE | |
| LOW | visidata/sheets.py | 7 | CODE | |
| LOW | visidata/mainloop.py | 5 | CODE | |
| LOW | visidata/mainloop.py | 9 | CODE | |
| LOW | visidata/mainloop.py | 9 | CODE | |
| LOW | visidata/tuiwin.py | 1 | CODE | |
| LOW | visidata/fuzzymatch.py | 14 | CODE | |
| LOW | visidata/memory.py | 1 | CODE | |
| LOW | visidata/memory.py | 1 | CODE | |
| LOW | visidata/pyobj.py | 3 | CODE | |
| LOW | visidata/_open.py | 3 | CODE | |
| LOW | visidata/_open.py | 5 | CODE | |
| LOW | visidata/textsheet.py | 5 | CODE | |
| LOW | visidata/graph.py | 1 | CODE | |
| LOW | visidata/graph.py | 4 | CODE | |
| LOW | visidata/__init__.py | 29 | CODE | |
| LOW | visidata/__init__.py | 31 | CODE | |
| LOW | visidata/__init__.py | 32 | CODE | |
| LOW | visidata/__init__.py | 40 | CODE | |
| LOW | visidata/__init__.py | 42 | CODE | |
| LOW | visidata/__init__.py | 44 | CODE | |
| LOW | visidata/__init__.py | 143 | CODE | |
| LOW | visidata/__init__.py | 154 | CODE | |
| LOW | visidata/stored_list.py | 3 | CODE | |
| LOW | visidata/movement.py | 3 | CODE | |
| LOW | visidata/menu.py | 1 | CODE | |
| LOW | visidata/menu.py | 3 | CODE | |
| LOW | visidata/menu.py | 7 | CODE | |
| LOW | visidata/aggregators.py | 9 | CODE | |
| LOW | visidata/threads.py | 11 | CODE | |
| LOW | visidata/threads.py | 11 | CODE | |
| LOW | visidata/utils.py | 2 | CODE | |
| LOW | visidata/utils.py | 4 | CODE | |
| LOW | visidata/macros.py | 3 | CODE | |
| LOW | visidata/macros.py | 6 | CODE | |
| LOW | visidata/macros.py | 7 | CODE | |
| LOW | visidata/macros.py | 7 | CODE | |
| LOW | visidata/cmdlog.py | 1 | CODE | |
| 192 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | visidata/save.py | 192 | except FileExistsError: | CODE |
| HIGH | visidata/basesheet.py | 342 | except (ValueError, IndexError): | CODE |
| HIGH | visidata/color.py | 91 | except Exception: | CODE |
| HIGH | visidata/sheets.py | 821 | except ValueError: # from .index | CODE |
| HIGH | visidata/sheets.py | 833 | except IndexError: | CODE |
| HIGH | visidata/sheets.py | 955 | except (TypeError, ValueError): | CODE |
| HIGH | visidata/vdobj.py | 137 | except curses.error: | CODE |
| HIGH | visidata/pyobj.py | 58 | except AttributeError: #2631 attributes like formatted_help can raise AttributeError | CODE |
| HIGH | visidata/pyobj.py | 221 | except Exception: | CODE |
| HIGH | visidata/_open.py | 77 | except FileNotFoundError: | CODE |
| HIGH | visidata/shell.py | 127 | except subprocess.TimeoutExpired: | CODE |
| HIGH | visidata/movement.py | 83 | except Exception: | CODE |
| HIGH | visidata/menu.py | 171 | except IndexError: | CODE |
| HIGH | visidata/aggregators.py | 39 | except Exception: | CODE |
| HIGH | visidata/threads.py | 411 | except ValueError: #"ValueError: Another profiling tool is already active" | CODE |
| HIGH | visidata/motd.py | 28 | except Exception: | CODE |
| HIGH | visidata/utils.py | 118 | except Exception: | CODE |
| HIGH | visidata/utils.py | 97 | except Exception: | CODE |
| HIGH | visidata/utils.py | 135 | except IndexError: | CODE |
| HIGH | visidata/wrappers.py | 94 | except Exception: | CODE |
| HIGH | visidata/cmdlog.py | 442 | except ValueError: | CODE |
| HIGH | visidata/cmdlog.py | 447 | except Exception: | CODE |
| HIGH | visidata/mouse.py | 124 | except curses.error: | CODE |
| HIGH | visidata/_input.py | 82 | except curses.error: | CODE |
| HIGH | visidata/errors.py | 44 | except ValueError: | CODE |
| HIGH | visidata/selection.py | 198 | except Exception: | CODE |
| HIGH | visidata/main.py | 201 | except IndexError: | CODE |
| HIGH | visidata/main.py | 363 | except Exception: | CODE |
| HIGH | visidata/cliptext.py | 260 | except curses.error: | CODE |
| HIGH | visidata/cliptext.py | 303 | except curses.error: | CODE |
| HIGH | visidata/column.py | 364 | except KeyError: | CODE |
| HIGH | visidata/features/command_server.py | 183 | except FileNotFoundError: | CODE |
| HIGH | visidata/features/command_server.py | 285 | except (TypeError, ValueError): | CODE |
| HIGH | visidata/features/melt.py | 81 | except Exception: | CODE |
| HIGH | visidata/apps/vdsql/_ibis.py | 45 | except TypeError: | CODE |
| HIGH | visidata/apps/vdsql/_ibis.py | 238 | except Exception: | CODE |
| HIGH | visidata/loaders/orgmode.py | 308 | except FileNotFoundError: | CODE |
| HIGH | visidata/loaders/pcap.py | 405 | except Exception: | CODE |
| HIGH | visidata/loaders/claude.py | 96 | except Exception: | CODE |
| HIGH | visidata/loaders/texttables.py | 19 | except ModuleNotFoundError: | CODE |
| HIGH | visidata/loaders/vds.py | 28 | except TypeError: | CODE |
| HIGH | visidata/loaders/_pandas.py | 106 | except TypeError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | setup.py | 35 | CODE | |
| LOW | visidata/save.py | 40 | CODE | |
| LOW | visidata/sidebar.py | 103 | CODE | |
| LOW | visidata/choose.py | 42 | CODE | |
| LOW | visidata/color.py | 222 | CODE | |
| LOW | visidata/color.py | 126 | CODE | |
| LOW | visidata/sheets.py | 1174 | CODE | |
| LOW | visidata/sheets.py | 114 | CODE | |
| LOW | visidata/sheets.py | 680 | CODE | |
| LOW | visidata/sheets.py | 851 | CODE | |
| LOW | visidata/sheets.py | 936 | CODE | |
| LOW | visidata/mainloop.py | 76 | CODE | |
| LOW | visidata/mainloop.py | 126 | CODE | |
| LOW | visidata/mainloop.py | 180 | CODE | |
| LOW | visidata/mainloop.py | 270 | CODE | |
| LOW | visidata/fuzzymatch.py | 97 | CODE | |
| LOW | visidata/fuzzymatch.py | 111 | CODE | |
| LOW | visidata/fuzzymatch.py | 184 | CODE | |
| LOW | visidata/fuzzymatch.py | 377 | CODE | |
| LOW | visidata/pyobj.py | 183 | CODE | |
| LOW | visidata/_open.py | 98 | CODE | |
| LOW | visidata/_open.py | 205 | CODE | |
| LOW | visidata/graph.py | 100 | CODE | |
| LOW | visidata/graph.py | 147 | CODE | |
| LOW | visidata/shell.py | 114 | CODE | |
| LOW | visidata/stored_list.py | 22 | CODE | |
| LOW | visidata/movement.py | 71 | CODE | |
| LOW | visidata/menu.py | 164 | CODE | |
| LOW | visidata/menu.py | 260 | CODE | |
| LOW | visidata/menu.py | 411 | CODE | |
| LOW | visidata/menu.py | 262 | CODE | |
| LOW | visidata/aggregators.py | 324 | CODE | |
| LOW | visidata/threads.py | 357 | CODE | |
| LOW | visidata/threads.py | 415 | CODE | |
| LOW | visidata/form.py | 60 | CODE | |
| LOW | visidata/wrappers.py | 98 | CODE | |
| LOW | visidata/macros.py | 98 | CODE | |
| LOW | visidata/macros.py | 199 | CODE | |
| LOW | visidata/cmdlog.py | 333 | CODE | |
| LOW | visidata/settings.py | 489 | CODE | |
| LOW | visidata/settings.py | 26 | CODE | |
| LOW | visidata/settings.py | 95 | CODE | |
| LOW | visidata/settings.py | 217 | CODE | |
| LOW | visidata/mouse.py | 94 | CODE | |
| LOW | visidata/_input.py | 375 | CODE | |
| LOW | visidata/_input.py | 569 | CODE | |
| LOW | visidata/_input.py | 178 | CODE | |
| LOW | visidata/_input.py | 252 | CODE | |
| LOW | visidata/selection.py | 187 | CODE | |
| LOW | visidata/hint.py | 12 | CODE | |
| LOW | visidata/ddwplay.py | 83 | CODE | |
| LOW | visidata/main.py | 181 | CODE | |
| LOW | visidata/main.py | 288 | CODE | |
| LOW | visidata/cliptext.py | 86 | CODE | |
| LOW | visidata/cliptext.py | 126 | CODE | |
| LOW | visidata/cliptext.py | 154 | CODE | |
| LOW | visidata/cliptext.py | 315 | CODE | |
| LOW | visidata/cliptext.py | 402 | CODE | |
| LOW | visidata/cliptext.py | 526 | CODE | |
| LOW | visidata/pivot.py | 125 | CODE | |
| 113 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/save.py | 62 | except Exception as e: | CODE |
| LOW | visidata/save.py | 80 | except Exception: | CODE |
| LOW | visidata/basesheet.py | 217 | except Exception as e: | CODE |
| LOW | visidata/sidebar.py | 139 | except Exception as e: | CODE |
| LOW | visidata/statusbar.py | 127 | except Exception as e: | CODE |
| LOW | visidata/color.py | 91 | except Exception: | STRING |
| LOW | visidata/color.py | 167 | except Exception: | CODE |
| MEDIUM | visidata/color.py | 88 | def setup(self): | CODE |
| LOW | visidata/sheets.py | 243 | except Exception as e: | CODE |
| LOW | visidata/sheets.py | 927 | except Exception as e: | CODE |
| LOW | visidata/mainloop.py | 30 | except Exception as e: | CODE |
| LOW | visidata/mainloop.py | 39 | except Exception as e: | CODE |
| LOW | visidata/mainloop.py | 230 | except Exception as e: | CODE |
| LOW | visidata/mainloop.py | 251 | except Exception as e: #2859 | CODE |
| LOW | visidata/mainloop.py | 279 | except Exception as e: | CODE |
| MEDIUM | visidata/mainloop.py | 270 | def _playNextQueuedCommand(vd, sheet): | CODE |
| LOW | visidata/pyobj.py | 221 | except Exception: | CODE |
| LOW | visidata/_open.py | 79 | except Exception as e: | CODE |
| LOW | visidata/graph.py | 123 | except Exception as e: | CODE |
| LOW | visidata/deprecated.py | 217 | except Exception as e: | CODE |
| MEDIUM | visidata/deprecated.py | 214 | def __exit__(self, exc_type, exc_value, exc_traceback): | CODE |
| LOW | visidata/shell.py | 133 | except Exception as e: | CODE |
| LOW | visidata/shell.py | 378 | except Exception as e: | STRING |
| MEDIUM | visidata/shell.py | 114 | def calcValue(self, row): | CODE |
| LOW | visidata/movement.py | 83 | except Exception: | CODE |
| LOW | visidata/aggregators.py | 39 | except Exception: | STRING |
| LOW | visidata/aggregators.py | 115 | except Exception as e: | STRING |
| LOW | visidata/threads.py | 276 | except Exception as e: | CODE |
| LOW | visidata/threads.py | 288 | except Exception as e: | CODE |
| LOW | visidata/form.py | 92 | except Exception as e: | CODE |
| LOW | visidata/motd.py | 28 | except Exception: | CODE |
| MEDIUM | visidata/motd.py | 22 | def domotd(vd): | CODE |
| LOW | visidata/utils.py | 82 | except Exception: | CODE |
| LOW | visidata/utils.py | 97 | except Exception: | CODE |
| LOW | visidata/utils.py | 105 | except Exception: | CODE |
| LOW | visidata/utils.py | 118 | except Exception: | CODE |
| LOW | visidata/utils.py | 125 | except Exception: | CODE |
| LOW | visidata/utils.py | 192 | except Exception: | CODE |
| MEDIUM | visidata/utils.py | 22 | def __getattr__(self, k): | CODE |
| MEDIUM | visidata/utils.py | 189 | def get_value(self, key, args, kwargs): | CODE |
| LOW | visidata/wrappers.py | 94 | except Exception: | CODE |
| LOW | visidata/wrappers.py | 115 | except Exception as e: | CODE |
| LOW | visidata/cmdlog.py | 294 | except Exception as e: | CODE |
| LOW | visidata/cmdlog.py | 312 | except Exception as e: | CODE |
| LOW | visidata/cmdlog.py | 355 | except Exception as e: | CODE |
| LOW | visidata/cmdlog.py | 447 | except Exception: | CODE |
| LOW | visidata/modify.py | 186 | except Exception as e: | CODE |
| LOW | visidata/modify.py | 214 | except Exception: | CODE |
| LOW | visidata/modify.py | 232 | except Exception as e: | CODE |
| LOW | visidata/modify.py | 254 | except Exception as e: | CODE |
| LOW | visidata/settings.py | 457 | except Exception as e: | CODE |
| LOW | visidata/settings.py | 509 | except Exception as e: | CODE |
| LOW | visidata/settings.py | 518 | except Exception as e: | CODE |
| LOW | visidata/settings.py | 532 | except Exception as e: | CODE |
| LOW | visidata/search.py | 104 | except Exception as e: | STRING |
| LOW | visidata/search.py | 122 | except Exception as e: | STRING |
| LOW | visidata/_input.py | 333 | except Exception: | CODE |
| LOW | visidata/selection.py | 135 | except Exception as e: | CODE |
| LOW | visidata/selection.py | 198 | except Exception: | CODE |
| LOW | visidata/hint.py | 31 | except Exception as e: | CODE |
| 74 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/experimental/daw/tests/test_vdaw.py | 29 | def test_bulk_combine_groups_by_speaker(minisheet): | CODE |
| LOW | visidata/experimental/daw/tests/test_vdaw.py | 40 | def test_bulk_combine_save_preserves_sourceaudio(daw, minisheet, tmp_path): | CODE |
| LOW | visidata/experimental/daw/tests/test_vdaw.py | 54 | def test_discovered_audio_overrides_missing_sourceaudio(daw, tmp_path): | CODE |
| LOW | visidata/features/condfmt.py | 214 | def test_condfmt_bare_column_name(vd): #3061 | STRING |
| LOW | visidata/features/condfmt.py | 227 | def test_condfmt_value_binding(vd): #3061 | STRING |
| LOW | visidata/features/condfmt.py | 251 | def test_condfmt_row_binding_string_column(vd): #3061 | STRING |
| LOW | visidata/features/condfmt.py | 264 | def test_condfmt_silent_eval_error(vd): #3061 | STRING |
| LOW | visidata/features/condfmt.py | 282 | def test_condfmt_color_option_name(vd): #3061 | STRING |
| LOW | visidata/features/condfmt.py | 293 | def test_condfmt_value_is_typed_not_wrapper(vd): #3061 | STRING |
| LOW | visidata/tests/test_pandas_pickle.py | 30 | def test_pickle_refused_by_default(probe): | CODE |
| LOW | visidata/tests/test_pandas_pickle.py | 38 | def test_pickle_runs_when_allowed(probe): | CODE |
| LOW⚡ | visidata/tests/test_unzip_http.py | 17 | def test_extract_refuses_escaping_member(tmp_path, member): | CODE |
| LOW⚡ | visidata/tests/test_unzip_http.py | 25 | def test_extract_writes_inside_target(tmp_path): | CODE |
| LOW⚡ | visidata/tests/test_unzip_http.py | 30 | def test_cli_full_filepaths_refuses_escaping_member(tmp_path, monkeypatch): | CODE |
| LOW⚡ | visidata/tests/test_cmdlog.py | 9 | def test_go_commands_not_loggable(self): | CODE |
| LOW⚡ | visidata/tests/test_cmdlog.py | 16 | def test_movement_does_not_replace_last_command(self): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 42 | def test_keystroke_from_macros_jsonl(self, macrodir): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 45 | def test_edit_keystroke_rebinds(self, macrodir): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 55 | def test_clear_keystroke_unbinds(self, macrodir): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 99 | def test_input_param_and_default(self, replayed): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 108 | def test_digit_names_not_params(self, replayed): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 118 | def test_json_input_untouched(self, replayed): | CODE |
| LOW | visidata/tests/test_macros.py | 129 | def test_braces_from_macros_jsonl(self, macrodir): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 150 | def test_record_with_braces_is_literal(self, macrodir, monkeypatch): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 154 | def test_record_without_braces_is_param(self, macrodir, monkeypatch): | CODE |
| LOW⚡ | visidata/tests/test_macros.py | 157 | def test_macrosheet_save_keeps_braces(self, macrodir, monkeypatch): | CODE |
| LOW | visidata/tests/test_setenv.py | 12 | def test_setenv_replays_from_sheet_cmdlog(monkeypatch): | CODE |
| LOW | visidata/tests/test_llm.py | 99 | def test_long_cell_sent_whole(self, fake): | CODE |
| LOW | visidata/tests/test_llm.py | 110 | def test_missing_key_fails_before_thread(self, monkeypatch): | CODE |
| LOW | visidata/tests/test_llm.py | 118 | def test_confirm_in_main_thread(self, fake, monkeypatch): | CODE |
| LOW | visidata/tests/test_llm.py | 143 | def test_query_confirm_in_main_thread(self, fake, monkeypatch): | CODE |
| LOW⚡ | visidata/tests/test_quit_free.py | 23 | def test_quit_sheet_free_frees_rows(cmds): | CODE |
| LOW | visidata/tests/test_editor.py | 25 | def test_trailing_newlines_trimmed(self, tmp_path, monkeypatch): | CODE |
| LOW | visidata/tests/test_editor.py | 30 | def test_unchanged_roundtrips(self, tmp_path, monkeypatch): | CODE |
| LOW | visidata/tests/test_vcf.py | 18 | def test_vcf_reads_folded_photo(tmp_path): | CODE |
| LOW | visidata/tests/test_fixed_width.py | 10 | def test_data_with_internal_spaces(self): #2265 | CODE |
| LOW | visidata/tests/test_fixed_width.py | 34 | def test_right_justified_headers(self): #3029 | CODE |
| LOW | visidata/tests/test_lazycomputerow.py | 10 | def test_currow_reads_cursor_column(): | CODE |
| LOW | visidata/tests/test_archive.py | 13 | def test_nested_tar_member_csv_gz(tmp_path, monkeypatch): #3212 | CODE |
| LOW | visidata/tests/test_cliptext.py | 87 | def test_clipstr_wide_truncator(self, s, w, clippeds, clippedw): | CODE |
| LOW | visidata/tests/test_cliptext.py | 113 | def test_clipstr_empty_truncator(self, s, w, clippeds, clippedw): | CODE |
| LOW | visidata/tests/test_cliptext.py | 163 | def test_clipstr_start_truncator(self, s, w, clippeds, clippedw): | CODE |
| LOW | visidata/tests/test_cliptext.py | 269 | def test_truncate_markup_middle(self, s, dispw, clipped): | CODE |
| LOW | visidata/tests/test_cliptext.py | 298 | def test_wraptext_color_spans_lines(self, text, width, expected): | CODE |
| LOW | visidata/tests/test_cliptext.py | 312 | def test_wraptext_escaped_literals(self, text, width, expected): | CODE |
| LOW | visidata/tests/test_inputmultiple.py | 22 | def test_tab_completes_in_field_with_completer(monkeypatch): #3169 | CODE |
| LOW | visidata/tests/test_inputmultiple.py | 31 | def test_tab_switches_field_without_completer(monkeypatch): | CODE |
| LOW | visidata/tests/test_open.py | 5 | def test_filetype_overrides_url_scheme(self): | CODE |
| LOW | visidata/tests/test_history_palette.py | 21 | def test_history_palette_default(mock_screen, monkeypatch, default, keys, expected): | CODE |
| LOW | visidata/tests/test_eml.py | 21 | def test_extract_parts_refuses_escaping_filename(tmp_path, sync_exec, fn): | CODE |
| LOW⚡ | visidata/tests/test_options_undefined.py | 22 | def test_numeric_formatter_without_type_fmt(): | CODE |
| LOW⚡ | visidata/tests/test_options_undefined.py | 32 | def test_get_with_default_is_silent(): | CODE |
| LOW⚡ | visidata/tests/test_options_undefined.py | 38 | def test_undefined_read_returns_none_and_warns_once(): | CODE |
| LOW | visidata/tests/test_options_undefined.py | 75 | def test_defined_falsy_options_do_not_warn(): | CODE |
| LOW | visidata/tests/test_options_undefined.py | 88 | def test_setting_unknown_option_still_warns(): | CODE |
| LOW | visidata/tests/test_options_undefined.py | 94 | def test_private_attrs_are_not_options(): | CODE |
| LOW | visidata/tests/test_commands.py | 137 | def test_command_execstrs_compile(self): | CODE |
| LOW | visidata/tests/test_color.py | 45 | def test_pairnum_within_terminal_limit(self, fake_curses): | CODE |
| LOW | visidata/tests/test_path.py | 40 | def test_iterdir_yields_visidata_paths(self): # #2188 | CODE |
| LOW | visidata/tests/test_path.py | 45 | def test_name_returns_full_filename(self): # #2188 | CODE |
| 30 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/_types.py | 21 | COMMENT | |
| LOW | visidata/fuzzymatch.py | 21 | scoreGapStart = -3 | COMMENT |
| LOW | visidata/loaders/pandas_freqtbl.py | 121 | )[_pivot_count_column].sort_values(ascending=False, kind="mergesort") | COMMENT |
| LOW | visidata/loaders/arrow.py | 41 | pa.lib.Type_TIMESTAMP: date, | COMMENT |
| LOW | visidata/loaders/unzip_http.py | 1 | #!/usr/bin/env python3 | COMMENT |
| LOW | tests/test-options-precedence.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | tests/test-save.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | tests/test-options-config.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | tests/test-url.sh | 1 | #!/usr/bin/env bash | COMMENT |
| LOW | docs/api/conf.py | 1 | # Configuration file for the Sphinx documentation builder. | COMMENT |
| LOW | dev/test.sh | 1 | #!/usr/bin/env bash | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/color.py | 10 | __all__ = ['ColorAttr', 'colors', 'update_attr', 'ColorMaker', 'rgb_to_attr', 'css_to_xterm256', 'xterm256_to_rgb', 'rgb | CODE |
| LOW | visidata/mainloop.py | 11 | __all__ = ['ReturnValue', 'run'] | CODE |
| LOW | visidata/vdobj.py | 6 | __all__ = ['ENTER', 'ALT', 'ESC', 'asyncthread', 'VisiData'] | CODE |
| LOW | visidata/utils.py | 8 | __all__ = ['AlwaysDict', 'AttrDict', 'DefaultAttrDict', 'moveListItem', 'namedlist', 'classproperty', 'MissingAttrFormat | CODE |
| LOW | visidata/ddwplay.py | 6 | __all__ = ['Animation', 'AnimationMgr'] | CODE |
| LOW | visidata/extensible.py | 4 | __all__ = ['Extensible', 'cache', 'drawcache', 'drawcache_property'] | CODE |
| LOW | visidata/apps/vdsql/__about__.py | 1 | __all__ = ['__title__', '__author__', '__version__', '__description__', '__license__', '__copyright__'] | CODE |
| LOW | visidata/loaders/postgres.py | 8 | __all__ = ['openurl_postgres', 'openurl_postgresql', 'openurl_rds', 'PgTable', 'PgTablesSheet'] | CODE |
| LOW | visidata/loaders/scrape.py | 3 | __all__=[ 'SelectorColumn', 'soupstr' ] | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | visidata/experimental/daw/vdaw.py | 99 | CODE | |
| MEDIUM | visidata/loaders/html.py | 95 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/sheets.py | 968 | CODE | |
| LOW | visidata/sort.py | 70 | CODE | |
| LOW | visidata/_input.py | 375 | CODE | |
| LOW | visidata/loaders/f5log.py | 86 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/main.py | 230 | # don't change the stack order -- just return the sheet for cursor moves. | COMMENT |
| LOW | visidata/pivot.py | 218 | # (more bins than int vals) or (if bins are of width 1), just use the vals as bins | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | visidata/features/graph_zoom_y.py | 18 | # Check if the point is within the current x range | COMMENT |