Skip to main content

Plugins

VisiData's plugin system extends the tool with additional file format support, new commands, and third-party integrations. Plugins are Python files loaded at startup via .visidatarc.

Learning Focus

Learn how to install plugins from the built-in plugin index and how to write a minimal custom plugin for your own use case.

Plugin Index

# Open the plugin index inside VisiData
Space
# Enter: open-plugins
# OR use the menu: Alt+H → Plugins

# Or from the CLI
vd -P open-plugins

The plugin index lists available community plugins with descriptions.

Installing a Plugin

# From the Plugin Index sheet:
Enter # install the plugin under cursor
# VisiData downloads and enables it

# Or manually, add to ~/.visidatarc:
import importlib
# (plugins are Python modules dropped in the visidata plugins dir)

Default plugin directory:

~/.config/visidata/plugins/

To list installed plugins:

ls ~/.config/visidata/plugins/

Enabling/Disabling Plugin Autoload

# ~/.visidatarc

# Disable autoloading of all plugins
options.plugins_autoload = False

# Selectively import specific plugins
import visidata.plugins.vds3 # S3 support
PluginWhat it adds
vds3Browse Amazon S3 buckets like directories
vdplusAdditional aggregators and commands
vgitBrowse git history as a sheet
vdredditBrowse Reddit as a VisiData sheet
vdzulipZulip chat as a sheet
vdairtableAirtable as a VisiData sheet
vdgpxGPX GPS track files
vdfixerLive currency conversion

Writing a Custom Plugin

A minimal plugin is a Python file placed in the plugin directory:

# ~/.config/visidata/plugins/my_plugin.py

from visidata import vd, Sheet, Column

# Add a custom command to all sheets
Sheet.addCommand(
'F5', # keybinding
'my-custom-command', # longname
'vd.status("Hello VisiData!")', # Python expression to execute
'Show a status message' # help text
)

To load it:

# ~/.visidatarc
import sys, os
sys.path.insert(0, os.path.expanduser('~/.config/visidata/plugins'))
import my_plugin

Adding Custom Column Transformations

# ~/.visidatarc

from visidata import Sheet, Column, vd

# Add a command to add a 'size' column showing length of each cell
@Sheet.api
def add_len_column(sheet):
col = sheet.cursorCol
sheet.addColumn(
Column(
f'len_{col.name}',
getter=lambda col, row: len(str(col.sheet.cursorCol.getDisplayValue(row)))
)
)

Sheet.addCommand('zL', 'add-len-col', 'sheet.add_len_column()', 'Add length column')

Plugin Security

warning

VisiData plugins are executed as Python code with full system access. Only install plugins from trusted sources. Review plugin source code before enabling in production environments.

ProblemCauseFix
Plugin not loadingSyntax error in plugin fileRun python3 plugin.py to check
Command not foundPlugin not importedCheck .visidatarc import statement
Plugin conflicts with keyKey already boundChange the keybinding in the plugin
S3 plugin failsMissing boto3pip install boto3

Best Practices

  • Keep plugins minimal — VisiData's core is powerful without plugins for most use cases.
  • Pin plugin versions in a requirements.txt if using plugins in automated pipelines.
  • Test plugins on non-production data first — a poorly written plugin can corrupt data.

Custom Plugin: Cell-Level Selection

The cell_select.py plugin adds the ability to select individual cells (instead of entire rows) with visual highlighting. Cell selection is purely visual — it does not affect row-level operations like filtering, delete, or copy.

Keybindings

KeyAction
Alt+5Toggle selection of current cell (5 resembles s for select)
Alt+uClear all cell selections (u for unselect)

Selected cells appear highlighted with a configurable color (default: bold yellow on blue).

Source

~/.visidata/plugins/cell_select.py

How It Works

  • Selected cells are tracked per sheet as (rowid, column_name) pairs in _selectedCells
  • Uses CellColorizer for visual highlighting — does not interact with VisiData's row-level selection system
  • Selection persists through sort and row reordering (uses stable rowid internally)
  • Alt+5 toggles the current cell on/off with each press

Registering the Plugin

Add to ~/.visidatarc:

import sys
sys.path.insert(0, os.path.expanduser('~/.config/visidata/plugins'))
import cell_select

Or use the common-config loader pattern:

import sys
sys.path.insert(0, '/path/to/shared/plugins')
import cell_select

Customizing the Highlight Color

Add to ~/.visidatarc:

vd.options.color_selected_cell = 'bold cyan on black'

Custom Plugin: Column Selection System

The 42-column-selection.py plugin adds 18 commands for selecting, toggling, hiding, and operating on columns directly from the main sheet — without opening the Columns Sheet (Shift+C). Selected columns are highlighted in bold cyan for clear visual feedback.

This mirrors VisiData's row selection pattern (s/t/u) but for columns, using the Alt+ prefix which VisiData reserves for user customization.

Keybindings

Selection:

