No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-20 00:50:53 +05:00
doc feat(authoring): replace per-template insert actions with one picker action 2026-10-20 00:43:44 +05:00
lsp feat(lsp): in-process code action server, :Liquibase command and plugin glue 2026-10-20 00:37:06 +05:00
lua/liquibase feat(authoring): replace per-template insert actions with one picker action 2026-10-20 00:43:44 +05:00
plugin feat(lsp): in-process code action server, :Liquibase command and plugin glue 2026-10-20 00:37:06 +05:00
tests test: read the reference project path from NVIM_TEST_REFERENCE_PROJECT 2026-10-20 00:44:47 +05:00
.gitignore chore: initialize repository 2026-10-20 00:15:06 +05:00
.luarc.json chore: initialize repository 2026-10-20 00:15:06 +05:00
.stylua.toml chore: initialize repository 2026-10-20 00:15:06 +05:00
LICENSE chore: initialize repository 2026-10-20 00:15:06 +05:00
Makefile chore: initialize repository 2026-10-20 00:15:06 +05:00
README.md docs: install from git.bivashy.dev 2026-10-20 00:50:53 +05:00

liquibase.nvim

Liquibase authoring helpers for Neovim, modelled on the Liquibase support in IntelliJ IDEA Ultimate. Most features are offered as LSP code actions from an in-process server, and all of them are available through a single :Liquibase command.

The main use case is turning SQL DDL into Liquibase changesets without starting a database. A built-in PostgreSQL-oriented parser converts CREATE TABLE, ALTER TABLE, indexes, sequences and similar statements into YAML, XML, JSON or formatted SQL changesets, including rollbacks where they can be derived. Statements the parser does not understand are kept as sql changes.

Features

Authoring (no external tools required):

  • Convert the SQL under the cursor or in a selection to a YAML, XML, JSON or formatted SQL changeset.
  • Wrap plain SQL statements in formatted SQL changesets in place, with --rollback lines.
  • Add a derived rollback to a formatted SQL changeset.
  • Insert changeset templates (createTable, addColumn, createIndex, ...) as snippets after the changeset under the cursor. The code action "Insert changeset..." opens a picker over the templates.
  • Paste SQL from the clipboard as a changeset in the current changelog.

Runtime (needs the Liquibase CLI and Java, or Docker):

  • update, update-sql, status, validate, history, rollback-count, rollback-count-sql, tag, clear-checksums and changelog-sync. Output goes to a scratch split. Commands that change the database ask for confirmation first.
  • new [name]: create the next numbered changelog file and register it in the master changelog.
  • from-ddl [file] and diff-ddl [file]: use a throwaway PostgreSQL container to generate changesets from DDL, or to diff DDL against the current changelog.
  • connection and info: choose the active connection and show the detected project.

Requirements

  • Neovim 0.11 or newer (developed on 0.12).
  • Runtime commands: the liquibase CLI (5.x tested) with Java, or Docker. Without the executable the commands run in the image from docker.image with the project mounted and --network host.
  • from-ddl and diff-ddl always need Docker and support PostgreSQL images only.
  • A JDBC driver for the target database. Liquibase 5 Community bundles only H2. The plugin looks in the Liquibase installation (lib/, internal/lib/), then in ~/.m2/repository (PostgreSQL, MySQL, MariaDB, H2, SQL Server), and passes the jar with --classpath. Set classpath to choose a jar explicitly, or install one with lpm add <driver>.

Installation

With lazy.nvim:

{
  url = "https://git.bivashy.dev/bivashy/liquibase.nvim",
  -- or, for a local checkout:
  -- dir = "~/Code/Project/nvim/liquibase.nvim",
  init = function()
    vim.g.liquibase = { author = "your.name" }
  end,
}

No setup() call is required. The plugin enables its language server configuration on startup.

Usage

Place the cursor on a SQL statement (or select several) and run :lua vim.lsp.buf.code_action() or your picker of choice. The server attaches to every sql buffer, and to YAML, XML and JSON buffers that contain databaseChangeLog.

The same operations are available as subcommands:

:Liquibase convert yaml        " also xml, json, sql; accepts a range
:Liquibase wrap                " whole buffer, or a range
:Liquibase insert createTable  " template name completes
:Liquibase paste [format]
:Liquibase update-sql

Mappings are not defined by default. Available <Plug> targets: (liquibase-convert), (liquibase-wrap), (liquibase-insert), (liquibase-paste), (liquibase-update), (liquibase-update-sql), (liquibase-status), (liquibase-new), (liquibase-from-ddl) and (liquibase-diff-ddl).

vim.keymap.set({ "n", "x" }, "<leader>lc", "<Plug>(liquibase-convert)")

Configuration

Set vim.g.liquibase to a table (or a function returning one) before or after the plugin loads. Defaults:

vim.g.liquibase = {
  lsp = true,                  -- enable the language server configuration
  author = nil,                -- nil: git user.name, then $USER
  changeset_id = "timestamp",  -- "timestamp", "sequence" or function(index)
  format = nil,                -- default output format, nil: match the changelog, else "yaml"
  output = "split",            -- "split", "vsplit", "tab" or "register"
  one_change_per_changeset = true,
  rollback = true,             -- emit derivable rollbacks
  -- runtime
  cmd = nil,                   -- nil: liquibase if executable, else Docker
  classpath = nil,             -- JDBC driver jar or classpath passed as --classpath
  docker = { image = "liquibase/liquibase:latest", database_image = "postgres:17-alpine" },
  connections = {},            -- name -> { url, username, password }
  connection = nil,
  profile = nil,               -- Spring/Quarkus profile
  changelog_dir = nil,
  file_name = "%03d_%s",
}

Connections

Connections are collected from several sources. Later sources override earlier ones:

  1. vim-dadbod (vim.g.dbs, vim.b.db, vim.g.db)
  2. the project's application configuration (Spring, Quarkus, Micronaut)
  3. liquibase.properties
  4. the connections option

:Liquibase connection selects the active one for the session. Passwords are passed to Liquibase through environment variables, not on the command line. Quarkus dev services (a datasource without a URL) yield no connection; set connections or use dadbod instead. See :help liquibase-connections.

See :help liquibase-config for details.

Health check

:checkhealth liquibase reports the Neovim version, configuration validity, whether the language server is enabled, and whether the authoring and runtime modules loaded.

Documentation

:help liquibase has the full reference, including the Lua API for other plugins.

License

See LICENSE.