Skip to content

Feat: Automatically backup and Restore Json, JSON foramtting options #8

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

Merged
merged 2 commits into from
Feb 2, 2024
Merged
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.luacheckrc
.luarc.json
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ nvim-macros is your go-to Neovim plugin for supercharging your macro game! 🚀
- **Select & Yank** 📋: Pick a macro from your saved collection and yank it into a register, ready for its moment in the spotlight.
- **Smart Encoding/Decoding** 🤓: nvim-macros speaks Base64 fluently, so it effortlessly handles macros with special characters.
- **Your Storage, Your Rules** 🗂️: Point nvim-macros to your chosen JSON file for macro storage. It's your macro library, after all!
- **Pretty Printing** 🎨: Choose your JSON formatter ([jq](https://jqlang.github.io/jq/) or [yq](https://github.com/mikefarah/yq)) to keep your JSON file looking sharp. No more squinting at a jumbled mess of macros!
- **Backup & Restore** 📦: Made a mess editing the JSON file? No worries! nvim-macros keeps a backup of your JSON file, so you can always restore your macros to their former glory auto-magically!

## Getting Started 🚀

Expand All @@ -19,8 +21,11 @@ Time to get nvim-macros into your Neovim setup! If you're rolling with [lazy.nvi
"kr40/nvim-macros",
cmd = {"MacroSave", "MacroYank", "MacroSelect", "MacroDelete"},
opts = {
json_file_path = vim.fs.normalize(vim.fn.stdpath("config") .. "/macros.json"), -- Optional

json_file_path = vim.fs.normalize(vim.fn.stdpath("config") .. "/macros.json"), -- Location where the macros will be stored
default_macro_register = "q", -- Use as default register for :MacroYank and :MacroSave and :MacroSelect Raw functions
json_formatter = "none", -- can be "none" | "jq" | "yq" used to pretty print the json file (jq or yq must be installed!)

}
}
```
Expand All @@ -46,15 +51,17 @@ vim.keymap.set('n', '<Leader>t', '^i-<Space>[<Space>]<Space><Esc>', { remap = tr

## Making It Yours 🎨

nvim-macros loves to fit in just right. Set up your JSON file path like so:
nvim-macros loves to fit in just right. Set up your custom options like so:

```lua
require('nvim-macros').setup({
json_file_path = '/your/very/own/path/to/macros.json'
json_file_path = "/your/very/own/path/to/macros.json",
default_macro_register = "a",
json_formatter = "jq",
})
```

No config? No worries! nvim-macros will go with the flow and use a default path.
Fine with the defaults? No worries! nvim-macros will go with the flow and use the [defaults](#getting-started-🚀) no need to call `setup` or `opts`.

## Join the Party 🎉

Expand Down
66 changes: 46 additions & 20 deletions lua/nvim-macros/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,48 @@ local util = require("nvim-macros.util")
local json = require("nvim-macros.json")

-- Default configuration
---@class Config
---@field json_file_path string
---@field default_macro_register string
---@field json_formatter "none" | "jq" | "yq"
local config = {
json_file_path = vim.fs.normalize(vim.fn.stdpath("config") .. "/macros.json"),
default_macro_register = "q",
json_formatter = "none",
}

local M = {}

-- Initialize with user config
function M.setup(user_config)
---@param user_config? Config
M.setup = function(user_config)
if user_config ~= nil then
for key, value in pairs(user_config) do
if config[key] ~= nil then
config[key] = value
else
util.print_message("Invalid config key: " .. key)
util.print_error("Invalid config key: " .. key)
end
end
end
end

-- Yank macro from register to default register
M.yank = function(register)
local valid_registers = "[a-z0-9]"
if not register or register == "" then
register = vim.fn.input("Specify a register to yank from: ")
register = util.get_register_input("Specify a register to yank from: ", config.default_macro_register)
end

if not register or register == "" then
register = config.default_macro_register
util.print_info("No register specified. Using default `" .. config.default_macro_register .. "`.")
while not (register:match("^" .. valid_registers .. "$")) do
util.print_error(
"Invalid register: `" .. register .. "`. Register must be a single lowercase letter or number 1-9."
)

register = util.get_register_input("Specify a register to yank from: ", config.default_macro_register)
end

local register_content = vim.fn.getreg(register)

if not register_content or register_content == "" then
util.print_error("Register `" .. register .. "` is empty or invalid!")
return
Expand All @@ -52,18 +61,23 @@ M.run = function(macro)
util.print_error("Macro is empty. Cannot run.")
return
end

vim.cmd.normal(vim.api.nvim_replace_termcodes(macro, true, true, true))
end

-- Save macro to JSON (Raw and Escaped)
M.save_macro = function(register)
local valid_registers = "[a-z0-9]"
if not register or register == "" then
register = vim.fn.input("Specify a register to save from: ")
register = util.get_register_input("Specify a register to save from: ", config.default_macro_register)
end

if not register or register == "" then
register = config.default_macro_register
util.print_info("No register specified. Using default `" .. config.default_macro_register .. "`.")
while not (register:match("^" .. valid_registers .. "$")) do
util.print_error(
"Invalid register: `" .. register .. "`. Register must be a single lowercase letter or number 1-9."
)

register = util.get_register_input("Specify a register to save from: ", config.default_macro_register)
end

local register_content = vim.fn.getreg(register)
Expand All @@ -81,17 +95,17 @@ M.save_macro = function(register)
local macro = vim.fn.keytrans(register_content)
local macro_raw = base64.enc(register_content)

local macros = json.handle_json_file(config.json_file_path, "r")
local macros = json.handle_json_file(config.json_formatter, config.json_file_path, "r")
if macros then
table.insert(macros.macros, { name = name, content = macro, raw = macro_raw })
json.handle_json_file(config.json_file_path, "w", macros)
json.handle_json_file(config.json_formatter, config.json_file_path, "w", macros)
util.print_message("Macro `" .. name .. "` saved.")
end
end

-- Delete macro from JSON file
M.delete_macro = function()
local macros = json.handle_json_file(config.json_file_path, "r")
local macros = json.handle_json_file(config.json_formatter, config.json_file_path, "r")
if not macros or not macros.macros or #macros.macros == 0 then
util.print_error("No macros to delete.")
return
Expand Down Expand Up @@ -126,14 +140,14 @@ M.delete_macro = function()
end

table.remove(macros.macros, macro_index)
json.handle_json_file(config.json_file_path, "w", macros)
json.handle_json_file(config.json_formatter, config.json_file_path, "w", macros)
util.print_message("Macro `" .. macro_name .. "` deleted.")
end)
end

-- Select and yank macro from JSON (Raw or Escaped)
M.select_and_yank_macro = function()
local macros = json.handle_json_file(config.json_file_path, "r")
local macros = json.handle_json_file(config.json_formatter, config.json_file_path, "r")
if not macros or not macros.macros or #macros.macros == 0 then
util.print_error("No macros to select.")
return
Expand Down Expand Up @@ -179,11 +193,23 @@ M.select_and_yank_macro = function()
util.set_macro_to_register(macro_content)
util.print_message("Yanked macro `" .. macro_name .. "` to clipboard.")
elseif yank_option == "2" then
local target_register = vim.fn.input("Specify a register to yank the raw macro to: ")
if not target_register or target_register == "" then
target_register = config.default_macro_register
util.print_info("No register specified. Using default `" .. config.default_macro_register .. "`.")
local valid_registers = "[a-z0-9]"
local target_register =
util.get_register_input("Specify a register to yank the raw macro to: ", config.default_macro_register)

while not (target_register:match("^" .. valid_registers .. "$")) do
util.print_error(
"Invalid register: `"
.. target_register
.. "`. Register must be a single lowercase letter or number 1-9."
)

target_register = util.get_register_input(
"Specify a register to yank the raw macro to: ",
config.default_macro_register
)
end

util.set_decoded_macro_to_register(encoded_content, target_register)
util.print_message("Yanked raw macro `" .. macro_name .. "` into register `" .. target_register .. "`.")
else
Expand Down
Loading