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: scroll_lock_pinned #401

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ require'barbar'.setup {
-- Sets the maximum buffer name length.
maximum_length = 30,

-- Ensure pinned buffers stay visible in the tabline
scroll_lock_pinned = true,

-- If set, the letters for each buffer in buffer-pick mode will be
-- assigned based on their name. Otherwise or in case all letters are
-- already assigned, the behavior is to assign letters in order of
Expand Down
27 changes: 16 additions & 11 deletions doc/barbar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Highlight groups are created in this way: `Buffer<STATUS><PART>`.
`<STATUS>` Meaning
--------- --------------------------------------------------
`Alternate` The |alternate-file|.
`Current` The current buffer.
`Current` The |current-file|.
`Inactive` |hidden-buffer|s and |inactive-buffer|s.
`Visible` |active-buffer|s which are not alternate or current.

Expand Down Expand Up @@ -162,22 +162,22 @@ exclude_name ~
focus_on_close ~
`'left'|'right'` (default: `'left'`)
A buffer to this direction will be focused (if it exists) when closing the
current buffer.
|current-file|.

*barbar-setup.hide*
hide ~
Sets which elements are hidden in the bufferline. Possible options are:
Sets which elements are hidden in the 'tabline'. Possible options are:

*barbar-setup.hide.alternate*
hide.alternate ~
`boolean` (default: `false`)
Controls the visibility of the |alternate-file|.
|barbar-setup.highlight_alternate| must be `true`.
NOTE: |barbar-setup.highlight_alternate| must be `true`.

*barbar-setup.hide.current*
hide.current ~
`boolean` (default: `false`)
Controls the visibility of the current buffer.
Controls the visibility of the |current-file|.

*barbar-setup.hide.extensions*
hide.extensions ~
Expand All @@ -193,7 +193,7 @@ hide ~
hide.visible ~
`boolean` (default: `false`)
Controls visibility of |active-buffer|s.
|barbar-setup.highlight_visible| must be `true`.
NOTE: |barbar-setup.highlight_visible| must be `true`.

*barbar-setup.highlight_alternate*
highlight_alternate ~
Expand Down Expand Up @@ -242,10 +242,10 @@ icons ~
[vim.diagnostic.severity.INFO] = {enabled = false, icon = 'ⓘ '},
[vim.diagnostic.severity.WARN] = {enabled = false, icon = '⚠️ '},
}
< Enables or disables showing diagnostics in the bufferline. The options
< Enables or disables showing diagnostics in the 'tabline'. The options
are:
- `enabled`, whether this diagnostics of this severity are shown in the
bufferline.
'tabline'.
- `icon`, which controls what icon accompanies the number of diagnostics.

*barbar-setup.icons.filetype.custom_colors*
Expand Down Expand Up @@ -311,7 +311,7 @@ icons ~
*barbar-setup.icons.current*
icons.current ~
`table`
The icons which should be used for current buffer.
The icons which should be used for |current-file|.
Supports all the base options (e.g. `buffer_index`, `filetype.enabled`,
etc) as well as `modified` and `pinned`.

Expand Down Expand Up @@ -346,14 +346,14 @@ icons ~
insert_at_start ~
`boolean` (default: `false`)
If true, new buffers appear at the start of the list. Default is to
open after the current buffer.
open after the |current-file|.
Has priority over |barbar-setup.insert_at_end|

*barbar-setup.insert_at_end*
insert_at_end ~
`boolean` (default: `false`)
If true, new buffers appear at the end of the list. Default is to
open after the current buffer.
open after the |current-file|.

*barbar-setup.letters*
letters ~
Expand Down Expand Up @@ -383,6 +383,11 @@ no_name_title ~
Sets the name of unnamed buffers. By default format is `'[Buffer X]'`
where `X` is the buffer number. But only a static string is accepted here.

*barbar-setup.scroll_lock.pinned*
scroll_lock_pinned ~
`boolean` (default: `false`)
If `true`, pinned buffers will always be shown in the 'tabline'.

*barbar-setup.semantic_letters*
semantic_letters ~
`boolean` (default: `true`)
Expand Down
15 changes: 11 additions & 4 deletions lua/barbar/bbye.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,16 @@ local function get_focus_on_close(closing_number)

if #state_bufnrs < 1 then -- all of the buffers are excluded or unlisted
local open_bufnrs = list_bufs()
if focus_on_close == 'right' then
open_bufnrs = utils.list_reverse(open_bufnrs)

local start, end_, step
if focus_on_close == 'left' then
start, end_, step = 1, #open_bufnrs, 1
else
start, end_, step = #open_bufnrs, 1, -1
end

for _, nr in ipairs(open_bufnrs) do
for i = start, end_, step do
local nr = open_bufnrs[i]
if buf_get_option(nr, 'buflisted') then
return nr -- there was a listed buffer open, focus it.
end
Expand Down Expand Up @@ -194,7 +199,9 @@ function bbye.delete(action, force, buffer, mods)

-- For cases where adding buffers causes new windows to appear or hiding some
-- causes windows to disappear and thereby decrement, loop backwards.
for _, window_number in ipairs(utils.list_reverse(list_wins())) do
local wins = list_wins()
for i = #wins, 1, -1 do
local window_number = wins[i]
if win_get_buf(window_number) == buffer_number then
set_current_win(window_number)

Expand Down
2 changes: 2 additions & 0 deletions lua/barbar/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ local DEPRECATED_OPTIONS = {
--- @field maximum_padding integer
--- @field minimum_padding integer
--- @field no_name_title string
--- @field scroll_lock_pinned boolean
--- @field semantic_letters boolean
--- @field tabpages boolean

Expand Down Expand Up @@ -208,6 +209,7 @@ function config.setup(user_config)
maximum_padding = 4,
minimum_padding = 1,
no_name_title = nil,
scroll_lock_pinned = false,
semantic_letters = true,
tabpages = true,
})
Expand Down
41 changes: 27 additions & 14 deletions lua/barbar/render.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,15 @@ local function slice_groups_left(groups, width)

local new_groups = {}

for _, group in ipairs(utils.list_reverse(groups)) do
for i = #groups, 1, -1 do
local group = groups[i]
local text_width = strwidth(group.text)
accumulated_width = accumulated_width + text_width

if accumulated_width >= width then
local length = text_width - (accumulated_width - width)
local start = text_width - length
local new_group = {hl = group.hl, text = strcharpart(group.text, start, length)}
table_insert(new_groups, 1, new_group)
table_insert(new_groups, 1, {hl = group.hl, text = strcharpart(group.text, start, length)})
break
end

Expand Down Expand Up @@ -526,13 +526,16 @@ local function generate_tabline(bufnrs, refocus)
local current_buffer_position = 0
local items = {}

local scroll_lock_pinned = config.options.scroll_lock_pinned
local scroll_locked = {}

for i, bufnr in ipairs(bufnrs) do
local activity = Buffer.activities[Buffer.get_activity(bufnr)]

local buffer_data = state.get_buffer_data(bufnr)
local buffer_hl = hl_tabline('Buffer' .. activity .. (
buf_get_option(bufnr, 'modified') and 'Mod' or ''
))
buf_get_option(bufnr, 'modified') and 'Mod' or '')
)
local buffer_name = buffer_data.name or '[no name]'

buffer_data.real_width = Layout.calculate_width(layout.base_widths[i], layout.padding_width)
Expand All @@ -552,15 +555,15 @@ local function generate_tabline(bufnrs, refocus)
local buffer_index = {hl = '', text = ''}
if icons_option.buffer_index then
buffer_index.hl = hl_tabline('Buffer' .. activity .. 'Index')
buffer_index.text = tostring(i) .. ' '
buffer_index.text = i .. ' '
end

--- The buffer number
--- @type barbar.render.group
local buffer_number = {hl = '', text = ''}
if icons_option.buffer_number then
buffer_number.hl = hl_tabline('Buffer' .. activity .. 'Number')
buffer_number.text = tostring(bufnr) .. ' '
buffer_number.text = bufnr .. ' '
end

local button = icons_option.button or ''
Expand Down Expand Up @@ -651,7 +654,11 @@ local function generate_tabline(bufnrs, refocus)
current_buffer_position = current_buffer_position + item.width

local scroll_current = min(scroll.current, max_scroll)
if current_buffer_position < scroll_current then
if current_buffer_position < scroll_current then
if buffer_data.pinned and scroll_lock_pinned then
table_insert(scroll_locked, item)
end

goto continue -- HACK: there is no `continue` keyword
end

Expand Down Expand Up @@ -695,15 +702,21 @@ local function generate_tabline(bufnrs, refocus)

-- Crop to scroll region

local scroll_current = min(scroll.current, max_scroll)
local buffers_end = layout.actual_width - scroll_current
do
local scroll_current = min(scroll.current, max_scroll)
local buffers_end = layout.actual_width - scroll_current

if buffers_end > layout.buffers_width then
bufferline_groups = slice_groups_right(bufferline_groups, scroll_current + layout.buffers_width)
end

if buffers_end > layout.buffers_width then
bufferline_groups = slice_groups_right(bufferline_groups, scroll_current + layout.buffers_width)
if scroll_current > 0 then
bufferline_groups = slice_groups_left(bufferline_groups, layout.buffers_width)
end
end

if scroll_current > 0 then
bufferline_groups = slice_groups_left(bufferline_groups, layout.buffers_width)
for i = #scroll_locked, 1, -1 do
bufferline_groups = groups_insert(bufferline_groups, 0, scroll_locked[i].groups)
end

result = result ..
Expand Down
5 changes: 3 additions & 2 deletions lua/barbar/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ local get_current_buf = vim.api.nvim_get_current_buf --- @type function
local list_bufs = vim.api.nvim_list_bufs --- @type function
local list_extend = vim.list_extend
local severity = vim.diagnostic.severity --- @type {[integer]: string, [string]: integer}
local tbl_contains = vim.tbl_contains
local tbl_filter = vim.tbl_filter

local Buffer = require'barbar.buffer'
Expand Down Expand Up @@ -116,10 +117,10 @@ function state.get_buffer_list()

for _, bufnr in ipairs(list_bufs()) do
if buf_get_option(bufnr, 'buflisted') and
not utils.has(exclude_ft, buf_get_option(bufnr, 'filetype'))
not tbl_contains(exclude_ft, buf_get_option(bufnr, 'filetype'))
then
local name = buf_get_name(bufnr)
if not utils.has(exclude_name, utils.basename(name, hide_extensions)) then
if not tbl_contains(exclude_name, utils.basename(name, hide_extensions)) then
table_insert(result, bufnr)
end
end
Expand Down
9 changes: 0 additions & 9 deletions lua/barbar/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,6 @@ local utils = {
notify_once_util(name .. ' is deprecated. Use ' .. alternative .. 'instead.', vim.log.levels.WARN)
end,

--- Return whether element `n` is in a `list.
--- @generic T
--- @param list T[]
--- @param t T
--- @return boolean
has = function(list, t)
return index_of(list, t) ~= nil
end,

--- utilities for working with highlight groups.
--- @class barbar.utils.hl
hl = {
Expand Down