https://github.com/zerochae/dbab.nvim
https://github.com/zerochae/dbab.nvim
Last synced: 24 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/zerochae/dbab.nvim
- Owner: zerochae
- License: mit
- Created: 2026-02-05T08:24:09.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-02-19T00:38:10.000Z (2 months ago)
- Last Synced: 2026-02-19T06:38:45.655Z (2 months ago)
- Language: Lua
- Size: 12.4 MB
- Stars: 23
- Watchers: 0
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-neovim-sorted - zerochae/dbab.nvim
- awesome-neovim - zerochae/dbab.nvim - Lightweight database client with a modern UI and async execution. (Database / Automation)
README
# dbab.nvim
A lightweight database client for Neovim. Query databases directly from your editor.

## Features
- **Multi-database support**: PostgreSQL, MySQL, MariaDB, SQLite
- **Flexible layout**: Choose from presets or define your own pane arrangement
- **Schema browser**: Navigate schemas, tables, and columns in sidebar
- **Query editor**: Write and execute SQL with syntax highlighting
- **Query history**: Track executed queries with timing, re-execute or load to editor
- **Multiple query tabs**: Work with multiple queries simultaneously
- **Save queries**: Store frequently used queries per connection
- **Result viewer**: Multiple display styles (table, json, vertical, markdown, raw) with type-aware highlighting
## Layout
### Classic (default)

```
┌─────────────────────┬─────────────────────────────────────┐
│ Sidebar (20%) │ Query Editor (80%) │
├─────────────────────┼─────────────────────────────────────┤
│ History (20%) │ Result Viewer (80%) │
└─────────────────────┴─────────────────────────────────────┘
```
### Wide

