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

Animations: pin/unpin & fix close/open #455

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
5 changes: 4 additions & 1 deletion lua/barbar/animate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,12 @@ function animate.start(duration, initial, final, type, callback)
return state
end

--- @param state barbar.animate.state
--- @param state barbar.animate.state|nil
--- @return nil
function animate.stop(state)
if state == nil then
return
end
if state.timer then
state.timer:stop()
state.timer:close()
Expand Down
107 changes: 3 additions & 104 deletions lua/barbar/api.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
local char = string.char
local max = math.max
local min = math.min
local table_insert = table.insert
local table_remove = table.remove
local table_sort = table.sort

local buf_get_name = vim.api.nvim_buf_get_name --- @type function
Expand All @@ -16,12 +14,9 @@ local set_current_buf = vim.api.nvim_set_current_buf --- @type function
-- TODO: remove `vim.fs and` after 0.8 release
local normalize = vim.fs and vim.fs.normalize

local animate = require'barbar.animate'
local bbye = require'barbar.bbye'
local Buffer = require'barbar.buffer'
local config = require'barbar.config'
local JumpMode = require'barbar.jump_mode'
local Layout = require'barbar.ui.layout'
local render = require'barbar.ui.render'
local state = require'barbar.state'
local utils = require'barbar.utils'
Expand Down Expand Up @@ -213,101 +208,6 @@ function api.goto_buffer_relative(steps)
set_current_buf(state.buffers[(idx + steps - 1) % #state.buffers + 1])
end

local move_animation = nil --- @type nil|barbar.animate.state
local move_animation_data = {
next_positions = nil, --- @type nil|integer[]
previous_positions = nil --- @type nil|integer[]
}

--- An incremental animation for `move_buffer_animated`.
--- @return nil
local function move_buffer_animated_tick(ratio, current_animation)
for _, current_number in ipairs(Layout.buffers) do
local current_data = state.get_buffer_data(current_number)

if current_animation.running == true then
current_data.position = animate.lerp(
ratio,
(move_animation_data.previous_positions or {})[current_number],
(move_animation_data.next_positions or {})[current_number]
)
else
current_data.position = nil
current_data.moving = false
end
end

render.update()

if current_animation.running == false then
move_animation = nil
move_animation_data.next_positions = nil
move_animation_data.previous_positions = nil
end
end

local MOVE_DURATION = 150

--- Move a buffer (with animation, if configured).
--- @param from_idx integer the buffer's original index.
--- @param to_idx integer the buffer's new index.
--- @return nil
local function move_buffer(from_idx, to_idx)
to_idx = max(1, min(#state.buffers, to_idx))
if to_idx == from_idx then
return
end

local animation = config.options.animation
local buffer_number = state.buffers[from_idx]

local previous_positions
if animation == true then
previous_positions = Layout.calculate_buffers_position_by_buffer_number()
end

table_remove(state.buffers, from_idx)
table_insert(state.buffers, to_idx, buffer_number)
state.sort_pins_to_left()

if animation == true then
local current_index = utils.index_of(Layout.buffers, buffer_number)
local start_index = min(from_idx, current_index)
local end_index = max(from_idx, current_index)

if start_index == end_index then
return
elseif move_animation ~= nil then
animate.stop(move_animation)
end

local next_positions = Layout.calculate_buffers_position_by_buffer_number()

for _, layout_bufnr in ipairs(Layout.buffers) do
local current_data = state.get_buffer_data(layout_bufnr)

local previous_position = previous_positions[layout_bufnr]
local next_position = next_positions[layout_bufnr]

if next_position ~= previous_position then
current_data.position = previous_positions[layout_bufnr]
current_data.moving = true
end
end

move_animation_data = {
previous_positions = previous_positions,
next_positions = next_positions,
}

move_animation =
animate.start(MOVE_DURATION, 0, 1, vim.v.t_float,
function(ratio, current_animation) move_buffer_animated_tick(ratio, current_animation) end)
end

render.update()
end

--- Move the current buffer to the index specified.
--- @param idx integer
--- @return nil
Expand All @@ -325,7 +225,7 @@ function api.move_current_buffer_to(idx)
return notify_buffer_not_found(current_bufnr)
end

move_buffer(from_idx, idx)
render.move_buffer(from_idx, idx)
end

--- Move the current buffer a certain number of times over.
Expand All @@ -341,7 +241,7 @@ function api.move_current_buffer(steps)
return notify_buffer_not_found(current_bufnr)
end

move_buffer(idx, idx + steps)
render.move_buffer(idx, idx + steps)
end

--- Order the buffers by their buffer number.
Expand Down Expand Up @@ -472,8 +372,7 @@ end
--- @param buffer_number? integer
--- @return nil
function api.toggle_pin(buffer_number)
state.toggle_pin(buffer_number or 0)
render.update()
render.toggle_pin(buffer_number or 0)
end

return api
22 changes: 14 additions & 8 deletions lua/barbar/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ local CACHE_PATH = vim.fn.stdpath('cache') .. '/barbar.json'
--------------------------------

--- @class barbar.state.data
--- @field closing boolean whether the buffer is being closed
--- @field name? string the name of the buffer
--- @field position? integer the absolute position of the buffer
--- @field computed_position? integer the real position of the buffer
--- @field computed_width? integer the width of the buffer plus invisible characters
--- @field pinned boolean whether the buffer is pinned
--- @field closing boolean whether the buffer is being closed
--- @field width? integer the width of the buffer minus invisible characters
--- @field padding? integer the padding width for one side
--- @field position? integer the absolute position of the buffer
--- @field computed_width? integer the logical width of the buffer plus invisible characters
--- @field computed_padding? integer the logical padding of the buffer
--- @field computed_position? integer the logical position of the buffer

--- @class barbar.state.offset.side
--- @field hl? string the highlight group to use
Expand Down Expand Up @@ -69,16 +71,20 @@ local state = {

--- Get the state of the `id`
--- @param bufnr integer the `bufnr`
--- @param data_by_bufnr? {[integer]: barbar.state.data}
--- @return barbar.state.data
function state.get_buffer_data(bufnr)
function state.get_buffer_data(bufnr, data_by_bufnr)
if bufnr == 0 then
bufnr = get_current_buf()
end
if data_by_bufnr == nil then
data_by_bufnr = state.data_by_bufnr
end

local data = state.data_by_bufnr[bufnr]
local data = data_by_bufnr[bufnr]
if data == nil then
data = {closing = false, pinned = false}
state.data_by_bufnr[bufnr] = data
data = { closing = false, pinned = false }
data_by_bufnr[bufnr] = data
end

return data
Expand Down
Loading