Skip to content

Commit

Permalink
feat(scratchPad): provide pathToFile option (#332)
Browse files Browse the repository at this point in the history
## 📃 Summary

It's hard to compose a scratchpad file location today, it requires 3
props to determine the full `pathToFile` and the custom filetype doesn't
work everytime.

The idea is to propose a single property that does it all, which will
deprecate all the other options in the next major

before, in order to define custom buffers
```lua
buffers = {
    left = {
        bo = {
            filetype = "custom"
        },
        scratchPad = {
            enabled = true,
            fileName = "notes",
            location = "~/Documents"
        },
    },
    right = {
        bo = {
            filetype = "md"
        },
        scratchPad = {
            enabled = true,
            fileName = "foo",
            location = "./bar/baz"
        },
    },
},
```

now
```lua
buffers = {
    left = {
        bo = {
            filetype = "custom"
        },
        scratchPad = {
            enabled = true,
            pathToFile = "~/Documents/notes.custom"
        },
    },
    right = {
        scratchPad = {
            enabled = true,
            pathToFile = "./bar/baz/foo.md"
        },
    },
},
```
  • Loading branch information
shortcuts committed Mar 27, 2024
1 parent a54ffe9 commit 9a8d96d
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 168 deletions.
31 changes: 13 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ _Creates evenly sized empty buffers on each side of your focused buffer, which a
- Multiple tabs support
- [Highly customizable experience](https://github.com/shortcuts/no-neck-pain.nvim#configuration)
- [Support split/vsplit windows](https://github.com/shortcuts/no-neck-pain.nvim/wiki/Showcase#window-layout-support)
- [Built-in scratchpad feature](https://github.com/shortcuts/no-neck-pain.nvim/wiki/Showcase#side-buffer-as-scratch-pad)
- [Built-in scratchPad feature](https://github.com/shortcuts/no-neck-pain.nvim/wiki/Showcase#side-buffer-as-scratch-pad)
- [Themed side buffers](https://github.com/shortcuts/no-neck-pain.nvim/wiki/Showcase#custom-background-color)
- Fully integrates with [neo-tree.nvim](https://github.com/nvim-neo-tree/neo-tree.nvim), [nvim-tree.lua](https://github.com/nvim-tree/nvim-tree.lua), [undotree](https://github.com/mbbill/undotree), [tmux, and more!](https://github.com/shortcuts/no-neck-pain.nvim/wiki/Showcase#window-layout-support)
- Keep your workflow intact
Expand Down Expand Up @@ -183,7 +183,7 @@ require("no-neck-pain").setup({
-- When `false`, the mapping is not created.
--- @type string | { mapping: string, value: number }
widthDown = "<Leader>n-",
-- Sets a global mapping to Neovim, which allows you to toggle the scratchpad feature.
-- Sets a global mapping to Neovim, which allows you to toggle the scratchPad feature.
-- When `false`, the mapping is not created.
--- @type string
scratchPad = "<Leader>ns",
Expand All @@ -196,9 +196,9 @@ require("no-neck-pain").setup({
--- @type boolean
setNames = false,
-- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
-- note: quitting an unsaved scratchpad buffer is non-blocking, and the content is still saved.
--- see |NoNeckPain.bufferOptionsScratchpad|
scratchPad = NoNeckPain.bufferOptionsScratchpad,
-- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
--- see |NoNeckPain.bufferOptionsScratchPad|
scratchPad = NoNeckPain.bufferOptionsScratchPad,
-- colors to apply to both side buffers, for buffer scopped options @see |NoNeckPain.bufferOptions|
--- see |NoNeckPain.bufferOptionsColors|
colors = NoNeckPain.bufferOptionsColors,
Expand Down Expand Up @@ -282,8 +282,8 @@ NoNeckPain.bufferOptions = {
bo = NoNeckPain.bufferOptionsBo,
--- @see NoNeckPain.bufferOptionsWo `:h NoNeckPain.bufferOptionsWo`
wo = NoNeckPain.bufferOptionsWo,
--- @see NoNeckPain.bufferOptionsScratchpad `:h NoNeckPain.bufferOptionsScratchpad`
scratchPad = NoNeckPain.bufferOptionsScratchpad,
--- @see NoNeckPain.bufferOptionsScratchPad `:h NoNeckPain.bufferOptionsScratchPad`
scratchPad = NoNeckPain.bufferOptionsScratchPad,
}

NoNeckPain.bufferOptionsWo = {
Expand Down Expand Up @@ -320,29 +320,24 @@ NoNeckPain.bufferOptionsBo = {
swapfile = false,
}

--- NoNeckPain's scratchpad buffer options.
--- NoNeckPain's scratchPad buffer options.
---
--- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
--- note: quitting an unsaved scratchpad buffer is non-blocking, and the content is still saved.
--- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
---
---@type table
---Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
NoNeckPain.bufferOptionsScratchpad = {
NoNeckPain.bufferOptionsScratchPad = {
-- When `true`, automatically sets the following options to the side buffers:
-- - `autowriteall`
-- - `autoread`.
--- @type boolean
enabled = false,
-- The name of the generated file. See `location` for more information.
--- @type string
--- @example: `no-neck-pain-left.norg`
fileName = "no-neck-pain",
-- By default, files are saved at the same location as the current Neovim session.
-- note: filetype is defaulted to `norg` (https://github.com/nvim-neorg/neorg), but can be changed in `buffers.bo.filetype` or |NoNeckPain.bufferOptions| for option scoped to the `left` and/or `right` buffer.
-- The path to the file to save the scratchPad content to and load it in the buffer.
--- @type string?
--- @example: `no-neck-pain-left.norg`
location = nil,
--- @example: `~/notes.norg`
pathToFile = "",
}

NoNeckPain.bufferOptionsColors = {
Expand Down
22 changes: 15 additions & 7 deletions doc/no-neck-pain.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ values:
<

------------------------------------------------------------------------------
*NoNeckPain.bufferOptionsScratchpad*
`NoNeckPain.bufferOptionsScratchpad`
*NoNeckPain.bufferOptionsScratchPad*
`NoNeckPain.bufferOptionsScratchPad`
NoNeckPain's scratchPad buffer options.

Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
Expand All @@ -105,21 +105,29 @@ Type ~
`(table)`
values:
>
NoNeckPain.bufferOptionsScratchpad = {
NoNeckPain.bufferOptionsScratchPad = {
-- When `true`, automatically sets the following options to the side buffers:
-- - `autowriteall`
-- - `autoread`.
--- @type boolean
enabled = false,
-- The name of the generated file. See `location` for more information.
-- /!\ deprecated /!\ use `pathToFile` instead.
--- @type string
--- @example: `no-neck-pain-left.norg`
--- @deprecated: use `pathToFile` instead.
fileName = "no-neck-pain",
-- By default, files are saved at the same location as the current Neovim session.
-- note: filetype is defaulted to `norg` (https://github.com/nvim-neorg/neorg), but can be changed in `buffers.bo.filetype` or |NoNeckPain.bufferOptions| for option scoped to the `left` and/or `right` buffer.
-- /!\ deprecated /!\ use `pathToFile` instead.
--- @type string?
--- @example: `no-neck-pain-left.norg`
--- @deprecated: use `pathToFile` instead.
location = nil,
-- The path to the file to save the scratchPad content to and load it in the buffer.
--- @type string?
--- @example: `~/notes.norg`
pathToFile = "",
}
<
Expand Down Expand Up @@ -186,8 +194,8 @@ values:
bo = NoNeckPain.bufferOptionsBo,
--- @see NoNeckPain.bufferOptionsWo `:h NoNeckPain.bufferOptionsWo`
wo = NoNeckPain.bufferOptionsWo,
--- @see NoNeckPain.bufferOptionsScratchpad `:h NoNeckPain.bufferOptionsScratchpad`
scratchPad = NoNeckPain.bufferOptionsScratchpad,
--- @see NoNeckPain.bufferOptionsScratchPad `:h NoNeckPain.bufferOptionsScratchPad`
scratchPad = NoNeckPain.bufferOptionsScratchPad,
}
<
Expand Down Expand Up @@ -283,8 +291,8 @@ values:
setNames = false,
-- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
-- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
--- see |NoNeckPain.bufferOptionsScratchpad|
scratchPad = NoNeckPain.bufferOptionsScratchpad,
--- see |NoNeckPain.bufferOptionsScratchPad|
scratchPad = NoNeckPain.bufferOptionsScratchPad,
-- colors to apply to both side buffers, for buffer scopped options @see |NoNeckPain.bufferOptions|
--- see |NoNeckPain.bufferOptionsColors|
colors = NoNeckPain.bufferOptionsColors,
Expand Down
2 changes: 1 addition & 1 deletion doc/tags
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
NoNeckPain.bufferOptions no-neck-pain.txt /*NoNeckPain.bufferOptions*
NoNeckPain.bufferOptionsBo no-neck-pain.txt /*NoNeckPain.bufferOptionsBo*
NoNeckPain.bufferOptionsColors no-neck-pain.txt /*NoNeckPain.bufferOptionsColors*
NoNeckPain.bufferOptionsScratchpad no-neck-pain.txt /*NoNeckPain.bufferOptionsScratchpad*
NoNeckPain.bufferOptionsScratchPad no-neck-pain.txt /*NoNeckPain.bufferOptionsScratchPad*
NoNeckPain.bufferOptionsWo no-neck-pain.txt /*NoNeckPain.bufferOptionsWo*
NoNeckPain.disable() no-neck-pain.txt /*NoNeckPain.disable()*
NoNeckPain.enable() no-neck-pain.txt /*NoNeckPain.enable()*
Expand Down
98 changes: 62 additions & 36 deletions lua/no-neck-pain/config.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local A = require("no-neck-pain.util.api")
local D = require("no-neck-pain.util.debug")
local C = require("no-neck-pain.colors")
local Co = require("no-neck-pain.util.constants")
Expand Down Expand Up @@ -58,21 +59,29 @@ NoNeckPain.bufferOptionsBo = {
---@type table
---Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
NoNeckPain.bufferOptionsScratchpad = {
NoNeckPain.bufferOptionsScratchPad = {
-- When `true`, automatically sets the following options to the side buffers:
-- - `autowriteall`
-- - `autoread`.
--- @type boolean
enabled = false,
-- The name of the generated file. See `location` for more information.
-- /!\ deprecated /!\ use `pathToFile` instead.
--- @type string
--- @example: `no-neck-pain-left.norg`
--- @deprecated: use `pathToFile` instead.
fileName = "no-neck-pain",
-- By default, files are saved at the same location as the current Neovim session.
-- note: filetype is defaulted to `norg` (https://github.com/nvim-neorg/neorg), but can be changed in `buffers.bo.filetype` or |NoNeckPain.bufferOptions| for option scoped to the `left` and/or `right` buffer.
-- /!\ deprecated /!\ use `pathToFile` instead.
--- @type string?
--- @example: `no-neck-pain-left.norg`
--- @deprecated: use `pathToFile` instead.
location = nil,
-- The path to the file to save the scratchPad content to and load it in the buffer.
--- @type string?
--- @example: `~/notes.norg`
pathToFile = "",
}

--- NoNeckPain's buffer color options.
Expand Down Expand Up @@ -127,8 +136,8 @@ NoNeckPain.bufferOptions = {
bo = NoNeckPain.bufferOptionsBo,
--- @see NoNeckPain.bufferOptionsWo `:h NoNeckPain.bufferOptionsWo`
wo = NoNeckPain.bufferOptionsWo,
--- @see NoNeckPain.bufferOptionsScratchpad `:h NoNeckPain.bufferOptionsScratchpad`
scratchPad = NoNeckPain.bufferOptionsScratchpad,
--- @see NoNeckPain.bufferOptionsScratchPad `:h NoNeckPain.bufferOptionsScratchPad`
scratchPad = NoNeckPain.bufferOptionsScratchPad,
}

--- NoNeckPain's plugin config.
Expand Down Expand Up @@ -218,8 +227,8 @@ NoNeckPain.options = {
setNames = false,
-- Leverages the side buffers as notepads, which work like any Neovim buffer and automatically saves its content at the given `location`.
-- note: quitting an unsaved scratchPad buffer is non-blocking, and the content is still saved.
--- see |NoNeckPain.bufferOptionsScratchpad|
scratchPad = NoNeckPain.bufferOptionsScratchpad,
--- see |NoNeckPain.bufferOptionsScratchPad|
scratchPad = NoNeckPain.bufferOptionsScratchPad,
-- colors to apply to both side buffers, for buffer scopped options @see |NoNeckPain.bufferOptions|
--- see |NoNeckPain.bufferOptionsColors|
colors = NoNeckPain.bufferOptionsColors,
Expand Down Expand Up @@ -297,6 +306,38 @@ NoNeckPain.options = {
---@private
local defaults = vim.deepcopy(NoNeckPain.options)

--- Parses the deprecated scratchPad options into the new `pathToFile` option.
---
---@param side "left"|"right" The side of the buffer.
---@param options table Module config table. See |NoNeckPain.bufferOptionsScratchPads|.
---@param fileType string The file extension to leverage.
---
---@private
local function parseDeprecatedScratchPad(side, options, fileType)
-- set the defaults if the user rely on them
if A.length(options) == 0 or options.pathToFile == nil then
options = A.tde(options, defaults.buffers.scratchPad)
end

-- handle the deprecation to `fileName` and `location`
if options.pathToFile == "" then
if options.location ~= nil then
options.pathToFile = options.location
end

if options.pathToFile ~= "" and string.sub(options.pathToFile, -1) ~= "/" then
options.pathToFile = options.pathToFile .. "/"
end

fileType = fileType or "norg"

options.pathToFile =
string.format("%s%s-%s.%s", options.pathToFile, options.fileName, side, fileType)
end

return options
end

--- Defaults NoNeckPain options by merging user provided options with the default plugin values.
---
---@param options table Module config table. See |NoNeckPain.options|.
Expand All @@ -305,42 +346,20 @@ local defaults = vim.deepcopy(NoNeckPain.options)
function NoNeckPain.defaults(options)
options.buffers = options.buffers or {}

local tde = function(t1, t2)
return vim.deepcopy(vim.tbl_deep_extend("keep", t1 or {}, t2 or {}))
end

for _, side in pairs(Co.SIDES) do
options.buffers[side] = options.buffers[side] or {}

options.buffers[side].bo = tde(options.buffers[side].bo, options.buffers.bo)
options.buffers[side].wo = tde(options.buffers[side].wo, options.buffers.wo)
options.buffers[side].colors = tde(options.buffers[side].colors, options.buffers.colors)
options.buffers[side].scratchPad =
tde(options.buffers[side].scratchPad, options.buffers.scratchPad)

if options.buffers[side].scratchPad.enabled then
-- if the user wants scratchPads, but did not provided a custom filetype, we default to `norg`.
if options.buffers[side].bo == nil or options.buffers[side].bo.filetype == nil then
options.buffers[side].bo = options.buffers[side].bo or {}
options.buffers[side].bo.filetype = "norg"
end

options.buffers[side].bo.bufhidden = ""
options.buffers[side].bo.buftype = ""
options.buffers[side].bo.buflisted = false
options.buffers[side].bo.autoread = true
options.buffers[side].wo.conceallevel = 2

if options.buffers[side].scratchPad.location ~= nil then
assert(
type(options.buffers[side].scratchPad.location) == "string",
"`scratchPad.location` must be nil or a string."
)
end
end
options.buffers[side].bo = A.tde(options.buffers[side].bo, options.buffers.bo)
options.buffers[side].wo = A.tde(options.buffers[side].wo, options.buffers.wo)
options.buffers[side].colors = A.tde(options.buffers[side].colors, options.buffers.colors)
options.buffers[side].scratchPad = parseDeprecatedScratchPad(
side,
A.tde(options.buffers[side].scratchPad, options.buffers.scratchPad),
options.buffers[side].bo.filetype
)
end

NoNeckPain.options = tde(options, defaults)
NoNeckPain.options = A.tde(options, defaults)
NoNeckPain.options.buffers = C.parse(NoNeckPain.options.buffers)

-- assert `width` values through vim options
Expand Down Expand Up @@ -370,6 +389,13 @@ function NoNeckPain.defaults(options)
)
end

-- cleanup deprecated options to sanitize the saved config
NoNeckPain.options.buffers.left.scratchPad.location = nil
NoNeckPain.options.buffers.left.scratchPad.fileName = nil
NoNeckPain.options.buffers.right.scratchPad.location = nil
NoNeckPain.options.buffers.right.scratchPad.fileName = nil
NoNeckPain.options.buffers.scratchPad = nil

return NoNeckPain.options
end

Expand Down
16 changes: 10 additions & 6 deletions lua/no-neck-pain/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,23 @@ function N.toggleScratchPad()

-- store the current win to later restore focus
local currWin = vim.api.nvim_get_current_win()
local currentState = S.tabs[S.activeTab].scratchPadEnabled

-- save new state of the scratchPad and update tabs
S.setScratchPad(S, not currentState)

-- map over both sides and let the init method either setup or cleanup the side buffers
for _, side in pairs(Co.SIDES) do
vim.fn.win_gotoid(S.getSideID(S, side))
W.initScratchPad(side, S.getScratchpad(S))
local id = S.getSideID(S, side)
if id ~= nil then
vim.fn.win_gotoid(id)
W.initScratchPad(side, id, currentState)
end
end

-- restore focus
vim.fn.win_gotoid(currWin)

-- save new state of the scratchpad and update tabs
S.setScratchpad(S, not S.tabs[S.activeTab].scratchPadEnabled)

S.save(S)
end

Expand Down Expand Up @@ -363,7 +367,7 @@ function N.enable(scope)
not S.hasTabs(S)
or not S.isActiveTabRegistered(S)
or E.skip()
or S.getScratchpad(S)
or S.getScratchPad(S)
then
return D.log(p.event, "skip")
end
Expand Down
12 changes: 6 additions & 6 deletions lua/no-neck-pain/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -486,19 +486,19 @@ function State:getTabSafe()
return self.getTab(self)
end

---Sets the given `bool` value to the active tab scratchpad.
---Sets the given `bool` value to the active tab scratchPad.
---
---@param bool boolean: the value of the scratchpad.
---@param bool boolean: the value of the scratchPad.
---@private
function State:setScratchpad(bool)
function State:setScratchPad(bool)
self.tabs[self.activeTab].scratchPadEnabled = bool
end

---Gets the scratchpad value for the active tab.
---Gets the scratchPad value for the active tab.
---
---@return boolean: the value of the scratchpad.
---@return boolean: the value of the scratchPad.
---@private
function State:getScratchpad()
function State:getScratchPad()
return self.tabs[self.activeTab].scratchPadEnabled
end

Expand Down
Loading

0 comments on commit 9a8d96d

Please sign in to comment.