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

feature: allow pick_win to ignore specific filetypes and buftypes #877

Closed
1 task done
jemag opened this issue Feb 2, 2025 · 3 comments · Fixed by #810
Closed
1 task done

feature: allow pick_win to ignore specific filetypes and buftypes #877

jemag opened this issue Feb 2, 2025 · 3 comments · Fixed by #810
Labels
enhancement New feature or request

Comments

@jemag
Copy link

jemag commented Feb 2, 2025

Did you check the docs?

  • I have read all the snacks.nvim docs

Is your feature request related to a problem? Please describe.

snacks.picker.util.pick_win is extremely useful to my workflow. I use it countless times each day alongside other plugins.

The only remaining problem that I miss from nvim-window-picker is the possibility to ignore specific filetype and buftype.For example, I use snacks.picker.util.pick_win with neo-tree to pick and split pick windows to edit from. However, currently neo-tree itself will appear in the list of possible windows, as it cannot be excluded.
Here is an example workflow with pick_win

https://github.com/user-attachments/assets/a29a4798-2eba-4a24-9769-b356307c38c5
Here is the current equivalent with nvim-window-picker
https://github.com/user-attachments/assets/713aa272-4635-4a6a-a061-1d6f5ee42491

Currently, with nvim-window-picker the first split is instant given only 1 window is detected, and subsequent splits do not give neo-tree as a choice

Describe the solution you'd like

Provide configurable filetype and buftype exclusions, e.g.:

      filetype = { "notify", "neo-tree", "neo-tree-popup", "quickfix", "scrollview", "snacks_picker_preview"},

      -- if the buffer type is one of following, the window will be ignored
      buftype = {"nofile", "prompt"},

Describe alternatives you've considered

Not transition these specific workflows to snacks pick_win

Additional context

I think it would be really nice to publicize pick_win as a full fledged snacks rather than a utility function.

Although simple it is incredibly powerful for numerous workflows. For example:
Simple selection + splitting with snacks.picker:

          ["<c-v>"] = { { "pick_win", "edit_vsplit" }, mode = { "i", "n" } },
          ["<c-s>"] = { { "pick_win", "edit_split" }, mode = { "i", "n" } },
          ["<c-e>"] = { { "pick_win", "edit" }, mode = { "i", "n" } },

Moving, swapping, close windows with pick_win

local function switch_window()
  local window = snacks.picker.util.pick_win()
  if window ~= nil then
    vim.api.nvim_set_current_win(window)
  end
end
local function close_window()
  local window = snacks.picker.util.pick_win()
  if window ~= nil then
    vim.api.nvim_win_close(window, false)
  end
end
local function swap_window()
  local picked_window = snacks.picker.util.pick_win()
  if picked_window ~= nil then
    local picked_buffer = vim.api.nvim_win_get_buf(picked_window)
    local current_buffer = vim.api.nvim_get_current_buf()
    local current_window = vim.api.nvim_get_current_win()
    vim.api.nvim_win_set_buf(picked_window, current_buffer)
    vim.api.nvim_win_set_buf(current_window, picked_buffer)
  end
end

vim.keymap.set("n", "<c-w>S", swap_window, { desc = "Swap window by id" })
vim.keymap.set("n", "<c-w>m", switch_window, { desc = "Move to window by id" })
vim.keymap.set("n", "<c-w>Q", close_window, { desc = "Close window by id" })

Splitting with neo-tree and pick_win

    commands = {
      pick = function(state)
        local path = state.tree:get_node().path
        local win = require("snacks").picker.util.pick_win()
        if win ~= nil then
          vim.api.nvim_set_current_win(win)
          vim.cmd("edit " .. path)
        end
      end,
      pick_split = function(state)
        local path = state.tree:get_node().path
        local win = require("snacks").picker.util.pick_win()
        if win ~= nil then
          vim.api.nvim_set_current_win(win)
          vim.cmd("split " .. path)
        end
      end,
      pick_vsplit = function(state)
        local path = state.tree:get_node().path
        local win = require("snacks").picker.util.pick_win()
        if win ~= nil then
          vim.api.nvim_set_current_win(win)
          vim.cmd("vsplit " .. path)
        end
      end,   
    },
@jemag jemag added the enhancement New feature or request label Feb 2, 2025
@folke folke closed this as completed in 5c5b40b Feb 2, 2025
@folke
Copy link
Owner

folke commented Feb 2, 2025

I'm going to turn this in a separate module at some point.

For now, I just added some extra options:

---@param opts? {main?: number, float?:boolean, filter?: fun(win:number, buf:number):boolean?}
function M.pick_win(opts)

@jemag
Copy link
Author

jemag commented Feb 2, 2025

amazing thanks!

