initial commit

This commit is contained in:
swaits committed 2023-10-30 22:04:32 -06:00
commit b8dfde353a
4 files changed
+283

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
indent_type = "Spaces"
indent_width = 2
column_width = 100
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright © 2023 Stephen Waits <steve@waits.net>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+93
View File
@@ -0,0 +1,93 @@
# Neovim Scratch Buffer Plugin
This plugin provides a simple way to work with scratch buffers in Neovim. It
allows you to quickly open a scratch buffer in your current window or in a new
split window. The plugin also offers the flexibility to configure the default
name of the scratch buffer.
This plugin is based on
[vim-scratch](https://github.com/duff/vim-scratch/tree/master), but written in
lua for Neovim.
## Features
- Open a scratch buffer in the current window.
- Open a scratch buffer in a new split window.
- Automatically switch to an existing scratch buffer if it's already open.
- Configure the default name for the scratch buffer.
- The scratch buffer acts as a temporary workspace and is not backed by a file.
## Installation
To install this plugin, you can use your favorite Neovim package manager. For example:
### [lazy](https://github.com/folke/lazy.nvim) (recommended)
```lua
{
"https://git.sr.ht/~swaits/scratch.nvim",
lazy = true,
keys = {
{ "<leader>bs", "<cmd>Scratch<cr>", desc = "Scratch Buffer", mode = "n" },
{ "<leader>bS", "<cmd>ScratchSplit<cr>", desc = "Scratch Buffer (split)", mode = "n" },
},
cmd = {
"Scratch",
"ScratchSplit",
},
opts = {},
}
```
### [pckr](https://github.com/lewis6991/pckr.nvim)
```lua
{
"https://git.sr.ht/~swaits/scratch.nvim",
config = function()
require("scratch").setup()
end
}
```
### [vim-plug](https://github.com/junegunn/vim-plug)
```vim
Plug 'https://git.sr.ht/~swaits/scratch.nvim'
lua require("scratch").setup()
```
### Configuring
The default configuration options are listed below:
```lua
opts = {
-- The name of the scratch buffer
buffer_name = "_SCRATCH_",
}
```
## Usage
### Commands
The plugin provides two commands:
- `:Scratch` — Opens or switches to the scratch buffer in the current window.
- `:ScratchSplit` — Opens or switches to the scratch buffer in a new split window.
### Lua Functions
You can also use the plugin's Lua functions directly:
- `require('scratch').open()` — Equivalent to `:Scratch`.
- `require('scratch').split()` — Equivalent to `:ScratchSplit`.
## License
[MIT License](LICENSE)
## Contributing
Contributions are welcome! Feel free to open issues or submit pull requests.
+166
View File
@@ -0,0 +1,166 @@
local M = {}
--- Checks if the current buffer is modified.
--
-- Returns:
-- bool: True if the buffer is modified, False otherwise.
--
local function is_buffer_modified()
local buf = vim.api.nvim_get_current_buf()
return vim.api.nvim_buf_get_option(buf, "modified")
end
--- Switch to an existing buffer in Neovim.
--
-- This function checks if a buffer is already open in a window. If it is, it
-- switches to that window. If it is not, it switches to the existing buffer.
--
-- @param new_window (boolean) Whether to open the buffer in a new window. If
-- true, the buffer will be opened in a new split window. If false, the buffer
-- will be opened in the current window.
-- @param buffer_num (number) The buffer number of the buffer.
--
-- @return None
--
local function switch_to_existing_buffer(new_window, buffer_num)
-- Check if the buffer number is valid
if type(buffer_num) ~= "number" or buffer_num < 1 then
error("Invalid buffer number provided to switch_to_existing_buffer")
return
end
-- See if this buffer is already open in a window
local window_num = vim.fn.bufwinnr(buffer_num)
if window_num ~= -1 then
-- Switch to that window (even if we're already there)
vim.cmd(window_num .. " wincmd w")
else
-- Switch to the existing scratch buffer
local cmd = new_window and "split +buffer " or "buffer "
vim.cmd(cmd .. buffer_num)
end
end
--- Creates a new scratch buffer in Neovim.
--
-- This function creates a new scratch buffer in Neovim, either in a new window
-- or by editing the current buffer. The buffer is configured to work like a
-- scratch buffer, meaning it is not backed by a file and has specific options
-- set.
--
-- @param new_window (boolean) Whether to create the scratch buffer in a new
-- window. If true, the buffer will be created in a new window. If false, the
-- buffer will be created by editing the current buffer.
-- @param buffer_name (string) The name of the buffer.
--
-- @return None
--
local function create_new_scratch_buffer(new_window, buffer_name)
-- Check if the buffer name is set
if not buffer_name or type(buffer_name) ~= "string" then
error("Buffer name not set or invalid in create_new_scratch_buffer")
return
end
-- Either new (for split) or edit the new buffer with buffer_name
local cmd = new_window and "new " or "edit "
vim.cmd(cmd .. buffer_name)
-- Sets the options for the buffer to work like a scratch buffer.
local buf = vim.api.nvim_get_current_buf() -- should always be 0
vim.api.nvim_buf_set_option(buf, "bufhidden", "hide") -- what to do when the buffer is hidden
vim.api.nvim_buf_set_option(buf, "buflisted", true) -- include the buffer in the :bnext list
vim.api.nvim_buf_set_option(buf, "buftype", "nofile") -- nofile means the buffer isn't backed by a file and we control its name
vim.api.nvim_buf_set_option(buf, "swapfile", false) -- never swapfiles
end
--- Opens or splits a window based on the specified conditions.
--
-- This function checks if a new window needs to be opened or if it should
-- switch to an existing buffer. It first determines if a new window is
-- required based on the input parameter or if the current buffer is modified.
-- Then, it searches for an existing scratch buffer. If found, it switches to
-- that buffer. Otherwise, it creates a new scratch buffer.
--
-- @param new_window A boolean indicating whether a new window should be created. If not provided,
-- it defaults to the state of the buffer's modification (true if modified).
--
-- @return None
--
local function open_or_split(new_window)
-- Create new window if requested or if buffer is modified
new_window = new_window or is_buffer_modified()
-- Look for an existing scratch buffer
local scratch_buffer_num = vim.fn.bufnr(M.config.buffer_name)
if scratch_buffer_num ~= -1 then
-- Found it, switch to it
switch_to_existing_buffer(new_window, scratch_buffer_num)
else
-- Didn't find it, create one
create_new_scratch_buffer(new_window, M.config.buffer_name)
end
end
--- Splits the current window and opens or switches to the scratch buffer.
--
-- This function is designed to be a public interface for opening or switching
-- to the scratch buffer in a new split window. It internally calls the
-- `open_or_split` function with `true` to indicate the need for a split window.
--
-- Usage:
-- :lua require('scratch').split()
--
function M.split()
open_or_split(true)
end
--- Opens or switches to the scratch buffer in the current window.
--
-- This function is a public interface for opening or switching to the scratch
-- buffer in the current window without splitting. It calls the `open_or_split`
-- function with `false`, indicating no new window is needed.
--
-- Usage:
-- :lua require('scratch').open()
--
function M.open()
open_or_split(false)
end
--- Sets up the scratch buffer plugin with optional configuration.
--
-- This function initializes the scratch buffer plugin and binds Neovim
-- commands to the plugin's functionalities. It also allows for optional
-- configuration through the `opts` parameter.
--
-- @param opts (table) Optional configuration table. It can contain a key
-- `buffer_name` to specify the name of the scratch buffer. If not provided,
-- defaults to "_SCRATCH_". An error is raised if `buffer_name` is provided but
-- is not a string.
--
-- Usage:
-- :lua require('scratch').setup({ buffer_name = "my_scratch" })
--
function M.setup(opts)
-- Default configuration
M.config = {
buffer_name = "_SCRATCH_",
}
-- Check for configuration overrides passed in via opts
if opts ~= nil and type(opts) == "table" then
if opts.buffer_name and type(opts.buffer_name) ~= "string" then
error("Invalid buffer name provided in setup options")
return
end
M.config.buffer_name = opts.buffer_name or M.config.buffer_name
end
-- Bind commands to our lua functions
vim.api.nvim_create_user_command("Scratch", M.open, {})
vim.api.nvim_create_user_command("ScratchSplit", M.split, {})
end
return M