```
┌─────────────────────┬─────────────────────┬───────────────┐
│ Sidebar (33%) │ Query Editor (34%) │ History (33%) │
├───────────────────────────────────────────────────────────┤
│ Result Viewer (100%) │
└───────────────────────────────────────────────────────────┘
```
## Requirements
- Neovim >= 0.9.0
- Database CLI tools:
- `psql` for PostgreSQL
- `mysql` for MySQL/MariaDB
- `sqlite3` for SQLite
- [nui.nvim](https://github.com/MunifTanjim/nui.nvim)
- [vim-dadbod](https://github.com/tpope/vim-dadbod) (optional: for `executor = "dadbod"`)
- [plenary.nvim](https://github.com/nvim-lua/plenary.nvim) (optional: for async execution)
## Installation
### lazy.nvim
```lua
{
"zerochae/dbab.nvim",
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim", -- Optional: for async execution
"tpope/vim-dadbod", -- Optional: for executor = "dadbod"
"hrsh7th/nvim-cmp", -- Optional: for nvim-cmp autocompletion
},
-- For blink.cmp, the source is included in this plugin (blink_dbab)
config = function()
require("dbab").setup({
connections = {
{ name = "local", url = "postgres://user:pass@localhost:5432/mydb" },
{ name = "prod", url = "$DATABASE_URL" }, -- supports env vars
},
})
end,
}
```
## Autocompletion (Optional)
### nvim-cmp
If you use `nvim-cmp`, add `dbab` to your sources to enable SQL autocompletion (tables, columns, keywords):
```lua
require("cmp").setup({
sources = {
{ name = "dbab" },
-- other sources...
},
})
```
### blink.cmp
If you use `blink.cmp`, add `dbab` to your sources:
```lua
require("blink.cmp").setup({
sources = {
default = { "lsp", "path", "snippets", "buffer", "dbab" },
providers = {
dbab = {
name = "dbab",
module = "blink_dbab",
},
},
},
})
```
## Usage
### Commands
| Command | Description |
|---------|-------------|
| `:Dbab` | Open dbab sidebar |
| `:DbabClose` | Close dbab |
### Sidebar Keymaps
| Key | Action |
|-----|--------|
| `` / `o` | Toggle node / Open query |
| `` | Move to editor |
| `S` | Select table (SELECT *) |
| `i` | Insert table (INSERT template) |
| `d` | Delete saved query |
| `q` | Close |
### Editor Keymaps
| Key | Action |
|-----|--------|
| `` | Execute query |
| `` | Save query |
| `gt` / `gT` | Next / Previous tab |
| `w` | Close tab |
| `` | Move to result |
| `q` | Close |
### History Keymaps
| Key | Action |
|-----|--------|
| `` | Load or execute query (based on config) |
| `R` | Re-execute query immediately |
| `y` | Copy query to clipboard |
| `d` | Delete entry |
| `C` | Clear all history |
| `` | Move to sidebar |
| `` | Move to result |
| `q` | Close |
### Result Keymaps
| Key | Action |
|-----|--------|
| `y` | Yank current row as JSON |
| `Y` | Yank all rows as JSON |
| `` | Move to sidebar |
| `` | Move to editor |
| `q` | Close |
## Screenshots
### Schema Browser

### Query Result with Type Highlighting

### Query History

## Configuration
```lua
require("dbab").setup({
connections = {
{ name = "local", url = "postgres://localhost/mydb" },
},
executor = "cli", -- "cli" (self-contained) | "dadbod" (requires vim-dadbod)
layout = "classic", -- "classic" | "wide" | custom layout table
sidebar = {
width = 0.2,
use_brand_icon = false, -- true: per-DB icons, false: generic db icon
use_brand_color = false, -- true: per-DB brand colors, false: single color (Number)
show_brand_name = false, -- true: show [postgres] label, false: icon + name only
show_system_schemas = true,
},
editor = {
show_tabbar = true, -- show tab bar above editor
},
result = {
max_width = 120,
max_height = 20,
show_line_number = true,
header_align = "fit", -- "fit" or "full"
style = "table", -- "table", "json", "raw", "vertical", "markdown"
},
history = {
width = 0.2,
style = "compact", -- "compact" or "detailed"
max_entries = 100,
on_select = "execute", -- "execute" or "load"
persist = true,
filter_by_connection = true,
query_display = "auto", -- "short", "full", or "auto"
short_hints = { "where", "join", "order", "group", "limit" },
},
keymaps = {
open = "db",
execute = "",
close = "q",
sidebar = {
toggle_expand = { "", "o" },
refresh = "R",
rename = "r",
new_query = "n",
copy_name = "y",
insert_template = "i",
delete = "d",
copy_query = "c",
paste_query = "p",
to_editor = "",
to_history = "",
},
history = {
select = "",
execute = "R",
copy = "y",
delete = "d",
clear = "C",
to_sidebar = "",
to_result = "",
},
editor = {
execute_insert = "",
execute_leader = "r",
save = "",
next_tab = "gt",
prev_tab = "gT",
close_tab = "w",
to_result = "",
to_sidebar = "",
},
result = {
yank_row = "y",
yank_all = "Y",
to_sidebar = "",
to_editor = "",
},
},
highlights = {
-- Override any Dbab highlight group
-- DbabHeader = { bg = "#ff6600", fg = "#000000" },
},
})
```
### Layout Presets
| Preset | Description |
|--------|-------------|
| `"classic"` | 4-pane layout (sidebar 20%, history 20%) |
| `"wide"` | 3-column top + full-width bottom (sidebar 33%, history 33%) |
### Custom Layout
Define your own pane arrangement:
```lua
-- No history panel
layout = {
{ "sidebar", "editor" },
{ "result" },
}
-- Editor on the left
layout = {
{ "editor", "sidebar" },
{ "result", "history" },
}
```
Components: `"sidebar"`, `"editor"`, `"history"`, `"result"` (editor and result are required)
### Result Styles
Configure with `result.style`:
| Style | Description |
|-------|-------------|
| `"table"` | Table with zebra striping and type-aware highlighting (default) |
| `"json"` | JSON format with Treesitter syntax highlighting |
| `"vertical"` | One record per block, column names on the left (like `psql \x`) |
| `"markdown"` | Markdown table with Treesitter syntax highlighting |
| `"raw"` | Unprocessed CLI output |
```lua
result = {
style = "vertical",
},
```
#### table

#### raw

#### json

#### vertical

#### markdown

### History Styles
Configure with `history.style`:
| Style | Description |
|-------|-------------|
| `"compact"` | One line per entry with verb, target, hints (default) |
| `"detailed"` | Multi-line: full query with syntax highlighting + metadata below |
```lua
history = {
style = "detailed",
},
```
### Sidebar Display Options
Control how database connections appear in the sidebar:
```lua
sidebar = {
use_brand_icon = false, -- default
use_brand_color = false, -- default
show_brand_name = false, -- default
},
```
| Option | `false` (default) | `true` |
|--------|-------------------|--------|
| `use_brand_icon` | Generic DB icon for all connections | Per-DB brand icons (PostgreSQL, MySQL, etc.) |
| `use_brand_color` | Single color (`Number` highlight) | Per-DB brand colors (blue, red, green, etc.) |
| `show_brand_name` | `icon my_db` | `icon [postgres] my_db` |
## Highlight Groups
All highlight groups can be overridden by defining them before `setup()`.
Groups marked with **(computed)** are always recalculated based on your colorscheme.
### Result
| Group | Default | Description |
|-------|---------|-------------|
| `DbabRowOdd` | **(computed)** | Odd row background |
| `DbabRowEven` | **(computed)** | Even row background |
| `DbabHeader` | **(computed)** | Result header (from `Function` fg) |
| `DbabSeparator` | `Comment` | Result separator lines |
| `DbabCellActive` | `CursorLine` | Active cell |
### Window
| Group | Default | Description |
|-------|---------|-------------|
| `DbabFloat` | `NormalFloat` | Float window background |
| `DbabBorder` | `WinSeparator` | Window border |
| `DbabTitle` | `Title` | Window title |
### Data Types
| Group | Default | Description |
|-------|---------|-------------|
| `DbabNull` | `Comment` | NULL values |
| `DbabNumber` | `Number` | Numeric values |
| `DbabString` | `Normal` | String values |
| `DbabBoolean` | `Boolean` | Boolean values |
| `DbabDateTime` | `Special` | Date/time values |
| `DbabUuid` | `Constant` | UUID values |
| `DbabJson` | `Function` | JSON values |
### Schema
| Group | Default | Description |
|-------|---------|-------------|
| `DbabTable` | `Type` | Table names |
| `DbabKey` | `Keyword` | Key names |
| `DbabPK` | `ErrorMsg` | Primary key (bold) |
| `DbabFK` | `Function` | Foreign key (bold) |
### Sidebar
| Group | Default | Description |
|-------|---------|-------------|
| `DbabIconDb` | `Number` | Default DB icon color (`use_brand_color = false`) |
| `DbabIconPostgres` | `fg=#4169E1` | PostgreSQL brand color (bold) |
| `DbabIconMysql` | `fg=#4479A1` | MySQL brand color (bold) |
| `DbabIconMariadb` | `fg=#003545` | MariaDB brand color (bold) |
| `DbabIconSqlite` | `fg=#003B57` | SQLite brand color (bold) |
| `DbabIconRedis` | `fg=#FF4438` | Redis brand color (bold) |
| `DbabIconMongodb` | `fg=#47A248` | MongoDB brand color (bold) |
| `DbabSidebarIconConnection` | `Number` | Connection icon |
| `DbabSidebarIconActive` | `String` | Active connection icon |
| `DbabSidebarIconNewQuery` | `Function` | New query icon |
| `DbabSidebarIconBuffers` | `Function` | Buffers icon |
| `DbabSidebarIconSaved` | `Keyword` | Saved queries icon |
| `DbabSidebarIconSchemas` | `Special` | Schemas icon |
| `DbabSidebarIconSchema` | `Type` | Schema icon |
| `DbabSidebarIconTable` | `Type` | Table icon |
| `DbabSidebarIconColumn` | `Function` | Column icon |
| `DbabSidebarIconPK` | `ErrorMsg` | Primary key icon |
| `DbabSidebarText` | `Normal` | Default text |
| `DbabSidebarTextActive` | `String` | Active item text (bold) |
| `DbabSidebarType` | `Comment` | Type annotation |
### History
| Group | Default | Description |
|-------|---------|-------------|
| `DbabHistoryHeader` | `Title` | Section header (bold) |
| `DbabHistoryRowOdd` | **(computed)** | Odd row background |
| `DbabHistoryRowEven` | **(computed)** | Even row background |
| `DbabHistoryTime` | `Comment` | Timestamp |
| `DbabHistoryVerb` | `Keyword` | SQL verb |
| `DbabHistoryTarget` | `Type` | Target table name |
| `DbabHistoryDuration` | `Number` | Execution duration |
| `DbabHistoryConnName` | `Normal` | Connection name |
| `DbabHistorySelect` | `Function` | SELECT queries |
| `DbabHistoryInsert` | `String` | INSERT queries |
| `DbabHistoryUpdate` | `Type` | UPDATE queries |
| `DbabHistoryDelete` | `ErrorMsg` | DELETE queries |
| `DbabHistoryCreate` | `String` | CREATE statements |
| `DbabHistoryDrop` | `ErrorMsg` | DROP statements |
| `DbabHistoryAlter` | `Special` | ALTER statements |
| `DbabHistoryTruncate` | `WarningMsg` | TRUNCATE statements |
Hint badges (compact mode):
| Group | Default | Description |
|-------|---------|-------------|
| `DbabHistoryHintWhere` | `WarningMsg` | WHERE clause |
| `DbabHistoryHintJoin` | `Special` | JOIN clause |
| `DbabHistoryHintOrder` | `Keyword` | ORDER BY |
| `DbabHistoryHintGroup` | `Type` | GROUP BY |
| `DbabHistoryHintLimit` | `Number` | LIMIT |
### Tab Bar
| Group | Default | Description |
|-------|---------|-------------|
| `DbabTabActive` | `bg=#3a3a4a` | Active tab (bold) |
| `DbabTabActiveIcon` | `bg=#3a3a4a fg=#a6e3a1` | Active tab icon |
| `DbabTabInactive` | `Comment` | Inactive tab |
| `DbabTabInactiveIcon` | `Comment` | Inactive tab icon |
| `DbabTabModified` | `WarningMsg` | Modified indicator |
| `DbabTabIconSaved` | `String` | Saved query icon |
| `DbabTabIconUnsaved` | `Function` | Unsaved query icon |
| `DbabTabbarBg` | `Normal` | Tab bar background |
### Customization
Override highlights via `setup()`:
```lua
require("dbab").setup({
highlights = {
DbabHeader = { bg = "#ff6600", fg = "#000000" },
DbabNull = { fg = "#555555", italic = true },
},
})
```
## Connection URL Format
```
postgres://user:password@host:port/database
mysql://user:password@host:port/database
mariadb://user:password@host:port/database
sqlite:///path/to/database.db
```
Environment variables are supported: `$DATABASE_URL` or `${DATABASE_URL}`
## Acknowledgements
This project was inspired by excellent existing plugins:
- [vim-dadbod-ui](https://github.com/kristijanhusak/vim-dadbod-ui): The classic DB UI for Vim/Neovim.
- [nvim-dbee](https://github.com/kndndrj/nvim-dbee): A modern approach to DB client in Neovim.
`dbab.nvim` aims to provide a lightweight, self-contained alternative with a modern Lua-based UI. It can optionally integrate with [vim-dadbod](https://github.com/tpope/vim-dadbod) via `executor = "dadbod"`.
## License
MIT