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

XCode Folding Ribbon #24

Open
kevinhwang91 opened this issue Jun 22, 2022 · 22 comments
Open

XCode Folding Ribbon #24

kevinhwang91 opened this issue Jun 22, 2022 · 22 comments
Labels
enhancement New feature or request

Comments

@kevinhwang91
Copy link
Owner

kevinhwang91 commented Jun 22, 2022

Feature description

https://github.com/CodeEditApp/CodeEditTextView/issues/43

Describe the solution you'd like

Use the sign column Use floating window

Additional context

No response

@kevinhwang91 kevinhwang91 added the enhancement New feature or request label Jun 22, 2022
@kevinhwang91
Copy link
Owner Author

High priority for this feature.

@xiyaowong
Copy link
Contributor

🐮

@kevinhwang91
Copy link
Owner Author

image

No idea how to handle lower and upper bar icons. The suggestion is welcome.

@kevinhwang91
Copy link
Owner Author

kevinhwang91 commented Jul 30, 2022

image

It's too hard.

  1. 19-22 and 23-43 are level1, 22 line is the lower but 23 line is the upper, it can't balance aesthetics and practicality;
  2. A line may be lower/upper of different levels, like 1-4 is level1, but 1-3 can be level2, so upper and lower are not a pair, WTF;

@akinsho
Copy link

akinsho commented Jul 30, 2022

@kevinhwang91 I don't fully understand some of the issue you are seeing, but the result of the screenshot so far looks great. I'm guessing that the highlights are in slightly wrong places because of confusing behaviour of nvim folds maybe

@kevinhwang91
Copy link
Owner Author

kevinhwang91 commented Jul 30, 2022

@kevinhwang91 I don't fully understand some of the issue you are seeing, but the result of the screenshot so far looks great. I'm guessing that the highlights are in slightly wrong places because of confusing behaviour of nvim folds maybe

  1. not pretty as GUI, depending on the user icon and font.
    image
  2. The endLnum of folds may overlap each, hard to compute with high perf. Must take a time to explore.

IMO, must highlight the current fold range with uppe/lower or the bar body, otherwise, it's useless.

@kevinhwang91
Copy link
Owner Author

kevinhwang91 commented Jul 30, 2022

maybe only use to indicator the startLnum and highlight current range is a compromise method. The upper/lower icon is hard to select and ⁀‿ in some fonts are asymmetric. This is the limitation of terminal.

image

@kevinhwang91
Copy link
Owner Author

I get sucked with the UI. There're many potential errors that need to handle. BTW, ctrl-w+o will work fine with the floating window foldcolumn.
https://user-images.githubusercontent.com/17562139/181925985-66dbf19e-bd79-4659-9c3f-c66b1cbe0796.mp4

@shofel
Copy link

shofel commented Aug 12, 2022

I love the appearance of the xcode folding ribbon. Thanks for sharing it!

Looks like the lower bounds do not add lot's of value, so it's ok to omit them.

Regarding the upper boundary: what if just leave the arrow as it is? That is the only change to make is to encode levels of a fold with a color instead of a number 🤔

image

image

@kevinhwang91
Copy link
Owner Author

I love the appearance of the xcode folding ribbon. Thanks for sharing it!

Looks like the lower bounds do not add lot's of value, so it's ok to omit them.

Regarding the upper boundary: what if just leave the arrow as it is? That is the only change to make is to encode levels of a fold with a color instead of a number thinking

image

image

Not bad, but must solve the perf first, I will give a try if I have time.

@i-am-the-slime
Copy link

@kevinhwang91 whatever comes of this, your prototype looks really cool!

@WhiteBlackGoose
Copy link

Hi, Kevin, this looks great. Do you mind pushing the branch yet? Ik it's WIP, but I could be an alpha tester 😆
I mean, even the prototype looks good for me.

Btw, does your new feature depend on the patch to nvim?

@kevinhwang91
Copy link
Owner Author

@WhiteBlackGoose Thanks for your attention.
I have tested the incomplete code and found it will make nearly a millisecond regression for redraw even if using ffi. If the code is complete, I think the regression will be worse which makes me think it's not a productive implementation.
IMO, the enhanced UI shouldn't make Neovim lag, so I have stopped dev for this feature for now.

