nvim-focus / focus.nvim

Auto-Focusing and Auto-Resizing Splits/Windows for Neovim written in Lua. A full suite of window management enhancements. Vim splits on steroids!
MIT License
725 stars 35 forks source link

Usefulness on ultra wide displays? #134

Open lougreenwood opened 1 year ago

lougreenwood commented 1 year ago

I really like the intent of this plugin, however after trying it I'm not sure if either I have it configured incorrectly or I have the wrong expectations.

What I'm looking to do is achieve a view where I can auto-collapse all splits except for the currently active one.

I work on an ultra monitor, so space isn't an issue and I don't want to resize to the golden ratio (seems this might be more useful on smaller screen?), what I do want to see is an ability to automatically expand the current split and collapse it's sibling splits to a pre-defined, relative size.

It seems that there is :FocusMaximize, but I don't see how to enable this as the default "autoresize" option (seems that by default everything is autoresized using the GR?).

Additionally, I don't see how to define a maxwidth or maxheight (I guess these aren't implemented?), nor do I see a way to define the units as relative for any of the sizing?

So, please correct my assumptions if they are wrong. But in any case, nice work here, I like what you're trying to do, even if it turns out that it's not right for me!

lougreenwood commented 1 year ago

For more context, these are the (incorrect?) expectations I installed this addon with.

The backstory is that I actually suggested the feature as an improvement the smart-splits.nvim addon and that author suggested focus.nvim πŸ˜„

willothy commented 1 year ago

Correct me if I'm wrong, but it seems like the FR here is to add an option for the default resize mode?

Max dimensions are definitely something we should add as well.

Relative sizing would be complex as retrieving the available space for a window is not easy given that some windows may be disabled or of fixed size, etc. Definitely work looking into though, it would be a cool feature.

lougreenwood commented 1 year ago

@willothy Hi! Yes, I think a default resize mode would be useful.

However, is it possible to configure the widths which the "maximise" resize action uses to minimise the non-active splits? if not, then should they use the same values, or would each resize mode need it's own config?

Additionally, I think that the ability to set widths in proportional widths (I'm not quite sure what the current width/height values are, are they rows/cols in the terminal?), ideally I'd like to say "min width of 5 cols, max width of 20%".

To provide some more context... I use the Amethyst window management tool on MacOS, it is kind of a port of xmonad for MacOS.

I have my layout in a 3 column split arrangement, where in the centre of my ultra wide I have my current working window, this is full height. Then to the left and right I have "wings" where other secondary apps are stacked in columns. The tool automatically puts new windows in the stacks in these wings when I open windows.

It looks like this:

|               |                      |       4      |
|       2       |                      |--------------|
|---------------|           1          |       5      |
|       3       |                      |--------------|
|               |                      |       6      |

I have a key combo to switch the currently focused window to the centre, this can toggle/swap from "central" to "in the wings" (to be clear any window may be focussed, not just the central one).

I then have another shortcut for growing / shrinking the central window (and the "wings" resize respectively).

This is the kind of split management that I'm trying to simulate. So that my windows are tiled and my vim splits are also tiled - and following the same paradigm - within nvim. You could describe it as fractal in the sense that the window contents is able to tile in the same way as many windows.... (and maybe one day I'll get a bunch of robotic monitor arms and more monitors and do the same with them 🀑 πŸ˜‰ ).

So yeah, it's a bit more complex and something that I'd love to help out with, if only I had more time (young children, house to renovate etc 😴).

willothy commented 1 year ago

However, are the widths that "maximise" minimises to configurable, if not, then should they use the same values, or would each resize mode need it's own config?

Maximize widths are currently not configurable other than the minwidth for unfocused windows, but that could be changed easily. I don't think giving each mode it's own full config would be necessary, but separating maxwidth when it's implemented would be a good idea I think

ideally I'd like to say "min width of 5 cols, max width of 20%".

Do you mean 20% of the (window manger, not nvim) window size, or 20% of the available space in the nvim window layout? The former is quite doable I think, but like I mentioned earlier determining available space would be very difficult.

So yeah, it's a bit more complex and something that I'd love to help out with

As long as resizing is still based on the total vim screen size this shouldn't be too difficult, I'll try to work on this sometime soon. If you end up having time to work on it feel free to submit a PR though :)

lougreenwood commented 1 year ago

Maximize widths are currently not configurable other than the minwidth for unfocused windows, but that could be changed easily.

Yeah, being able to set a max width (and use proportional values) I think would be necessary.

I don't think giving each mode it's own full config would be necessary, but separating maxwidth when it's implemented would be a good idea I think

In this case would the default mode (aka golden ratio) also obey the max_width value, or ignore? If it ignores it then there needs to be documentation that this value is only for the "maximise" mode. If it were possible to configure each mode independently then this makes the config more self documenting. It could also be possible to support both configs by allowing something like the following as an alternate config:

autoresize = {
        enable = true, -- Enable or disable auto-resizing of splits
        width = 0, -- Force width for the focused window
        height = 0, -- Force height for the focused window
        minwidth = 0, -- Force minimum width for the unfocused window
        minheight = 0, -- Force minimum height for the unfocused window
        height_quickfix = 10, -- Set the height of quickfix panel

        -- Allow configuring per mode, this would override any defaults above (and not be a breaking change)
        modes = {
          golden_ratio = {
            min_width = 0 -- override the min width for this mode
          }
        }
    },

But... (and I know you already said you don't see a need for custom config, but maybe the above changed your mind πŸ˜„)... if per-mode config of sizing were allowed, why not allow per-mode config of everything instead? Maybe - as a user - I would want to see relative line numbers in the golden_ratio mode, but not in the maximise mode... etc, so maybe the config to allow per-mode config (or overrides) might look like:

    enable = true, -- Enable module
    commands = true, -- Create Focus commands
    autoresize = {
        default_mode = 'maximise',
        enable = true, -- Enable or disable auto-resizing of splits
        width = 0, -- Force width for the focused window
        height = 0, -- Force height for the focused window
        minwidth = 0, -- Force minimum width for the unfocused window
        minheight = 0, -- Force minimum height for the unfocused window
        height_quickfix = 10, -- Set the height of quickfix panel
    },
    split = {
        bufnew = false, -- Create blank buffer for new split windows
        tmux = false, -- Create tmux splits instead of neovim splits
    },
    ui = {
        number = false, -- Display line numbers in the focussed window only
        relativenumber = false, -- Display relative line numbers in the focussed window only
        hybridnumber = false, -- Display hybrid line numbers in the focussed window only
        absolutenumber_unfocussed = false, -- Preserve absolute numbers in the unfocussed windows

        cursorline = true, -- Display a cursorline in the focussed window only
        cursorcolumn = false, -- Display cursorcolumn in the focussed window only
        colorcolumn = {
            enable = false, -- Display colorcolumn in the foccused window only
            list = '+1', -- Set the comma-saperated list for the colorcolumn
        },
        signcolumn = true, -- Display signcolumn in the focussed window only
        winhighlight = false, -- Auto highlighting for focussed/unfocussed windows
    }
    modes = {
      maximise = {
        autoresize = {
          minwidth = 30,
          maxwidth = 80,
        }
        split = {
          tmux = true -- allow creating tmux splits when in maximise mode
        }
      }
    }

It's not ideal, it would require some logic to block overriding autoresize.enable & autoresize.default_mode in a mode config (but this could also be solved by moving these to top-level config (i.e auto_resize_enable = true auto_resize_default_mode = "maximise") and then only allow overriding top-level objects & their children).

This could also open the door to allowing users to define their own "modes" which implement a given "base mode", so maybe I have a mode in a given vim tab which I use for tmux stuff, and I want it to behave in one way. Maybe I have another mode for when I have multiple related files, and I want it to adopt the "maximise" semantics. Maybe I have a general/default mode that I use for working in a group of un-related files, and this uses the default config. I can invoke each mode in a given vim tab and have everything work as expected.... I know I'm going way out of scope with all of this, but it's an attempt to describe why considering per-mode config might open the door to some quite interesting use cases in the future...

Do you mean 20% of the (window manger, not nvim) window size, or 20% of the available space in the nvim window layout? The former is quite doable I think, but like I mentioned earlier determining available space would be very difficult.

all proportional values (20% etc) would be relative to the total space available in the nvim window, so 20% would take up 20% of the total width in nvim, not 20% of the remaining space after pushing other to their max width. Telescope seems to handle this by using fractional numbers as percentage (e.g 0.5 = 50%) - however, I have an open issue about and I wonder if instead a new optional min_width_unit = 'percentage' or min_width_unit = 'absolute' would be a cleaner way to handle this and avoid the edge cases issue I identified in telescope.

As long as resizing is still based on the total vim screen size this shouldn't be too difficult, I'll try to work on this sometime soon. If you end up having time to work on it feel free to submit a PR though :)

πŸ‘