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

feat(fzf): allow fzf win_configs to contain functions, fix vertical offsets #131

Merged
merged 9 commits into from
Feb 5, 2024

Conversation

willothy
Copy link
Collaborator

This PR fixes the issue with fzf placement I mentioned in #123.

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 23, 2024

Thanks! It is not clear to me what is the exact bug and how to reproduce it.


EDIT: In addition could you explain how it works and what problem it addresses? I tried to understand but the logic seems a bit twisted.


EDIT 2: Also observed that the offset of fzf window is wrong when border is 'single' (not introduced by this PR):

image

Could we fix it in this PR too?

@willothy
Copy link
Collaborator Author

Thanks! It is not clear to me what is the exact bug and how to reproduce it.

EDIT: In addition could you explain how it works and what problem it addresses? I tried to understand but the logic seems a bit twisted.

Essentially, the fzf menu uses relative=win, so with anchor the position can be off by a few cells depending on the border and can end up overlapping the menu (covering entries).

This fixes the vertical overlap and ensures the fzf menu is always just a small bar at the bottom.

EDIT 2: Also observed that the offset of fzf window is wrong when border is 'single' (not introduced by this PR):

image

Could we fix it in this PR too?

Sure! That's exactly the issue I was trying to fix (some other cases of it as well). It was overlapping vertically on some occasions, that's what I've fixed so far. I'll look into the horizontal position now.

@willothy
Copy link
Collaborator Author

I'll try to provide a video or something later but honestly this one is hard to explain lol.

It happens with certain scroll positions, when the menu opens above the cursor only.

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 23, 2024

@willothy The misalignment should be fixed now, can you confirm?

@willothy
Copy link
Collaborator Author

@willothy The misalignment should be fixed now, can you confirm?

Partially, but there are still the header cases to handle. I'll update this PR.

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 23, 2024

Partially, but there are still the header cases to handle

Why the header will affect the alignment?

@willothy
Copy link
Collaborator Author

willothy commented Jan 23, 2024

It affects vertical alignment. There can be a gap above the fzf window, or an empty row if there's a header (like in the ui-select menu, which uses only a top border).

image
(the header is covering the second available code action)

Edit: Can confirm horizontal alignment is fixed now, nice!

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 23, 2024

@willothy Do you mean the header of the fzf window?

@willothy
Copy link
Collaborator Author

Yeah, it can inherit a header from the parent window. I will update this PR to only fix that and remove the things you fixed.

@willothy
Copy link
Collaborator Author

Should be good now

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 24, 2024

@willothy I cannot reproduce the bug where the menu is overlapped with the title/header of the fzf window using the script below, with vim.ui.select() being replaced by dropbar's select menu:

vim.ui.select({ "tabs", "spaces" }, {
	prompt = "Select tabs or spaces:",
	format_item = function(item)
		return "I'd like to choose " .. item
	end,
}, function() end)

