nvim-neo-tree / neo-tree.nvim

Neovim plugin to manage the file system and other tree like structures.
MIT License
3.66k stars 216 forks source link

Telescope live grep always navigate to the begining of the file #958

Open ghostbuster91 opened 1 year ago

ghostbuster91 commented 1 year ago

For some reason when calling telescope live grep from the neo-tree window and going to one of the results instead of putting cursor on the line that I selected my cursor is moved to the top of the file that contains it.

Kooha-2023-05-28-22-00-19.webm The video shows me calling telescope three times. First from the neotree window, second time from the result buffer, and the last time again from the neo-tree window. Both in the first and third time I have my cursor at the top of the file.

cseickel commented 1 year ago

This is the result of focus stealing prevention. If neo-tree is focused when you open telescope, then telescope will try to open your chosen file in the neo-tree window. If you use position=current, that's fine, but if you have a sidebar then it will take the window back. After neo-tree retakes its sidebar window, then it will re-open the file using similar logic to when you open a file from neo-tree itself.

In all this, I never thought to try to retain the cursor position.

nhat-vo commented 1 year ago

I have had a look at this, and it seems that it would be quite complicated and "hacky" to implement this as there are many edge cases. Currently, whenever a buffer steals neo-tree's window, neo-tree will change back to the neo-tree buffer, delete the stealing buffer, then reopen it as a file. This avoids neo-tree window being stolen, but it makes it quite complicated to restore things like cursor locations. This is because the "stealing" plugin will first open the buffer, then set these values while assuming that the buffer will not be restolen.

In this case, Telescope opens the live_grep result in neo-tree's window, then call vim.api.nvim_win_set_cursor() to set the cursor there (this is actually the only possible implementation, as we only have nvim_win_set_cursor() and not nvim_buf_set_cursor() or other functions). It seems that if we immediately switches the buffer like the current implementation, then due to some race conditions, this switching could be done before vim.api.nvim_win_set_cursor(), and thus the cursor location is lost.

I have also tried to make neo-tree wait for this opening to be finished before stealing the window. This works - the cursor is where we want it to be - but it results in a rather glitchy behavior: we will see the neo-tree's window first change to the "stealing" buffer, and then changed back.

For now, I do not have any good idea for a fix on this. A much simpler workaround I think we should consider is to prevent plugins from stealing the neo-tree window in the first place. For the case of Telescope, there is a config :h telescope.defaults.get_selection_window that does this.

cseickel commented 1 year ago

A much simpler workaround I think we should consider is to prevent plugins from stealing the neo-tree window in the first place. For the case of Telescope, there is a config :h telescope.defaults.get_selection_window that does this.

That is great to know! I don't know if the Telescope maintainers would accept it or not, but an ideal solution would be to submit a PR that makes the default handler a little smarter and provide a list of filetype / buftypes to avoid. For neo-tree, we would have to check both the filetype and the neo_tree_position option, because it is ok to steal the window when the position = "current".

ghostbuster91 commented 1 year ago

Before we start making changes to some other projects do you know how it works in https://github.com/nvim-tree/nvim-tree.lua ?

cseickel commented 1 year ago

I was under the impression that neo-tree was the only one that had any focus stealing prevention. I think nvim-tree would just let its window get stolen by telescope.

ghostbuster91 commented 1 year ago

Maybe I misunderstand what focus stealing prevention means but I have just checked and calling telescope live grep from nvim-tree window shows results correctly in a separate window, without overriding nvim-tree window.

cseickel commented 1 year ago

I just tried out nvim-tree and I could clearly see that there was some kind of focus stealing prevention at play.

When I used telescope to open a file from the nvim-tree window, I could see the file flash into the nvim-tree window and then get replaced by nvim-tree and move to the window on the right, just like neo-tree does. The only difference is that it was re-opened with the correct line focused.

folke commented 11 months ago

This should be a better default for telescope:

          -- open files in the first window that is an actual file.
          -- use the current window if no other window is available.
          get_selection_window = function()
            local wins = vim.api.nvim_list_wins()
            table.insert(wins, 1, vim.api.nvim_get_current_win())
            for _, win in ipairs(wins) do
              local buf = vim.api.nvim_win_get_buf(win)
              if vim.bo[buf].buftype == "" then
                return win
              end
            end
            return 0
          end,