Question

The company I work for uses special headers for source files, which contain the date of last modification.

I wrote a vim script that updates this date automatically on each buffer write.

I am using the search/substitue feature to do the trick.

Now the problem is that the replace does move the cursor at the beginning of the file, which is very annoying because at each buffer write, the user has to jump back manually to the previous editing position.

Does anyone know a way to prevent vim from jumping when updating the date, or at least to make it jump back to the previous position?

Was it helpful?

Solution

Interactively, you can use <C-O> or the change mark `` to move back to the original position, as shown at vim replace all without cursor moving.

In a Vimscript, especially when this runs on every buffer write, I would wrap the code:

let l:save_view = winsaveview()
    %substitute///
call winrestview(l:save_view)

The former move commands might still affect the window view (i.e. which exact lines and columns are shown in the viewport), whereas this solution restores everything as it was.

Bonus stuff

Also, be aware that the {pattern} used in the :substitute is added to the search history. To avoid that, append

call histdel('search', -1)

(The search pattern itself isn't affected when you have this in a :function.)

or use the :keeppatterns command introduced in Vim 8:

keeppatterns %substitute///

Related plugins

I've implemented similar functionality in my AutoAdapt plugin. You'll see all these tricks used there, too.

OTHER TIPS

I think using the function substitute() will keep your changelist and jumplist. In neovim I am using a function to change the date of file modification this way:

M.changeheader = function()
    -- We only can run this function if the file is modifiable
    local bufnr = vim.api.nvim_get_current_buf()
    if not vim.api.nvim_buf_get_option(bufnr, "modifiable") then
        require("notify")("Current file not modifiable!")
        return
    end
    -- if not vim.api.nvim_buf_get_option(bufnr, "modified") then
    --     require("notify")("Current file has not changed!")
    --     return
    -- end
    if vim.fn.line("$") >= 7 then
    os.setlocale("en_US.UTF-8") -- show Sun instead of dom (portuguese)
    local time = os.date("%a, %d %b %Y %H:%M:%S")
    local l = 1
    while l <= 7 do
        vim.fn.setline(l, vim.fn.substitute(vim.fn.getline(l), 'last (change|modified): \\zs.*', time , 'gc'))
        l = l + 1
    end

        require("notify")("Changed file header!")
    end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top