在 :r

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

我做了一个自定义命令,我尝试使用

mark
来保存光标位置。但标记设置在第6行文件插入的位置(使用
r
命令)。

vim.cmd [[ command! -nargs=1 Include call feedkeys("mx") | 6r <args> | call feedkeys("`x")]]

我认为

6r <args>
feedkeys("mx")
之前执行。我们有什么办法可以解决这个问题吗?或者是否有其他方法可以恢复光标位置

neovim
3个回答
2
投票

我在lua(neovim)中有一个“保留光标位置”功能,它位于我的utils.lua文件中,它是这样的:

M.preserve = function(arguments)
    local arguments = string.format("keepjumps keeppatterns execute %q", arguments)
    -- local original_cursor = vim.fn.winsaveview()
    local line, col = unpack(vim.api.nvim_win_get_cursor(0))
    vim.api.nvim_command(arguments)
    local lastline = vim.fn.line("$")
    -- vim.fn.winrestview(original_cursor)
    if line > lastline then
        line = lastline
    end
    vim.api.nvim_win_set_cursor({ 0 }, { line, col })
end

上面的函数封装了任何给定的命令,例如,如果我想重新缩进整个文件,我创建一个 Reindent 命令:

vim.cmd([[command! Reindent lua require('utils').preserve("sil keepj normal! gg=G")]])

然后运行:

:Reindent

要删除任何行末尾的空格:

vim.cmd([[cnoreab cls Cls]])
vim.cmd([[command! Cls lua require("utils").preserve('%s/\\s\\+$//ge')]])

Vimscript 版本:

" preserve function
if !exists('*Preserve')
    function! Preserve(command)
        try
            let l:win_view = winsaveview()
            "silent! keepjumps keeppatterns execute a:command
            silent! execute 'keeppatterns keepjumps ' . a:command
        finally
            call winrestview(l:win_view)
        endtry
    endfunction
endif

就我而言,我有另一个函数来挤压空白行(如果我有多个连续的空白,就像它们变成一个一样),所以,我有这个函数:

M.squeeze_blank_lines = function()
    -- references: https://vi.stackexchange.com/posts/26304/revisions
    if vim.bo.binary == false and vim.opt.filetype:get() ~= "diff" then
        local old_query = vim.fn.getreg("/") -- save search register
        M.preserve("sil! 1,.s/^\\n\\{2,}/\\r/gn") -- set current search count number
        local result = vim.fn.searchcount({ maxcount = 1000, timeout = 500 }).current
        local line, col = unpack(vim.api.nvim_win_get_cursor(0))
        M.preserve("sil! keepp keepj %s/^\\n\\{2,}/\\r/ge")
        M.preserve("sil! keepp keepj %s/\\v($\\n\\s*)+%$/\\r/e")
        if result > 0 then
            vim.api.nvim_win_set_cursor({ 0 }, { (line - result), col })
        end
        vim.fn.setreg("/", old_query) -- restore search register
    end
end

然后我删除了连续的空白行,但光标保留在原来的位置:

:nnoremap <leader>d :lua require('utils').squeeze_blank_lines()<cr>

或者如果你是的话,有机会使用 init.lua

-- map helper
local function map(mode, lhs, rhs, opts)
    local options = { noremap = true }
    if opts then
        options = vim.tbl_extend("force", options, opts)
    end
    vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end

map("n", "<leader>d", '<cmd>lua require("utils").squeeze_blank_lines()<cr>')

我希望这些想法可以帮助您找到问题的解决方案

最后的提示:如果您使用建议的 utils.lua,您必须在其开头插入:

local M = {}

最后:

return M

0
投票

对于一些读者来说,如果您立即拨打

vim.fn.winsaveview()
,似乎它发生在
do things
之前并且位置被恢复,这是我的理论。 为了让
winrestview
工作,你必须延迟它,要么使用 feed 键(恶心),要么以小的(例如 0)异步延迟调用它:

vim.g.cursor_position = vim.fn.winsaveview()
-- do things
-- Now we restore the cursor position with a delay of 0ms
vim.defer_fn(function() vim.fn.winrestview(vim.g.cursor_position) end, 0)

延迟键版本(不推荐,按 然后转义在字符串开头插入转义符,并在字符串末尾插入 CR(这些特殊字符已被 stackoverflow 删除):

vim.fn.feedkeys([[:lua vim.fn.winrestview(vim.g.cursor_position)]])

0
投票

这是从 Vim 默认值转换而来的 -

https://github.com/vim/vim/blob/master/runtime/defaults.vim#L105-L116

-- When editing a file, always jump to the last known cursor position.
-- Don't do it when the position is invalid, when inside an event handler,
-- for a commit or rebase message
-- (likely a different one than last time), and when using xxd(1) to filter
-- and edit binary files (it transforms input files back and forth, causing
-- them to have dual nature, so to speak)
function RestoreCursorPosition()
  local line = vim.fn.line("'\"")
  if line > 1 and line <= vim.fn.line("$") and vim.bo.filetype ~= 'commit' and vim.fn.index({'xxd', 'gitrebase'}, vim.bo.filetype) == -1 then
    vim.cmd('normal! g`"')
  end
end

if vim.fn.has("autocmd") then
  vim.cmd([[
    autocmd BufReadPost * lua RestoreCursorPosition()
  ]])
end

© www.soinside.com 2019 - 2024. All rights reserved.