However, I can observe that the fzf window has an improperly thick top border because it inherits the border from the select menu (border = { "", " ", "", "", "", "", "", "" }:

image

Can we just merge opts.win_configs and fzf-window-specific window configs in fuzzy_find_open(), excluding self._win_configs? That should be a simpler solution. Notice that we have to re-evaluate the merged result using eval_win_configs().

@willothy
Copy link
Collaborator Author

@willothy I cannot reproduce the bug where the menu is overlapped with the title/header of the fzf window using the script below, with vim.ui.select() being replaced by dropbar's select menu:

It can occur both ways, either with overlap or the thick border, depending on factors I have not yet determined. I will see if your new commits have fixed it on my end.

@willothy
Copy link
Collaborator Author

Ok I now don't have the overlap issue, but I do have the thick border issue.

@willothy
Copy link
Collaborator Author

Can we just merge opts.win_configs and fzf-window-specific window configs in fuzzy_find_open(), excluding self._win_configs? That should be a simpler solution. Notice that we have to re-evaluate the merged result using eval_win_configs().

I don't think so, because then it would break some configs that use borders. I think the complex checks are kinda needed here tbh. Not 100% sure though, I'm testing the idea right now. Have just not found a solution that works for all edge cases.

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 24, 2024

I don't think so, because then it would break some configs that use borders

Why does it break configs for borders given that opts.win_configs contains options for borders?

@willothy
Copy link
Collaborator Author

I don't think so, because then it would break some configs that use borders

Why does it break configs for borders given that opts.win_configs contains options for borders?

Because those can be fzf-specific I think. Honestly I'm not sure. But without self._win_configs.border the border doesn't inherit properly. I am looking into it to provide a more specific repro, sorry for not explaining well lol

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 24, 2024

Emm I think the border of the menu is calculated from opts.menu.win_configs right? So it may be sufficient to use the option value to determine the fzf window's border.


To make it clearer:

  • opts.menu.win_configs contains border configuration that the user WANTs it to be
  • self._win_configs is the EVALUATED window configs (function to actual win config value) with MODIFICATIONS to make sure a ui-select header will be displayed when provided, so it does not always reflect users' intention.

For example, we will change the original border config to add a thick upper border if a header is provided to the ui-select function but opts.menu.win_configs.border=='none', in this case merging self._win_configs will give the fzf-window an undesirable thick upper border. So the proper way is to ignore self._win_configs and just merge opts.menu.win_configs with some fzf-specific settings.

@willothy
Copy link
Collaborator Author

Sounds good, I will keep trying different configurations of this.

@willothy
Copy link
Collaborator Author

I am struggling to implement something that works with all three of (1) full borders provided by name, (2) full borders provided by array and (3) partial borders provided by array.

I can get either partial borders or full borders to work but not both lol

@Bekaboo
Copy link
Owner

Bekaboo commented Jan 25, 2024

@willothy You can leave it to me if you find it hard to implement. I will give it a closer look later.

@willothy
Copy link
Collaborator Author

willothy commented Jan 25, 2024

I think I'll be able to do it (feel free to have a look though),I am just not sure how the fzf window can inherit the parent window's border without having the thick header, unless we manually remove the header or add a hack just for the ui-select implementation which I don't think is ideal.

Using self.opts.win_configs has the same issue because the header is defined in self.opts.win_configs.

@willothy willothy force-pushed the fix-fzf-overlap branch 2 times, most recently from 6ad710d to 66b9661 Compare January 25, 2024 03:40
@willothy
Copy link
Collaborator Author

This seems to work well, it is a mix of your idea and removing the top border when possible.

@willothy
Copy link
Collaborator Author

Actually, maybe we should leave the border alone since the border for the fzf window is already configurable separately from the menu, so if the users would like to get rid of the thicker header they can. We can also update the defaults so that the fzf menu does not have a thick header by default. Thoughts?

@Bekaboo
Copy link
Owner

Bekaboo commented Feb 3, 2024

@willothy Is this ready to merge?

@willothy
Copy link
Collaborator Author

willothy commented Feb 3, 2024

I think so, yeah. I've been using my fork with it for a week or so

Edit: nevermind, do not merge - found a bug lol

@willothy
Copy link
Collaborator Author

willothy commented Feb 3, 2024

Might be worth making sure it works for you too tho if you haven't tested the latest version :)

@willothy willothy marked this pull request as draft February 3, 2024 08:08
@willothy
Copy link
Collaborator Author

willothy commented Feb 3, 2024

Agh it behaves differently in the ui-select menu vs the winbar dropdowns. I'll try to finish this up tomorrow.

@willothy willothy marked this pull request as ready for review February 5, 2024 03:10
@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Ok I've fixed the issues I found, I think this is ready for merge. There are still some edge cases, but none that weren't present before afaik. Just things like different borders between fzf and the menu:

  • If menu has a border and the fzf window has no border, the fzf window is not wide enough but it is aligned properly.
  • If the fzf window has a border but the menu doesn't, then the fzf window is too wide, but again aligned properly.

imo those are obscure use cases and can be fixed in followups.

But if you want me to work out the width things in this PR I can.

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Nvm, fixing the widths was pretty trivial so everything seems to be working now.

It does require potentially evaluating the fzf window border twice, but I don't think that's a huge deal.

@Bekaboo
Copy link
Owner

Bekaboo commented Feb 5, 2024

@willothy I have the following error on fix-fzf-overlap branch when I press i in the ui-select menu:

image

E5108: Error executing lua: /home/zeng/Code/dropbar.nvim/lua/dropbar/configs.lua:374: attempt to perfor
m arithmetic on local 'left' (a boolean value)
stack traceback:
        /home/zeng/Code/dropbar.nvim/lua/dropbar/configs.lua:374: in function 'border_width'
        /home/zeng/Code/dropbar.nvim/lua/dropbar/configs.lua:377: in function 'v'
        /home/zeng/Code/dropbar.nvim/lua/dropbar/menu.lua:910: in function 'merge_win_configs'
        /home/zeng/Code/dropbar.nvim/lua/dropbar/menu.lua:956: in function 'fuzzy_find_open'
        /home/zeng/Code/dropbar.nvim/lua/dropbar/configs.lua:278: in function </home/zeng/Code/dropbar.
nvim/lua/dropbar/configs.lua:273>

Code snippet used to open the ui-select menu (same as the example in :h ui.select):

vim.ui.select({ "tabs", "spaces" }, {
	prompt = "Select tabs or spaces:",
	format_item = function(item)
		return "I'd like to choose " .. item
	end,
}, function(choice)
	if choice == "spaces" then
		vim.o.expandtab = true
	else
		vim.o.expandtab = false
	end
end)

config:

require('dropbar').setup({
  menu = {
    scrollbar = { background = false },
    win_configs = {
      border = { '', '', '', '' },
    }
  },
})
vim.ui.select = require('dropbar.utils.menu').select

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Hmm interesting, let me check that out.

Edit: too many ternaries haha I will fix that now.

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Alright, I think it should work now

@Bekaboo
Copy link
Owner

Bekaboo commented Feb 5, 2024

@willothy fzf window sticking out

image

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Ahhhh ok just a sec. I think that's specific to ui-select.

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Ah figured it out. I was confused about how nvim handled 4-char borders.

@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Sorry for the confusion, just lots of edge cases here haha. I think it should work now, hopfully I'm not wrong again lol

@Bekaboo
Copy link
Owner

Bekaboo commented Feb 5, 2024

Sorry for the confusion, just lots of edge cases here haha. I think it should work now, hopfully I'm not wrong again lol

Yeah it's annoying. I think we could simplify the logic by expanding table-valued border whose length is less than 8 to the equivalent border table with 8 elements first then change the borders in different conditions. It can be a utils function in utils/menu.lua.

But let's merge this first.

@Bekaboo Bekaboo merged commit ef73236 into Bekaboo:master Feb 5, 2024
4 checks passed
@willothy
Copy link
Collaborator Author

willothy commented Feb 5, 2024

Yeah, that would definitely make things simpler, as would utilities so we're not repeating any of this border code anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants