neovim / neovim

Vim-fork focused on extensibility and usability
https://neovim.io
Other
82.87k stars 5.68k forks source link

Add ability to set window-local mappings #16263

Open rmagatti opened 2 years ago

rmagatti commented 2 years ago

Feature already in Vim?

Not that I know of

Feature description

Motivation

With the advent of floating windows I found myself yearning for the ability to set window-local mappings. I am aware of buffer-local mappings, i.e nnoremap <buffer> q :q<CR> but window-local mappings would provide an extra layer of control. If I happen to open a floating window that has the same buffer as another already existing non-floating window, I am currently not able to set different mappings for each of the windows, and while there are workarounds, this feature would make it more straightforward.

Desired feature:

:nnoremap <window> q :q<CR>

Behaviour

Setting a window-local mapping would behave exactly like <buffer> but window-bound instead of buffer-bound. I imagine the precedence being buffer > window > global.

Use-case

https://github.com/rmagatti/goto-preview/issues/7 In this use-case one wants to map q for closing preview (floating) window instead of triggering a macro recording through a provided hook function for when a preview window is opened, but if that floating window ends up having the same buffer as the main window, the mapping is also applied there.

Showcase

Current behaviour

require('goto-preview').setup {
  post_open_hook = function()
    vim.cmd[[nnoremap <buffer> q :q<CR>]]
  end
}

2021-11-08 01 58 41

Desired behaviour (simulated by previewing a separate buffer)

require('goto-preview').setup {
  post_open_hook = function()
    vim.cmd[[nnoremap <window> q :q<CR>]]
  end
}

2021-11-08 02 03 27

Shougo commented 2 years ago

I think it should be requested in Vim.

bfredl commented 2 years ago

Instead of tying mappings directly to a window, more general would be some kind of namespaced mappings, and then you could activate this namespace for a specific window and/or buffer (like emacs minor modes, I suppose).

rmagatti commented 2 years ago

I guess I just went off of how the <buffer> mappings work for this proposal, but you're right, there could be a more generic way of achieving the same result here. Disclaimer: I am not familiar with how emacs minor modes work, so your point might just be going over my head @bfredl

@Shougo, is it customary to open these feature requests in Vim instead of Neovim or is focusing on Neovim then perhaps porting something to Vim when things are more flushed out also a valid route for things like this?

zeertzjq commented 2 years ago

Vim's popup windows cannot show the same buffer as other windows, so this feature may be less useful in Vim.

Shougo commented 2 years ago

If the feature is for floating window only, it is not useful in Vim.

zeertzjq commented 2 years ago

Well, I didn't mean that. I just wanted to mean that it is more useful in Nvim than in Vim because in Nvim there are more examples of cases where window-local mappings can be helpful.

rmagatti commented 2 years ago

Kay, so, thoughts on instead of making a whole new "namespaced mappings" thing, looking into something that just follows what <buffer> does currently, but applying it to a new <window> tag instead?

Given that <buffer> already exists for buffer specific mappings, it makes sense in my head that <window> would also exist, regardless of the ability to do "namespaced mappings".

If this makes sense at all, where is somewhere I could start looking at to implement this? Disclaimer: I haven't coded C in quite a few years, so it'll probably take a long time for me to figure this out. The more help I get in the beginning here the easier it'll go. :)

clason commented 2 years ago

Thoughts are: for something Neovim-centric, we definitely want to go with the "namespaced" approach since that fits the overall design language (diagnostics, highlights, etc.) A new <window> keyword just in the Vimscript API would have to go through Vim first; we would then port that patch.