diff --git a/README.md b/README.md index 4444af9..968053a 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,12 @@ require('incline').setup { }, render = "basic", window = { + overlap = { + statusline = false, + winbar = false, + tabline = false, + borders = true, + }, margin = { horizontal = 1, vertical = 1 diff --git a/doc/incline.txt b/doc/incline.txt index 707b71c..e6418aa 100644 --- a/doc/incline.txt +++ b/doc/incline.txt @@ -265,9 +265,8 @@ window.margin.vertical~ - If an `int >= 0`, the value is used for both the top and bottom margin. - If a table, both `top` and `bottom` fields must be present. - If `window.placement.vertical` is `top` and 'laststatus' is `3`, you can set - `window.margin.vertical.top` to `0` to allow Incline statuslines to overlap - window borders. + If 'laststatus' is `3`, you can set `window.overlap.borders` to `true` + to allow Incline statuslines to overlap window borders. *incline-config-window.margin.horizontal* window.margin.horizontal~ @@ -280,6 +279,17 @@ window.margin.horizontal~ - If an `int`, the value is used for both the left and right margin. - If a table, both `left` and `right` fields must be present. + *incline-config-window.overlap* +window.overlap~ + Type: `table` + Valid: `table { tabline: bool, winbar: bool, borders: bool }` + Default: `{ tabline = false, winbar = false, borders = true, statusline = false }` + + Controls which bars and lines the inline windows are allowed to overlap. + - `tabline` takes priority over `winbar` for windows at the top of the tabpage, + if both are set and `vertical == "top"`. + - `borders` takes priority for windows below the top of the tabpage. + *incline-config-window.winhighlight* window.winhighlight~ Type: `table` diff --git a/lua/incline/config/init.lua b/lua/incline/config/init.lua index 476f0f1..80fdf8d 100644 --- a/lua/incline/config/init.lua +++ b/lua/incline/config/init.lua @@ -30,6 +30,12 @@ M.schema = Schema(function(s) ), window = { width = s:entry('fit', vx.any { 'fit', 'fill', vx.number.natural, vx.number.percentage }), + overlap = { + winbar = s:entry(false, vx.bool), + tabline = s:entry(false, vx.bool), + borders = s:entry(true, vx.bool), + statusline = s:entry(false, vx.bool), + }, placement = { vertical = s:entry('top', vx.any { 'top', 'bottom' }), horizontal = s:entry('right', vx.any { 'left', 'center', 'right' }), diff --git a/lua/incline/winline.lua b/lua/incline/winline.lua index 8de93ab..aa2ceed 100644 --- a/lua/incline/winline.lua +++ b/lua/incline/winline.lua @@ -68,12 +68,58 @@ function Winline:get_win_geom_row() if placement.vertical == 'top' then -- if margin-top is 0, avoid overlapping tabline, and avoid overlapping -- statusline if laststatus is not 3 - if cw.margin.vertical.top == 0 and (vim.o.laststatus ~= 3 or a.nvim_win_get_position(self.target_win)[1] <= 1) then - return 1 + + -- TODO(willothy): this can obviously be simplified a lot, there is a good bit of repetition + if a.nvim_win_get_position(self.target_win)[1] <= 1 then + if cw.margin.vertical.top == 0 then + if + config.window.overlap.tabline + -- don't try to overlap tabline if it doesn't exist + and (vim.o.showtabline > 1 or (vim.o.showtabline == 1 and #vim.api.nvim_list_tabpages() > 1)) + then + return cw.margin.vertical.top - 1 + -- only overlap winbar if it exists and is configured to overlap + elseif config.window.overlap.winbar or vim.wo[self.target_win].winbar == '' then + return cw.margin.vertical.top + else + return cw.margin.vertical.top + 1 + end + -- ensure we skip the winbar if we are overlapping it + elseif config.window.overlap.winbar or vim.wo[self.target_win].winbar == '' then + return cw.margin.vertical.top - 1 + else + return cw.margin.vertical.top + end + end + -- only overlap border if user has set it + if config.window.overlap.borders then + return cw.margin.vertical.top - 1 + elseif config.window.overlap.winbar == false and vim.wo[self.target_win].winbar ~= '' then + return cw.margin.vertical.top + 1 + else + return cw.margin.vertical.top end - return cw.margin.vertical.top elseif placement.vertical == 'bottom' then - return a.nvim_win_get_height(self.target_win) - cw.margin.vertical.bottom + if + vim.o.laststatus ~= 3 + or ( + ( + a.nvim_win_get_position(self.target_win)[1] + + a.nvim_win_get_height(self.target_win) + + 1 -- for global status + ) == vim.o.lines + ) + then + if config.window.overlap.statusline then + return a.nvim_win_get_height(self.target_win) - cw.margin.vertical.bottom + else + return a.nvim_win_get_height(self.target_win) - (cw.margin.vertical.bottom + 1) + end + elseif vim.o.laststatus == 3 and config.window.overlap.borders then + return a.nvim_win_get_height(self.target_win) - cw.margin.vertical.bottom + end + + return a.nvim_win_get_height(self.target_win) - (cw.margin.vertical.bottom + 1) end assert(false, 'invalid value for placement.vertical: ' .. tostring(placement.vertical)) end @@ -113,27 +159,26 @@ end function Winline:get_win_geom() local win_width = a.nvim_win_get_width(self.target_win) + local win_pos = a.nvim_win_get_position(self.target_win) local geom = {} geom.height = 1 geom.width = self:get_win_geom_width(win_width) - geom.row = self:get_win_geom_row() - geom.col = self:get_win_geom_col(win_width, geom.width) + geom.row = win_pos[1] + self:get_win_geom_row() + geom.col = win_pos[2] + self:get_win_geom_col(win_width, geom.width) return geom end function Winline:get_win_config() local geom = self:get_win_geom() return { - win = self.target_win, zindex = config.window.zindex, width = geom.width, height = geom.height, row = geom.row, col = geom.col, - relative = 'win', + relative = 'editor', style = 'minimal', focusable = false, - anchor = 'SW', } end @@ -178,7 +223,8 @@ function Winline:render(opts) end if (config.hide.cursorline == true or (config.hide.cursorline == 'focused_win' and self.focused)) - and self:get_win_geom_row() == a.nvim_win_call(self.target_win, vim.fn.winline) + and (self:get_win_geom_row() + ((vim.wo[self.target_win].winbar == '') and 1 or 0)) + == a.nvim_win_call(self.target_win, vim.fn.winline) then self:hide(HIDE_TEMP) return diff --git a/test/config.lua b/test/config.lua index a81429a..7b91668 100644 --- a/test/config.lua +++ b/test/config.lua @@ -214,6 +214,9 @@ Describe('the incline.config module', function() { 'render', Which.Is.A.Function }, { 'debounce_threshold', Which.Is.A.Table }, { 'window', Which.Is.A.Table }, + { 'window.overlap', Which.Is.A.Table }, + { 'window.overlap.winbar' }, + { 'window.overlap.tabline' }, { 'window.placement', Which.Is.A.Table }, { 'window.placement.vertical' }, { 'window.placement.horizontal' }, @@ -242,6 +245,9 @@ Describe('the incline.config module', function() { 'window.placement', Which.Is.A.Table }, { 'window.placement.vertical' }, { 'window.placement.horizontal' }, + { 'window.overlap', Which.Is.A.Table }, + { 'window.overlap.winbar' }, + { 'window.overlap.tabline' }, { 'window.width' }, { 'window.margin', Which.Is.A.Table }, { 'window.padding', Which.Is.A.Table },