b0o / incline.nvim

🎈 Floating statuslines for Neovim, winbar alternative
MIT License
759 stars 14 forks source link

Add Option `hide > inactive_window` #49

Open jonahfang opened 9 months ago

jonahfang commented 9 months ago

I've used lualine before and I could hide the status line in inactive window, why doesn't incline have such functionality?

When I split the current window vertically, I see the incline status message on both windows, which is annoying.

image
fitrh commented 9 months ago

That can be achieved by setting your render to something like this

require('incline').setup({
  render = function(props)
    if props.focused then
      return require('incline.presets').basic(props)
      -- or return whatever you want to render in the focused window
    end

    return nil
  end,
})

I don't think the additional options are needed as the render option already gives us a lot of customization flexibility

jonahfang commented 9 months ago

@fitrh Thanks for reply! Your solution works for my problem but has side effects on floating windows. I use carbon-steel/detour.nvim to edit the file in a floating window. When the floating window is displayed, the incline status message disappears.Apparently, props.focused of the render method becomes false when the floating window is focused.

jonahfang commented 9 months ago

I has a solution like this:

..
          render = function(props)
            if not props.focused and not w.is_floating() then
                return
            end
            -- my incline status message config here

and is_floating() like this:

M.is_floating = function()
    local parent = vim.api.nvim_get_current_win()
    return vim.api.nvim_win_get_config(parent).relative ~= ''
end
fitrh commented 9 months ago

The default behavior is to ignore floating windows, configurable via ignore.floating_wins, so

require('incline').setup({
  render = function(props)
    if props.focused then
      return require('incline.presets').basic(props)
      -- or return whatever you want to render in the focused window
    end

    return nil
  end,
  ignore = {
    floating_wins = false,
  },
})

Maybe achieve what you want

jonahfang commented 9 months ago

ignore.floating_win does not achieve what I want!

tom-gora commented 6 months ago

Hello I have a question and I am sorry for reviving this thread, but my question is the same thing at its core - rendering incline differently based on props.focused. Everything seems pretty clear yet, I fail trying to do a similar condition. Apply different colors based of off the condition. I did something like that:

config = function()
    local center_hl = vim.api.nvim_get_hl(0, { name = "InclineCenter" })
    local outer_hl = vim.api.nvim_get_hl(0, { name = "InclineOuter" })
    local center_hl_inactive =
      vim.api.nvim_get_hl(0, { name = "InclineCenterInactive" })
    local outer_hl_inactive =
      vim.api.nvim_get_hl(0, { name = "InclineOuterInactive" })

    require("incline").setup {
      window = {
        margin = { vertical = 0, horizontal = 0 },
        options = { signcolumn = false, wrap = false },
        padding = 0,
      },
      hide = {
        cursorline = false,
      },
      render = function(props)
        local filename =
          vim.fn.fnamemodify(vim.api.nvim_buf_get_name(props.buf), ":t")
        if vim.bo[props.buf].modified then
          filename = filename .. "  "
        end

        local active_pill_end_hl = {
          guifg = "#" .. string.format("%06x", outer_hl.fg),
          guibg = "#" .. string.format("%06x", outer_hl.bg),
        }
        local active_pill_center_hl = {
          guifg = "#" .. string.format("%06x", center_hl.fg),
          guibg = "#" .. string.format("%06x", center_hl.bg),
        }
        local inactive_pill_end_hl = {
          guifg = "#" .. string.format("%06x", outer_hl_inactive.fg),
          guibg = "#" .. string.format("%06x", outer_hl_inactive.bg),
        }
        local inactive_pill_center_hl = {
          guifg = "#" .. string.format("%06x", center_hl_inactive.fg),
          guibg = "#" .. string.format("%06x", center_hl_inactive.bg),
        }

        local icon, color =
          require("nvim-web-devicons").get_icon_color(filename)
        if props.focused then
          return {
            {
              "",
              guifg = active_pill_end_hl.guifg,
              guibg = active_pill_end_hl.guibg,
            },
            {
              icon,
              guifg = color,
              guibg = active_pill_center_hl.guibg,
            },
            {
              " ",
              guibg = active_pill_center_hl.guibg,
            },
            {
              filename,
              guibg = active_pill_center_hl.guibg,
              guifg = active_pill_center_hl.guifg,
            },
            {
              "î‚´",
              guifg = active_pill_end_hl.guifg,
              guibg = active_pill_end_hl.guibg,
            },
          }
        end
        return {
          {
            "",
            -- guifg = inactive_pill_end_hl.guifg,
            -- guibg = inactive_pill_end_hl.guibg,
            -- testing with plain black and white
            guifg = "#ffffff",
            guibg = "#000000",
          },
          {
            icon,
            -- guifg = color,
            -- guibg = inactive_pill_center_hl.guibg,
            guifg = "#ffffff",
            guibg = "#000000",
          },
          {
            " ",
            -- guibg = inactive_pill_center_hl.guibg,
            guibg = "#000000",
          },
          {
            filename,
            -- guibg = inactive_pill_center_hl.guibg,
            -- guifg = inactive_pill_center_hl.guifg,
            guifg = "#ffffff",
            guibg = "#000000",
          },
          {
            "î‚´",
            -- guifg = inactive_pill_end_hl.guifg,
            -- guibg = inactive_pill_end_hl.guibg,
            guifg = "#ffffff",
            guibg = "#000000",
          },
        }
      end,
    }
  end,

