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

(O)pen file and (e)dit file in the current nvim instance? #67

Open
Nikola-Milovic opened this issue Jul 30, 2022 · 32 comments
Open

(O)pen file and (e)dit file in the current nvim instance? #67

Nikola-Milovic opened this issue Jul 30, 2022 · 32 comments

Comments

@Nikola-Milovic
Copy link

Currently, the edit hotkey opens the file in the lazygits floating term and makes navigating back to the lazygit impossible. The open shortcut opens the file in the default text editor.

Is it possible for open and edit shortcuts to close the floaterm and just open the buffer in the nvim itself? I am currently on the default settings

@kdheepak
Copy link
Owner

If I'm understanding correctly, if you install nvr, i.e. neovim remote, this is the default behavior.

@Nikola-Milovic
Copy link
Author

Does it work out of the box? To me it doesn't seem to behave as I'd expect it to. Would love to see someones setup

@okuuva
Copy link

okuuva commented Sep 24, 2022

I think it should work out of the box but setting GIT_EDITOR env var somewhere might mess with it. I have the following in my settings:

if vim.fn.executable("nvr") == 1 then
  vim.env.GIT_EDITOR = "nvr --remote-tab-wait +'set bufhidden=delete'"
end

All the tutorials out there use just --remote-wait instead of --remote-tab-wait but it completely messes up my nvim UI after writing the commit message. Might be that I've misconfigured something else somewhere or something but the snippet above has worked for me quite nicely.

@Nikola-Milovic
Copy link
Author

Nikola-Milovic commented Sep 25, 2022

@okuuva can you expand a bit upon your setup, I am newish to this ecosystem. Where do you put this function, do you have any other setup going besides this? Do you start your nvim normally or do you use nvim remote?

@kdheepak
Copy link
Owner

I have the following lines in my dotfiles:

https://github.com/kdheepak/dotfiles/blob/1c844ed92675e9feffa2e3bdf00ec1385611bb65/nvim/lua/kd/config.lua#L313-L318

You can add @okuuva or my snippet into your .vimrc or init.lua and it should work.

@kdheepak
Copy link
Owner

kdheepak commented Sep 25, 2022

I also have the following in my .bashrc:

if [ -n "$NVIM_LISTEN_ADDRESS" ]; then
    export VISUAL="nvr -cc split --remote-wait +'set bufhidden=wipe'"
else
    export VISUAL="nvim"
fi

export EDITOR="$VISUAL"

I'm not sure if this is completely necessary though. It's been a while since I messed around with this.

@samodostal
Copy link

Behaviour I'm experiencing:

  • When pressing 'C': Commit message file is opened in the current neovim instance
  • When pressing 'e': A new neovim instance is created inside the floating window and the file is opened there
  • When pressing 'o': The file is opened in my default system editor (For me it is just a browser :D)

I would like to set it up so that all of the above would be opened in the current neovim instance. I should have nvr setup precisely as the readme suggests.

@monadplus
Copy link

Same behaviour here. Set up as readme suggested. With latest version of nvr and lazygit.nvim. Let me know if you need more debugging information ^.^

@lawrence-laz
Copy link
Contributor

lawrence-laz commented Nov 8, 2022

If anyone is looking for a vanilla way to edit files from lazygit directly in currently open nvim session, I managed to get it working like this:

# ~/.config/jesseduffield/lazygit/config.yml
os:
  editCommand: 'nvim'
  editCommandTemplate: '{{editor}} --server /tmp/nvim-server.pipe --remote-tab "$(pwd)/{{filename}}"'
# ~/.bashrc
alias vim='nvim --listen /tmp/nvim-server.pipe'

@kdheepak
Copy link
Owner

kdheepak commented Nov 8, 2022

That’s a neat trick! Would you like to submit a PR for that into the README?

@lawrence-laz
Copy link
Contributor

That’s a neat trick! Would you like to submit a PR for that into the README?

Sure, see if this makes sense: #85

@Nikola-Milovic
Copy link
Author

Hey @lawrence-laz what's the behaviour you're experiencing with this?

When I use (o)pen a new terminal window is opened in regular vim (I see that your above command was only for editing?)
And when I use (e)dit it opens up a floating terminal inside the current nvim session

@lawrence-laz
Copy link
Contributor

lawrence-laz commented Nov 12, 2022

Hey @lawrence-laz what's the behaviour you're experiencing with this?

When I use (o)pen a new terminal window is opened in regular vim (I see that your above command was only for editing?)

And when I use (e)dit it opens up a floating terminal inside the current nvim session

