Skip to content

Commit d7fc856

Browse files
authored
feat(backend): add save_to_disk option (#65)
This can be used to only copy to clipboard
1 parent 781d05a commit d7fc856

11 files changed

Lines changed: 89 additions & 31 deletions

File tree

README.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ See: [lazy.nvim](https://github.com/folke/lazy.nvim)
7979
```lua
8080
{
8181
'mistweaverco/snap.nvim',
82-
version = 'v1.4.5',
82+
version = 'v1.5.0',
83+
cmd = "Snap",
8384
---@type SnapUserConfig
8485
opts = {}
86+
event = "VeryLazy",
8587
},
8688
```
8789

@@ -95,7 +97,7 @@ See: [packer.nvim](https://github.com/wbthomason/packer.nvim)
9597
```lua
9698
use {
9799
'mistweaverco/snap.nvim',
98-
tag = 'v1.4.5',
100+
tag = 'v1.5.0',
99101
config = function()
100102

101103
---@type SnapUserConfig
@@ -114,7 +116,7 @@ use {
114116
```lua
115117
vim.pack.add({
116118
src = 'https://github.com/mistweaverco/snap.nvim.git',
117-
version = 'v1.4.5',
119+
version = 'v1.5.0',
118120
})
119121
---@type SnapUserConfig
120122
local cfg = {}
@@ -246,7 +248,7 @@ This would then translate to the following `font_settings`:
246248
```lua
247249
return {
248250
"mistweaverco/snap.nvim",
249-
version = 'v1.4.5',
251+
version = 'v1.5.0',
250252
---@type SnapUserConfig
251253
opts = {
252254
template = "linux",
@@ -323,6 +325,17 @@ Optional. Defaults to `nil`.
323325
Absolute path to a custom handlebars template file.
324326
If set, this option overrides the `template` option.
325327

328+
### Configure `save_to_disk`
329+
330+
Optional. Defaults to:
331+
332+
```lua
333+
{
334+
image = true,
335+
html = true,
336+
}
337+
```
338+
326339
### Configure `copy_to_clipboard`
327340

328341
Optional. Defaults to:
@@ -375,7 +388,7 @@ by running `bun install` in the plugin directory.
375388
```lua
376389
{
377390
'mistweaverco/snap.nvim',
378-
version = 'v1.4.5',
391+
version = 'v1.5.0',
379392
opts = {
380393
timeout = 5000, -- Timeout for screenshot command in milliseconds
381394
log_level = "error", -- Log level for debugging (e.g., "trace", "debug", "info", "warn", "error", "off")
@@ -388,6 +401,10 @@ by running `bun install` in the plugin directory.
388401
},
389402
output_dir = "$HOME/Pictures/Screenshots", -- Directory to save screenshots
390403
filename_pattern = "snap.nvim_%t", -- e.g., "snap.nvim_%t" (supports %t for timestamp)
404+
save_to_disk = {
405+
image = true, -- Whether to save the image to disk
406+
html = true, -- Whether to save the HTML to disk
407+
},
391408
copy_to_clipboard = {
392409
image = true, -- Whether to copy the image to clipboard
393410
html = true, -- Whether to copy the HTML to clipboard

backend/bun/src/generators/image.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const ImageGenerator = async (json: JSONObjectImageSuccessRequest): Promi
1919
// Convert HTML to image using our custom Playwright implementation
2020
// Pass the executable path explicitly to ensure Playwright uses the bundled browser
2121
const buffer = await htmlToImage({
22-
output: filepath,
22+
output: json.data.toDisk.image ? filepath : undefined,
2323
html: code,
2424
transparent: json.data.transparent,
2525
type: json.data.outputImageFormat,

backend/bun/src/generators/rtf.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ export const RTFGenerator = async (json: JSONObjectRTFSuccessRequest): Promise<[
120120

121121
const filepath = outputFilepath + ".rtf";
122122

123-
fs.writeFileSync(filepath, doc, { encoding: "utf-8" });
123+
if (json.data.toDisk.rtf) {
124+
fs.writeFileSync(filepath, doc, { encoding: "utf-8" });
125+
}
126+
124127
return [doc, filepath];
125128
};

backend/bun/src/index.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,32 @@ const main = async () => {
106106

107107
let bufstr: NodeHTMLToImageBuffer | Buffer | string | null = null;
108108
let filepath: string = "";
109+
let toClipboard: boolean = false;
110+
let toDisk: boolean = false;
109111

110112
switch (jsonPayload.data.type) {
111113
case JSONRequestType.CodeImageGeneration:
112114
json = jsonPayload as JSONObjectImageSuccessRequest;
115+
toClipboard = json.data.toClipboard.image;
116+
toDisk = json.data.toDisk.image;
113117
[bufstr, filepath] = await ImageGenerator(json);
114118
if (bufstr && json.data.toClipboard.image) {
115119
Clipboard.write(bufstr, "image/png");
116120
}
117121
break;
118122
case JSONRequestType.CodeHTMLGeneration:
119123
json = jsonPayload as JSONObjectHTMLSuccessRequest;
120-
[bufstr, filepath] = await HTMLGenerator(json, true);
124+
toClipboard = json.data.toClipboard.html;
125+
toDisk = json.data.toDisk.html;
126+
[bufstr, filepath] = await HTMLGenerator(json, json.data.toDisk.html);
121127
if (bufstr && json.data.toClipboard.html) {
122128
Clipboard.write(bufstr, "text/html");
123129
}
124130
break;
125131
case JSONRequestType.CodeRTFGeneration:
126132
json = jsonPayload as JSONObjectRTFSuccessRequest;
133+
toClipboard = json.data.toClipboard.rtf;
134+
toDisk = json.data.toDisk.rtf;
127135
[bufstr, filepath] = await RTFGenerator(json);
128136
if (bufstr && json.data.toClipboard.rtf) {
129137
Clipboard.write(bufstr, "text/rtf");
@@ -138,9 +146,19 @@ const main = async () => {
138146
return;
139147
}
140148

149+
const message =
150+
toClipboard && toDisk
151+
? `Written to clipboard and saved to disk at ${filepath}`
152+
: toClipboard
153+
? "Written to clipboard"
154+
: toDisk
155+
? `Saved to disk at ${filepath}`
156+
: "No output destination specified";
157+
141158
writeJSONToStdout({
142159
success: true,
143160
debug: json.debug,
161+
message,
144162
data: {
145163
...json.data,
146164
filepath,

backend/bun/src/types/index.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ export interface JSONObjectHTMLSuccessRequest {
6666
templateFilepath?: string;
6767
fontSettings: FontSettings;
6868
additionalTemplateData?: { [key: string]: unknown };
69+
toDisk: {
70+
image: boolean;
71+
html: boolean;
72+
rtf: boolean;
73+
};
6974
toClipboard: {
7075
image: boolean;
7176
html: boolean;
72-
css: boolean;
7377
rtf: boolean;
7478
};
7579
outputDir?: string;
@@ -95,10 +99,14 @@ export interface JSONObjectRTFSuccessRequest {
9599
templateFilepath?: string;
96100
fontSettings: FontSettings;
97101
additionalTemplateData?: { [key: string]: unknown };
102+
toDisk: {
103+
image: boolean;
104+
html: boolean;
105+
rtf: boolean;
106+
};
98107
toClipboard: {
99108
image: boolean;
100109
html: boolean;
101-
css: boolean;
102110
rtf: boolean;
103111
};
104112
outputDir?: string;
@@ -127,10 +135,14 @@ export interface JSONObjectImageSuccessRequest {
127135
fontSettings: FontSettings;
128136
templateFilepath?: string;
129137
additionalTemplateData?: { [key: string]: unknown };
138+
toDisk: {
139+
image: boolean;
140+
html: boolean;
141+
rtf: boolean;
142+
};
130143
toClipboard: {
131144
image: boolean;
132145
html: boolean;
133-
css: boolean;
134146
rtf: boolean;
135147
};
136148
outputDir?: string;
@@ -182,6 +194,7 @@ export interface JSONObjectInstallResponse {
182194

183195
export interface JSONObjectSuccessResponse {
184196
success: true;
197+
message: string;
185198
debug: boolean;
186199
context?: unknown;
187200
data:

lua/snap/config/init.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ M.defaults = {
2121
image = true, -- Whether to copy the image to clipboard
2222
html = true, -- Whether to copy the HTML to clipboard
2323
},
24+
save_to_disk = {
25+
image = true, -- Whether to save the image to disk
26+
html = true, -- Whether to save the HTML to disk
27+
},
2428
notify = {
2529
enabled = true, -- Whether to show notifications
2630
provider = "notify", -- Notification provider: "notify", "print"

lua/snap/export.lua

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,7 @@ end
267267
---Run backend export with given options
268268
---@param opts table Export options
269269
---@param export_type SnapPayloadType Export type
270-
---@param success_message string Success message format string (with %s for filepath)
271-
local function run_backend_export(opts, export_type, success_message)
270+
local function run_backend_export(opts, export_type)
272271
opts = opts or {}
273272
local conf = Config.get()
274273

@@ -327,7 +326,7 @@ local function run_backend_export(opts, export_type, success_message)
327326
return
328327
end
329328
if res.success then
330-
Logger.notify(string.format(success_message, tostring(res.data.filepath)), Logger.LoggerLogLevels.info)
329+
Logger.notify(tostring(res.message), Logger.LoggerLogLevels.info)
331330
else
332331
print("Backend error when exporting failed: " .. vim.inspect(res))
333332
end
@@ -385,25 +384,22 @@ end
385384
---Export current buffer to RTF
386385
---@param opts SnapExportOptions|nil Export options
387386
function M.rtf_to_clipboard(opts)
388-
run_backend_export(opts, types.SnapPayloadType.rtf, "Exported RTF to: %s")
387+
opts = opts or {}
388+
run_backend_export(opts, types.SnapPayloadType.rtf)
389389
end
390390

391391
---Export current buffer to HTML
392392
---@param opts SnapExportOptions|nil Export options
393393
function M.html_to_clipboard(opts)
394-
run_backend_export(opts, types.SnapPayloadType.html, "Exported HTML to: %s")
394+
opts = opts or {}
395+
run_backend_export(opts, types.SnapPayloadType.html)
395396
end
396397

397398
---Export current buffer to image
398399
---@param opts SnapExportOptions|nil Export options
399400
function M.image_to_clipboard(opts)
400401
opts = opts or {}
401-
local save_path = M.get_default_save_path()
402-
if not save_path then
403-
Logger.error("No valid save path found for screenshots. Please set 'output_dir' in config")
404-
return
405-
end
406-
run_backend_export({ range = opts.range }, types.SnapPayloadType.image, "Exported image to: %s")
402+
run_backend_export({ range = opts.range }, types.SnapPayloadType.image)
407403
end
408404

409405
return M
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
return "1.4.4"
1+
return "1.5.0"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
return "1.4.5"
1+
return "1.5.0"

lua/snap/payload.lua

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ function M.get_backend_payload_from_buf(opts, callback)
6767
local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
6868
local hl_map = highlights_map.build_hl_map(bufnr)
6969

70-
--- @type SnapPayload
71-
local tabstop = vim.api.nvim_buf_get_option(bufnr, "tabstop")
70+
local tabstop = vim.bo[bufnr].tabstop or 4
7271

7372
local snap_payload = {
7473
success = true,
@@ -82,13 +81,14 @@ function M.get_backend_payload_from_buf(opts, callback)
8281
fgColor = default_fg,
8382
},
8483
template = user_config.template or "default",
85-
toClipboard = user_config.copy_to_clipboard or Config.defaults.copy_to_clipboard,
86-
outputDir = user_config.output_dir or Config.defaults.output_dir,
84+
toDisk = user_config.save_to_disk,
85+
toClipboard = user_config.copy_to_clipboard,
86+
outputDir = user_config.output_dir,
8787
filename = M.get_filename(bufnr),
88-
filenamePattern = user_config.filename_pattern or Config.defaults.filename_pattern,
89-
fontSettings = user_config.font_settings or Config.defaults.font_settings,
88+
filenamePattern = user_config.filename_pattern,
89+
fontSettings = user_config.font_settings,
9090
outputImageFormat = types.SnapImageOutputFormat.png,
91-
templateFilepath = user_config.templateFilepath or Config.defaults.templateFilepath,
91+
templateFilepath = user_config.templateFilepath,
9292
transparent = true,
9393
minWidth = 0,
9494
type = (opts and opts.type) or types.SnapPayloadType.image,

0 commit comments

Comments
 (0)