As you can see, I did plain and clear black and white color definitions for the returned result for "inactive" just to see if the condition works. It does not. All my incline instances are rendered with the active colors. Anything obvious I might be missing here or is it worth investigating deeper? I'd be glad to provide details if needed. I use self modded config grown on top of nvchad base, the highlights I pull in for "active" are custom and they work (the behavior is as if all the splits returned focused=true). I am not using any plugins that might affect how splits are created. I'd appreciate a quick glance at this issue.

image

b0o commented 6 months ago

Hi @tom-gora. The issue with your config seems to be caused by window.options.signcolumn = false. false is not a valid value for the signcolumn option. This is causing an error, but Incline isn't displaying that error message, so it's failing silently and putting Incline into a semi-broken state.

You can fix this by changing it to window.options.signcolumn = 'no'.

I am going to make sure that an error message is displayed in a case like this so it doesn't fail silently.

Side note 1: It's usually not necessary to do things like this:

local outer_hl = vim.api.nvim_get_hl(0, { name = "InclineOuter" })
-- ...
local active_pill_end_hl = {
  guifg = "#" .. string.format("%06x", outer_hl.fg),
  guibg = "#" .. string.format("%06x", outer_hl.bg),
}

You can just use group instead:

local active_pill_end_hl = { group = "InclineOuter" }

The only time you should need to do the former is if you want to change something about the group, like swap the fg/bg colors or something like that.

Side note 2: I'm curious to know, why are you trying to disable signcolumn and wrap? I don't think this should be necessary.

b0o commented 6 months ago

@tom-gora Here's how I would simplify your config. This should be functionally equivalent:

require('incline').setup {
  window = {
    margin = { vertical = 0, horizontal = 0 },
    -- You can probably omit this because it should not be necessary
    options = { signcolumn = 'no', wrap = false },
    padding = 0,
  },
  -- Omit this if you've already set these highlight groups somewhere else in your config
  highlight = {
    groups = {
      InclineOuter = { guifg = 'red' },
      InclineCenter = { guibg = 'red', guifg = 'white' },
      InclineOuterInactive = { guifg = 'gray' },
      InclineCenterInactive = { guibg = 'gray', guifg = 'white' },
    },
  },
  hide = {
    -- You can omit this because false is the default value
    cursorline = false,
  },
  render = function(props)
    local filename = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(props.buf), ':t')
    if vim.bo[props.buf].modified then
      filename = filename .. '  '
    end
    local suffix = props.focused and '' or 'Inactive'
    local outerGroup = 'InclineOuter' .. suffix
    local centerGroup = 'InclineCenter' .. suffix
    local icon, iconColor = require('nvim-web-devicons').get_icon_color(filename)
    -- The result table can contain nested tables.
    -- This works similar to how nested HTML tags work, and makes it easier to apply
    -- styles to overlapping parts of the statusline without repeating yourself.
    -- Styles defined in nested tables will override styles defined in their parent 
    -- tables.
    return {
      '',
      {
        { icon, guifg = iconColor },
        ' ',
        filename,
        group = centerGroup,
      },
      'î‚´',
      group = outerGroup,
    }
  end,
}
tom-gora commented 6 months ago

Wow thank you for the quick response. I got an idea for my implementation from craftzdog's dotfiles. I copied some stuff from him where he had it set to true. Naturally I assumed false as opposite. I'll look into it after work. Thank you so much!

tom-gora commented 6 months ago

Confirmed, works. The issue was me in the end not being able to track it down and not knowing enough vim quirks like that some opts take a bool while others take a string as a value. Thanks again! image

tom-gora commented 6 months ago

Ah, and regarding sidenote 2: Signcolumn? I was under the impression this is where the spacing to the left came from (next to my rounded "pill" char) until I realised it was actually padding. It was wrong of me to keep settings I since knew were wrong, and then it turned out this was causing error. Learning every day IG. Wrap I set because I have seen it in someone else's config and I assumed it prevents wrapping on long filenames, diagnostics and other stuff like it. I will ditch it if you say it has no effect. Thanks!