通过键盘映射用字符串替换所选文本

问题描述 投票:0回答:3

我想用当前日期替换所选文本(在视觉模式下)。

目前我正在尝试调用cmd,然后使用“更改”方法。

keymap.set("x", "<leader>nf", function()
    vim.cmd(string.format("insert\n%s", os.date("%d.%m.%Y")))
end)

它现在所做的只是将日期插入到所选内容上方的行中,而不是删除它。

lua neovim keymapping
3个回答
0
投票

您可以使用需要处理缓冲区选择的行和列的自定义函数来实现此目的。其他选项是使用视觉选择中的更改块。参见

h v_c

用日期替换视觉选择(不是
v_c

此解决方案完全删除所选内容中的所有文本并插入日期

local function replace_date()
    -- Use unpack to give tuple values a name otherwise you can only use indexing.
    -- We are getting line, column, buffer nr etc based on the visual markers here.
    local s_buf, s_row, s_col, _ = unpack(vim.fn.getpos("'<"))
    local _, e_row, e_col, _ = unpack(vim.fn.getpos("'>"))
    local date = os.date("%d.%m.%Y")
    -- Indexing into buffer row needs - 1 because lua indexing starts from 1.
    -- Column subtracts are just to account for start and end scenarios.
    -- We use the positions to fully clear all selected text of a v-block.
    vim.api.nvim_buf_set_text(s_buf, e_row - 1, s_col - 1 , e_row - 1, e_col, {})
    -- Place date.
    vim.api.nvim_buf_set_text(s_buf, s_row - 1, s_col, s_row - 1, s_col, { date })
    -- Exit visual mode
    vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<esc>', true, false, true), 'x', false)
end
-- Bind to visual mode.
vim.keymap.set('v', '\\', replace_date, { noremap = true, silent = true })

选择完成后,您可以在可视模式下按

\
更改日期。

插入视觉块并保留尾随文本

这会将日期插入到视觉选择中,但会将插入日期之后的所有内容保留在 v 块中。

local function insert_date_v()
    local s_buf, s_row, s_col, _ = unpack(vim.fn.getpos("'<"))
    local _, e_row, e_col, _ = unpack(vim.fn.getpos("'>"))
    local date = os.date("%d.%m.%Y")
    -- Keeps trailing visual selection
    vim.api.nvim_buf_set_text(s_buf, e_row - 1, s_col - 1 , e_row - 1, e_col - 1, { date })
    vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes('<esc>', true, false, true), 'x', false)
end

vim.keymap.set('v', '\\', insert_date_v, { noremap = true, silent = true })

使用
v_c

参见

:h v_c
,您可以在选择可视块后输入 c 来替换文本。如果您在视觉模式下使用 c,然后使用
\
,则下面的函数将替换它。请注意,这绑定到插入模式而不是视觉模式。 比早期的解决方案击键次数更多,但边缘情况可能更少。

local function insert_date()
    local row, col = unpack(vim.api.nvim_win_get_cursor(0))
    local date = os.date("%d.%m.%Y")
    vim.api.nvim_buf_set_text(0, row - 1, col, row - 1, col, { date })
end

vim.keymap.set('i', '\\', insert_date, { noremap = true, silent = true })

考虑将领导者密钥添加到上述绑定中。使用

:h
查看调整方法。

其中任何一个都应该满足您的需求。


0
投票

我只能想到这个。

keymap.set("x", "<leader>nf", function()
    vim.cmd("delete")
    vim.cmd(string.format("insert\n%s", os.date("%d.%m.%Y")))
end)

0
投票

接受的答案使用

'<
'>
。这些标记有一个缺点:它们仅在用户(或脚本)离开可视模式时更新。另一种方法是使用
.
v
作为
getpos
的位置参数。

您可以在

line()
的帮助中阅读有关这些位置参数的更多信息。然而,由于这些文档有点神秘,以下是我如何理解它们的用途。在视觉模式下,
.
v
相辅相成。
.
指的是光标的位置(
.
的这种用法在vim和neovim中很常见),
v
指的是视觉选择的另一端。您可以将
v
想象为如果您在视觉模式下输入
v_o
o
将带您前往何处。

.
v
在字符视觉模式中特别有用,因为它们可以有效保证为您提供视觉选择的开始和结束位置。 (如果光标位于视觉选择的末尾,
.
表示结束,
v
表示选择的开始。如果光标位于视觉选择的开始,
.
表示选择的开始)开始,
v
指选择的结束。)

无论如何,调整 GreatGaga 的代码以使用

.
v
会给你这样的东西。 (我已经删除了解释性注释,并且我认为您不需要调用
buf_set_text
两次。):

local function replace_date()
    local s_buf, s_row, s_col, _ = unpack(vim.fn.getpos("."))
    local _, e_row, e_col, _ = unpack(vim.fn.getpos("v"))
    local date = os.date("%d.%m.%Y")

    vim.api.nvim_buf_set_text(
        s_buf,
        e_row - 1,
        s_col - 1,
        e_row - 1,
        e_col,
        { date }
    )
end
© www.soinside.com 2019 - 2024. All rights reserved.