forked from folke/neoconf.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eb53996
commit 945994a
Showing
4 changed files
with
400 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
local Config = require("neoconf.config") | ||
local Json = require("neoconf.utils.json") | ||
local Settings = require("neoconf.settings") | ||
local Util = require("neoconf.util") | ||
|
||
local M = {} | ||
|
||
-- Cache directory for temporary files | ||
M.TMP_DIR = vim.fn.stdpath("cache") .. "/.neoconf_tmp" | ||
|
||
---@class EditorOptions | ||
---@field on_save fun()|nil Called after saving settings | ||
---@field on_close fun()|nil Called when closing the editor | ||
|
||
---Create a temporary JSON file | ||
---@return string filepath | ||
function M.create_temp_file() | ||
vim.fn.mkdir(M.TMP_DIR, "p") | ||
local random_name = vim.fn.system("openssl rand -hex 8"):gsub("\n", "") | ||
return M.TMP_DIR .. "/" .. random_name .. ".json" | ||
end | ||
|
||
---Open settings in a new buffer | ||
---@param settings table The settings to edit | ||
---@param opts EditorOptions|nil | ||
---@return number bufnr | ||
function M.open(settings, opts) | ||
opts = vim.tbl_deep_extend("force", { | ||
on_save = function() end, | ||
on_close = function() end, | ||
}, opts or {}) | ||
|
||
local temp_file = M.create_temp_file() | ||
local formatted = Json.encode(settings, { sort = true }) | ||
|
||
-- Write formatted content to temp file | ||
local file = io.open(temp_file, "w") | ||
if file then | ||
file:write(formatted) | ||
file:close() | ||
else | ||
error("Failed to write temporary file: " .. temp_file) | ||
end | ||
|
||
-- Open in new tab | ||
vim.cmd("tabnew " .. temp_file) | ||
local buf = vim.api.nvim_get_current_buf() | ||
|
||
-- Mark as temporary buffer | ||
vim.api.nvim_buf_set_var(buf, "is_temp_settings_buffer", true) | ||
vim.api.nvim_buf_set_var(buf, "temp_file_path", temp_file) | ||
|
||
-- Setup buffer | ||
vim.api.nvim_buf_set_option(buf, "filetype", "json") | ||
vim.api.nvim_buf_set_option(buf, "bufhidden", "wipe") | ||
|
||
-- Save keymap | ||
vim.keymap.set("n", "<leader>s", function() | ||
M.save_current_buffer() | ||
opts.on_save() | ||
end, { buffer = buf, noremap = true, silent = true }) | ||
|
||
-- Clean up on buffer close | ||
vim.api.nvim_create_autocmd("BufUnload", { | ||
buffer = buf, | ||
once = true, | ||
callback = function() | ||
os.remove(temp_file) | ||
opts.on_close() | ||
end, | ||
}) | ||
|
||
return buf | ||
end | ||
|
||
---Save the current buffer settings | ||
function M.save_current_buffer() | ||
local buf = vim.api.nvim_get_current_buf() | ||
|
||
-- Verify this is a settings buffer | ||
if not pcall(vim.api.nvim_buf_get_var, buf, "is_temp_settings_buffer") then | ||
Util.error("This is not a temporary settings buffer") | ||
return | ||
end | ||
|
||
-- Get current content | ||
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) | ||
local content = table.concat(lines, "\n") | ||
|
||
-- Validate JSON | ||
local ok, decoded = pcall(vim.json.decode, content) | ||
if not ok then | ||
Util.error("Invalid JSON. Please check your changes") | ||
return | ||
end | ||
|
||
-- Write to local config | ||
local success = Settings.write_local(decoded) | ||
if success then | ||
Util.info("Settings saved successfully") | ||
Settings.refresh() | ||
vim.api.nvim_buf_delete(buf, { force = true }) | ||
end | ||
end | ||
|
||
---Close all temporary settings buffers | ||
function M.close_all() | ||
local closed = 0 | ||
for _, buf in ipairs(vim.api.nvim_list_bufs()) do | ||
local is_temp = pcall(vim.api.nvim_buf_get_var, buf, "is_temp_settings_buffer") | ||
if is_temp then | ||
local file = vim.api.nvim_buf_get_name(buf) | ||
os.remove(file) | ||
vim.api.nvim_buf_delete(buf, { force = true }) | ||
closed = closed + 1 | ||
end | ||
end | ||
if closed > 0 then | ||
Util.info(string.format("Closed %d temporary settings buffer(s)", closed)) | ||
end | ||
end | ||
|
||
return M |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
local uv = vim.uv or vim.loop | ||
|
||
local M = {} | ||
|
||
---@class JsonEncodeOptions | ||
---@field sort boolean Sort object keys | ||
---@field format boolean Format JSON output | ||
|
||
---Encode a Lua table to JSON | ||
---@param value any The value to encode | ||
---@param opts JsonEncodeOptions|nil | ||
---@return string | ||
function M.encode(value, opts) | ||
opts = vim.tbl_extend("force", { sort = false, format = true }, opts or {}) | ||
|
||
-- Basic JSON encode | ||
local ok, json = pcall(vim.json.encode, value) | ||
if not ok then | ||
error("Failed to encode JSON: " .. json) | ||
end | ||
|
||
-- Format with jq if requested | ||
if opts.format or opts.sort then | ||
local args = { "jq" } | ||
if opts.sort then | ||
table.insert(args, "--sort-keys") | ||
end | ||
table.insert(args, ".") | ||
|
||
local result = vim.fn.system(args, json) | ||
if vim.v.shell_error == 0 then | ||
return result | ||
end | ||
-- Fallback to unformatted JSON if jq fails | ||
return json | ||
end | ||
|
||
return json | ||
end | ||
|
||
---Write JSON to a file | ||
---@param filepath string | ||
---@param content any | ||
---@param opts JsonEncodeOptions|nil | ||
---@return boolean success, string? error | ||
function M.write(filepath, content, opts) | ||
-- Encode content | ||
local ok, data = pcall(M.encode, content, opts) | ||
if not ok then | ||
return false, "Failed to encode JSON" | ||
end | ||
|
||
-- Write to file | ||
local fd = uv.fs_open(filepath, "w", 438) -- 0666 octal | ||
if not fd then | ||
return false, "Could not open file for writing" | ||
end | ||
|
||
local success = pcall(function() | ||
uv.fs_write(fd, data, 0) | ||
uv.fs_close(fd) | ||
end) | ||
|
||
if not success then | ||
return false, "Failed to write file" | ||
end | ||
|
||
return true | ||
end | ||
|
||
---Read JSON from a file | ||
---@param filepath string | ||
---@return table|nil content | ||
---@return string|nil error | ||
function M.read(filepath) | ||
local fd = uv.fs_open(filepath, "r", 438) | ||
if not fd then | ||
return nil, "Could not open file" | ||
end | ||
|
||
local stat = uv.fs_fstat(fd) | ||
local data = uv.fs_read(fd, stat.size, 0) | ||
uv.fs_close(fd) | ||
|
||
if not data then | ||
return nil, "Could not read file" | ||
end | ||
|
||
local ok, content = pcall(vim.json.decode, data) | ||
if not ok then | ||
return nil, "Failed to decode JSON" | ||
end | ||
|
||
return content | ||
end | ||
|
||
return M |
Oops, something went wrong.