First-class Wave language support for Neovim. It uses the shared wave-agape language server and follows the behavior of the official VS Code and IntelliJ extensions.
.wavefile detection and syntax highlighting based on the current Wave lexer- Automatic
wave-agapeLSP startup over stdio - Diagnostics, completion, hover, definitions, references, rename, symbols, signature help, and import navigation
- Ctrl+click and completion for local,
std::, and external package imports - Wave-aware comments, matching, indentation, and
:compiler wavec :WaveRunand:WaveBuildterminal commands- No required plugin dependencies and no global keymaps
:checkhealth wavediagnostics
Neovim 0.10 or newer is required. wave-agape and wavec are external
executables; this plugin does not download or update them.
There is no required central Neovim plugin registry. Plugin managers install this repository directly from GitHub, and Git tags/releases provide stable version pins.
Install the language server first:
cargo install --git https://github.com/wavefnd/wave-agape --tag v0.2.0 --lockedInstall the Wave compiler separately if you want :WaveRun and :WaveBuild.
See wavefnd/Wave for compiler packages and
build instructions.
Create ~/.config/nvim/lua/plugins/wave.lua:
return {
{
"wavefnd/nvim-wave",
event = { "BufReadPre *.wave", "BufNewFile *.wave" },
opts = {},
keys = {
{ "<leader>wr", "<cmd>WaveRun<cr>", desc = "Run Wave file" },
{ "<leader>wb", "<cmd>WaveBuild<cr>", desc = "Build Wave file" },
},
},
}Using lazy = false instead of the two events is also valid. Avoid only
setting ft = "wave": the plugin supplies the .wave filetype detector, so
it needs to load before Neovim detects that filetype.
-- packer.nvim
use({
"wavefnd/nvim-wave",
})wave.nvim starts with its defaults automatically. A setup() call is only
needed to override them. Set vim.g.wave_nvim_disable_auto_setup = 1 before
plugins load if fully manual startup is preferred.
The standalone scripts detect LazyVim/lazy.nvim. For LazyVim they create
lua/plugins/wave.lua; for other configurations they install or update a
native Neovim start package.
Unix/macOS:
curl -fsSLO https://raw.githubusercontent.com/wavefnd/nvim-wave/master/scripts/install.sh
sh install.sh
# Or install wave-agape at the same time (requires Cargo):
sh install.sh --with-lsp
# Force a specific mode if automatic detection is not desired:
sh install.sh --lazy
sh install.sh --nativeWindows PowerShell:
Invoke-WebRequest https://raw.githubusercontent.com/wavefnd/nvim-wave/master/scripts/install.ps1 -OutFile install.ps1
.\install.ps1
# Or install wave-agape at the same time (requires Cargo):
.\install.ps1 -InstallLsp
# Force a specific mode if automatic detection is not desired:
.\install.ps1 -Mode Lazy
.\install.ps1 -Mode NativeBoth scripts respect NVIM_APPNAME, XDG_CONFIG_HOME, and XDG_DATA_HOME.
Pass an explicit native destination as the shell argument or as PowerShell's
-Target option. By default they leave
wave-agape and wavec installation separate so users control native binary
versions and build features; --with-lsp/-InstallLsp opts into the Cargo LSP
installation. The compiler always remains a separate install because its LLVM
target selection is system-specific.
The defaults work when wave-agape and wavec are on PATH:
require("wave").setup({
lsp = {
enabled = true,
cmd = { "wave-agape" },
args = {},
cmd_env = nil,
root_markers = { "wave.toml", ".git" },
single_file_support = true,
capabilities = {},
init_options = {
client = "neovim",
imports = {
standardLibraryPath = "", -- defaults to ~/.wave/lib/wave/std
dependencyRoots = {}, -- equivalent to wavec --dep-root
dependencies = {}, -- e.g. { math = "/path/to/math" }
},
},
settings = {},
on_attach = nil,
},
compiler = {
cmd = "wavec",
args = {},
auto_save = true,
terminal = {
position = "botright", -- botright, topleft, left, or right
size = 12,
start_insert = true,
},
},
})An explicit local server path is useful during development:
require("wave").setup({
lsp = {
cmd = { "/path/to/wave-agape/target/release/wave-agape" },
},
compiler = {
cmd = "/path/to/wavec",
},
})lsp.root_dir may be either a fixed path or a function accepting
(file_path, bufnr). User capabilities are merged into Neovim's standard LSP
capabilities, so completion plugins can pass their enhanced capabilities
without replacing the defaults.
To configure LSP keymaps, use the regular Neovim/LazyVim LspAttach mechanism.
wave.nvim deliberately does not overwrite any mappings.
Import paths use the same layout as wavec: std::io::format maps into the
Wave standard library and package::module searches the configured dependency
roots or explicit package map. Relative paths are resolved from the LSP root.
| Command | Description |
|---|---|
:WaveRun [args...] |
Save and run the current file with wavec run |
:WaveBuild [args...] |
Save and build the current file with wavec build |
:WaveLspStart |
Start wave-agape for the current buffer |
:WaveLspStop |
Stop the attached wave-agape client |
:WaveLspRestart |
Restart the attached wave-agape client |
:WaveLspInfo |
Show the attached client and workspace root |
:checkhealth wave |
Check Neovim, wave-agape, wavec, and filetype setup |
Compiler arguments configured in compiler.args are placed before run or
build. Arguments passed to :WaveRun and :WaveBuild are placed after the
source file.
If completion or diagnostics do not appear:
- Run
wave-agape --versionin a shell. - Open a
.wavefile and check:set filetype?(it should bewave). - Run
:checkhealth waveand:WaveLspInfo. - Inspect Neovim's LSP log with
:LspLog.
If another configuration already starts wave-agape, set
lsp.enabled = false here to keep only the filetype, syntax, compiler, and
editor support.
CI tests every branch push and pull request against Neovim 0.10.4, stable, and
nightly. Commits on master using Conventional Commit prefixes (fix:,
feat:, or a breaking feat!:) update an automated Release Please pull
request. Merging that release pull request updates CHANGELOG.md and
version.txt, creates a semantic Git tag, and publishes the corresponding
GitHub Release.
For Release Please to open pull requests, enable Allow GitHub Actions to
create and approve pull requests under the repository's Actions settings if
the organization has disabled it. The included workflow uses the repository's
built-in GITHUB_TOKEN by default, so no publishing secret or central registry
account is required. Optionally add a RELEASE_PLEASE_TOKEN repository secret
(a fine-grained token with Contents and Pull requests write access) if release
pull requests must trigger other workflows such as required CI checks.