Repository navigation
bug: cursor is reset after keymap function call #639
Copy link
Copy link
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Did you check the docs and existing issues?
- I have read the docs
- I have searched the existing issues
Neovim version (nvim -v)
v0.12.0-dev-683+g2b4c1127ad
Operating system/version
MacOS 15.5
Describe the bug
I am trying to set a function to manually Git Add and Git Reset the file under the cursor with a keymap.
The function is working but the cursor gets reset after I call the function to the top possition.
Calling :lua vim.fn.cursor(9,0) will work after my function call, so I think it is Oil the one resetting the cursor.
These are the functions in question:
["<leader>ga"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "add", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
["<leader>gr"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "reset", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
My full Config, though it repros with the minimal config so this is just noise.
local add = MiniDeps.add
add({
source = "stevearc/oil.nvim",
depends = { "nvim-tree/nvim-web-devicons" },
})
add({
source = "refractalize/oil-git-status.nvim",
depends = { "stevearc/oil.nvim" },
})
local oil = require("oil")
oil.setup({
win_options = {
signcolumn = "yes:2",
},
columns = { "icon" },
keymaps = {
-- Don't use motions I use for window management for splits
["<C-h>"] = false,
["<C-l>"] = false,
-- Splits
["<C-s>"] = { "actions.select", opts = { horizontal = true } },
["<C-v>"] = { "actions.select", opts = { vertical = true } },
["<leader>ga"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "add", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
["<leader>gr"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "reset", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
},
view_options = {
show_hidden = true,
},
-- EXPERIMENTAL support for performing file operations with git
git = {
-- Return true to automatically git add/mv/rm files
add = function(path)
return false
end,
mv = function(src_path, dest_path)
return true
end,
rm = function(path)
return false
end,
},
})
require("oil-git-status").setup()
-- Open parent directory in current window
vim.keymap.set("n", "-", "<CMD>Oil<CR>", { desc = "Open parent directory" })
-- Open parent directory in floating window
vim.keymap.set("n", "<space>-", require("oil").toggle_float, { desc = "Floating directory viewer" })
What is the severity of this bug?
tolerable (can work around it)
Steps To Reproduce
dir=$(mktemp -d)
cd $dir
touch a
nvim -u ~/oil-keymap-cursor/repro.lua
:Oil
# Scroll over to the file "a"
<space>ga
# At this point the cursor will jump to the top
# in another window you can confirm that the file was added to git
# Scroll over to the file "a"
<space>gr
# At this point the cursor will jump to the top
# in another window you can confirm that the file was reset from git
Expected Behavior
Since I set vim.fn.cursor() from within my keymap I expect the cursor to be retained.
Directory structure
a
Repro
-- save as repro.lua
-- run with nvim -u repro.lua
-- DO NOT change the paths
local root = vim.fn.fnamemodify("./.repro", ":p")
-- set stdpaths to use .repro
for _, name in ipairs({ "config", "data", "state", "runtime", "cache" }) do
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end
-- bootstrap lazy
local lazypath = root .. "/plugins/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git",
"clone",
"--filter=blob:none",
"--single-branch",
"https://github.com/folke/lazy.nvim.git",
lazypath,
})
end
vim.opt.runtimepath:prepend(lazypath)
-- install plugins
local plugins = {
"folke/tokyonight.nvim",
{
"stevearc/oil.nvim",
config = function()
require("oil").setup({
-- add any needed settings here
})
end,
},
-- add any other plugins here
}
require("lazy").setup(plugins, {
root = root .. "/plugins",
})
vim.cmd.colorscheme("tokyonight")
-- add anything else here
vim.g.mapleader = " "
local oil = require("oil")
oil.setup({
win_options = {
signcolumn = "yes:2",
},
columns = { "icon" },
keymaps = {
-- Don't use motions I use for window management for splits
["<C-h>"] = false,
["<C-l>"] = false,
-- Splits
["<C-s>"] = { "actions.select", opts = { horizontal = true } },
["<C-v>"] = { "actions.select", opts = { vertical = true } },
["<leader>ga"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "add", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
["<leader>gr"] = function()
local cwd = oil.get_current_dir()
local entry = oil.get_cursor_entry()
if cwd and entry then
local pos = vim.fn.getcurpos()
local line = pos[2]
local col = pos[3]
vim.fn.jobstart({ "git", "reset", string.format("%s/%s", cwd, entry.name) })
oil.open(cwd)
print("Cursor Position: Line " .. line .. ", Column " .. col)
vim.fn.cursor(line, 0)
end
end,
},
view_options = {
show_hidden = true,
},
-- EXPERIMENTAL support for performing file operations with git
git = {
-- Return true to automatically git add/mv/rm files
add = function(path)
return false
end,
mv = function(src_path, dest_path)
return true
end,
rm = function(path)
return false
end,
},
})Did you check the bug with a clean config?
- I have confirmed that the bug reproduces with
nvim -u repro.luausing the repro.lua file above.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Activity
restacksyj commentedon Jan 26, 2026
Hey @DavidGamba , I don't know if you are still facing the issue but I went through the issue and seems like not calling
oil.open(cwd)aftervim.fn.jobstartfixes the cursor issue. Since you call, oil.open(cwd) after that, it resets the cursor to the top.Let me know if this helps! For your reference
DavidGamba commentedon Jan 26, 2026
@restacksyj the reason I am doing
oil.openis because oil doesn't refresh the status view after I do git add. Even when addingwatch_for_changes = true.Also, triggering the
actions.refreshkeybind also sends me back to the top of the file.I want to be able to get immediate visual confirmation that the file was added to the list of staged files or removed from it.
restacksyj commentedon Jan 27, 2026
@DavidGamba This is kinda workaround by changing your config a little, you can use this instead of just oil.open(cwd). The thing is oil takes precedence when we call oil.open(cwd) and while rendering the buffer, resets the cursor position. Let me know if this helps!
https://asciinema.org/a/zKABCwNmdD9ysSBU
DavidGamba commentedon Jan 27, 2026
Oh wow, that really did it! Thanks so much for going out of your way to help me!
For the record, in case someone else runs into this, this is my config after the suggestion:
config