Whenever it does become a module, I think it could be nice to be able to configure the filter function globally (with possibility of local override when calling pick_win)

That way, no need to pass it on every pick_win call, and also it would still be possible to use the snacks.picker pick_win action with the default filtering applying.
For now, instead of the pick_win action, I am doing the following to filter out neo-tree and other buffers with snacks.picker:

    actions = {
      pick_vsplit = function(picker, item)
        picker:close()
        local win = snacks.picker.util.pick_win({ filter = filter_windows })
        if win ~= nil then
          vim.api.nvim_set_current_win(win)
          picker:action("edit_vsplit")
        end
      end,

@folke
Copy link
Owner

folke commented Feb 2, 2025

you can also just overide the pick_win action in your config to have it applied for all pickers.
But yes indeed a global filter is the better option when I get to it.

folke pushed a commit that referenced this issue Feb 3, 2025
🤖 I have created a release *beep* *boop*
---


##
[2.18.0](v2.17.0...v2.18.0)
(2025-02-03)


### Features

* **dashboard:** play nice with file explorer netrw replacement
([5420a64](5420a64))
* **explorer.git:** added git_status_open. When false, then dont show
recursive git status in open directories
([8646ba4](8646ba4))
* **explorer:** added `]g` and `[g` to jump between files mentioned in
`git status`
([263dfde](263dfde))
* **explorer:** added git status. Closes
[#817](#817)
([5cae48d](5cae48d))
* **explorer:** hide git status for open directories by default. it's
mostly redundant
([b40c0d4](b40c0d4))
* **explorer:** keep expanded dir state. Closes
[#816](#816)
([31984e8](31984e8))
* **explorer:** more keymaps and tree rework. See
[#837](#837)
([2ff3893](2ff3893))
* **explorer:** navigate with h/l to close/open directories. Closes
[#833](#833)
([4b29ddc](4b29ddc))
* **explorer:** new `explorer` module with shortcut to start explorer
picker and netrw replacement functionlity
([670c673](670c673))
* **explorer:** recursive copy and copying of selected items with `c`
([2528fcb](2528fcb))
* **explorer:** update on cwd change
([8dea225](8dea225))
* **explorer:** update status when saving a file that is currently
visible
([78d4116](78d4116))
* **picker.commands:** do not autorun commands that require arguments
([#879](#879))
([62d99ed](62d99ed))
* **picker.frecency:** added frecency support for directories
([ce67fa9](ce67fa9))
* **picker.input:** search syntax highlighting
([4242f90](4242f90))
* **picker.lines:** jump to first position of match. Closes
[#806](#806)
([ae897f3](ae897f3))
* **picker.list:** use regular CursorLine when picker window is not
focused
([8a570bb](8a570bb))
* **picker.matcher:** added opts.matcher.history_bonus that does fzf's
scheme=history. Closes
[#882](#882). Closes
[#872](#872)
([78c2853](78c2853))
* **picker.pickwin:** optional win/buf filter. Closes
[#877](#877)
([5c5b40b](5c5b40b))
* **picker.projects:** added `&lt;c-t&gt;` to open a new tab page with
the projects picker
([ced377a](ced377a))
* **picker.projects:** allow disabling projects from recent files
([c2dedb6](c2dedb6))
* **picker.projects:** default to tcd instead of cd
([3d2a075](3d2a075))
* **picker.projects:** enabled frecency for projects picker
([5a20565](5a20565))
* **picker.projects:** projects now automatically processes dev folders
and added a bunch of actions/keymaps. Closes
[#871](#871)
([6f8f0d3](6f8f0d3))
* **picker.undo:** better undo tree visualization. Closes
[#863](#863)
([44b8e38](44b8e38))
* **picker.undo:** make diff opts for undo configurable
([d61fb45](d61fb45))
* **picker:** added support for double cliking and confirm
([8b26bae](8b26bae))
* **picker:** automatically download sqlite3.dll on Windows when using
frecency / history for the first time.
([65907f7](65907f7))
* **picker:** beter API to interact with active pickers. Closes
[#851](#851)
([6a83373](6a83373))
* **picker:** better health checks. Fixes
[#855](#855)
([d245925](d245925))
* **picker:** history per source. Closes
[#843](#843)
([35295e0](35295e0))


### Bug Fixes

* **dashboard:** open pull requests with P instead of p in the github
exmaple
([b2815d7](b2815d7))
* **dashboard:** update on VimResized and WinResized
([558b0ee](558b0ee))
* **explorer:** after search, cursor always jumped to top. Closes
[#827](#827)
([d17449e](d17449e))
* **explorer:** always use `--follow` to make sure we see dir symlinks
as dirs. Fixes [#814](#814)
([151fd3d](151fd3d))
* **explorer:** cwd is now changed automatically, so no need to update
state.
([5549d4e](5549d4e))
* **explorer:** don't disable netrw fully. Just the autocmd that loads a
directory
([836eb9a](836eb9a))
* **explorer:** don't try to show when closed. Fixes
[#836](#836)
([6921cd0](6921cd0))
* **explorer:** fix git status sorting
([551d053](551d053))
* **explorer:** fixed hierarchical sorting. Closes
[#828](#828)
([fa32e20](fa32e20))
* **explorer:** keep global git status cache
([a54a21a](a54a21a))
* **explorer:** remove sleep :)
([efbc4a1](efbc4a1))
* **git:** use os.getenv to get env var. Fixes
[#5504](https://github.com/folke/snacks.nvim/issues/5504)
([16d700e](16d700e))
* **layout:** adjust zindex when needed when another layout is already
open. Closes [#826](#826)
([ab8af1b](ab8af1b))
* **layout:** destroy in schedule. Fixes
[#861](#861)
([c955a8d](c955a8d))
* **picker.actions:** fix split/vsplit/tab. Closes
[#818](#818)
([ff02241](ff02241))
* **picker.actions:** pass edit commands to jump. Closes
[#859](#859)
([df0e3e3](df0e3e3))
* **picker.actions:** reworked split/vsplit/drop/tab cmds to better do
what's intended. Closes
[#854](#854)
([2946875](2946875))
* **picker.actions:** tab -&gt; tabnew. Closes
[#842](#842)
([d962d5f](d962d5f))
* **picker.explorer:** do LSP stuff on move
([894ff74](894ff74))
* **picker.explorer:** use cached git status
([1ce435c](1ce435c))
* **picker.format:** extra slash in path
([dad3e00](dad3e00))
* **picker.format:** use item.file for filename_only
([e784a9e](e784a9e))
* **picker.git_log:** add extra space between the date and the message
([#885](#885))
([d897ead](d897ead))
* **picker.keymaps:** added normalized lhs to search text
([fbd39a4](fbd39a4))
* **picker.lazy:** don't use live searches. Fixes
[#809](#809)
([1a5fd93](1a5fd93))
* **picker.lines:** col is first non-whitespace. Closes
[#806](#806)
([ec8eb60](ec8eb60))
* **picker.list:** better virtual scrolling that works from any window
([4a50291](4a50291))
* **picker.matcher:** fix cwd_bonus check
([00af290](00af290))
* **picker.matcher:** regex offset by one. Fixes
[#878](#878)
([9a82f0a](9a82f0a))
* **picker.undo:** add newlines
([72826a7](72826a7))
* **picker.undo:** cleanup tmp buffer
([8368176](8368176))
* **picker.undo:** copy over buffer lines instead of just the file
([c900e2c](c900e2c))
* **picker.undo:** disable swap for tmp undo buffer
([033db25](033db25))
* **picker:** better main window management. Closes
[#842](#842)
([f0f053a](f0f053a))
* **picker:** improve resume. Closes
[#853](#853)
([0f5b30b](0f5b30b))
* **picker:** make pick_win work with split layouts. Closes
[#834](#834)
([6dbc267](6dbc267))
* **picker:** multi layouts that need async task work again.
([cd44efb](cd44efb))
* **picker:** no auto-close when entering a floating window
([08e6c12](08e6c12))
* **picker:** no need to track jumping
([b37ea74](b37ea74))
* **picker:** propagate WinEnter when going to the real window after
entering the layout split window
([8555789](8555789))
* **picker:** show regex matches in list when needed. Fixes
[#878](#878)
([1d99bac](1d99bac))
* **picker:** show_empty for files / grep. Closes
[#808](#808)
([a13ff6f](a13ff6f))
* **util:** better default icons when no icon plugin is installed
([0e4ddfd](0e4ddfd))
* **util:** better keymap normalization
([e1566a4](e1566a4))
* **util:** normkey. Closes
[#763](https://github.com/folke/snacks.nvim/issues/763)
([6972960](6972960))
* **win:** close help when leaving the win buffer
([4aba559](4aba559))


### Performance Improvements

* **explorer:** don't wait till git status finished. Update tree when
needed. See [#869](#869)
([287db30](287db30))
* **explorer:** use cache when possible for opening/closing directories.
Closes [#869](#869)
([cef4fc9](cef4fc9))
* **git:** also check top-level path to see if it's a git root. Closes
[#807](#807)
([b9e7c51](b9e7c51))
* **picker.files:** no need to check every time for cmd availability
([8f87c2c](8f87c2c))
* **picker.undo:** more performance improvements for the undo picker
([3d4b8ee](3d4b8ee))
* **picker.undo:** use a tmp buffer to get diffs. Way faster than
before. Closes [#863](#863)
([d4a5449](d4a5449))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants