Skip to content

Commit

Permalink
add tmux line
Browse files Browse the repository at this point in the history
  • Loading branch information
zztrieuzz committed Jan 5, 2024
1 parent ec334e4 commit 53b4c92
Show file tree
Hide file tree
Showing 4 changed files with 326 additions and 21 deletions.
14 changes: 8 additions & 6 deletions lua/windline/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ local click_utils = require('windline.click_utils')

M.state = M.state
or {
mode = {}, -- vim mode {normal insert}
comp = {}, -- component state it will reset on begin render
mode = {}, -- vim mode {normal insert}
comp = {}, -- component state it will reset on begin render
config = {},
runtime_colors = {}, -- some colors name added by function add_component
}
Expand Down Expand Up @@ -117,7 +117,7 @@ M.show_global = function(bufnr, winid)
if vim.g.statusline_winid == winid then
if utils.is_in_table(M.state.config.global_skip_filetypes, ft)
or (
api.nvim_win_get_config(winid).relative ~= ''
api.nvim_win_get_config(winid).relative ~= ''
and not check_line.global_show_float
)
then
Expand Down Expand Up @@ -239,6 +239,9 @@ M.get_colors = function(reload)
colors = vim.tbl_extend('force', colors, func_color(colors))
end
end
for key, c in ipairs(colors) do
colors[key] = string.lower(c)
end
M.state.colors = colors
assert(colors ~= nil, 'a colors_name on setup function should return a value')
return colors
Expand Down Expand Up @@ -329,7 +332,6 @@ M.setup_event = function()
callback = function() M.on_set_laststatus() end
})
api.nvim_create_user_command("WindLineBenchmark", "lua require('windline.benchmark').benchmark()", {})

end

M.remove_status_by_ft = function(filetypes)
Expand Down Expand Up @@ -380,7 +382,7 @@ end
--- position == left add component before a first divider (%=)
--- position == right add component after a first divider (%=)
--- auto_remove auto remove old component with same name
--- colors_name table a modifer colors to add to a new component
--- colors_name table a modifier colors to add to a new component
--- autocmd boolean It use an auto command to add component to default statusline.
M.add_component = function(component, opt)
if opt.autocmd then
Expand Down Expand Up @@ -427,7 +429,7 @@ M.add_component = function(component, opt)
end
M.setup_hightlight(M.state.colors)
else
vim.api.nvim_echo({ { string.format("Cant' find a position %s", opt.position), 'ErrorMsg' } }, true, {})
vim.api.nvim_echo({ { string.format("Can't find a position %s", opt.position), 'ErrorMsg' } }, true, {})
end
end

Expand Down
30 changes: 15 additions & 15 deletions lua/wltabline/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,23 @@ end
-- stylua: ignore
local default_config = {
template = {
select = { '', { 'NormalFg', 'NormalBg', 'bold' } },
select = { '', { 'NormalFg', 'NormalBg', 'bold' } },
select_start = { separators.block_thin .. ' ', { 'blue', 'NormalBg' } },
select_end = { ' ', { 'NormalFg', 'NormalBg' } },
select_fill = { ' ', { 'NormalFg', 'NormalBg' } },
normal = { '', { 'TabLineFg', 'TabLineBg' } },
normal_start = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_end = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_select = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_last = { ' ', { 'TabLineFg', 'TabLineBg' } },
select_end = { ' ', { 'NormalFg', 'NormalBg' } },
select_fill = { ' ', { 'NormalFg', 'NormalBg' } },
normal = { '', { 'TabLineFg', 'TabLineBg' } },
normal_start = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_end = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_select = { ' ', { 'TabLineFg', 'TabLineBg' } },
normal_last = { ' ', { 'TabLineFg', 'TabLineBg' } },
},
click = true,
tab_end = {
{ ' ', 'TabLineFill' },
},
}

local tab_template = function(template)
M.tab_template = function(template)
local hl_colors = {}
local sep_text = {}
for key, value in pairs(template) do
Expand All @@ -118,9 +118,9 @@ local tab_template = function(template)
hl_end = 'select_last'
end
return {
{ sep_text.select_start, 'select_start' },
{ sep_text.select_start, 'select_start' },
{ M.tab_name(data.tab_index), 'select' },
{ text_end, hl_end },
{ text_end, hl_end },
}
else
local hl_end = 'normal_end'
Expand All @@ -134,9 +134,9 @@ local tab_template = function(template)
hl_end = 'normal_select'
end
return {
{ text_start, 'normal_start' },
{ text_start, 'normal_start' },
{ M.tab_name(data.tab_index), 'normal' },
{ text_end, hl_end },
{ text_end, hl_end },
}
end
end,
Expand All @@ -145,7 +145,7 @@ end

