SkillAgentSearch skills...

Zuzu.nvim

Neovim build system plugin

Install / Use

/learn @gitpushjoe/Zuzu.nvim
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center"> <br/> <img src="https://i.postimg.cc/FRd8XcNH/zuzu.png" height="77" width="392" alt="Logo"> <br/> <br/> <p> <em> Fast, powerful, cross-platform build system for Neovim. </em> </p> </div> <br/>

https://github.com/user-attachments/assets/c0d6c5e6-1375-44a3-81f5-7481857f1e4e

🎁 Features

  • 🎨 customizable build profiles

    • write multiple different build scripts in one profile
    • project-wide, file-specific, or even global profiles
    • restrict profiles to specific filetypes/depth
    • create generalized setup code to apply to all builds
  • 🧠 smart profile resolution

    • if multiple profiles apply to one file, zuzu will intelligently choose the best one
    • allows you to create a "fallback" profile that will apply to every file for a specific language, without setup
  • ✔ quickfix integration!

    • view runtime errors as diagnostic messages in your source code
    • jump between lines of an error traceback quickly
  • 💲 hooks! (dynamic environment variables)

    • built-in core hooks for things like $file, $dir, $parent, etc.
    • create your own core hooks that will be always be initialized in every build
    • interactive interface for editing hooks
    • create hook choices to easily choose from a list of pre-defined options
  • 🖥 versatile display options

    • create your own display strategy (command mode, split terminal right, split terminal below, etc.)
    • bind keymaps to different display strategies
    • you can even run builds in the background!
  • ⚡ blazingly fast (<1ms of overhead)

    • build scripts are also cached to avoid writing files several times on repeated runs
  • 🌐 cross-platform!

    • supports Windows, Linux, MacOS, and other UNIX-based systems

Table of Contents

⚒ Installation

✅ Requirements

  • neovim 0.10.0+ (but will likely work on older versions)

[!Important] If you are on Windows, you will need to configure Neovim to use Powershell as its shell. Add the following to your init.lua:

<details> <summary>init.lua</summary>
vim.o.shell = 'powershell.exe'
vim.o.shellxquote = ''
vim.o.shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command '
vim.o.shellquote = ''
vim.o.shellpipe = '| Out-File -Encoding UTF8 %s'
vim.o.shellredir = '| Out-File -Encoding UTF8 %s'
</details> <br/>

zuzu.nvim can be installed with the usual plugin managers:

lazy.nvim

{
	"gitpushjoe/zuzu.nvim",
	opts = {
		--- add options here
	}
}

packer.nvim

use {
	"gitpushjoe/zuzu.nvim",
	config = function ()
		require("zuzu").setup({
			--- add options here
		})
	end
}
<br/>

⚙ Configuration

<details> <summary>Default Configuration</summary>
require("zuzu").setup({
	build_count = 4,
	display_strategy_count = 4,
	keymaps = {
		build = {
			{ "zu", "ZU", "zU", "Zu" },
			{ "zv", "ZV", "zV", "Zv" },
			{ "zs", "ZS", "zS", "Zs" },
			{ "zb", "ZB", "zB", "Zb" },
		},
		reopen = {
			"z.",
			'z"',
			"z:",
		},
		new_profile = "z+",
		new_project_profile = "z/",
		edit_profile = "z=",
		edit_all_applicable_profiles = "z?",
		edit_all_profiles = "z*",
		edit_hooks = "zh",
		qflist_prev = "z[",
		qflist_next = "z]",
		stable_toggle_qflist = "z\\",
		toggle_qflist = "z|",
	},
	display_strategies = {
		require("zuzu.display_strategies").command,
		require("zuzu.display_strategies").split_terminal(
			"vertical rightbelow", -- Split modifiers
			true                   -- Use "buffer mode"
		),
		require("zuzu.display_strategies").split_terminal(
			"horizontal rightbelow",
			true
		),
		require("zuzu.display_strategies").background(
			--- Delay between each elapsed time update in milliseconds
			1000 / 8
		),
	},
	path = {
		root = require("zuzu.platform").join_path(
			vim.fn.stdpath("data"), 
			"zuzu"
		),
		atlas_filename = "atlas.json",
		last_stdout_filename = "stdout.txt",
		-- Note: last_stderr_filename is not used on Windows
		last_stderr_filename = "stderr.txt",
		compiler_filename = "compiler.txt",
		reflect_filename = "reflect.txt",
	},
	core_hooks = {
		-- Note: these are actually "env:file", "env:dir", etc. on Windows
		{ "file", require("zuzu.hooks").file },
		{ "dir", require("zuzu.hooks").directory },
		{ "parent", require("zuzu.hooks").parent_directory },
		{ "base", require("zuzu.hooks").base },
		{ "filename", require("zuzu.hooks").filename },
	},
	colors = {
		reopen_stderr = require("zuzu.colors").bright_red,
		reflect = require("zuzu.colors").bright_yellow,
	},
	zuzu_function_name = "zuzu_cmd",
	prompt_on_simple_edits = false,
	hook_choices_suffix = "__c",
	compilers = {
		-- https://vi.stackexchange.com/a/44620
		{ "python3", '%A %#File "%f"\\, line %l\\, in %o,%Z %#%m' },
		{ "lua", "%E%\\\\?lua:%f:%l:%m,%E%f:%l:%m" },
		-- https://github.com/felixge/vim-nodejs-errorformat/blob/master/ftplugin/javascript.vim
		-- Note: This will also work for bun.
		{
			"node",
			[[%AError: %m,%AEvalError: %m,%ARangeError: %m,%AReferenceError: %m,%ASyntaxError: %m,%ATypeError: %m,%Z%*[\ ]at\ %f:%l:%c,%Z%*[\ ]%m (%f:%l:%c),%*[\ ]%m (%f:%l:%c),%*[\ ]at\ %f:%l:%c,%Z%p^,%A%f:%l,%C%m,%-G%.%#]],
		},
		{
			"bash",
			"%E%f: line %l: %m",
		},
	},
	qflist_as_diagnostic = true,
	reverse_qflist_diagnostic_order = false,
	qflist_diagnostic_error_level = "WARN",
	write_on_run = true,
	fold_profiles_in_editor = true,
	reflect = false,
	newline_after_reflect = true,
	newline_before_reopen = false,
	enter_closes_buffer = true,
	reopen_reflect = true,
})

|Key |Explanation | |-|-| |build_count|The number of different builds for each profile. |display_strategy_count|The number of display strategies. The 4 strategies by default are "command-mode" :!source run.sh, split-right-terminal, and split-below-terminal, and background. |keymaps.build|A 2D list of keymaps. The first row is mapped to the first display strategy, the second row to the second, and so on. The first keymap in each row is mapped to build #1, the second to build #2, and so on. So, for example, pressing "zV" will run the 3rd build in the current profile, with the 2nd build display style (split-right-terminal). Use "" to not bind any keymap. |keymaps.reopen|Every time zuzu is run, its output is saved to the path.root directory at path.last_output_filename. Pressing keymap.reopen[i] will show the output from the last time zuzu was run, using display strategy #i. |keymaps.new_profile|Creates a new profile. Sets the root to the current file and sets the depth to 0. |keymaps.new_project_profile|Creates a new profile. Sets the root to the directory of the current file and sets the depth to -1 (any depth). |keymaps.edit_profile|Shows the profile for the current file (the most applicable profile). |keymaps.edit_all_applicable_profiles|Shows all applicable profiles for the current file, in order from least applicable to most. |keymaps.edit_all_profiles|Shows all profiles. |keymaps.edit_hooks|Opens an interactive menu for updating a hook. |keymaps.qflist_prev|Opens the quickfix list if it's closed, and jumps to the previous error (see :cprevious). |keymaps.qflist_next|Opens the quickfix list if it's closed, and jumps to the nextious error (see :cnext). |keymaps.stable_toggle_qflist|Toggles the state of the quickfix list, keeping the cursor in the current window. |keymaps.toggle_qflist|Toggles the state of the quickfix list, putting the cursor in the quickfix list. Also toggles whether quickfix diagnostics are shown/hidden. |display_strategies|List of display strategies. |path.root|The root directory zuzu will use to save any files its creates. |path.atlas_filename|The filename for the atlas saved to path.root. |path.last_stdout_filename|The filename to save the stdout to from the last time zuzu was run. |path.last_stderr_filename|The filename to save the stderr to from the last time zuzu was run. |path.compiler_filename|The filename to save the compiler name to from the last time zuzu was run. |path.reflect_filename|The filename to save the source code of the build being run to. See Reflect. |core_hooks|A list of tuples. The first item in each tuple is the name of the hook, and the second item is a callback to get the value of the hook. For example, by default, the hooks $file and $dir will be automatically initialized to the current file and directory, respectively, before every build. |zuzu_function_name|To run a build, zuzu generates a shell file (.sh on UNIX-based, .ps1 on windows) and puts the build script in a function. This is the name of the function. |colors.reopen_stderr|The color to display errors in when reopening the output from the last run. Cross-pl

Related Skills

View on GitHub
GitHub Stars66
CategoryDevelopment
Updated1mo ago
Forks0

Languages

Lua

Security Score

100/100

Audited on Feb 12, 2026

No findings