Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: color slots #9

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
# 🎨 Last Color
**Last Color** saves the name of the last (successful) colorscheme change to your filesystem and allows you to recall it whenever you desire. As such, you can automatically set your colorscheme between sessions based on what you last used! See the [usage](#usage) section for an example.

## Why?
I'm *extremely* indecisive when choosing my colorscheme. I considered setting up my colors in a `.gitignore`d file, but **telescope**'s colorscheme picker is way too convenient compared to editing a file 🐵

## Installation
Ye olde plugin manager.
```lua
-- packer
use({ 'raddari/last-color.nvim' })
{ 'raddari/last-color.nvim' }
```

## Configuration
None. It'll call `setup` itself when loaded.
None.

## Usage
Dead simple. I use the snippet below in my `init.lua` to automatically use the last theme. There's also an Ex command; `:LastColor`.
### Simple
Drop something like this in your `init.lua`:
```lua
-- kanagawa as a backup, `recall()` can return `nil`.
local theme = require('last-color').recall() or 'kanagawa'
vim.cmd(('colorscheme %s'):format(theme))
```
I personally don't lazy load my plugins, but I'm sure you could modify the snippet to account for that 😀
### Different Colorscheme Slots
If you use a plugin like [`f-person/auto-dark-mode.nvim`](https://github.com/f-person/auto-dark-mode.nvim), you can choose which 'slot' the colorscheme will save to/load from:
```lua
-- LazySpec
return {
'f-person/auto-dark-mode.nvim',
config = {
set_dark_mode = function()
local last_color = require('last-color')
-- last-color will now write to `<cache_dir>/last-color.dark` for any subsequent `colorscheme` commands
last_color.slot('dark')
-- last-color will now read from `<cache_dir>/last-color.dark`
vim.cmd.colorscheme(last_color.recall())
end,
set_light_mode = function()
local last_color = require('last-color')
-- last-color will now write to `<cache_dir>/last-color.light` for any subsequent `colorscheme` commands
last_color.slot('light')
-- last-color will now read from `<cache_dir>/last-color.light`
vim.cmd.colorscheme(last_color.recall())
end,
},
}
```

## Showcase
Using the lua snippet above:
Using the simple lua snippet above:

![last-color](https://user-images.githubusercontent.com/25364469/189385514-563ca684-41c9-42db-a2a6-12921f4f3095.gif)

## Issues
Please open an issue for any problems you encounter, or suggestions for improving the code quality. This is my first plugin, so I'm still learning and looking to improve 😁
33 changes: 25 additions & 8 deletions lua/last-color/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ local cache_file = string.format('%s/last-color', vim.fn.stdpath('data'))

local M = {}

local open_cache_file = function(mode)
---@param mode string
---@param slot string|nil
local open_cache_file = function(mode, slot)
local filename = slot and ('%s.%s'):format(cache_file, slot) or cache_file
-- 438(10) == 666(8) [owner/group/others can read/write]
local flags = 438
return uv.fs_open(cache_file, mode, flags)
return uv.fs_open(filename, mode, flags)
end

local read_cache_file = function()
local fd, err_name, err_msg = open_cache_file('r')
---@param slot string|nil
local read_cache_file = function(slot)
local fd, err_name, err_msg = open_cache_file('r', slot)
if not fd then
if err_name == 'ENOENT' then
-- cache never written: ok, :colorscheme never executed
Expand All @@ -27,19 +31,32 @@ local read_cache_file = function()
return colorscheme
end

local write_cache_file = function(colorscheme)
local fd = assert(open_cache_file('w'))
---@param colorscheme string name of colorscheme
---@param slot string|nil name of slot to use
local write_cache_file = function(colorscheme, slot)
local fd = assert(open_cache_file('w', slot))
assert(uv.fs_write(fd, string.format('%s\n', colorscheme), -1))
assert(uv.fs_close(fd))
end

---@type string|nil name of slot in use
M.current_slot = nil

--- Read the cached colorscheme from disk.
--- @return string|nil colorscheme
M.recall = function()
local ok, result = pcall(read_cache_file)
local ok, result = pcall(read_cache_file, M.current_slot)
return ok and result or nil
end

---Sets the current slot to read/write colorscheme to.
---@return string|nil slot previous slot in use
M.slot = function(name)
local old = M.current_slot
M.current_slot = name
return old
end

--- Creates the autocommand which saves the last ':colorscheme' to disk, along
--- with the Ex command 'LastColor'. This is automatically called when the
--- plugin is loaded.
Expand All @@ -56,7 +73,7 @@ M.setup = function()
return nil
end

local ok, result = pcall(write_cache_file, new_scheme)
local ok, result = pcall(write_cache_file, new_scheme, M.current_slot)
if not ok then
vim.api.nvim_err_writeln(string.format('cannot write to cache file: %s', result))
-- delete the autocommand to prevent further error notifications
Expand Down