Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mikew/nvim-drawer
A Drawer plugin for Neovim. AKA "persistent split" / "persistent window".
https://github.com/mikew/nvim-drawer
drawer neovim neovim-plugin nvim nvim-plugin persistent split window
Last synced: about 1 month ago
JSON representation
A Drawer plugin for Neovim. AKA "persistent split" / "persistent window".
- Host: GitHub
- URL: https://github.com/mikew/nvim-drawer
- Owner: mikew
- Created: 2024-08-25T23:22:29.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2024-09-25T00:17:32.000Z (about 2 months ago)
- Last Synced: 2024-09-29T01:42:46.104Z (about 2 months ago)
- Topics: drawer, neovim, neovim-plugin, nvim, nvim-plugin, persistent, split, window
- Language: Lua
- Homepage:
- Size: 51.8 KB
- Stars: 22
- Watchers: 1
- Forks: 0
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# nvim-drawer
A Drawer plugin for Neovim.
Ever wanted your terminal or file explorer to be at the bottom, have the same
height, and appear on all tabs at a consistent size? And when you just want to
hide it, you don't want to have to do that across all tabs?Then this plugin is for you.
## Installation
```lua
{
'mikew/nvim-drawer',
opts = {},
config = function(_, opts)
local drawer = require('nvim-drawer')
drawer.setup(opts)-- See usage and examples below.
end
}
```## Features
https://github.com/user-attachments/assets/008b0d7f-2edc-408c-9422-0fa7b7bc72ed
- Attach to any side of the screen.
- Floating drawers.
- Automatically claim buffers.
- Size is consistent across tabs.
- Open/close state is consistent across tabs.
- Drawers can be zoomed to take up the whole screen.
- Drawers remember what buffer they were editing.
- Has a tab system.
- When the last non-drawer is closed in a tab, the tab (or vim) is closed.
- Simple API.
- Uses buffers and is very flexible.## About
At its core, nvim-drawer just creates and hides windows and tries _really_ hard
to keep them consistent across tabs. You could also call a "drawer" a
persistent window, or a persistent split.Since windows in vim require a buffer, nvim-drawer creates a scratch buffer for
you.## Usage
First, you need to create a drawer via `create_drawer`:
```lua
local drawer = require('nvim-drawer')drawer.create_drawer({
size = 15,
position = 'bottom',
})
```When opened, this drawer will be at the bottom of the screen, 15 lines tall,
editing a scratch buffer.This doesn't do much, you get a nice scratch space, but to get the most out of
it, you need to use the API and add some key mappings.Your drawer has methods like ...
- `open()`: Open the drawer.
- `close()`: Close the drawer.
- `toggle()`: Toggle the drawer.
- `focus()`: Focus the drawer.
- `go()`: Go to a different tab.... and callbacks like:
- `on_did_create_buffer`: Called after a buffer is created.
- `on_did_open_window`: Called after a drawer is opened.
- `on_did_close`: Called after a drawer is closed.## Examples
### Terminal
https://github.com/user-attachments/assets/a4818838-5c9a-4e68-87eb-396c7e781a11
```lua
local drawer = require('nvim-drawer')drawer.create_drawer({
size = 15,
position = 'below',-- Automatically claim any opened terminals.
does_own_buffer = function(context)
return context.bufname:match('term://') ~= nil
end,on_vim_enter = function(event)
-- Open the drawer on startup.
event.instance.open({
focus = false,
})-- Example keymaps:
-- C-`: focus the drawer.
-- tn: open a new terminal.
-- tt: go to the next terminal.
-- tT: go to the previous terminal.
-- tz: zoom the terminal.
vim.keymap.set('n', '', function()
event.instance.focus_or_toggle()
end)
vim.keymap.set('t', '', function()
event.instance.focus_or_toggle()
end)
vim.keymap.set('n', 'tn', function()
event.instance.open({ mode = 'new' })
end)
vim.keymap.set('n', 'tt', function()
event.instance.go(1)
end)
vim.keymap.set('n', 'tT', function()
event.instance.go(-1)
end)
vim.keymap.set('n', 'tz', function()
event.instance.toggle_zoom()
end)
end,-- When a new buffer is created, switch it to a terminal.
on_did_create_buffer = function()
vim.fn.termopen(os.getenv('SHELL'))
end,-- Remove some UI elements.
on_did_open_buffer = function()
vim.opt_local.number = false
vim.opt_local.signcolumn = 'no'
vim.opt_local.statuscolumn = ''
end,-- Scroll to the end when changing tabs.
on_did_open = function()
vim.cmd('$')
end,
})
```### nvim-tree
https://github.com/user-attachments/assets/5aad5f84-ccd2-4b25-9b32-369f01b508d3
```lua
local drawer = require('nvim-drawer')drawer.create_drawer({
size = 40,
position = 'right',
should_reuse_previous_bufnr = false,
should_close_on_bufwipeout = false,on_vim_enter = function(event)
--- Open the drawer on startup.
event.instance.open({
focus = false,
})--- Example mapping to toggle.
vim.keymap.set('n', 'e', function()
event.instance.focus_or_toggle()
end)
end,--- Ideally, we would just call this here and be done with it, but
--- mappings in nvim-tree don't seem to apply when re-using a buffer in
--- a new tab / window.
on_did_create_buffer = function()
local nvim_tree_api = require('nvim-tree.api')
nvim_tree_api.tree.open({ current_window = true })
end,--- This gets the tree to sync when changing tabs.
on_did_open = function()
local nvim_tree_api = require('nvim-tree.api')
nvim_tree_api.tree.reload()vim.opt_local.number = false
vim.opt_local.signcolumn = 'no'
vim.opt_local.statuscolumn = ''
end,--- Cleans up some things when closing the drawer.
on_did_close = function()
local nvim_tree_api = require('nvim-tree.api')
nvim_tree_api.tree.close()
end,
})
```### nvim-spectre
https://github.com/user-attachments/assets/6a5595b4-e5ed-4260-9037-431eccef3477
```lua
local drawer = require('nvim-drawer')drawer.create_drawer({
position = 'below',
size = 30,does_own_window = function(context)
return context.bufname:match('spectre') ~= nil
end,on_vim_enter = function(event)
vim.keymap.set('n', 'S', function()
-- If the drawer has never been opened, call spectre. Once its
-- window opens, it will be claimed by the drawer, and we can use
-- the drawer API afterwards.
if
#vim.tbl_keys(event.instance.state.windows_and_buffers) == 0
then
require('spectre').toggle()
else
event.instance.focus_or_toggle()
end
end)
end,-- Remove some UI elements.
on_did_open_buffer = function()
vim.opt_local.number = false
vim.opt_local.signcolumn = 'no'
vim.opt_local.statuscolumn = ''
end,
})
```### `NOTES.md` / `.plan`
https://github.com/user-attachments/assets/99161d29-6c41-4209-947e-d20dcea8dd89
```lua
local drawer = require('nvim-drawer')drawer.create_drawer({
position = 'float',
-- Technically unused when using `position = 'float'`.
size = 40,win_config = {
anchor = 'NC',
margin = 2,
border = 'rounded',
width = '100%',
height = 10,
},-- Automatically claim any opened NOTES.md file.
does_own_buffer = function(context)
return context.bufname:match('NOTES.md') ~= nil
end,on_vim_enter = function(event)
vim.keymap.set('n', 'nn', function()
event.instance.focus_or_toggle()
end)
vim.keymap.set('n', 'nz', function()
event.instance.toggle_zoom()
end)
end,on_did_create_buffer = function()
vim.cmd('edit NOTES.md')
end,
})
```## API
[API.md](API.md)
## Alternatives
- [nvim-ide](https://github.com/ldelossa/nvim-ide)
- [edgy.nvim](https://github.com/folke/edgy.nvim)