Skip to content

Commit

Permalink
chore!: refactored into freeze-code.api usage (#11)
Browse files Browse the repository at this point in the history
* feat!: api usage and config separation

* test: modified tests with the new api

* fix: formatting

* docs: added `FreezeLine` keymaps and api usage

* docs: update `doc/freeze-code.nvim.txt`
skip-checks: true

* fix: correct use of `api`

* fix: formatting

* docs: update `doc/freeze-code.nvim.txt`
skip-checks: true

* fix: `go_install_freeze` -> `go_installation`

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
AlejandroSuero and github-actions[bot] authored Jun 4, 2024
1 parent cf118dd commit 9435e6f
Show file tree
Hide file tree
Showing 11 changed files with 450 additions and 375 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,14 @@ visual mode, and it will take a screenshot of the selected lines.
### Keymaps

```lua
vim.keymap.set("n", "<leader>fz", require("freeze-code").freeze)
local fz_api = require("freeze-code.utils.api")
vim.keymap.set("n", "<leader>fz", fz_api.freeze)
vim.keymap.set("v", "<leader>fz", function()
require("freeze-code").freeze(vim.fn.line("'<"), vim.fn.line("'>"))
fz_api.freeze(vim.fn.line("'<"), vim.fn.line("'>"))
end)
-- or using `<cmd>Freeze<cr>`
vim.keymap.set("n", "<leader>fl", fz.freeze_line)
-- or using `<cmd>FreezeLine<cr>`
```

## Contributing
Expand Down
26 changes: 25 additions & 1 deletion doc/freeze-code.nvim.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
*freeze-code.nvim.txt* For Neovim >= 0.9.0 Last change: 2024 May 19
*freeze-code.nvim.txt* For Neovim >= 0.9.0 Last change: 2024 June 04

==============================================================================
Table of Contents *freeze-code.nvim-table-of-contents*

- Installation |freeze-code.nvim-installation|
- Usage |freeze-code.nvim-usage|
- Contributing |freeze-code.nvim-contributing|


Expand Down Expand Up @@ -89,6 +90,29 @@ tools.



USAGE *freeze-code.nvim-usage*

To use this plugin, simply call `:Freeze` and it will take a screenshot of the
current buffer and save it in the `dir` path you have configured.

If you want to take a screenshot of a specific line, you can use the `:Freeze`
in visual mode, and it will take a screenshot of the selected lines.


KEYMAPS ~

>lua
local fz_api = require("freeze-code.utils.api")
vim.keymap.set("n", "<leader>fz", fz_api.freeze)
vim.keymap.set("v", "<leader>fz", function()
fz_api.freeze(vim.fn.line("'<"), vim.fn.line("'>"))
end)
-- or using `<cmd>Freeze<cr>`
vim.keymap.set("n", "<leader>fl", fz.freeze_line)
-- or using `<cmd>FreezeLine<cr>`
<


CONTRIBUTING *freeze-code.nvim-contributing*

Thank you to everyone that is contributing and to those who want to contribute.
Expand Down
147 changes: 147 additions & 0 deletions lua/freeze-code/binary/binary_fetcher.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
local cfg = require("freeze-code.config")
local u = require("freeze-code.utils")
local logger = u.logger

local FreezeBinaryFetcher = {}

---@class FreezeBinaryFetcher
---@field go_installation function: installs `freeze` using `go install github.com/charmbracelet/freeze@latest`
---Freeze installation using `go install`
---@param opts FreezeCodeConfig
function FreezeBinaryFetcher:go_installation(opts)
local cmd_args = {
"go",
"install",
"github.com/charmbracelet/freeze@latest",
}
local stdio = { stdout = "", stderr = "" }
local job = nil

local function on_output(err, data)
if err then
logger.err(err)
end
if data then
stdio.stderr = stdio.stderr .. data
end
end
local callbacks = {
on_sterr = vim.schedule_wrap(function(_, data, _)
local out = table.concat(data, "\n")
on_output(out)
end),
on_exit = vim.schedule_wrap(function()
opts._installed = true
opts.freeze_path = vim.env.HOME .. "/go/bin/freeze"
opts.install_path = opts.freeze_path
logger.warn("[freeze-code] go install github.com/charmbracelet/freeze@latest completed")
cfg.setup(opts)
vim.fn.jobstop(job)
end),
}
job = vim.fn.jobstart(cmd_args, callbacks)
end

---@class FreezeBinaryFetcher
---@field agnostic_installation function: installs `freeze` using `cURL` from GitHub release
---Freeze installation using GitHub release
---@param opts FreezeCodeConfig
function FreezeBinaryFetcher:agnostic_installation(opts)
local os_name = u.get_os_info()
local release_url = u.release_file_url()
if release_url == "" then
logger.err("could not get release file")
return
end

local install_path = vim.fn.expand(opts.install_path)
if install_path == "" then
install_path = vim.fn.expand("~/.local/bin")
end
local output_filename = "freeze.tar.gz"
local download_command = { "curl", "-sL", "-o", output_filename, release_url }
local extract_command = { "tar", "-zxf", output_filename, "-C", install_path }
-- vim.loop.spawn("rm", { args = { "-rf", install_path .. "/" .. u.get_freeze_filename() } })
local rm_command_args = { "-rf", install_path .. "/" .. u.get_freeze_filename() }
if os_name == "Windows" then
extract_command = { "Expand-Archive", output_filename, install_path }
rm_command_args = { "-r", "-Force", install_path .. "/" .. u.get_freeze_filename() }
end
local binary_path = vim.fn.expand(table.concat({ install_path, u.get_freeze_filename() .. "/freeze" }, "/"))

-- check for existing files / folders
if vim.fn.isdirectory(install_path) == 0 then
vim.loop.fs_mkdir(install_path, tonumber("777", 8))
end

if vim.fn.filereadable(binary_path) == 1 then
local success = vim.loop.fs_unlink(binary_path)
if not success then
logger.err("[freeze-code.nvim] ERROR: `freeze` binary could not be removed!")
return
end
end
local stdio = { stdout = "", stderr = "" }
local job = nil

local function on_output(err, data)
if err then
logger.err(err)
end
if data then
stdio.stderr = stdio.stderr .. data
end
end

-- download and install the freeze binary
local callbacks = {
on_sterr = vim.schedule_wrap(function(_, data, _)
local out = table.concat(data, "\n")
on_output(out)
end),
on_exit = vim.schedule_wrap(function()
logger.info_fmt("[freeze-code.nvim] extracting release with `%s`", table.concat(extract_command, " "))
vim.fn.system(extract_command)
if vim.v.shell_error ~= 0 then
logger.err("[freeze-code.nvim] ERROR: extracting release failed")
return
end
-- remove the archive after completion
if vim.fn.filereadable(output_filename) == 1 then
local success = vim.loop.fs_unlink(output_filename)
if not success then
logger.err("[freeze-code.nvim] ERROR: existing archive could not be removed")
return
end
end
vim.loop.spawn("mv", { args = { binary_path, install_path .. "/freeze" } })
binary_path = install_path .. "/freeze"
opts.freeze_path = binary_path
opts._installed = true
opts.install_path = install_path
logger.warn_fmt("[freeze-code.nvim] `freeze` binary installed in installed in path=%s", cfg.config.freeze_path)
vim.loop.spawn("rm", { args = rm_command_args })
logger.warn_fmt("[freeze-code.nvim] `freeze` binary installed in path=%s", cfg.config.freeze_path)
cfg.setup(opts)
vim.fn.jobstop(job)
end),
}
logger.info_fmt("[freeze-code.nvim] downloading release from `%s`", release_url)
job = vim.fn.jobstart(download_command, callbacks)
end

---@class FreezeBinaryFetcher
---@field install_freeze function: `freeze` installation process
---Install freeze for the user
---@param opts FreezeCodeConfig
function FreezeBinaryFetcher:install_freeze(opts)
if u.check_executable("go", vim.fn.exepath("go")) then
logger.warn("[freeze-code.nvim] go install github.com/charmbracelet/freeze@latest completed")
self:go_installation(opts)
return
end
logger.info("[freeze-code.nvim] Installing info with `curl`")
self:agnostic_installation(opts)
end

return FreezeBinaryFetcher
92 changes: 92 additions & 0 deletions lua/freeze-code/binary/binary_handler.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
local binary_fetcher = require("freeze-code.binary.binary_fetcher")
local cfg = require("freeze-code.config")
local commands = require("freeze-code.commands")
local u = require("freeze-code.utils")
local logger = u.logger
local FreezeBinary = {}

---@class FreezeBinary
---@field freeze function: Running `freeze` function
---Freeze file with a range or current buffer if no range is given
---@param s_line? number: line to start range
---@param e_line? number: line to start range
function FreezeBinary:freeze(s_line, e_line)
if not cfg.config._installed then
logger.warn("[freeze-code.nvim] `freeze` not installed")
binary_fetcher:install_freeze(cfg.config)
return
end

s_line = s_line or 1
e_line = e_line or vim.api.nvim_buf_line_count(vim.api.nvim_get_current_buf())

local cmd = cfg.config.freeze_path

if not u.check_executable("freeze", cmd) then
return
end

local lang = ""
if vim.fn.has("nvim-0.10") == 1 then
lang = vim.api.nvim_get_option_value("filetype", { buf = vim.api.nvim_get_current_buf() })
else
---@diagnostic disable-next-line: deprecated
lang = vim.api.nvim_buf_get_option(vim.api.nvim_get_current_buf(), "filetype")
end
local file = vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf())
local conf = cfg.config.freeze_config.config
local dir = cfg.config.dir
local theme = cfg.config.freeze_config.theme
local output = cfg.config.freeze_config.output

