Quellcode durchsuchen

dev: automated commit - 2025-12-31 11:29:23

Mariano Z. vor 1 Monat
Commit
63a1065d3b
1 geänderte Dateien mit 219 neuen und 0 gelöschten Zeilen
  1. 219 0
      lua/freeze/init.lua

+ 219 - 0
lua/freeze/init.lua

@@ -0,0 +1,219 @@
+local M = {}
+
+-- Helper function to detect clipboard command
+local function detect_clipboard_cmd()
+  -- Check for Wayland
+  if vim.fn.executable("wl-copy") == 1 then
+    return "wl-copy --type image/png"
+  end
+  -- Check for X11
+  if vim.fn.executable("xclip") == 1 then
+    return "xclip -selection clipboard -t image/png"
+  end
+  -- Check for macOS
+  if vim.fn.executable("pbcopy") == 1 then
+    return "pbcopy"
+  end
+  -- Default fallback (Wayland)
+  return "wl-copy --type image/png"
+end
+
+-- Configuration
+local config = {
+  freeze_cmd = "freeze",
+  clipboard_cmd = detect_clipboard_cmd(),
+}
+
+-- Helper function to detect visual selection
+local function get_visual_selection()
+  local mode = vim.fn.mode()
+  
+  -- If we're in visual mode, capture directly from visual marks
+  if mode:match("[vV]") then
+    local v_pos = vim.fn.getpos("v")  -- Start of visual selection
+    local dot_pos = vim.fn.getpos(".")  -- Current cursor position (end of selection)
+    
+    if v_pos[2] > 0 and dot_pos[2] > 0 then
+      return math.min(v_pos[2], dot_pos[2]), math.max(v_pos[2], dot_pos[2])
+    end
+  end
+  
+  return nil, nil
+end
+
+-- Helper function to get language from filetype
+local function get_language_from_filetype()
+  local filetype = vim.bo.filetype
+  if filetype == "" then
+    return nil
+  end
+  return filetype
+end
+
+-- Helper function to validate yes/no input
+local function parse_yes_no(input, default)
+  if not input or input == "" then
+    return default
+  end
+
+  local lower = string.lower(input)
+  if lower == "y" or lower == "yes" then
+    return true
+  elseif lower == "n" or lower == "no" then
+    return false
+  end
+
+  return default
+end
+
+-- Helper function to build freeze command
+local function build_freeze_command(filepath, output, opts)
+  local cmd = config.freeze_cmd .. " " .. vim.fn.shellescape(filepath)
+
+  if opts.language then
+    cmd = cmd .. " --language " .. vim.fn.shellescape(opts.language)
+  end
+
+  if opts.show_line_numbers then
+    cmd = cmd .. " --show-line-numbers"
+  end
+
+  if opts.window then
+    cmd = cmd .. " --window"
+  end
+
+  if opts.start_line and opts.end_line then
+    cmd = cmd .. " --lines " .. opts.start_line .. "," .. opts.end_line
+  end
+
+  cmd = cmd .. " -o " .. vim.fn.shellescape(output)
+
+  return cmd
+end
+
+-- Helper function to execute freeze and copy to clipboard
+local function execute_freeze(cmd, output)
+  vim.fn.system(cmd)
+  local clipboard_cmd = config.clipboard_cmd .. " < " .. vim.fn.shellescape(output)
+  vim.fn.system(clipboard_cmd)
+  vim.fn.delete(output)
+end
+
+local function freeze_screenshot(start_line, end_line)
+  local filepath = vim.fn.expand("%:p")
+  if filepath == "" then
+    vim.notify("No file to screenshot", vim.log.levels.ERROR)
+    return
+  end
+
+  -- Auto-detect visual selection if not provided
+  if not start_line or not end_line then
+    start_line, end_line = get_visual_selection()
+  end
+
+  local output = vim.fn.tempname() .. ".png"
+  local cmd = config.freeze_cmd .. " " .. vim.fn.shellescape(filepath) .. " --show-line-numbers -o " .. vim.fn.shellescape(output)
+
+  if start_line and end_line then
+    cmd = cmd .. " --lines " .. start_line .. "," .. end_line
+  end
+
+  execute_freeze(cmd, output)
+
+  local msg = start_line and string.format("Screenshot of lines %d–%d copied", start_line, end_line)
+    or "Screenshot of entire file copied"
+  vim.notify(msg, vim.log.levels.INFO)
+end
+
+local function freeze_interactive(start_line, end_line)
+  local filepath = vim.fn.expand("%:p")
+  if filepath == "" then
+    vim.notify("No file to screenshot", vim.log.levels.ERROR)
+    return
+  end
+
+  -- Check if snacks.nvim is available
+  local ok, snacks = pcall(require, "snacks")
+  if not ok or not snacks or not snacks.input then
+    vim.notify("snacks.nvim is required for interactive mode", vim.log.levels.ERROR)
+    return
+  end
+
+  -- Auto-detect visual selection if not provided
+  if not start_line or not end_line then
+    start_line, end_line = get_visual_selection()
+  end
+
+  local opts = {
+    show_line_numbers = true,  -- default: yes
+    window = false,            -- default: no
+    language = get_language_from_filetype(),
+    start_line = start_line,
+    end_line = end_line,
+  }
+
+  -- First prompt: show line numbers
+  snacks.input.input({
+    prompt = "Mostrar números de línea? (y/n)",
+    default = "y",
+  }, function(value)
+    if value then
+      opts.show_line_numbers = parse_yes_no(value, true)
+    end
+
+    -- Second prompt: show window controls
+    snacks.input.input({
+      prompt = "Mostrar controles de ventana? (y/n)",
+      default = "n",
+    }, function(value2)
+      if value2 then
+        opts.window = parse_yes_no(value2, false)
+      end
+
+      -- Execute freeze with selected options
+      local output = vim.fn.tempname() .. ".png"
+      local cmd = build_freeze_command(filepath, output, opts)
+      execute_freeze(cmd, output)
+
+      local msg = start_line and string.format("Screenshot of lines %d–%d copied", start_line, end_line)
+        or "Screenshot copied to clipboard"
+      vim.notify(msg, vim.log.levels.INFO)
+    end)
+  end)
+end
+
+function M.setup(opts)
+  opts = opts or {}
+  
+  -- Configure freeze command path
+  if opts.freeze_cmd then
+    config.freeze_cmd = opts.freeze_cmd
+  end
+  
+  -- Configure clipboard command
+  if opts.clipboard_cmd then
+    config.clipboard_cmd = opts.clipboard_cmd
+  end
+end
+
+-- Wrapper functions that properly handle visual mode
+-- These should be used in keymaps to ensure selection is captured correctly
+local function freeze_screenshot_wrapper()
+  -- Try to get visual selection - this will work if called from visual mode keymap
+  local start_line, end_line = get_visual_selection()
+  freeze_screenshot(start_line, end_line)
+end
+
+local function freeze_interactive_wrapper()
+  -- Try to get visual selection - this will work if called from visual mode keymap
+  local start_line, end_line = get_visual_selection()
+  freeze_interactive(start_line, end_line)
+end
+
+M.freeze_screenshot = freeze_screenshot
+M.freeze_interactive = freeze_interactive
+M.freeze_screenshot_wrapper = freeze_screenshot_wrapper
+M.freeze_interactive_wrapper = freeze_interactive_wrapper
+
+return M
+