diff --git a/README.md b/README.md index 80128fc..f5119e4 100644 --- a/README.md +++ b/README.md @@ -46,12 +46,23 @@ Run the command `:Pantran` to open an interactive translation window and start typing to get an understanding of how things work. Type `g?` in normal mode or `i_CTRL-/` in insert mode to open a help buffer with available keybindings. `:Pantran` also supports command ranges to initialize the translation window. +Additionally, you can pass text directly to the command without selecting buffer content first: +```vim +:Pantran Hello, World! " Translate text directly +:Pantran target=uk engine=google Hello " Translate with specific options +:1,5Pantran " Translate lines 1-5 from buffer +:'<,'>Pantran " Translate visual selection +``` +The command can also be used when starting nvim: +nvim +Pantran " Open nvim with translation window +nvim +"Pantran Hello, World!" " Start nvim and translate text directly Further, some optional flags for configuration of the translation process are available, consult the [documentation](doc/README.md) for more details. If you plan to translate frequently, the command can also be mapped to the following recommended keybindings: +
diff --git a/lua/pantran/command.lua b/lua/pantran/command.lua index 3cdfc8e..9313abd 100644 --- a/lua/pantran/command.lua +++ b/lua/pantran/command.lua @@ -37,9 +37,21 @@ end -- we need to create marks for coords, since coords could change during -- non-interactive translations with a large delay function command._coords2marks(coords) + -- Validate and clamp coordinates to buffer bounds + local buf_lines = vim.api.nvim_buf_line_count(0) + local srow = math.max(0, math.min(coords.srow, buf_lines - 1)) + local erow = math.max(0, math.min(coords.erow, buf_lines - 1)) + + -- Get actual line lengths for column bounds + local sline = vim.api.nvim_buf_get_lines(0, srow, srow + 1, true)[1] or "" + local eline = vim.api.nvim_buf_get_lines(0, erow, erow + 1, true)[1] or "" + + local scol = math.max(0, math.min(coords.scol, #sline)) + local ecol = math.max(0, math.min(coords.ecol, #eline)) + return { - start = vim.api.nvim_buf_set_extmark(0, command.namespace, coords.srow, coords.scol, {}), - stop = vim.api.nvim_buf_set_extmark(0, command.namespace, coords.erow, coords.ecol, {}) + start = vim.api.nvim_buf_set_extmark(0, command.namespace, srow, scol, {}), + stop = vim.api.nvim_buf_set_extmark(0, command.namespace, erow, ecol, {}) } end @@ -80,8 +92,13 @@ function command.range_translate(opts) local srow, erow, scol, ecol srow, scol = vim.api.nvim_win_get_cursor(0)[1] - 1, 0 erow = srow + math.max(0, (opts.count or vim.v.count) - 1) - ecol = #vim.api.nvim_buf_get_lines(0, erow, erow + 1, true)[1] - 1 - + local lines = vim.api.nvim_buf_get_lines(0, erow, erow + 1, true) + if #lines == 0 then + local total_lines = vim.api.nvim_buf_line_count(0) + erow = math.min(erow, total_lines - 1) + lines = vim.api.nvim_buf_get_lines(0, erow, erow + 1, true) + end + ecol = lines[1] and #lines[1] - 1 or 0 local marks = command._coords2marks{srow = srow, scol = scol, erow = erow, ecol = ecol} local input = table.concat(uapi.nvim_buf_get_text(0, srow, scol, erow + 1, ecol + 1), "\n") command._translate(input, (opts.count or vim.v.count) > 0, marks, opts) @@ -112,15 +129,24 @@ end function command.parse(line1, line2, ...) local opts = {count = line2 ~= -1 and line2 - (line1 - 1)} + local text_to_translate = nil for _, arg in ipairs{...} do local key, value = arg:match("(.-)=(.+)") if key and value then opts[key] = value + else + text_to_translate = (text_to_translate and text_to_translate .. " " or "") .. arg end end - command.range_translate(opts) + if text_to_translate then + -- Use provided text instead of buffer content + local marks = command._coords2marks{srow = 0, scol = 0, erow = 0, ecol = 0} + command._translate(text_to_translate, true, marks, opts) + else + command.range_translate(opts) + end end return config.apply(config.user.command, command)