Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow opening files from lazy git as nvim buffer (not inside floating terminal) #22

Closed
akinsho opened this issue Aug 9, 2020 · 13 comments
Labels
enhancement New feature or request

Comments

@akinsho
Copy link

akinsho commented Aug 9, 2020

Is your feature request related to a problem? Please describe.
When using lazygit, it would be nice to be able to edit the current file inside neovim using nvr similar to how you can use nvr to open the commit buffer in the current neovim session rather than an embedded terminal.
I have nvr setup as specified in the README and I've set my open command to nvim {{filename}} but this still opens the file I've selected in lazygit inside the embedded terminal

Describe the solution you'd like
When I select a file in lazygit and hit e it should open the file as a buffer in my nvim session not within the floating window.

NOTE: I've tried explicitly setting my open command to nvr {{filename}} but lazygit seems to be executing nvim afile.ext regardless

Additional context
nvr seems to be setup correctly as committing correctly opens the buffer in the nvim session not in the terminal. It just doesn't behave the same way for files.

@akinsho akinsho added the enhancement New feature or request label Aug 9, 2020
@kdheepak
Copy link
Owner

kdheepak commented Aug 9, 2020

Interesting. I've never tried that. I'll look into it. I suspect it has to do with this:

let $GIT_EDITOR = "nvr -cc split --remote-wait +'set bufhidden=wipe'"

You might need to add:

if has('nvim') && executable('nvr')
  let $EDITOR = "nvr -cc split --remote-wait +'set bufhidden=wipe'"
endif

as well, and experiment with the options.

@akinsho
Copy link
Author

akinsho commented Aug 9, 2020

Gave the $EDITOR suggestion above a try but doesn't seem to work still

@kdheepak
Copy link
Owner

It seems like by default lazygit uses core.editor from your gitconfig.

https://github.com/jesseduffield/lazygit/blob/23299f88e9c5da84902cc872772333c4ab755946/pkg/commands/os.go#L235

However, I tried changing that on my point to use nvr and wasn't able to get it to work. I'm still looking into it. I also tried setting the EDITOR and VISUAL environment variable before calling lazygit but no luck. I'm not sure if it is something to do with my machine though.

I think even if we are able to get lazygit to open the file using nvr, we will have to restore the instance of the floating window where lazygit is running. Currently when opening the commit editor, this is done using gitcommit.vim but that won't work for this case. So there are some additional changes that I'll have to make to the package for this to work, if I can figure out how to trigger nvr.

Surprisingly, if I open a terminal in the separate pane in neovim, and open lazygit there and try to edit a file, it tries to open the file using nvr. So it is possible to do, we just have to figure out the right combination of EDITOR / VISUAL environment variables I think.

@akinsho
Copy link
Author

akinsho commented Aug 10, 2020

Thanks for looking into it, wasn't sure if it was just my setup and other people were able to do it. It's weird that manually opening a terminal split with lazy git works 🤔.

@caojoshua
Copy link

Submitted a pull request for lazygit jesseduffield/lazygit#1324. This will allow use to set EditCommand = nvr ... in the lazygit config file. If you want to use it, you can build from source, or just wait until the change is released in your package repository.

@kdheepak
Copy link
Owner

kdheepak commented Jun 2, 2021

Awesome!

@akinsho
Copy link
Author

akinsho commented Jun 2, 2021

I think I can close this out and just wait on your PR then @caojoshua 👍🏾

@akinsho akinsho closed this as completed Jun 2, 2021
@ranelpadon
Copy link

ranelpadon commented Aug 21, 2021

@kdheepak Your comment here is useful in my Neovim issue: #22 (comment)

I have this cryptic, annoying error when editing a file from lazygit floating term (i.e. by pressing e)

Error detected while processing function <SNR>14_LoadRemotePlugins[1]..<SNR>14_GetManifest[1]..<SNR>
14_GetManifestPath:
line    7:
E117: Unknown function: stdpath
Press ENTER or type command to continue

which is related to here:
neovim/neovim#9960

and I didn't understand why Neovim will trigger vi/vim in the embedded terminal. But in the logic above, it checks the

  • $GIT_EDITOR
  • $VISUAL
  • $EDITOR
    and the default is vi/vim if those vars are not set!

So, it makes sense now, and fixed the issue by setting those environment variables to nvim in my ~/.zshrc. Thanks for the idea. :)

@kdheepak
Copy link
Owner

Glad that worked!

@nikbrunner
Copy link

Is this now possible? This would be incredible! Desperately looking for this feature 😊

@SeniorMars
Copy link

SeniorMars commented Jun 21, 2022

Is there any way to close the lazygit buffer and open the file in the current window?

@cosmicbuffalo
Copy link

cosmicbuffalo commented Oct 6, 2023

so I know lazyvim doesn't even use this plugin but I came across this this issue when searching for how to do this so thought I'd share my results.

