Commands, Keymaps, and a Floating Window

A config table that merges

local defaults = { width = 60, height = 15, border = "rounded" }

function M.setup(opts)
  M.config = vim.tbl_deep_extend("force", defaults, opts or {})
end

tbl_deep_extend("force", ...) means the user’s values win, and anything they omit keeps your default.

A command and a keymap

vim.api.nvim_create_user_command("Scratch", function() M.toggle() end, {})
vim.keymap.set("n", "<leader>j", M.toggle, { desc = "Toggle scratchpad" })

Always pass desc — it is what shows up in which-key and :map.

The floating window

local buf = vim.api.nvim_create_buf(false, true)      -- not listed, scratch
local win = vim.api.nvim_open_win(buf, true, {
  relative = "editor",
  width = M.config.width,
  height = M.config.height,
  row = math.floor((vim.o.lines - M.config.height) / 2),
  col = math.floor((vim.o.columns - M.config.width) / 2),
  border = M.config.border,
})

A buffer is the text; a window is a view onto it. Floating windows are just windows positioned over the grid.

Toggle by checking vim.api.nvim_win_is_valid(win) before opening a second one.