@WhiteBlackGoose
Copy link

Oh, I see, sad :/

@kevinhwang91
Copy link
Owner Author

@WhiteBlackGoose Maybe can get better perf to use statuscolumn. I will give it a try if I have spare time.

@WhiteBlackGoose
Copy link

Nice, good luck with that!

@kevinhwang91
Copy link
Owner Author

#4 (comment)

The ribbon is slightly more complicated than the VSCode style. The perf is not bad. Less than 1ms regression in a redraw even if a monitor in portrait orientation with hundred visible lines.

Go ahead if statuscolumn become stable.

@Chaitanyabsprip
Copy link

I was trying to do the vscode style markers using the status column, could make it work with treesitter method(not ufo), couldn't figure out how to convert promise to a function that could be fed into the status column opt, can you help me with that? I was trying to use the ufo.getFolds() method

@ribru17
Copy link

ribru17 commented Oct 1, 2023

Is there any code available showing how to achieve this affect? If anyone wants to use the unfinished feature now

@kevinhwang91
Copy link
Owner Author

Is there any code available showing how to achieve this affect? If anyone wants to use the unfinished feature now

No, will implement it if I have spare time.

@ribru17
Copy link

ribru17 commented Oct 1, 2023

Thank you. Also I managed to create a minimal version of this without the start and end indicators. If anyone is interested:

      {
        'luukvbaal/statuscol.nvim',
        config = function()
          local builtin = require('statuscol.builtin')
          local c = require('statuscol.ffidef').C
          local util = require('utils')
          for i = 0, 8, 1 do
            vim.api.nvim_set_hl(0, 'FoldCol' .. i, {
              bg = util.blend(
                string.format(
                  '#%06x',
                  vim.api.nvim_get_hl(0, { name = 'Normal' }).fg
                ),
                string.format(
                  '#%06x',
                  vim.api.nvim_get_hl(0, { name = 'Normal' }).bg
                ),
                0.125 * i
              ),
            })
          end
          require('statuscol').setup {
            relculright = true,
            segments = {
              { text = { '%s' }, click = 'v:lua.ScSa' },
              { text = { builtin.lnumfunc, ' ' }, click = 'v:lua.ScLa' },
              {
                -- hl = 'FoldColumn',
                text = {
                  function(args)
                    local fold_level = c.fold_info(args.wp, args.lnum).level
                    local hl = '%#FoldCol' .. fold_level .. '#'
                    if fold_level > 8 then
                      hl = '%#FoldCol8#'
                    end
                    return hl .. ' '
                  end,
                },
                click = 'v:lua.ScFa',
              },
            },
          }
        end,
      },

Util functions:

local function hexToRgb(hex_str)
  local hex = '[abcdef0-9][abcdef0-9]'
  local pat = '^#(' .. hex .. ')(' .. hex .. ')(' .. hex .. ')$'
  hex_str = string.lower(hex_str)

  assert(
    string.find(hex_str, pat) ~= nil,
    'hex_to_rgb: invalid hex_str: ' .. tostring(hex_str)
  )

  local r, g, b = string.match(hex_str, pat)
  return { tonumber(r, 16), tonumber(g, 16), tonumber(b, 16) }
end

function M.blend(fg, bg, alpha)
  bg = hexToRgb(bg)
  fg = hexToRgb(fg)

  local blendChannel = function(i)
    local ret = (alpha * fg[i] + ((1 - alpha) * bg[i]))
    return math.floor(math.min(math.max(0, ret), 255) + 0.5)
  end

  return string.format(
    '#%02X%02X%02X',
    blendChannel(1),
    blendChannel(2),
    blendChannel(3)
  )
end

@ribru17
Copy link

ribru17 commented Mar 14, 2024

UPDATE: For anyone still interested I managed to get this working with the statuscol plugin.

foldpreview

Implementation for the status column is here and the necessary highlight groups are here (with some utility functions here)

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

No branches or pull requests

8 participants