I got this to work using some lazyvim utils but those dependencies could probably be switched to whatever this plugin uses. my keymaps overwrite the lazyvim default of <leader>gg to open lazygit and then sets<c-i> within lazygit to open a file by copying the path, closing lazygit, then opening the file in a new buffer in the original window. I figured a simple sequence of commands like this would be much easier to set up than something like nvr. I originally had this mapped over the existing e command within lazygit, but that actually broke a lot of things because hitting e in any context within lazygit, including in the commit description, triggered the mapping 🤦

local Util = require("lazyvim.util")

function LazygitEdit(original_buffer)
  -- git current terminal channel
  local bufnr = vim.fn.bufnr("%")
  local channel_id = vim.fn.getbufvar(bufnr, "terminal_job_id")

  if channel_id == nil then
    print("No terminal job ID found.")
    return
  end

  -- Use <c-o> to copy the relative file path to the system clipboard in Lazygit
  vim.fn.chansend(channel_id, "\15") -- \15 is <c-o>
  -- Give some time for the copy operation to complete
  vim.cmd("sleep 200m")

  -- Close Lazygit
  vim.cmd("close")

  -- Get the copied relative file path from the system clipboard
  local rel_filepath = vim.fn.getreg("+")

  -- Combine with the current working directory to get the full path
  local cwd = Util.get_root()
  local abs_filepath = cwd .. "/" .. rel_filepath

  print("Opening " .. abs_filepath)

  -- focus on the original window
  local winid = vim.fn.bufwinid(original_buffer)
  if winid ~= -1 then
    vim.fn.win_gotoid(winid)
  else
    print("Could not find the original window")
    return
  end

  -- Open the file in a new buffer
  vim.cmd("e " .. abs_filepath)
end

-- Start Lazygit
function StartLazygit()
  local current_buffer = vim.api.nvim_get_current_buf()
  local float_term = Util.float_term({ "lazygit" }, { cwd = Util.get_root(), esc_esc = false, ctrl_hjkl = false })
  local created_buffer = float_term.buf
  -- set the custom keymap for "<c-i>" within it
  vim.api.nvim_buf_set_keymap(created_buffer, "t", "<c-i>", string.format([[<Cmd>lua LazygitEdit(%d)<CR>]], current_buffer), { noremap = true, silent = true })
end

vim.api.nvim_set_keymap("n", "<leader>gg", [[<Cmd>lua StartLazygit()<CR>]], { noremap = true, silent = true, desc={ "Lazygit (root dir)" } })

@HakonHarnes
Copy link

HakonHarnes commented Nov 16, 2023

Thank you, @cosmicbuffalo! Your script worked pretty good, but the absolute file path didn't always resolve correctly for me. The solution was to use the relative path instead. I also found that the 200ms delay was not needed, so I added a no delay option with a retry mechanism instead. That made it alot snappier for me. I also changed the default keybinding from c-i to c-e, which makes more sense to me, and slightly improved the error handling and logging.

local Util = require("lazyvim.util")

-- Function to check clipboard with retries
local function getRelativeFilepath(retries, delay)
  local relative_filepath
  for i = 1, retries do
    relative_filepath = vim.fn.getreg("+")
    if relative_filepath ~= "" then
      return relative_filepath -- Return filepath if clipboard is not empty
    end
    vim.loop.sleep(delay) -- Wait before retrying
  end
  return nil -- Return nil if clipboard is still empty after retries
end

-- Function to handle editing from Lazygit
function LazygitEdit(original_buffer)
  local current_bufnr = vim.fn.bufnr("%")
  local channel_id = vim.fn.getbufvar(current_bufnr, "terminal_job_id")

  if not channel_id then
    vim.notify("No terminal job ID found.", vim.log.levels.ERROR)
    return
  end

  vim.fn.chansend(channel_id, "\15") -- \15 is <c-o>
  vim.cmd("close") -- Close Lazygit

  local relative_filepath = getRelativeFilepath(5, 50)
  if not relative_filepath then
    vim.notify("Clipboard is empty or invalid.", vim.log.levels.ERROR)
    return
  end

  local winid = vim.fn.bufwinid(original_buffer)

  if winid == -1 then
    vim.notify("Could not find the original window.", vim.log.levels.ERROR)
    return
  end

  vim.fn.win_gotoid(winid)
  vim.cmd("e " .. relative_filepath)
end

-- Function to start Lazygit in a floating terminal
function StartLazygit()
  local current_buffer = vim.api.nvim_get_current_buf()
  local float_term = Util.terminal.open({ "lazygit" }, { cwd = Util.root(), esc_esc = false, ctrl_hjkl = false })

  vim.api.nvim_buf_set_keymap(
    float_term.buf,
    "t",
    "<c-e>",
    string.format([[<Cmd>lua LazygitEdit(%d)<CR>]], current_buffer),
    { noremap = true, silent = true }
  )
end

vim.api.nvim_set_keymap("n", "<leader>gg", [[<Cmd>lua StartLazygit()<CR>]], { noremap = true, silent = true })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants