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

Revamp option scopes #29314

Open
famiu opened this issue Jun 13, 2024 · 0 comments
Open

Revamp option scopes #29314

famiu opened this issue Jun 13, 2024 · 0 comments
Labels
compatibility compatibility with Vim or older Neovim options configuration, settings refactor changes that are not features or bugfixes
Milestone

Comments

@famiu
Copy link
Member

famiu commented Jun 13, 2024

Currently options can have the following scopes:

  • Buffer local. These options, despite the name, do still have a global value which is used as the default.
  • Window local: Despite the name, these options can be dependent on the buffer as well. You can set a window option for all buffers on that window, or for a single buffer, which means there is nested scoping at play.
  • Global-local options: These options have a global value and a value that is local to the buffer/window. When a local value doesn't exist, the global value is used instead.
  • There is also a much lesser known tab scope for options, which is currently only used for cmdheight.

These scopes are confusing even to veteran Vim/Neovim users, including Neovim developers. They do not follow a consistent or intuitive pattern and have all sorts of quirks, which can befuddle new and old users alike. The maintenance burden is also much higher for options because of this reason.

I propose a complete revamp of the scoping method we use. Note that while this is a revamp, it aims to keep most of the behavior that makes sense, while removing the unintuitive behaviors of the current method.

My proposal is, instead of having different scoping schemes for different options, we instead have a set of scopes that follow a linear hierarchy. Which could look like:
Global scope -> Tab scope -> Window scope -> Buffer scope.

An option could choose to support one or more (any number) of these scopes. So an option could just use the global scope, or the global and buffer scope, or the global, window and buffer scope.

The value of the innermost scope in the scope hierarchy will always be used. For example: If an option has global, window and buffer scopes, first it will check for a value in the buffer scope and use it if it exists, then check window scope if there is no value in the buffer scope, and then use the global value if window scope doesn't have a value either.

Through this method, the current scopes could be implemented like this:

  1. Buffer local and Global-local buffer options would use the Global and Buffer scopes.
  2. Window local options would use the Global, Window and Buffer scopes.
  3. Global-local window options would use the Global and Window scopes.
  4. Global-local tab options would use the Global and Tab scopes.

This should keep most of the behavior that options currently have, whilst getting rid of the weird quirks and inconsistencies. Buffer-local and global-local options will have almost the same behavior as they do now. Window-local options will have a lot of breaking changes, but window-local options are already broken and unintuitive as they are currently, so we have to fix that one way or another anyway.

This approach also allows us the opportunity to do things like add an option that uses a new combination of scopes (e.g. tab and window) in the future, with zero additional complexity.

Keeping almost complete backwards compatibility with :set and other Vim script option interfaces is also an explicit goal of this revamp. This is to ensure Vim plugins don't have to do anything special to continue supporting Neovim.

Lua interfaces for setting options and the Neovim API will have some changed behavior due to the change in scoping.

CC: @bfredl, @justinmk, @zeertzjq, @lewis6991, @dundargoc

@famiu famiu added refactor changes that are not features or bugfixes options configuration, settings labels Jun 13, 2024
@justinmk justinmk added the compatibility compatibility with Vim or older Neovim label Jun 17, 2024
@justinmk justinmk added this to the unplanned milestone Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compatibility compatibility with Vim or older Neovim options configuration, settings refactor changes that are not features or bugfixes
Projects
None yet
Development

No branches or pull requests

2 participants