I'm currently away from my machine, but I only use (e)diting, not sure about (o)pen.

The editing for me opens up in the same nvim instance full screen.

I can make a gif once I am back to show how it looks.

If it launches a new instance of nvim for you, it might be that your nvim didn't succeed in starting a server. You could try experimenting with it a bit with multiple terminals and the commands from config.

EDIT:
Just an update with a GIF of how it works on my machine.
The bottom split terminal windows is pinging the same nvim instance and nvim echoes my message.
lazygit-edit-in-nvim

@samodostal
Copy link

samodostal commented Mar 16, 2023

If you are wondering how to make this work with multiple neovim instances, here is my approach:

The issue arises when starting two neovim instances using the same alias:

alias nvim='nvim --listen /tmp/nvim-server.pipe'

This causes both instances to listen to the same pipe, making it impossible to use. When attempting to open a file from lazygit, both instances try to open it.

In my workflow, I use tmux which enables me to create an alias like this:

alias nvim="nvim --listen /tmp/nvim-server-$(tmux display-message -p '#S').pipe"

This creates a pipe specific to the tmux session, solving the previous issue. The next step is to communicate with this pipe. This is my lazygit configuration:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

With this, we can communicate with the correct pipe. In the --remote-send part, you can execute any neovim command you want. I call a Lua script that closes the floating lazygit window and opens the file in the buffer underneath it.

The current behavior that I am experiencing is:

  • When pressing 'e/o': The lazygit floating window is closed, and the file is opened in the window below it.

If you want to look at details you can check my .dotfiles

@samodostal
Copy link

Also, I guess this answers the original question. You can close the floating LazyGit window and open a file in the window underneath. The Lua script you need to call in editCommand and openCommand in LazyGit config file is:

return function(filename, line_number)
	line_number = tonumber(line_number) or 1

	vim.api.nvim_win_close(0, true)
	vim.api.nvim_command('edit +' .. line_number.. " " .. filename)
end

misterbander added a commit to misterbander/lvim that referenced this issue Jun 29, 2023
misterbander added a commit to misterbander/lvim that referenced this issue Jun 29, 2023
jensenojs added a commit to jensenojs/dotfiles that referenced this issue Sep 20, 2023
@jensenojs
Copy link

Hey @lawrence-laz what's the behaviour you're experiencing with this?

When I use (o)pen a new terminal window is opened in regular vim (I see that your above command was only for editing?) And when I use (e)dit it opens up a floating terminal inside the current nvim session

when I use (e)dit it opens up a floating terminal inside the current nvim session, but when I use (o)pen a new terminal window is opened in vscode, did i miss sth?

setting showed below

# zshrc
if [ -n "$NVIM_LISTEN_ADDRESS" ]; then
    export VISUAL="nvr -cc split --remote-wait +'set bufhidden=wipe'"
else
    export VISUAL="nvim"
fi
export EDITOR="$VISUAL"

alias ni='nvim --listen /tmp/nvim-server.pipe'

neovim related settings are

-- init.lua
if vim.fn.executable("nvr") == 1 then
  vim.env.GIT_EDITOR = "nvr --remote-wait +'set bufhidden=delete'"
end

lazygit related settings are ( /Users/jensen/Library/Application Support/lazygit/config.xml)

os:
  editCommand: 'nvim'
  editCommandTemplate: '{{editor}} --server /tmp/nvim-server.pipe --remote-tab "$(pwd)/{{filename}}"'

any advice? i want open file in current neovim instance as a buffer @lawrence-laz @Nikola-Milovic @kdheepak

@samodostal
Copy link

I would recommend not using 'nvr', but the 'listen and send command via pipe' feature in neovim. Look at the @lawrence-laz comment. With that approach I have it working as intended ('o'pen and 'e'dit both open new tab in current neovim session)

@searleser97
Copy link

Also, I guess this answers the original question. You can close the floating LazyGit window and open a file in the window underneath. The Lua script you need to call in editCommand and openCommand in LazyGit config file is:

return function(filename, line_number)
	line_number = tonumber(line_number) or 1

	vim.api.nvim_win_close(0, true)
	vim.api.nvim_command('edit +' .. line_number.. " " .. filename)
end

Could you elaborate on this one @samodostal ? LazyGit accepts lua code in the config ? or where does that function should be placed ?

@searleser97
Copy link

If you are wondering how to make this work with multiple neovim instances, here is my approach:

The issue arises when starting two neovim instances using the same alias:

alias nvim='nvim --listen /tmp/nvim-server.pipe'

This causes both instances to listen to the same pipe, making it impossible to use. When attempting to open a file from lazygit, both instances try to open it.

In my workflow, I use tmux which enables me to create an alias like this:

alias nvim="nvim --listen /tmp/nvim-server-$(tmux display-message -p '#S').pipe"

This creates a pipe specific to the tmux session, solving the previous issue. The next step is to communicate with this pipe. This is my lazygit configuration:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

With this, we can communicate with the correct pipe. In the --remote-send part, you can execute any neovim command you want. I call a Lua script that closes the floating lazygit window and opens the file in the buffer underneath it.

The current behavior that I am experiencing is:

  • When pressing 'e/o': The lazygit floating window is closed, and the file is opened in the window below it.

If you want to look at details you can check my .dotfiles

@samodostal Do you know what does (tmux display-message -p '#S' does ? So that we can see if we can replicate the behavior in other terminal emulator ? Thanks

@samodostal
Copy link

samodostal commented Oct 22, 2023

Could you elaborate on this one @samodostal ? LazyGit accepts lua code in the config ? or where does that function should be placed ?

In neovim you can execute lua code (functions). With the --remote-send command you can trigger any neovim command (like executing a lua function). Here it is used in the lazygit config:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

@samodostal Do you know what does (tmux display-message -p '#S' does ? So that we can see if we can replicate the behavior in other terminal emulator ? Thanks

It prints the name of the current tmux session to stdout. I name my neovim pipes based on the tmux session name, making it possible to use this feature with more neovim instances. If you want this to work only for one neovim instance, use the @lawrence-laz solution.

@kdheepak
Copy link
Owner

If you’d like to make this part of the README that’d be awesome!

@Chaitanya-Shahare
Copy link

Also, I guess this answers the original question. You can close the floating LazyGit window and open a file in the window underneath. The Lua script you need to call in editCommand and openCommand in LazyGit config file is:

return function(filename, line_number)
	line_number = tonumber(line_number) or 1

	vim.api.nvim_win_close(0, true)
	vim.api.nvim_command('edit +' .. line_number.. " " .. filename)
end

Could you elaborate on this one @samodostal ? LazyGit accepts lua code in the config ? or where does that function should be placed ?

Did you figure out where to use that function?

@samodostal
Copy link

samodostal commented Apr 30, 2024

You can put that lua function in any file, the important part is how you set up the 'edit' and 'open' commands in your lazygit configuration.
I'll give an example. You have you init.lua file somewhere in your file system, let's say ~/.dotfiles/neovim/init.lua. This is your neovim configuration. Now put that lua function into a file ~/.dotfiles/neovim/lua/lazygit-open-file.lua and modify the commands in your lazygit configuration:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S').pipe --remote-send "<cmd>lua require('lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

This should work, because by default when you call lua require(...) in neovim, it looks for the file in this lua/ directory next to your init.lua file. Hope this makes it clearer

@Chaitanya-Shahare
Copy link

Thanks for the reply, I just got it working & it works like a charm. Thank you!

@joshfullmer
Copy link

@samodostal I really like your solution! I did encounter a small issue with it though, as I tend to have multiple windows open, with multiple panes, often each window having at least one nvim instance.

I modified your nvim alias to:

alias nvim="nvim --listen /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe"

And the :LazyGitConfig to:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

And this works much more seamlessly for my workflow. The primary change is modifying the tmux message to use session, window, and pane to generate the temporary server. '#S' -> '#S-#W-#P'

@gustavclausen
Copy link

@samodostal I really like your solution! I did encounter a small issue with it though, as I tend to have multiple windows open, with multiple panes, often each window having at least one nvim instance.

I modified your nvim alias to:

alias nvim="nvim --listen /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe"

And the :LazyGitConfig to:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

And this works much more seamlessly for my workflow. The primary change is modifying the tmux message to use session, window, and pane to generate the temporary server. '#S' -> '#S-#W-#P'

Thanks @joshfullmer – just what I needed. As my window name is changing dynamically, I decided to use the session, window and pane IDs.

nvim alias:

alias nvim="nvim --listen /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe"

Lazygit config:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"

@karamanliev
Copy link

karamanliev commented Jul 3, 2024

Thanks everyone for the solutions, it really helped me make this work!

Just something I want to add - edit doesn't really send {{line}} variable to neovim, as the lazygit README states:

  # Command for editing a file. Should contain "{{filename}}".
  edit: ""

  # Command for editing a file at a given line number. Should contain
  # "{{filename}}", and may optionally contain "{{line}}".
  editAtLine: ""

  # Same as EditAtLine, except that the command needs to wait until the
  # window is closed.
  editAtLineAndWait: ""

If you want editing at the specified line to work (pressing enter on a changed file inside lazygit and selecting a line, then pressing e) just add:

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}')<CR>"
  editAtLine: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}', '{{line}}')<CR>"
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '#S-#W-#P').pipe --remote-send "<cmd>lua require('core.scripts.lazygit-open-file')('{{filename}}')<CR>"

Also I've found that if you're already using tmux, you don't really need this plugin. This keymap opens lazygit in a tmux popup, with rounded corners (my preference inside neovim for popups), sets env variable for TERM because for some reason my delta diff colors are messed inside tmux, sets position (center) and width/height of the popup (90%), adds background (just tokyonight's bg_popup color) and loads the custom lazygit config for neovim.

-- Open lazygit in new tmux window
vim.keymap.set(
  'n',
  '<leader>gg',
  '<cmd>silent !tmux set -w popup-border-lines rounded; tmux popup -E -eTERM=screen-256color -xC -yC -w90\\% -h90\\% -sbg=\\#1f2335 -Sbg=\\#1f2335 -d "'
    .. vim.fn.getcwd()
    .. '" lazygit -ucf $XDG_CONFIG_HOME/lazygit/config_nvim.yml<cr>',
  { desc = 'Lazygit' }
)

Inside the config I added (you can make it as a neovim function, and require it, just a personal preference):

os:
  edit: nvim --server /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe --remote-send "<cmd>e {{filename}}<cr>";tmux popup -C;
  editAtLine: nvim --server /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe --remote-send "<cmd>e +{{line}} {{filename}}<cr>";tmux popup -C;
  open: nvim --server /tmp/nvim-server-$(tmux display-message -p '\#{session_id}-#{window_id}-#{pane_id}').pipe --remote-send "<cmd>e {{filename}}<cr>";tmux popup -C;

tmux popup -C closes the tmux floating popup.

Here's a video of it in action:

Screencast.from.2024-07-03.22-51-46.mp4

Cheers!

@kdheepak
Copy link
Owner

kdheepak commented Jul 4, 2024

Thanks for sharing! I’d be open to adding your tmux command to the repo. I’m thinking maybe people will find it useful to do the same with zellij too.

@jensenojs
Copy link

jensenojs commented Jul 6, 2024

sorry, I got a little lost in the context.

I came back to this question to see what was wrong with my configuration, because I didn't have editAtLine configured, but it seemed to work, and then I tried further, and then I was completely lost, especially after I tried to upgrade lazygit(version=0.42.0), The editAtLine function was gone too

image

i have tired @karamanliev config.yml but i only have nvim-server.pipe even when i in tmux.

image

then i retired with remove $(tmux display-message, it shows sth like

image

editAtLine work with below config

os:
edit: nvim --server /tmp/nvim-server.pipe --remote-send "<cmd>e {{filename}}<cr>";tmux popup -C;
editAtLine: nvim --server /tmp/nvim-server.pipe --remote-send "<cmd>e +{{line}} {{filename}}<cr>";tmux popup -C;
open: nvim --server /tmp/nvim-server.pipe --remote-send "<cmd>e {{filename}}<cr>";tmux popup -C;
image

But I'm not sure if this is another bug, the page returned after :q is empty, not lazygit

image

The above is my attempt, and thanks everyone for the solutions, in particularly @kdheepak , but since the context is probably too long, maybe we need a centralized place to reorganize things a bit.

ps

  • tmux version : 3.4
  • lazygit version 0.42.0
  • this plugin lastest
  • mac m2 air

pps

  • Also, this script doesn't seem to take into account the situation of opening it directly with lazygit. ?

@dudicoco
Copy link

dudicoco commented Jul 9, 2024

lazygit now has a native integration with nvim remote: https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#configuring-file-editing

In my case I didn't even have to open nvim with the --listen flag, it just worked out of the box.

@jensenojs
Copy link

lazygit now has a native integration with nvim remote: https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#configuring-file-editing

In my case I didn't even have to open nvim with the --listen flag, it just worked out of the box.

same, and in case anyone want to skip "press enter to return to lazygit" like this

image

plz refer to

@punsii2
Copy link

punsii2 commented Oct 17, 2024

@jensenojs

same, and in case anyone want to skip "press enter to return to lazygit" like this

When i do that i don't get the prompt, but the lazygit-nvim window does not close properly.
Screenshot from 2024-10-17 16-27-48
In that state :q closes the empty window and i can start editing the file.

Is there another option that i am missing?

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

No branches or pull requests