if output ~= "freeze" then
local t_stamp = os.date("%Y%m%d%H%M%S")
local filename = file:match("^.+/(.*)$") or file

output = string.format("%s_%s_%s", tostring(t_stamp), filename, output)
end

cfg.config.output = dir .. "/" .. output .. ".png"

local cmd_args = {
"--output",
cfg.config.output,
"--language",
lang,
"--lines",
s_line .. "," .. e_line,
"--config",
conf,
file,
}
if conf == "base" or conf == "full" then
vim.list_extend(cmd_args, {
"--theme",
theme,
})
end

commands.job = {}
commands.job.stdout = vim.loop.new_pipe(false)
commands.job.stderr = vim.loop.new_pipe(false)

local job_opts = {
args = cmd_args,
stdio = { nil, commands.job.stdout, commands.job.stderr },
}

local msg = "🍧 frozen frame in path=" .. cfg.config.output
commands.job.handle = vim.loop.spawn(cmd, job_opts, commands.on_exit(msg))
vim.loop.read_start(commands.job.stdout, vim.schedule_wrap(commands.on_output))
vim.loop.read_start(commands.job.stderr, vim.schedule_wrap(commands.on_output))
end

---@class FreezeBinary
---@field freeze_line function: Running `freeze` function for current line
---Freeze file with a range or current buffer if no range is given
function FreezeBinary:freeze_line()
local curent_line = vim.api.nvim_win_get_cursor(0)[1]
self:freeze(curent_line, curent_line)
end

return FreezeBinary
10 changes: 5 additions & 5 deletions lua/freeze-code/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@ end
---@param msg string: Message to display if success
---@return function cb: Schedule wrap callback function
function M.on_exit(msg, opts)
local freeze_code = require("freeze-code")
local cfg = require("freeze-code.config")
return vim.schedule_wrap(function(code, _)
if code == 0 then
vim.notify("[freeze-code.nvim] " .. msg, vim.log.levels.INFO, { title = "FreezeCode" })
else
vim.notify(M.stdio.stdout, vim.log.levels.ERROR, { title = "Freeze" })
end
if freeze_code.config.copy == true then
freeze_code.copy(freeze_code.config)
if cfg.config.copy == true then
M.copy(cfg.config)
end
if freeze_code.config.open == true then
freeze_code.open(freeze_code.config)
if cfg.config.open == true then
M.open(cfg.config)
end
if opts and opts.freeze then
vim.wait(5000, function()
Expand Down
51 changes: 51 additions & 0 deletions lua/freeze-code/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---@meta

---@class FreezeConfig
---@field output string: Freeze output filename `--output "freeze.png"`
---@field theme string: Freeze theme `--theme "default"`
---@field config string: Freeze configuration `--config "base"`

---@class FreezeCodeConfig
---@field freeze_path string: Path to `freeze` executable
---@field copy_cmd string: Path to copy `image/png` to clipboard command
---@field copy boolean: Open image after creation option
---@field open boolean: Open image after creation option
---@field dir string: Directory to create image
---@field freeze_config FreezeConfig
---@field output? string: output filename
---@field install_path string: path in where to install `freeze`
---@field _installed boolean:

---@type FreezeCodeConfig
local default_config = {
freeze_config = {
output = "freeze",
config = "base",
theme = "default",
},
_installed = vim.fn.exepath("freeze") ~= "",
install_path = vim.env.HOME .. "/.local/bin",
freeze_path = vim.fn.exepath("freeze"),
copy_cmd = vim.env.HOME .. "/dev/nvim_plugins/freeze-code.nvim/bin/pngcopy-macos",
copy = false,
open = false,
dir = vim.env.PWD,
output = nil,
}

local M = {
config = vim.deepcopy(default_config),
}

M.setup = function(opts)
M.config = vim.tbl_deep_extend("force", vim.deepcopy(default_config), opts or {})
end

return setmetatable(M, {
__index = function(_, key)
if key == "setup" then
return M.setup
end
return rawget(M.config, key)
end,
})
Loading

0 comments on commit 9435e6f

Please sign in to comment.