Skip to content

Is it possible to make open_vsplit, open_split to open on right, bottom? #85

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

Closed
nyngwang opened this issue Jan 22, 2022 · 15 comments
Closed
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@nyngwang
Copy link

nyngwang commented Jan 22, 2022

As title.

Why? Because creating new splits on right/bottom is the default behaviour on Tmux. I want to sync. my experience. I highly hope this is possible 🥺

Debug info.

NVIM Version

NVIM v0.7.0-dev+913-ge07a4b97f
Build type: Release
LuaJIT 2.1.0-beta3
@cseickel
Copy link
Contributor

Yes. The question I am trying to answer for myself is: is this a documentation/how-to issue or a feature request.

One way this can be handled is by overriding the built-in "open_split" and "open_vsplit" commands. I'll put up a recipe in the wiki at some point today.

@cseickel cseickel added documentation Improvements or additions to documentation enhancement New feature or request labels Jan 22, 2022
@nyngwang
Copy link
Author

nyngwang commented Jan 22, 2022

This is something I did for my own plugin facing a similar issue. This might be too simple but if it could save your time it for reading some docs:

https://github.com/nyngwang/NeoZoom.lua/blob/caa644400b0853e986121fc1a9bb9ced58dd95bc/lua/neo-zoom.lua#L58

function M.neo_split() -- this will create a new vsplit on the bottom
  local bottom_win = vim.api.nvim_get_current_win()
  vim.cmd('split')
  local top_win = vim.api.nvim_get_current_win()
  vim.cmd('wincmd j')
  -- the following is not related to this issue.
  if bottom_win == top_win then print('***ing IMPOSSIBLE'); return end
  clone_parent_info_to(bottom_win, top_win)
end

@cseickel
Copy link
Contributor

As it turns out, I needed to add something to allow overriding in a reasonable way. If you are willing to try out the main branch, you can now handle a new "file_open_requested" event and implement your own window picking logic. Here is an example that recreates the complete built-in logic, it should be a good starting point for you to customize it:

"neo-tree").setup({
  event_handlers = {
    {
      event = "file_open_requested",
      handler = function(args)
        local state = args.state
        local path = args.path
        local open_cmd = args.open_cmd or "edit"

        -- use last window if possible
        local suitable_window_found = false
        local nt = require("neo-tree")
        if nt.config.open_files_in_last_window then
          local prior_window = nt.get_prior_window()
          if prior_window > 0 then
            local success = pcall(vim.api.nvim_set_current_win, prior_window)
            if success then
              suitable_window_found = true
            end
          end
        end
        -- find a suitable window to open the file in
        if not suitable_window_found then
          if state.window.position == "right" then
            vim.cmd("wincmd t")
          else
            vim.cmd("wincmd w")
          end
        end
        local attempts = 0
        while attempts < 4 and vim.bo.filetype == "neo-tree" do
          attempts = attempts + 1
          vim.cmd("wincmd w")
        end
        if vim.bo.filetype == "neo-tree" then
          -- Neo-tree must be the only window, restore it's status as a sidebar
          local winid = vim.api.nvim_get_current_win()
          local width = require("neo-tree.utils").get_value(state, "window.width", 40)
          vim.cmd("vsplit " .. path)
          vim.api.nvim_win_set_width(winid, width)
        else
          vim.cmd(open_cmd .. " " .. path)
        end

        -- If you don't return this, it will proceed to open the file using built-in logic.
        return { handled = true }
      end
    },
  },
})

@nyngwang
Copy link
Author

nyngwang commented Jan 23, 2022

Is it possible to keep the floating tree open after the file gets open in either existing windows or a new window under the current tab? I will call this behaviour 'preview'. Might be more appropriate to open as a separate issue?

@cseickel
Copy link
Contributor

I gotta say no to that one. If you want the tree to stay open, then you don't want a floating window! That's is what a sidebar is for. If you just want it on the right hand side, you can set the filesystem.window.position to "right" in your config.

@nyngwang
Copy link
Author

nyngwang commented Jan 23, 2022

@cseickel: The reason I want to use floating tree is that it won't mess-up my carefully organized window-layout. The current problem of open is that I cannot select with window to open the buffer I selected(or hovered by my cursor.). Since I came from nvim-tree.lua I would like to have a function to do the similar. While your script above works, it's too complicated and I'm afraid that I will forget what it does in the future. So I will expect a window selector, when possible for sure.

@cseickel
Copy link
Contributor

If it helps, there is also a open_files_in_last_window option. It will use the last focused window as the target for open commands. My current project is to improve the documentation...

@nyngwang
Copy link
Author

nyngwang commented Jan 23, 2022

@cseickel: Wow, let me try it now! And thanks for your effort.

@nyngwang
Copy link
Author

nyngwang commented Jan 23, 2022

open_files_in_last_window

@cseickel

Now I got a warning:

Invalid mapping for <cr> : nil

So why I cannot use two different keys for the same behavior? This is my settings:

            mappings = {
              -- My custom
              ['-'] = 'navigate_up',
              ['<C-]>'] = 'set_root',
              ['%'] = 'open_vsplit',
              ['"'] = 'open_split',
              ['<Tab>'] = 'open_files_in_last_window', ['<cr>'] = 'open_files_in_last_window',
              ['/'] = 'filter_on_submit',
              -- Disable
              ['<BS>'] = 'none',
              ['.'] = 'none',
              ['s'] = 'none',
              ['S'] = 'none',
            },

@cseickel
Copy link
Contributor

Oh, sorry for the confusion, it is an option, not a command. You can leave <tab> and <cr> mapped to "open", but add this into your config:

require("neo-tree").setup({
  open_files_in_last_window = true
  filesystem = {
    ...

@wookayin
Copy link
Contributor

wookayin commented Feb 3, 2022

@nyngwang Have you tried set splitbelow, set splitright option?

@nyngwang
Copy link
Author

nyngwang commented Feb 3, 2022

@nyngwang Have you tried set splitbelow, set splitright option?

OK then I've wasted some time on these builtin functions...

@nyngwang
Copy link
Author

nyngwang commented Feb 5, 2022

@wookayin I just tested it and there is no problem currently. But I think the problem of this one is that some plugins will depend on it (while this means a bad design tho.)

@wookayin
Copy link
Contributor

wookayin commented Feb 5, 2022

It is a practical config that many users are often using. So if this breaks the plugin, that's a problem of the plugin. Managing windows can be controlled explicitly by the plugin (e.g. :botright 10vsplit), so you should have no problem with the option.

@nyngwang
Copy link
Author

nyngwang commented Feb 5, 2022

@wookayin: thanks for the confirmation. As a gift: if you need a layout preserving buffer-killer try this plugin: https://github.com/nyngwang/NeoNoName.lua, which I haven't released on reddit, while I feel that it's extremely stable now.

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

No branches or pull requests

3 participants