M.setup = function(opts)
opts = vim.tbl_deep_extend('force', default_config, opts or {})
opts.tab_template = opts.tab_template or tab_template(opts.template or {})
opts.tab_template = opts.tab_template or M.tab_template(opts.template or {})
WindLine.hl_data = {}
_G.WindLine.tabline = {
setup_hightlight = M.setup_hightlight,
Expand All @@ -156,7 +156,7 @@ M.setup = function(opts)
M.setup_hightlight(opts.colors)
utils.hl_create()
end
vim.cmd([[set tabline=%!v:lua.WindLine.tabline.show()]])
vim.opt.tabline = '%!v:lua.WindLine.tabline.show()'
end

return M
218 changes: 218 additions & 0 deletions lua/wltmuxline/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
local M = {}
local api = vim.api
local tmux_component = require('wltmuxline.tmux_component')

local uv = vim.uv or vim.loop

---@class tmux_line
---@field original string
---@field tmux 'status-left'|'status-right'
---@field tabline boolean
---@field stdin? uv_pipe_t
---@field job? uv_process_t
---@field shutdown function
---@field setup function
---@field restore function
---@field last_status string
---@field active tmux_component[]|tmux_component
---@field data? any

---@class tmux_config
---@field is_run boolean
---@field statuslines tmux_line[]
local default_config = {
autocmd = { "BufEnter", "TabEnter" },
is_run = true,
statuslines = {}
}

---@type tmux_config
---@diagnostic disable-next-line: missing-fields
local tmux_state = {}

---@param line tmux_line
local function render_tabline(line)
local total_tab = vim.fn.tabpagenr('$')
local status = ''
local tab_select = vim.fn.tabpagenr()
for i = 1, total_tab, 1 do
local data = {
is_selection = i == tab_select,
is_next_select = ((i + 1) == tab_select),
is_tab_finish = i == total_tab,
template = line.data,
tab_index = i,
}
status = status .. line.active[1]:render(data)
end
line.last_status = status
return status
end

---@param line tmux_line
local function render_status_line(line)
tmux_component.reset()
local status = ''
local winid = api.nvim_get_current_win()
local bufnr = api.nvim_get_current_buf()
local win_width = vim.o.columns
for _, comp in pairs(line.active) do
status = status .. comp:render(bufnr, winid, win_width)
end
line.last_status = status
return status
end


M.update = function()
if not tmux_state.is_run then return false end
for _, line in pairs(tmux_state.statuslines) do
local text = line.tabline and render_tabline(line) or render_status_line(line)
if text ~= '' and line.stdin then
line.stdin:write(text .. '\n')
end
end
end

M.stop = function()
tmux_state.is_run = false
for _, line in pairs(tmux_state.statuslines) do
if line.job then
line.shutdown()
line.restore()
end
end
end

M.tmux_set = function()
for _, line in pairs(tmux_state.statuslines) do
line.setup()
end
M.update()
end

M.tmux_restore = function()
for _, line in pairs(tmux_state.statuslines) do
line.restore(true)
end
end

---@param line tmux_line
---@param colors table
local function init_tmux(line, colors)
assert(line.tmux == 'status-left' or line.tmux == 'status-right', ' tmux config is wrong')
-- compile component
if #line.active > 0 then
for key, value in pairs(line.active) do
local comp = tmux_component.create(value)
line.active[key] = comp
comp:setup_hl(colors)
end
end

local original = vim.fn.systemlist(
string.format([[sh -c 'tmux display-message -p "#{%s}"']], line.tmux))[1]

local session_id = vim.env.TMUX:match(',(%d*)$')
local tmux_pipe = vim.env.TMUX:match('/tmp/tmux%-%d*/default')
local pipe_path = string.format('%s-$%s-%s', tmux_pipe, session_id, line.tmux)
local function setup()
local tmux_set_command = string.format([[tmux set -g %s '#(cat #{socket_path}-\#{session_id}-%s)']],
line.tmux, line.tmux)
vim.fn.systemlist(tmux_set_command);
end
local function restore(verify)
if verify then
local check = vim.fn.readfile(pipe_path, '', 1)
if check and check[1] ~= line.last_status then
return
end
end
pcall(vim.fn.system,
string.format('tmux set -g %s %s', line.tmux, vim.fn.shellescape(line.original)))
end

local stdin = uv.new_pipe(false)
local job_script = string.format(
[[while IFS=''$\n'' read -r l; do echo "$l" > '%s';tmux refresh-client -S; done]],
pipe_path
)

local job = uv.spawn("bash",
{ cwd = uv.cwd(), stdio = { stdin }, args = { "-c", job_script } }
)
setup()
if not job then return end
line.original = original
line.stdin = stdin
line.job = job
line.restore = vim.schedule_wrap(restore)
line.setup = vim.schedule_wrap(setup)
line.shutdown = function()
if stdin and stdin.is_active then stdin:close() end
if job and job.is_active then job:close() end
line.stdin = nil
line.job = nil
end
end


---@param opts tmux_config
M.setup = function(opts)
if not vim.env.TMUX then return end
opts = vim.tbl_deep_extend('force', default_config, opts or {})
tmux_state = opts
if #opts.statuslines == 0 then
return vim.notify('tmuxline: you need to input statuslines on setup')
end
M.stop()
local group = vim.api.nvim_create_augroup('WindlineTmuxLine', { clear = true })
vim.api.nvim_create_autocmd('FocusGained', {
group = group,
pattern = "*",
callback = function()
tmux_state.is_run = true
M.tmux_set()
end
})
vim.api.nvim_create_autocmd('FocusLost', {
group = group,
pattern = "*",
callback = function()
tmux_state.is_run = false
vim.schedule(M.tmux_restore)
end
})
vim.api.nvim_create_autocmd('VimLeavePre', {
group = group,
pattern = "*",
callback = vim.schedule_wrap(M.stop)
})
vim.api.nvim_create_autocmd(
tmux_state.autocmd,
{ group = group, pattern = '*', callback = M.update }
)
vim.api.nvim_create_autocmd('ColorScheme', {
group = group,
pattern = "*",
callback = function()
local colors = require('windline').get_colors()
for _, line in pairs(tmux_state.statuslines) do
if (line.component) then line.component:setup_hl(colors) end
if (line.active) then
for _, comp in pairs(line.active) do
comp:setup_hl(colors)
end
end
end
M.update()
end
})
local colors = require('windline').get_colors()
for _, line in pairs(tmux_state.statuslines) do
init_tmux(line, colors)
end
tmux_state.is_run = true
end

return M
Loading

0 comments on commit 53b4c92

Please sign in to comment.