ibhagwan / fzf-lua

Improved fzf.vim written in lua
GNU Affero General Public License v3.0
2.15k stars 141 forks source link

[Enhencement] Profile/Preconfigured layout that use splits instead of floating windows like nvim-fzf or CtrlP? #975

Closed Bekaboo closed 8 months ago

Bekaboo commented 8 months ago

Info

Not related

Description

Floating windows are great for displaying temporary buffers in that they do not ruin the previous split layout. But some people (including me) might find that splits are less intrusive and give more user control to the contents in the buffer displayed, for example, users can jump to the preview window and scroll/copy text directly from there, see the demo of nvim-fzf.

telescope.nvim provides a theme(aka 'profile' for fzf-lua) named 'ivy' to place the telescope window at the bottom of the screen to mimic the Emacs ivy fuzzy finder for a less intrusive experience BUT it's not quite there because it still uses floating windows instead of splits.

It would be great if fzf-lua could have a profile using splits to display fzf terminal window and the preview window (if any), like nvim-fzf/CtrlP/ivy. Since fzf-lua takes inspiration from nvim-fzf, it should not be too hard (idk)?


EDIT: typo

ibhagwan commented 8 months ago

Split option already exists, take a look at the default options:

https://github.com/ibhagwan/fzf-lua#default-options

require'fzf-lua'.setup {
winopts = {
-- split         = "belowright new",-- open in a split instead?
-- "belowright new"  : split below
-- "aboveleft new"   : split above
-- "belowright vnew" : split right
-- "aboveleft vnew   : split left
}
}

These are just recommendations, you can use any neovim command to create the split.

Bekaboo commented 8 months ago

Hi, thanks for your reply!

Split option already exists, take a look at the default options:

How could I miss that? Please forgive my ignorance.

This is the minimal conifg I am currently testing:

local tmp = '/tmp'
local data = tmp .. '/' .. (vim.env.NVIM_APPNAME or 'nvim')
local package_root = data .. '/site'
local clone_root = package_root .. '/pack/packages/start'
local clone_info = {
  {
    path = clone_root .. '/fzf-lua',
    url = 'https://github.com/ibhagwan/fzf-lua.git',
  },
}

vim.fn.mkdir(clone_root, 'p')
vim.opt.pp:prepend(package_root)
vim.opt.rtp:prepend(package_root)
vim.opt.mousemoveevent = true

for _, info in ipairs(clone_info) do
  if not vim.loop.fs_stat(info.path) then
    vim.notify('cloning ' .. info.url, vim.log.levels.INFO)
    vim.fn.system({ 'git', 'clone', info.url, info.path })
  end
end

require('fzf-lua').setup({
  winopts = {
    split = 'bo new',
    preview = {
      default = 'builtin',
      winopts = {
        split = 'vert new',
      },
    },
  },
})

vim.keymap.set('n', '<Space>.', '<Cmd>lua require("fzf-lua").files()<CR>')

With this minimal config, I can open fzf window as a split, but the preview is still in a floating window, and once I leave the fzf terminal window it gets closed, making it impossible to put my cursor in the preview window:

image

I was imagining something similar to nvim-fzf, like this:

where the preview window is also opened as a split side by side to the fzf terminal window.

Also, it seems that the relative position is "fixed" using the split layout. With the floating layout the preview window is automatically adjusted to be shown below or to the right of the fzf window according to the screen ratio, but it does not seem to be the case using a split layout?

So in summary, I have these questions:

  1. How to show the preview as a split beside fzf terminal window?
  2. How to prevent fzf auto-closing when I leave the window?
  3. Is it possible to automatically choose horizontal/vertical preview according to the screen ratio when I open fzf?

Thanks in advance!

ibhagwan commented 8 months ago

How to show the preview as a split beside fzf terminal window?

This is not possible ATM, would require new code, given it has been over 2 years and this is the first request ever for this I’m probably not going to invest time in this (would require a major refactor).

How to prevent fzf auto-closing when I leave the window?

It’s possible to wrap an action with {} or add { fn = <action function>, noclose=true } but this is used mostly to open a new interface without a “refresh”, I’m not sure if it will get you what you want.

Is it possible to automatically choose horizontal/vertical preview according to the screen ratio when I open fzf?

Yes, that’s what layout=flex and flip_columns are for.

Bekaboo commented 8 months ago

Emm 'flex' layout does not seem to work -- when the height is small and width is large the preview is still below the fzf window instead of being placed to the right of the fzf window:

image

Config:

require('fzf-lua').setup({
  winopts = {
    split = 'bo new',
    preview = {
      layout = 'flex',
      default = 'builtin',
      winopts = {
        split = 'vert new',
      },
    },
  },
})
ibhagwan commented 8 months ago

Emm 'flex' layout does not seem to work -- when the height is small and width is large the preview is still below

Flex is dependent on the width of vim.o.columns, by default if it’s below 120 it will use a vertical preview, if the width is over 120 it will setup the preview as horizontal.

I think what you want is your own setup, instead of winopts define a winopts_fn that returns a table based on certain conditions, it will get called every time you open the interface (same as on_create but before the UI is open) and you can decide when to use a split or what preview layout to use:

The returned table will be merged into your default winopts

winopts_fn = function()
if vim.o.lines > … then
end
return {
…
}
end
Bekaboo commented 8 months ago

Thanks, winopts_fn works like a charm!

How to show the preview as a split beside fzf terminal window?

This is not possible ATM, would require new code, given it has been over 2 years and this is the first request ever for this I’m probably not going to invest time in this (would require a major refactor).

Would you accept a PR for it? I would like to investigate on this and see if I can help.

ibhagwan commented 8 months ago

Would you accept a PR for it? I would like to investigate on this and see if I can help.

If done right absolutely, the issue is that the window creation code isn’t structured optimally since I started with one window (one float, only fzf native previews), then a neovim buffer, then splits, then fzf-tmux, many conditions and edge cases (resizing, rotating previews, scrolling, titles, highlighting, borders, etc) and although it’s a bit of a mess it currently works flawlessly. Doing this properly would require a lot of thought on the new window/preview class structure and code flow, that’s a major refactor.

If you do find the passion to do this and test this properly you have my blessing :)

Perhaps if more people used more involved window configs I’d do it myself, but I can count on one hand the users even using splits, or fzf-tmux, most users just use slightly modified defaults (floats).

Bekaboo commented 8 months ago

rotating previews

I don't think it is possible to rotate a split window with respect to another given current split window implementation of nvim. Is it ok that we ignore this feature (I don't see it useful in a split layout) if user select to ues a split layout?

ibhagwan commented 8 months ago

rotating previews

I don't think it is possible to rotate a split window with respect to another given current split window implementation of nvim. Is it ok that we ignore this feature (I don't see it useful in a split layout) if user select to ues a split layout?

It is possible to rotate the preview, it’s just a float window but you’d also need to send fzf a transform preview command since there is a hidden empty fzf window below the neovim preview buffer, without the empty fzf preview the neovim preview buffer would cover the results.

The reason I didn’t do it is because when I implemented the preview rotation fzf didn’t have an option of transforming the layout (which I believe it now has).

Bekaboo commented 8 months ago

I mean, it is not possible to rotate if the terminal and the nvim preview window are splits instead of floating windows.

ibhagwan commented 8 months ago

I mean, it is possible to rotate if the terminal and the nvim preview window are splits.

Understood, that’s why I said many edge cases which will require a new thoughtful code structure or it will be an absolute hacky mess.

ibhagwan commented 8 months ago

I’m going to close this issue since it’s generally “solved”, if you do decide to submit the PR, we can discuss it there.