jonathan warykowskijwarykowski

nvim-shepherd

shepherd inside Neovim: the board in a floating terminal, and todos added without leaving your buffer.

nvim-shepherd opens your shepherd board in a floating terminal, adds todos from the command line, and turns a TODO: in your code into an item. It has no dependencies of its own; it drives the shepherd you already have installed.

nvim-shepherd in action

Install

You need Neovim 0.11 or later and shepherd on your PATH; shepherd’s website covers installing it. Then, with lazy.nvim:

return {
	"jwarykowski/nvim-shepherd",
	cmd = { "Shepherd", "ShepherdAdd", "ShepherdList", "ShepherdCapture", "ShepherdStats", "ShepherdBoards" },
	keys = {
		{ "<leader>T", "<cmd>Shepherd<cr>", desc = "shepherd board" },
		{ "<leader>ta", "<cmd>ShepherdAdd<cr>", desc = "shepherd quick-add" },
		{ "<leader>tl", "<cmd>ShepherdList<cr>", desc = "shepherd list / pick" },
		{ "<leader>tc", "<cmd>ShepherdCapture<cr>", desc = "shepherd capture line" },
		{ "<leader>tc", ":ShepherdCapture<cr>", mode = "x", desc = "shepherd capture selection" },
	},
	opts = {
		-- a board per repo
		board = function() return vim.fn.fnamemodify(vim.fn.getcwd(), ":t") end,
	},
}

:checkhealth shepherd checks that the binary is found.

Commands

CommandWhat it does
:ShepherdOpen the board in a floating terminal; :Shepherd! opens every board, read-only
:ShepherdAddAdd a todo, with the same quick-add tokens as the board: :ShepherdAdd deploy api @work !h due:tomorrow
:ShepherdListPick an item, then toggle it, edit it, set its status, add a subtask, archive, remove or open its link
:ShepherdCaptureTurn the current line, or a selection, into a todo, without the comment marker and TODO:
:ShepherdStatsshepherd’s charts for the board; :ShepherdStats! for every board
:ShepherdBoardsSwitch, rename, archive or delete boards

Statusline

require("shepherd").status() returns the open count, with overdue items marked, and stays up to date as the board changes. With lualine:

lualine_x = { { function() return require("shepherd").status() end } },

Configuration

require("shepherd").setup({
	cmd = "shepherd",  -- binary name or path
	filter = nil,      -- string, or a function returning one
	board = nil,       -- string, or a function returning one
	float = { width = 0.8, height = 0.8, border = "rounded" },
	status = { icon = "" },
	watch = true,      -- keep the statusline live
})

The README has every option.