KeyAction
Alt+sSelect current column
Alt+tToggle column selection
Alt+uUnselect current column
Alt+gsSelect all visible columns
Alt+guUnselect all columns (multi-key)
Alt+Shift+UUnselect all columns (single key)
Alt+gzToggle all columns selection

Hide / Unhide:

KeyAction
Alt+-Hide all selected columns
Alt+gvUnhide selected columns
Alt+gVUnhide all hidden columns

Bulk Type Operations:

KeyAction
Alt+g#Set type = int for selected columns
Alt+g%Set type = float for selected columns
Alt+g~Set type = str for selected columns
Alt+g$Set type = currency for selected columns
Alt+g@Set type = date for selected columns

Width Operations:

KeyAction
Alt+g_Set width for selected columns (prompts for value)
Alt+z_Auto-fit width for selected columns

Status:

KeyAction
Alt+:Show selected column names in status bar

Source

~/.visidatarc.d/Keybindings/42-column-selection.py

How It Works

  • Selected columns are tracked per sheet as a set of Column objects in TableSheet.selectedCols
  • Uses ColumnColorizer._make((8, 'color_selected_col', is_selected_col)) for bold cyan highlighting — note this uses the tuple constructor, not class instantiation
  • All commands use @TableSheet.api decorators for clean registration
  • State is session-only — selections clear when VisiData closes (intentional)

Kitty + tmux Compatibility

Multi-key Alt+ sequences (e.g. Alt+gu) may not work reliably in Kitty + tmux. When you hold Alt across both letters, VisiData receives Alt+g then Alt+u — where Alt+u means "unselect current column," not "unselect all."

Workarounds:

SequenceHow it works
Esc g uRelease Alt, press g, then u — works reliably
Alt+Shift+USingle-key fallback for unselect-all

Single-key Alt+ bindings (Alt+s, Alt+-, Alt+gv, Alt+Shift+U) work directly in Kitty + tmux.

# Recommended workflow in Kitty + tmux
Alt+Shift+U # unselect all
Alt+s # select column
Alt+- # hide selected
Alt+gv # unhide selected

tmux tip: Set escape-time 0 in ~/.tmux.conf for cleaner Alt prefix resolution:

set -sg escape-time 0

Registering the Plugin

This plugin loads automatically via the common-config .visidatarc.d/ loader pattern. If you want to use it standalone, add to ~/.visidatarc:

import sys
sys.path.insert(0, '/path/to/your/keybindings')
import column_selection

Or copy the file directly into ~/.config/visidata/plugins/ and import it.

Customizing the Highlight Color

Add to ~/.visidatarc:

vd.option('color_selected_col', 'bold yellow on blue', 'color for selected columns')

Example Workflow

vd data.csv

# Select columns to hide
Alt+s # select first column (e.g. 'id')
l # move right
Alt+s # select second column (e.g. 'internal_ref')
l
Alt+s # select third column (e.g. 'created_at')

# Hide them all at once
Alt+- # all 3 columns disappear

# Later, bring them back
Alt+gv # unhide the selected columns

Kitty + tmux Workflow

vd data.csv

# Clear any previous selection
Alt+Shift+U # unselect all

# Select columns to hide
Alt+s # select first column
l
Alt+s # select second column
l
Alt+s # select third column

# Hide them all at once
Alt+- # all 3 columns disappear

# Later, bring them back
Alt+gv # unhide the selected columns

Custom Plugin: Tmux Copy

The 41-tmux-copy.py plugin adds a zm keybinding that copies the current cell value to the tmux paste buffer, enabling cross-pane pasting with Ctrl+b ].

Keybindings

KeyAction
zmCopy current cell to tmux paste buffer

Source

~/.visidatarc.d/Keybindings/41-tmux-copy.py

How It Works

  • Uses cursorDisplay to get the formatted cell value (same as zY for system clipboard)
  • Pipes the value to tmux load-buffer - via subprocess.run
  • Works with any tmux pane — paste in another pane with Ctrl+b ]

Usage

# Copy a cell value
# Move to any cell, press:
zm # "copied cell to tmux buffer" appears in status

# Switch to another tmux pane
Ctrl+b ] # cell value is pasted

Prerequisite

tmux must be running. The plugin does nothing if tmux is not available.

Hands-On Practice

# Open VisiData and launch plugin index
vd -P open-plugins

# Browse available plugins
# Move cursor to a plugin you want to try
# Press Enter to install

# Or create a minimal custom status command:
mkdir -p ~/.config/visidata/plugins
cat > ~/.config/visidata/plugins/hello.py << 'EOF'
from visidata import Sheet
Sheet.addCommand('F12', 'hello-world', 'vd.status("Hello from plugin!")', 'Say hello')
EOF

# Add to ~/.visidatarc:
echo "import sys; sys.path.insert(0, '/root/.config/visidata/plugins'); import hello" >> ~/.visidatarc

# Test:
vd ~/github/practice-folder/visidata/03-join/01-servers.csv
# Press F12 → see "Hello from plugin!" in status bar

What's Next