Skip to content

Neovim (scaf.nvim)

scaf.nvim provides comprehensive Neovim support for scaf.

  • Syntax highlighting with tree-sitter
  • Language injection — Query bodies highlighted as Cypher/SQL
  • LSP integration — Diagnostics and hover info
  • Neotest adapter — Run tests from Neovim
{
"rlch/scaf.nvim",
dependencies = {
"nvim-treesitter/nvim-treesitter",
},
config = function()
require("scaf").setup({})
end,
}
  1. Add parser configuration

    Add to your nvim-treesitter config:

    local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
    parser_config.scaf = {
    install_info = {
    url = "https://github.com/rlch/tree-sitter-scaf",
    files = { "src/parser.c" },
    branch = "main",
    },
    filetype = "scaf",
    }
  2. Install the parser

    Run :TSInstall scaf

  3. Verify installation

    Open a .scaf file and check highlighting works.

scaf.nvim automatically injects syntax highlighting for query bodies.

The dialect for syntax highlighting is determined from the database configured in .scaf.yaml:

neo4j: # → Cypher highlighting
uri: bolt://localhost:7687
# postgres: # → SQL highlighting
# uri: postgres://localhost:5432/db
DialectTree-sitter Language
cypher, neo4jcypher
sql, postgres, mysqlsql

Add custom mappings:

require("scaf").setup({
dialect_map = {
mongodb = "javascript",
graphql = "graphql",
},
})

If scaf-lsp is in PATH, the LSP starts automatically.

Install the LSP:

Terminal window
go install github.com/rlch/scaf/cmd/scaf-lsp@latest
require("scaf").setup({
lsp = {
-- Command to start LSP (default: {"scaf-lsp"})
cmd = { "scaf-lsp" },
-- Auto-start on .scaf files (default: true)
enabled = true,
},
})
require("scaf").start_lsp()
local lspconfig = require("lspconfig")
local configs = require("lspconfig.configs")
if not configs.scaf then
configs.scaf = {
default_config = require("scaf").get_lsp_config(),
}
end
lspconfig.scaf.setup({})

For Neovim 0.11+, scaf.nvim provides an auto-discovered LSP configuration:

vim.lsp.enable("scaf")

Run tests directly from Neovim using neotest.

{
"nvim-neotest/neotest",
dependencies = {
"rlch/scaf.nvim",
-- other adapters...
},
config = function()
require("neotest").setup({
adapters = {
require("neotest-scaf"),
},
})
end,
}
require("neotest").setup({
adapters = {
require("neotest-scaf")({
-- Command to run scaf (default: "scaf")
scaf_command = "scaf",
-- Additional arguments
args = {},
}),
},
})
CommandDescription
:Neotest runRun test under cursor
:Neotest run fileRun all tests in file
:Neotest outputShow test output
:Neotest summaryToggle summary panel

Neotest discovers:

  • Query scopes as namespaces
  • Groups as nested namespaces
  • Tests as test positions

Configure the plugin.

require("scaf").setup({
-- Dialect to tree-sitter language mappings
dialect_map = {},
-- LSP configuration
lsp = {
cmd = { "scaf-lsp" },
enabled = true,
},
})

Get the dialect for a file path.

local dialect = require("scaf").get_dialect("/path/to/file.scaf")
-- Returns: "cypher", "sql", etc.

require("scaf").get_injection_language(bufnr)

Section titled “require("scaf").get_injection_language(bufnr)”

Get the tree-sitter language for injections.

local lang = require("scaf").get_injection_language(0)
-- Returns: "cypher", "sql", etc.

Clear the config cache (useful after editing .scaf.yaml).

Manually start the LSP for the current buffer.

Get LSP configuration for use with nvim-lspconfig.

Suggested keymaps for scaf development:

-- Run test under cursor
vim.keymap.set("n", "<leader>tt", function()
require("neotest").run.run()
end, { desc = "Run test" })
-- Run all tests in file
vim.keymap.set("n", "<leader>tf", function()
require("neotest").run.run(vim.fn.expand("%"))
end, { desc = "Run file tests" })
-- Show test output
vim.keymap.set("n", "<leader>to", function()
require("neotest").output.open({ enter = true })
end, { desc = "Test output" })
-- Toggle summary
vim.keymap.set("n", "<leader>ts", function()
require("neotest").summary.toggle()
end, { desc = "Test summary" })
Error: Parser not found for language scaf

Solution: Run :TSInstall scaf after adding the parser config.

  1. Check your .scaf.yaml database setting (e.g., neo4j: for Cypher)
  2. Clear cache: :lua require("scaf").clear_cache()
  1. Verify scaf-lsp is installed: which scaf-lsp
  2. Check :LspInfo while in a .scaf file
  3. Check :LspLog for errors
  1. Ensure neotest-scaf adapter is configured
  2. Check file has .scaf extension
  3. Verify file parses correctly (no syntax errors)