Merge pull request refactor: components (#81)
* refactor: separate the child creation and initialization (#81) - includes modified class implementation from https://github.com/rxi/classic/blob/master/classic.lua - now base component class is created from classic. - change to how component classes are created. - Don't overwrite new method to initialize a component. Overwrite the init method. new is responsible for creating class object and calling init on it. Unlike previous new overwrite you don't need to create the class (table) and return it. Instead you will recive the object as self and do required manipulation on that just like any most other oop langs. Also don't need to return anything from init. init's job is to initialize. remember to call classes init before running your operations unfortunately lua isn't full fledged oop lang and I don't how to automate this. - changes how super classes are accesed. - rename Component._parent -> Component.super - methods on super classes now ran through super class instead of objects _parent self._parent as that can lead to recursive inf loop. See branch, diff, tabs, buffer classes call to init for example on pattern. - All components updated to reflect current logic - component loader updated to use new initialization procedure. - updated tests - updated BREAKING_CHANGES.md - plus quite a bit of formatting changes in the components - comp.method = function(self, ...) -> function M:method(...) BREAKING_CHANGE * enhance: allow components to be functions too (#81) Some components like hostname, progress are so simple that the component class setup is just unnecessary boilerplate. Allowing them to be function simplifies things. With this you can put your regular component functions in ~/.config/nvim/lua/lualine/components/ folder and treat then as regular lualine components just like 'mode' or 'branch'. Hopefully this will help lualine plugins grow. * refactor: allow components, extensions, themes to be multi file module (#81) utilize that to split tabs & buffers components into smaller files * refactor: rename component type luae and vimf - rename luae -> lua_expr - rename vimf -> vim_fun luae & vimf were too vague and hand to understand. BREAKING_CHANGE * chore: remove deprecation notices and deprecated options from #24 + fix tests * refactor: split diagnostics component (#81) * refactor: split branch component (#81) * refactor: split diff component (#81)
This commit is contained in:
commit
7d15304449
|
@ -61,3 +61,33 @@ See [#24](https://github.com/shadmansaleh/lualine.nvim/pull/24) for details
|
|||
modified, removed in diff_color table option
|
||||
- color_error, color_warning, color_info, color_hint are now available
|
||||
as error, warn, info, hint in diagnostics_color table option
|
||||
|
||||
### Component class refactor
|
||||
***Applicable only ones responsible for custom components***
|
||||
- Now call extend method on super class to create new type of component instead of calling new with empty args.
|
||||
- Don't overrite new method for initialization. Overrite init instead.
|
||||
- rename Component._parent -> Component.super
|
||||
- Call methods from super class directly on classes super not through
|
||||
objects super or self.super
|
||||
So basically if you had something like
|
||||
```lua
|
||||
local my_comp = require'lualine.component':new()
|
||||
function mycomp:new(options, child)
|
||||
local obj = self._parent:new(options, child or my_comp)
|
||||
obj.x = 1
|
||||
obj.y = 2
|
||||
return obj
|
||||
end
|
||||
```
|
||||
change it to
|
||||
```lua
|
||||
local my_comp = require('lualine.component'):extend()
|
||||
|
||||
function my_comp:init(options)
|
||||
-- Notice carefully it's not self.super.init nor my_comp.super:init
|
||||
my_comp.super.init(self, options)
|
||||
self.x = 1
|
||||
self.y = 2
|
||||
end
|
||||
```
|
||||
|
||||
|
|
|
@ -390,8 +390,8 @@ sections = {
|
|||
-- When type is omitted lualine will guess it.
|
||||
-- Available types [format: type_name(example)]
|
||||
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
||||
-- luae(lua expressions), vimf(viml function name)
|
||||
-- luae is short for lua-expression and vimf is short fror vim-function
|
||||
-- lua_expr(lua expressions), vim_fun(viml function name)
|
||||
-- lua_expr is short for lua-expression and vim_fun is short fror vim-function
|
||||
type = nil,
|
||||
padding = 1, -- adds padding to the left and right of components
|
||||
-- padding can be specified to left or right separately like
|
||||
|
|
|
@ -371,8 +371,8 @@ for all components.
|
|||
-- When type is omitted lualine will guess it.
|
||||
-- Available types [format: type_name(example)]
|
||||
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
||||
-- luae(lua expressions), vimf(viml function name)
|
||||
-- luae is short for lua-expression and vimf is short fror vim-function
|
||||
-- lua_expr(lua expressions), vim_fun(viml function name)
|
||||
-- lua_expr is short for lua-expression and vim_fun is short fror vim-function
|
||||
type = nil,
|
||||
padding = 1, -- adds padding to the left and right of components
|
||||
-- padding can be specified to left or right separately like
|
||||
|
|
|
@ -1,216 +1,180 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local highlight = require 'lualine.highlight'
|
||||
local M = require('lualine.utils.class'):extend()
|
||||
|
||||
-- Used to provide a unique id for each component
|
||||
local component_no = 1
|
||||
|
||||
local function check_deprecated_options(options)
|
||||
local function rename_notice(before, now)
|
||||
if options[before] then
|
||||
require('lualine.utils.notices').add_notice(string.format(
|
||||
[[
|
||||
### option.%s
|
||||
%s option has been renamed to `%s`. Please use `%s` instead in your config
|
||||
for %s component.
|
||||
]],
|
||||
before,
|
||||
before,
|
||||
now,
|
||||
now,
|
||||
options.component_name or 'function'
|
||||
))
|
||||
options[now] = options[before]
|
||||
options[before] = nil
|
||||
function M:__tostring()
|
||||
local str = 'Component: ' .. self.options.component_name
|
||||
if self.debug then
|
||||
str = str .. '\n---------------------\n' .. vim.inspect(self)
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
-- Initialize new component
|
||||
function M:init(options)
|
||||
self.options = options or {}
|
||||
component_no = component_no + 1
|
||||
if not options.component_name then
|
||||
self.options.component_name = tostring(component_no)
|
||||
end
|
||||
self.component_no = component_no
|
||||
self:set_separator()
|
||||
self:create_option_highlights()
|
||||
end
|
||||
|
||||
function M:set_separator()
|
||||
if self.options.separator == nil then
|
||||
if self.options.component_separators then
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
self.options.separator = self.options.component_separators.left
|
||||
else
|
||||
self.options.separator = self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
end
|
||||
rename_notice('format', 'fmt')
|
||||
rename_notice('condition', 'cond')
|
||||
end
|
||||
local Component = {
|
||||
-- Creates a new component
|
||||
new = function(self, options, child)
|
||||
local new_component = {}
|
||||
new_component.options = options
|
||||
new_component._parent = child or self
|
||||
setmetatable(new_component, { __index = new_component._parent })
|
||||
-- Operation that are required for creating new components but not for inheritence
|
||||
if options ~= nil then
|
||||
component_no = component_no + 1
|
||||
check_deprecated_options(new_component.options)
|
||||
if not options.component_name then
|
||||
new_component.options.component_name = tostring(component_no)
|
||||
|
||||
function M:create_option_highlights()
|
||||
-- set custom highlights
|
||||
if self.options.color then
|
||||
self.options.color_highlight = highlight.create_component_highlight_group(
|
||||
self.options.color,
|
||||
self.options.component_name,
|
||||
self.options
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
-- Adds spaces to left and right of a component
|
||||
function M:apply_padding()
|
||||
local padding = self.options.padding
|
||||
local l_padding, r_padding
|
||||
if padding == nil then
|
||||
padding = 1
|
||||
end
|
||||
if type(padding) == 'number' then
|
||||
l_padding, r_padding = padding, padding
|
||||
elseif type(padding) == 'table' then
|
||||
l_padding, r_padding = padding.left, padding.right
|
||||
end
|
||||
if l_padding then
|
||||
if self.status:find '%%#.*#' == 1 then
|
||||
-- When component has changed the highlight at begining
|
||||
-- we will add the padding after the highlight
|
||||
local pre_highlight = vim.fn.matchlist(self.status, [[\(%#.\{-\}#\)]])[2]
|
||||
self.status = pre_highlight .. string.rep(' ', l_padding) .. self.status:sub(#pre_highlight + 1, #self.status)
|
||||
else
|
||||
self.status = string.rep(' ', l_padding) .. self.status
|
||||
end
|
||||
end
|
||||
if r_padding then
|
||||
self.status = self.status .. string.rep(' ', r_padding)
|
||||
end
|
||||
end
|
||||
|
||||
-- Applies custom highlights for component
|
||||
function M:apply_highlights(default_highlight)
|
||||
if self.options.color_highlight then
|
||||
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
||||
end
|
||||
if type(self.options.separator) ~= 'table' and self.status:find '%%#' then
|
||||
-- Apply default highlight only when we aren't applying trans sep and
|
||||
-- the component has changed it's hl. since we won't be applying
|
||||
-- regular sep in those cases so ending with default hl isn't neccessay
|
||||
self.status = self.status .. default_highlight
|
||||
-- Also put it in applied sep so when sep get struped so does the hl
|
||||
self.applied_separator = default_highlight
|
||||
end
|
||||
-- Prepend default hl when the component doesn't start with hl otherwise
|
||||
-- color in previous component can cause side effect
|
||||
if not self.status:find '^%%#' then
|
||||
self.status = default_highlight .. self.status
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply icon in front of component
|
||||
function M:apply_icon()
|
||||
if self.options.icons_enabled and self.options.icon then
|
||||
self.status = self.options.icon .. ' ' .. self.status
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply separator at end of component only when
|
||||
-- custom highlights haven't affected background
|
||||
function M:apply_separator()
|
||||
local separator = self.options.separator
|
||||
if type(separator) == 'table' then
|
||||
if self.options.separator[2] == '' then
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
separator = self.options.component_separators.left
|
||||
else
|
||||
separator = self.options.component_separators.right
|
||||
end
|
||||
new_component.component_no = component_no
|
||||
new_component:set_separator()
|
||||
new_component:create_option_highlights()
|
||||
end
|
||||
return new_component
|
||||
end,
|
||||
|
||||
set_separator = function(self)
|
||||
if self.options.separator == nil then
|
||||
if self.options.component_separators then
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
self.options.separator = self.options.component_separators.left
|
||||
else
|
||||
self.options.separator = self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
create_option_highlights = function(self)
|
||||
-- set custom highlights
|
||||
if self.options.color then
|
||||
self.options.color_highlight = highlight.create_component_highlight_group(
|
||||
self.options.color,
|
||||
self.options.component_name,
|
||||
self.options
|
||||
)
|
||||
end
|
||||
end,
|
||||
|
||||
-- set upper or lower case
|
||||
apply_case = function(self)
|
||||
-- Donn't work on components that emit vim statusline escaped chars
|
||||
if self.status:find '%%' and not self.status:find '%%%%' then
|
||||
else
|
||||
return
|
||||
end
|
||||
if self.options.upper == true then
|
||||
self.status = self.status:upper()
|
||||
elseif self.options.lower == true then
|
||||
self.status = self.status:lower()
|
||||
end
|
||||
end,
|
||||
end
|
||||
if separator and #separator > 0 then
|
||||
self.status = self.status .. separator
|
||||
self.applied_separator = self.applied_separator .. separator
|
||||
end
|
||||
end
|
||||
|
||||
-- Adds spaces to left and right of a component
|
||||
apply_padding = function(self)
|
||||
local padding = self.options.padding
|
||||
local l_padding, r_padding
|
||||
if padding == nil then
|
||||
padding = 1
|
||||
end
|
||||
if type(padding) == 'number' then
|
||||
l_padding, r_padding = padding, padding
|
||||
elseif type(padding) == 'table' then
|
||||
l_padding, r_padding = padding.left, padding.right
|
||||
end
|
||||
if l_padding then
|
||||
if self.status:find '%%#.*#' == 1 then
|
||||
-- When component has changed the highlight at begining
|
||||
-- we will add the padding after the highlight
|
||||
local pre_highlight = vim.fn.matchlist(self.status, [[\(%#.\{-\}#\)]])[2]
|
||||
self.status = pre_highlight .. string.rep(' ', l_padding) .. self.status:sub(#pre_highlight + 1, #self.status)
|
||||
else
|
||||
self.status = string.rep(' ', l_padding) .. self.status
|
||||
end
|
||||
end
|
||||
if r_padding then
|
||||
self.status = self.status .. string.rep(' ', r_padding)
|
||||
end
|
||||
end,
|
||||
function M:apply_section_separators()
|
||||
if type(self.options.separator) ~= 'table' then
|
||||
return
|
||||
end
|
||||
if self.options.separator.left ~= nil and self.options.separator.left ~= '' then
|
||||
self.status = string.format('%%s{%s}%s', self.options.separator.left, self.status)
|
||||
self.strip_previous_separator = true
|
||||
end
|
||||
if self.options.separator.right ~= nil and self.options.separator.right ~= '' then
|
||||
self.status = string.format('%s%%S{%s}', self.status, self.options.separator.right)
|
||||
end
|
||||
end
|
||||
|
||||
-- Applies custom highlights for component
|
||||
apply_highlights = function(self, default_highlight)
|
||||
if self.options.color_highlight then
|
||||
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
||||
end
|
||||
if type(self.options.separator) ~= 'table' and self.status:find '%%#' then
|
||||
-- Apply default highlight only when we aren't applying trans sep and
|
||||
-- the component has changed it's hl. since we won't be applying
|
||||
-- regular sep in those cases so ending with default hl isn't neccessay
|
||||
self.status = self.status .. default_highlight
|
||||
-- Also put it in applied sep so when sep get struped so does the hl
|
||||
self.applied_separator = default_highlight
|
||||
end
|
||||
-- Prepend default hl when the component doesn't start with hl otherwise
|
||||
-- color in previous component can cause side effect
|
||||
if not self.status:find '^%%#' then
|
||||
self.status = default_highlight .. self.status
|
||||
end
|
||||
end,
|
||||
|
||||
-- Apply icon in front of component
|
||||
apply_icon = function(self)
|
||||
if self.options.icons_enabled and self.options.icon then
|
||||
self.status = self.options.icon .. ' ' .. self.status
|
||||
end
|
||||
end,
|
||||
|
||||
-- Apply separator at end of component only when
|
||||
-- custom highlights haven't affected background
|
||||
apply_separator = function(self)
|
||||
local separator = self.options.separator
|
||||
if type(separator) == 'table' then
|
||||
if self.options.separator[2] == '' then
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
separator = self.options.component_separators.left
|
||||
else
|
||||
separator = self.options.component_separators.right
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
end
|
||||
if separator and #separator > 0 then
|
||||
self.status = self.status .. separator
|
||||
self.applied_separator = self.applied_separator .. separator
|
||||
end
|
||||
end,
|
||||
|
||||
apply_section_separators = function(self)
|
||||
if type(self.options.separator) ~= 'table' then
|
||||
return
|
||||
end
|
||||
if self.options.separator.left ~= nil and self.options.separator.left ~= '' then
|
||||
self.status = string.format('%%s{%s}%s', self.options.separator.left, self.status)
|
||||
self.strip_previous_separator = true
|
||||
end
|
||||
if self.options.separator.right ~= nil and self.options.separator.right ~= '' then
|
||||
self.status = string.format('%s%%S{%s}', self.status, self.options.separator.right)
|
||||
end
|
||||
end,
|
||||
|
||||
strip_separator = function(self)
|
||||
if not self.applied_separator then
|
||||
self.applied_separator = ''
|
||||
end
|
||||
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
||||
self.applied_separator = nil
|
||||
return self.status
|
||||
end,
|
||||
|
||||
-- variable to store component output for manipulation
|
||||
status = '',
|
||||
-- Actual function that updates a component. Must be overwritten with component functionality
|
||||
-- luacheck: push no unused args
|
||||
update_status = function(self, is_focused) end,
|
||||
-- luacheck: pop
|
||||
|
||||
-- Driver code of the class
|
||||
draw = function(self, default_highlight, is_focused)
|
||||
self.status = ''
|
||||
function M:strip_separator()
|
||||
if not self.applied_separator then
|
||||
self.applied_separator = ''
|
||||
end
|
||||
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
||||
self.applied_separator = nil
|
||||
return self.status
|
||||
end
|
||||
|
||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||
return self.status
|
||||
end
|
||||
local status = self:update_status(is_focused)
|
||||
if self.options.fmt then
|
||||
status = self.options.fmt(status or '')
|
||||
end
|
||||
if type(status) == 'string' and #status > 0 then
|
||||
self.status = status
|
||||
self:apply_icon()
|
||||
self:apply_case()
|
||||
self:apply_padding()
|
||||
self:apply_highlights(default_highlight)
|
||||
self:apply_section_separators()
|
||||
self:apply_separator()
|
||||
end
|
||||
-- variable to store component output for manipulation
|
||||
M.status = ''
|
||||
-- Actual function that updates a component. Must be overwritten with component functionality
|
||||
-- luacheck: push no unused args
|
||||
function M:update_status(is_focused) end
|
||||
-- luacheck: pop
|
||||
|
||||
-- Driver code of the class
|
||||
function M:draw(default_highlight, is_focused)
|
||||
self.status = ''
|
||||
self.applied_separator = ''
|
||||
|
||||
if self.options.cond ~= nil and self.options.cond() ~= true then
|
||||
return self.status
|
||||
end,
|
||||
}
|
||||
end
|
||||
local status = self:update_status(is_focused)
|
||||
if self.options.fmt then
|
||||
status = self.options.fmt(status or '')
|
||||
end
|
||||
if type(status) == 'string' and #status > 0 then
|
||||
self.status = status
|
||||
self:apply_icon()
|
||||
self:apply_padding()
|
||||
self:apply_highlights(default_highlight)
|
||||
self:apply_section_separators()
|
||||
self:apply_separator()
|
||||
end
|
||||
return self.status
|
||||
end
|
||||
|
||||
return Component
|
||||
return M
|
||||
|
|
|
@ -1,51 +1,64 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Branch = require('lualine.component'):new()
|
||||
local modules = require('lualine_require').lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
local M = {}
|
||||
|
||||
local require = require('lualine_require').require
|
||||
local utils = require 'lualine.utils.utils'
|
||||
|
||||
-- vars
|
||||
Branch.git_branch = ''
|
||||
Branch.git_dir = ''
|
||||
local current_git_branch = ''
|
||||
local current_git_dir = ''
|
||||
local branch_cache = {} -- stores last known branch for a buffer
|
||||
local active_bufnr = '0'
|
||||
-- os specific path separator
|
||||
Branch.sep = package.config:sub(1, 1)
|
||||
local sep = package.config:sub(1, 1)
|
||||
-- event watcher to watch head file
|
||||
-- Use file wstch for non windows and poll for windows.
|
||||
-- windows doesn't like file watch for some reason.
|
||||
Branch.file_changed = Branch.sep ~= '\\' and vim.loop.new_fs_event() or vim.loop.new_fs_poll()
|
||||
Branch.active_bufnr = '0'
|
||||
local branch_cache = {} -- stores last known branch for a buffer
|
||||
-- Initilizer
|
||||
Branch.new = function(self, options, child)
|
||||
local new_branch = self._parent:new(options, child or Branch)
|
||||
if not new_branch.options.icon then
|
||||
new_branch.options.icon = '' -- e0a0
|
||||
end
|
||||
-- run watch head on load so branch is present when component is loaded
|
||||
Branch.find_git_dir()
|
||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||
modules.utils.define_autocmd('BufEnter', "lua require'lualine.components.branch'.find_git_dir()")
|
||||
return new_branch
|
||||
end
|
||||
|
||||
Branch.update_status = function(_, is_focused)
|
||||
if Branch.active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
Branch.find_git_dir()
|
||||
end
|
||||
if not is_focused then
|
||||
return branch_cache[vim.fn.bufnr()] or ''
|
||||
end
|
||||
return Branch.git_branch
|
||||
end
|
||||
|
||||
local file_changed = sep ~= '\\' and vim.loop.new_fs_event() or vim.loop.new_fs_poll()
|
||||
local git_dir_cache = {} -- Stores git paths that we already know of
|
||||
-- returns full path to git directory for current directory
|
||||
function Branch.find_git_dir()
|
||||
|
||||
-- sets git_branch veriable to branch name or commit hash if not on branch
|
||||
local function get_git_head(head_file)
|
||||
local f_head = io.open(head_file)
|
||||
if f_head then
|
||||
local HEAD = f_head:read()
|
||||
f_head:close()
|
||||
local branch = HEAD:match 'ref: refs/heads/(.+)$'
|
||||
if branch then
|
||||
current_git_branch = branch
|
||||
else
|
||||
current_git_branch = HEAD:sub(1, 6)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Update branch
|
||||
local function update_branch()
|
||||
active_bufnr = tostring(vim.fn.bufnr())
|
||||
file_changed:stop()
|
||||
local git_dir = current_git_dir
|
||||
if git_dir and #git_dir > 0 then
|
||||
local head_file = git_dir .. sep .. 'HEAD'
|
||||
get_git_head(head_file)
|
||||
file_changed:start(
|
||||
head_file,
|
||||
sep ~= '\\' and {} or 1000,
|
||||
vim.schedule_wrap(function()
|
||||
-- reset file-watch
|
||||
update_branch()
|
||||
end)
|
||||
)
|
||||
else
|
||||
-- set to '' when git dir was not found
|
||||
current_git_branch = ''
|
||||
end
|
||||
branch_cache[vim.fn.bufnr()] = current_git_branch
|
||||
end
|
||||
|
||||
-- returns full path to git directory for dir_path or current directory
|
||||
function M.find_git_dir(dir_path)
|
||||
-- get file dir so we can search from that dir
|
||||
local file_dir = vim.fn.expand '%:p:h'
|
||||
local file_dir = dir_path or vim.fn.expand '%:p:h'
|
||||
local root_dir = file_dir
|
||||
local git_dir
|
||||
-- Search upward for .git file or folder
|
||||
|
@ -54,7 +67,7 @@ function Branch.find_git_dir()
|
|||
git_dir = git_dir_cache[root_dir]
|
||||
break
|
||||
end
|
||||
local git_path = root_dir .. Branch.sep .. '.git'
|
||||
local git_path = root_dir .. sep .. '.git'
|
||||
local git_file_stat = vim.loop.fs_stat(git_path)
|
||||
if git_file_stat then
|
||||
if git_file_stat.type == 'directory' then
|
||||
|
@ -66,12 +79,12 @@ function Branch.find_git_dir()
|
|||
git_dir = git_dir:match 'gitdir: (.+)$'
|
||||
file:close()
|
||||
-- submodule / relative file path
|
||||
if git_dir and git_dir:sub(1, 1) ~= Branch.sep and not git_dir:match '^%a:.*$' then
|
||||
if git_dir and git_dir:sub(1, 1) ~= sep and not git_dir:match '^%a:.*$' then
|
||||
git_dir = git_path:match '(.*).git' .. git_dir
|
||||
end
|
||||
end
|
||||
if git_dir then
|
||||
local head_file_stat = vim.loop.fs_stat(git_dir .. Branch.sep .. 'HEAD')
|
||||
local head_file_stat = vim.loop.fs_stat(git_dir .. sep .. 'HEAD')
|
||||
if head_file_stat and head_file_stat.type == 'file' then
|
||||
break
|
||||
else
|
||||
|
@ -79,54 +92,34 @@ function Branch.find_git_dir()
|
|||
end
|
||||
end
|
||||
end
|
||||
root_dir = root_dir:match('(.*)' .. Branch.sep .. '.-')
|
||||
root_dir = root_dir:match('(.*)' .. sep .. '.-')
|
||||
end
|
||||
|
||||
git_dir_cache[file_dir] = git_dir
|
||||
if Branch.git_dir ~= git_dir then
|
||||
Branch.git_dir = git_dir
|
||||
Branch.update_branch()
|
||||
if dir_path == nil and current_git_dir ~= git_dir then
|
||||
current_git_dir = git_dir
|
||||
update_branch()
|
||||
end
|
||||
return git_dir
|
||||
end
|
||||
|
||||
-- sets git_branch veriable to branch name or commit hash if not on branch
|
||||
function Branch.get_git_head(head_file)
|
||||
local f_head = io.open(head_file)
|
||||
if f_head then
|
||||
local HEAD = f_head:read()
|
||||
f_head:close()
|
||||
local branch = HEAD:match 'ref: refs/heads/(.+)$'
|
||||
if branch then
|
||||
Branch.git_branch = branch
|
||||
else
|
||||
Branch.git_branch = HEAD:sub(1, 6)
|
||||
end
|
||||
function M.init()
|
||||
-- run watch head on load so branch is present when component is loaded
|
||||
M.find_git_dir()
|
||||
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||
utils.define_autocmd('BufEnter', "lua require'lualine.components.branch.git_branch'.find_git_dir()")
|
||||
end
|
||||
function M.get_branch(bufnr)
|
||||
if vim.g.actual_curbuf ~= nil and active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
M.find_git_dir()
|
||||
end
|
||||
return nil
|
||||
if bufnr then
|
||||
return branch_cache[bufnr] or ''
|
||||
end
|
||||
return current_git_branch
|
||||
end
|
||||
|
||||
-- Update branch
|
||||
function Branch.update_branch()
|
||||
Branch.active_bufnr = tostring(vim.fn.bufnr())
|
||||
Branch.file_changed:stop()
|
||||
local git_dir = Branch.git_dir
|
||||
if git_dir and #git_dir > 0 then
|
||||
local head_file = git_dir .. Branch.sep .. 'HEAD'
|
||||
Branch.get_git_head(head_file)
|
||||
Branch.file_changed:start(
|
||||
head_file,
|
||||
Branch.sep ~= '\\' and {} or 1000,
|
||||
vim.schedule_wrap(function()
|
||||
-- reset file-watch
|
||||
Branch.update_branch()
|
||||
end)
|
||||
)
|
||||
else
|
||||
-- set to '' when git dir was not found
|
||||
Branch.git_branch = ''
|
||||
end
|
||||
branch_cache[vim.fn.bufnr()] = Branch.git_branch
|
||||
end
|
||||
|
||||
return Branch
|
||||
return M
|
|
@ -0,0 +1,20 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
local require = require('lualine_require').require
|
||||
local git_branch = require 'lualine.components.branch.git_branch'
|
||||
|
||||
-- Initilizer
|
||||
M.init = function(self, options)
|
||||
M.super.init(self, options)
|
||||
if not self.options.icon then
|
||||
self.options.icon = '' -- e0a0
|
||||
end
|
||||
git_branch.init()
|
||||
end
|
||||
|
||||
M.update_status = function(_, is_focused)
|
||||
return git_branch.get_branch((not is_focused and vim.fn.bufnr()))
|
||||
end
|
||||
|
||||
return M
|
|
@ -1,270 +0,0 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Buffers = require('lualine.component'):new()
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local default_options = {
|
||||
show_filename_only = true,
|
||||
show_modified_status = true,
|
||||
max_length = 0,
|
||||
filetype_names = {
|
||||
TelescopePrompt = 'Telescope',
|
||||
dashboard = 'Dashboard',
|
||||
packer = 'Packer',
|
||||
fzf = 'FZF',
|
||||
alpha = 'Alpha',
|
||||
},
|
||||
buffers_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
}
|
||||
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and '_normal' or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
local Buffer = {}
|
||||
|
||||
function Buffer:new(buffer)
|
||||
assert(buffer.bufnr, 'Cannot create Buffer without bufnr')
|
||||
local newObj = { bufnr = buffer.bufnr, options = buffer.options, highlights = buffer.highlights }
|
||||
self.__index = self
|
||||
newObj = setmetatable(newObj, self)
|
||||
newObj:get_props()
|
||||
return newObj
|
||||
end
|
||||
|
||||
function Buffer:get_props()
|
||||
self.file = vim.fn.bufname(self.bufnr)
|
||||
self.buftype = vim.api.nvim_buf_get_option(self.bufnr, 'buftype')
|
||||
self.filetype = vim.api.nvim_buf_get_option(self.bufnr, 'filetype')
|
||||
local modified = self.options.show_modified_status and vim.api.nvim_buf_get_option(self.bufnr, 'modified')
|
||||
local modified_icon = self.options.icons_enabled and ' ●' or ' +'
|
||||
self.modified_icon = modified and modified_icon or ''
|
||||
self.icon = ''
|
||||
if self.options.icons_enabled then
|
||||
local dev
|
||||
local status, _ = pcall(require, 'nvim-web-devicons')
|
||||
if not status then
|
||||
dev, _ = '', ''
|
||||
elseif self.filetype == 'TelescopePrompt' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'telescope'
|
||||
elseif self.filetype == 'fugitive' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'git'
|
||||
elseif self.filetype == 'vimwiki' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'markdown'
|
||||
elseif self.buftype == 'terminal' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'zsh'
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
dev, _ = '', nil
|
||||
else
|
||||
dev, _ = require('nvim-web-devicons').get_icon(self.file, vim.fn.expand('#' .. self.bufnr .. ':e'))
|
||||
end
|
||||
if dev then
|
||||
self.icon = dev .. ' '
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Buffer:render()
|
||||
local name
|
||||
if self.ellipse then
|
||||
name = '...'
|
||||
else
|
||||
name = string.format(' %s%s%s ', self.icon, self:name(), self.modified_icon)
|
||||
end
|
||||
self.len = vim.fn.strchars(name)
|
||||
|
||||
local line = string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
||||
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
|
||||
|
||||
if self.options.self.section < 'lualine_x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
function Buffer:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%S{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
function Buffer:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%s{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
function Buffer:name()
|
||||
if self.options.filetype_names[self.filetype] then
|
||||
return self.options.filetype_names[self.filetype]
|
||||
elseif self.buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(self.file, ':t:r')
|
||||
elseif self.buftype == 'terminal' then
|
||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
return vim.fn.fnamemodify(self.file, ':p:.')
|
||||
elseif self.file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
return self.options.show_filename_only and vim.fn.fnamemodify(self.file, ':t')
|
||||
or vim.fn.pathshorten(vim.fn.fnamemodify(self.file, ':p:.'))
|
||||
end
|
||||
|
||||
function Buffers:new(options, child)
|
||||
local newObj = self._parent:new(options, child or Buffers)
|
||||
default_options.buffers_color = {
|
||||
active = get_hl(options.self.section, true),
|
||||
inactive = get_hl(options.self.section, false),
|
||||
}
|
||||
newObj.options = vim.tbl_deep_extend('keep', newObj.options or {}, default_options)
|
||||
newObj.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
newObj.options.buffers_color.active,
|
||||
'buffers_active',
|
||||
newObj.options
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
newObj.options.buffers_color.inactive,
|
||||
'buffers_active',
|
||||
newObj.options
|
||||
),
|
||||
}
|
||||
return newObj
|
||||
end
|
||||
|
||||
function Buffers:update_status()
|
||||
local data = {}
|
||||
local buffers = {}
|
||||
for b = 1, vim.fn.bufnr '$' do
|
||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
||||
buffers[#buffers + 1] = Buffer:new { bufnr = b, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
end
|
||||
local current_bufnr = vim.fn.bufnr()
|
||||
local current = -2
|
||||
if buffers[1] then
|
||||
buffers[1].first = true
|
||||
end
|
||||
if buffers[#buffers] then
|
||||
buffers[#buffers].last = true
|
||||
end
|
||||
for i, buffer in ipairs(buffers) do
|
||||
if buffer.bufnr == current_bufnr then
|
||||
buffer.current = true
|
||||
current = i
|
||||
end
|
||||
end
|
||||
if buffers[current - 1] then
|
||||
buffers[current - 1].beforecurrent = true
|
||||
end
|
||||
if buffers[current + 1] then
|
||||
buffers[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(2 * vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, buffer in pairs(buffers) do
|
||||
if buffer.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
if current == -2 then
|
||||
local b = Buffer:new { bufnr = vim.fn.bufnr(), options = self.options, highlights = self.highlights }
|
||||
b.current = true
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
b.last = true
|
||||
if #buffers > 0 then
|
||||
buffers[#buffers].last = nil
|
||||
end
|
||||
buffers[#buffers + 1] = b
|
||||
current = #buffers
|
||||
else
|
||||
b.first = true
|
||||
if #buffers > 0 then
|
||||
buffers[1].first = nil
|
||||
end
|
||||
table.insert(buffers, 1, b)
|
||||
current = 1
|
||||
end
|
||||
end
|
||||
local current_buffer = buffers[current]
|
||||
data[#data + 1] = current_buffer:render()
|
||||
total_length = current_buffer.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = buffers[current - i]
|
||||
after = buffers[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
end
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
end
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
if after then
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
vim.cmd [[
|
||||
function! LualineSwitchBuffer(bufnr, mouseclicks, mousebutton, modifiers)
|
||||
execute ":buffer " . a:bufnr
|
||||
endfunction
|
||||
]]
|
||||
|
||||
return Buffers
|
|
@ -0,0 +1,103 @@
|
|||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local Buffer = require('lualine.utils.class'):extend()
|
||||
|
||||
function Buffer:init(opts)
|
||||
assert(opts.bufnr, 'Cannot create Buffer without bufnr')
|
||||
self.bufnr = opts.bufnr
|
||||
self.options = opts.options
|
||||
self.highlights = opts.highlights
|
||||
self:get_props()
|
||||
end
|
||||
|
||||
function Buffer:get_props()
|
||||
self.file = vim.fn.bufname(self.bufnr)
|
||||
self.buftype = vim.api.nvim_buf_get_option(self.bufnr, 'buftype')
|
||||
self.filetype = vim.api.nvim_buf_get_option(self.bufnr, 'filetype')
|
||||
local modified = self.options.show_modified_status and vim.api.nvim_buf_get_option(self.bufnr, 'modified')
|
||||
local modified_icon = self.options.icons_enabled and ' ●' or ' +'
|
||||
self.modified_icon = modified and modified_icon or ''
|
||||
self.icon = ''
|
||||
if self.options.icons_enabled then
|
||||
local dev
|
||||
local status, _ = pcall(require, 'nvim-web-devicons')
|
||||
if not status then
|
||||
dev, _ = '', ''
|
||||
elseif self.filetype == 'TelescopePrompt' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'telescope'
|
||||
elseif self.filetype == 'fugitive' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'git'
|
||||
elseif self.filetype == 'vimwiki' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'markdown'
|
||||
elseif self.buftype == 'terminal' then
|
||||
dev, _ = require('nvim-web-devicons').get_icon 'zsh'
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
dev, _ = '', nil
|
||||
else
|
||||
dev, _ = require('nvim-web-devicons').get_icon(self.file, vim.fn.expand('#' .. self.bufnr .. ':e'))
|
||||
end
|
||||
if dev then
|
||||
self.icon = dev .. ' '
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Buffer:render()
|
||||
local name
|
||||
if self.ellipse then
|
||||
name = '...'
|
||||
else
|
||||
name = string.format(' %s%s%s ', self.icon, self:name(), self.modified_icon)
|
||||
end
|
||||
self.len = vim.fn.strchars(name)
|
||||
|
||||
local line = string.format('%%%s@LualineSwitchBuffer@%s%%T', self.bufnr, name)
|
||||
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
|
||||
|
||||
if self.options.self.section < 'lualine_x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
function Buffer:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%S{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
function Buffer:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%s{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
function Buffer:name()
|
||||
if self.options.filetype_names[self.filetype] then
|
||||
return self.options.filetype_names[self.filetype]
|
||||
elseif self.buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(self.file, ':t:r')
|
||||
elseif self.buftype == 'terminal' then
|
||||
local match = string.match(vim.split(self.file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif vim.fn.isdirectory(self.file) == 1 then
|
||||
return vim.fn.fnamemodify(self.file, ':p:.')
|
||||
elseif self.file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
return self.options.show_filename_only and vim.fn.fnamemodify(self.file, ':t')
|
||||
or vim.fn.pathshorten(vim.fn.fnamemodify(self.file, ':p:.'))
|
||||
end
|
||||
|
||||
return Buffer
|
|
@ -0,0 +1,170 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local Buffer = require 'lualine.components.buffers.buffer'
|
||||
local M = require('lualine.component'):extend()
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local default_options = {
|
||||
show_filename_only = true,
|
||||
show_modified_status = true,
|
||||
max_length = 0,
|
||||
filetype_names = {
|
||||
TelescopePrompt = 'Telescope',
|
||||
dashboard = 'Dashboard',
|
||||
packer = 'Packer',
|
||||
fzf = 'FZF',
|
||||
alpha = 'Alpha',
|
||||
},
|
||||
buffers_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
}
|
||||
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and '_normal' or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
default_options.buffers_color = {
|
||||
active = get_hl(options.self.section, true),
|
||||
inactive = get_hl(options.self.section, false),
|
||||
}
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
self.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.active,
|
||||
'buffers_active',
|
||||
self.options
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
self.options.buffers_color.inactive,
|
||||
'buffers_active',
|
||||
self.options
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local data = {}
|
||||
local buffers = {}
|
||||
for b = 1, vim.fn.bufnr '$' do
|
||||
if vim.fn.buflisted(b) ~= 0 and vim.api.nvim_buf_get_option(b, 'buftype') ~= 'quickfix' then
|
||||
buffers[#buffers + 1] = Buffer { bufnr = b, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
end
|
||||
local current_bufnr = vim.fn.bufnr()
|
||||
local current = -2
|
||||
if buffers[1] then
|
||||
buffers[1].first = true
|
||||
end
|
||||
if buffers[#buffers] then
|
||||
buffers[#buffers].last = true
|
||||
end
|
||||
for i, buffer in ipairs(buffers) do
|
||||
if buffer.bufnr == current_bufnr then
|
||||
buffer.current = true
|
||||
current = i
|
||||
end
|
||||
end
|
||||
if buffers[current - 1] then
|
||||
buffers[current - 1].beforecurrent = true
|
||||
end
|
||||
if buffers[current + 1] then
|
||||
buffers[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(2 * vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, buffer in pairs(buffers) do
|
||||
if buffer.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
if current == -2 then
|
||||
local b = Buffer { bufnr = vim.fn.bufnr(), options = self.options, highlights = self.highlights }
|
||||
b.current = true
|
||||
if self.options.self.section < 'lualine_x' then
|
||||
b.last = true
|
||||
if #buffers > 0 then
|
||||
buffers[#buffers].last = nil
|
||||
end
|
||||
buffers[#buffers + 1] = b
|
||||
current = #buffers
|
||||
else
|
||||
b.first = true
|
||||
if #buffers > 0 then
|
||||
buffers[1].first = nil
|
||||
end
|
||||
table.insert(buffers, 1, b)
|
||||
current = 1
|
||||
end
|
||||
end
|
||||
local current_buffer = buffers[current]
|
||||
data[#data + 1] = current_buffer:render()
|
||||
total_length = current_buffer.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = buffers[current - i]
|
||||
after = buffers[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
end
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
end
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
if after then
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
vim.cmd [[
|
||||
function! LualineSwitchBuffer(bufnr, mouseclicks, mousebutton, modifiers)
|
||||
execute ":buffer " . a:bufnr
|
||||
endfunction
|
||||
]]
|
||||
|
||||
return M
|
|
@ -1,248 +0,0 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require 'lualine_require'
|
||||
local modules = lualine_require.lazy_require {
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
}
|
||||
|
||||
local Diagnostics = lualine_require.require('lualine.component'):new()
|
||||
|
||||
local function check_deprecated_options(options)
|
||||
if options.color_error or options.color_warn or options.color_info or options.color_hint then
|
||||
options.diagnostics_color = options.diagnostics_color or {}
|
||||
require('lualine.utils.notices').add_notice(string.format [[
|
||||
### diagnostics.options.colors
|
||||
Previously colors in diagnostics section was set with color_error, color_warning..
|
||||
separate options . They've been unified under diagnostics_color options.
|
||||
Now it should be something like:
|
||||
```lua
|
||||
{ 'diagnostics',
|
||||
sources = {'nvim_lsp'},
|
||||
diagnostics_color = {
|
||||
error = color_error,
|
||||
warning = color_warning,
|
||||
info = color_info,
|
||||
hint = color_hint,
|
||||
}
|
||||
}
|
||||
```
|
||||
]])
|
||||
options.diagnostics_color.error = options.color_error
|
||||
options.diagnostics_color.warning = options.color_warning
|
||||
options.diagnostics_color.info = options.color_info
|
||||
options.diagnostics_color.hint = options.color_hint
|
||||
end
|
||||
end
|
||||
|
||||
local default_symbols = {
|
||||
icons = {
|
||||
error = ' ', -- xf659
|
||||
warn = ' ', -- xf529
|
||||
info = ' ', -- xf7fc
|
||||
hint = ' ', -- xf838
|
||||
},
|
||||
no_icons = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' },
|
||||
}
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
update_in_insert = false,
|
||||
sources = { 'nvim_lsp', 'coc' },
|
||||
sections = { 'error', 'warn', 'info', 'hint' },
|
||||
diagnostics_color = {
|
||||
error = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticError', 'LspDiagnosticsDefaultError', 'DiffDelete' },
|
||||
'#e32636'
|
||||
),
|
||||
},
|
||||
warn = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticWarn', 'LspDiagnosticsDefaultWarning', 'DiffText' },
|
||||
'#ffa500'
|
||||
),
|
||||
},
|
||||
info = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticInfo', 'LspDiagnosticsDefaultInformation', 'Normal' },
|
||||
'#ffffff'
|
||||
),
|
||||
},
|
||||
hint = {
|
||||
fg = modules.utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticHint', 'LspDiagnosticsDefaultHint', 'DiffChange' },
|
||||
'#273faf'
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
-- Initializer
|
||||
Diagnostics.new = function(self, options, child)
|
||||
-- Run super()
|
||||
local new_diagnostics = self._parent:new(options, child or Diagnostics)
|
||||
-- Apply default options
|
||||
new_diagnostics.options = vim.tbl_deep_extend('keep', new_diagnostics.options or {}, default_options)
|
||||
check_deprecated_options(new_diagnostics.options)
|
||||
-- Apply default symbols
|
||||
new_diagnostics.symbols = vim.tbl_extend(
|
||||
'keep',
|
||||
new_diagnostics.options.symbols or {},
|
||||
new_diagnostics.options.icons_enabled ~= false and default_symbols.icons or default_symbols.no_icons
|
||||
)
|
||||
-- Initialize highlight groups
|
||||
if new_diagnostics.options.colored then
|
||||
new_diagnostics.highlight_groups = {
|
||||
error = modules.highlight.create_component_highlight_group(
|
||||
new_diagnostics.options.diagnostics_color.error,
|
||||
'diagnostics_error',
|
||||
new_diagnostics.options
|
||||
),
|
||||
warn = modules.highlight.create_component_highlight_group(
|
||||
new_diagnostics.options.diagnostics_color.warn,
|
||||
'diagnostics_warn',
|
||||
new_diagnostics.options
|
||||
),
|
||||
info = modules.highlight.create_component_highlight_group(
|
||||
new_diagnostics.options.diagnostics_color.info,
|
||||
'diagnostics_info',
|
||||
new_diagnostics.options
|
||||
),
|
||||
hint = modules.highlight.create_component_highlight_group(
|
||||
new_diagnostics.options.diagnostics_color.hint,
|
||||
'diagnostics_hint',
|
||||
new_diagnostics.options
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
-- Error out no source
|
||||
if #new_diagnostics.options.sources < 1 then
|
||||
print 'no sources for diagnostics configured'
|
||||
return ''
|
||||
end
|
||||
-- Initialize variable to store last update so we can use it in insert
|
||||
-- mode for no update_in_insert
|
||||
new_diagnostics.last_update = ''
|
||||
return new_diagnostics
|
||||
end
|
||||
|
||||
Diagnostics.update_status = function(self)
|
||||
if not self.options.update_in_insert and vim.api.nvim_get_mode().mode:sub(1, 1) == 'i' then
|
||||
return self.last_update
|
||||
end
|
||||
local error_count, warning_count, info_count, hint_count = 0, 0, 0, 0
|
||||
local diagnostic_data = self.get_diagnostics(self.options.sources)
|
||||
for _, data in pairs(diagnostic_data) do
|
||||
error_count = error_count + data.error
|
||||
warning_count = warning_count + data.warn
|
||||
info_count = info_count + data.info
|
||||
hint_count = hint_count + data.hint
|
||||
end
|
||||
local result = {}
|
||||
local data = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
if self.options.colored then
|
||||
local colors = {}
|
||||
for name, hl in pairs(self.highlight_groups) do
|
||||
colors[name] = modules.highlight.component_format_highlight(hl)
|
||||
end
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, colors[section] .. self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
self.last_update = ''
|
||||
if result[1] ~= nil then
|
||||
self.last_update = table.concat(result, ' ')
|
||||
end
|
||||
return self.last_update
|
||||
end
|
||||
|
||||
Diagnostics.diagnostic_sources = {
|
||||
nvim_lsp = function()
|
||||
local error_count = vim.lsp.diagnostic.get_count(0, 'Error')
|
||||
local warning_count = vim.lsp.diagnostic.get_count(0, 'Warning')
|
||||
local info_count = vim.lsp.diagnostic.get_count(0, 'Information')
|
||||
local hint_count = vim.lsp.diagnostic.get_count(0, 'Hint')
|
||||
return error_count, warning_count, info_count, hint_count
|
||||
end,
|
||||
nvim = function()
|
||||
local diagnostics = vim.diagnostic.get(0)
|
||||
local count = { 0, 0, 0, 0 }
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
count[diagnostic.severity] = count[diagnostic.severity] + 1
|
||||
end
|
||||
return count[vim.diagnostic.severity.ERROR],
|
||||
count[vim.diagnostic.severity.WARN],
|
||||
count[vim.diagnostic.severity.INFO],
|
||||
count[vim.diagnostic.severity.HINT]
|
||||
end,
|
||||
coc = function()
|
||||
local data = vim.b.coc_diagnostic_info
|
||||
if data then
|
||||
return data.error, data.warning, data.information, data.hint
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
ale = function()
|
||||
local ok, data = pcall(vim.fn['ale#statusline#Count'], vim.fn.bufnr())
|
||||
if ok then
|
||||
return data.error + data.style_error, data.warning + data.style_warning, data.info, 0
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
vim_lsp = function()
|
||||
local ok, data = pcall(vim.fn['lsp#get_buffer_diagnostics_counts'])
|
||||
if ok then
|
||||
return data.error, data.warning, data.information
|
||||
else
|
||||
return 0, 0, 0
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
Diagnostics.get_diagnostics = function(sources)
|
||||
local result = {}
|
||||
for index, source in ipairs(sources) do
|
||||
if type(source) == 'string' then
|
||||
local error_count, warning_count, info_count, hint_count = Diagnostics.diagnostic_sources[source]()
|
||||
result[index] = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
elseif type(source) == 'function' then
|
||||
local source_result = source()
|
||||
source_result = type(source_result) == 'table' and source_result or {}
|
||||
result[index] = {
|
||||
error = source_result.error or 0,
|
||||
warn = source_result.warn or 0,
|
||||
info = source_result.info or 0,
|
||||
hint = source_result.hint or 0,
|
||||
}
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return Diagnostics
|
|
@ -0,0 +1,52 @@
|
|||
local require = require('lualine_require').require
|
||||
local utils = require 'lualine.utils.utils'
|
||||
local M = {}
|
||||
|
||||
M.symbols = {
|
||||
icons = {
|
||||
error = ' ', -- xf659
|
||||
warn = ' ', -- xf529
|
||||
info = ' ', -- xf7fc
|
||||
hint = ' ', -- xf838
|
||||
},
|
||||
no_icons = { error = 'E:', warn = 'W:', info = 'I:', hint = 'H:' },
|
||||
}
|
||||
|
||||
M.options = {
|
||||
colored = true,
|
||||
update_in_insert = false,
|
||||
sources = { 'nvim_lsp', 'coc' },
|
||||
sections = { 'error', 'warn', 'info', 'hint' },
|
||||
diagnostics_color = {
|
||||
error = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticError', 'LspDiagnosticsDefaultError', 'DiffDelete' },
|
||||
'#e32636'
|
||||
),
|
||||
},
|
||||
warn = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticWarn', 'LspDiagnosticsDefaultWarning', 'DiffText' },
|
||||
'#ffa500'
|
||||
),
|
||||
},
|
||||
info = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticInfo', 'LspDiagnosticsDefaultInformation', 'Normal' },
|
||||
'#ffffff'
|
||||
),
|
||||
},
|
||||
hint = {
|
||||
fg = utils.extract_color_from_hllist(
|
||||
'fg',
|
||||
{ 'DiagnosticHint', 'LspDiagnosticsDefaultHint', 'DiffChange' },
|
||||
'#273faf'
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return M
|
|
@ -0,0 +1,109 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require 'lualine_require'
|
||||
local modules = lualine_require.lazy_require {
|
||||
default_config = 'lualine.components.diagnostics.config',
|
||||
sources = 'lualine.components.diagnostics.sources',
|
||||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
}
|
||||
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
M.diagnostics_sources = modules.sources.sources
|
||||
M.get_diagnostics = modules.sources.get_diagnostics
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
-- Run super()
|
||||
M.super.init(self, options)
|
||||
-- Apply default options
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, modules.default_config.options)
|
||||
-- Apply default symbols
|
||||
self.symbols = vim.tbl_extend(
|
||||
'keep',
|
||||
self.options.symbols or {},
|
||||
self.options.icons_enabled ~= false and modules.default_config.symbols.icons
|
||||
or modules.default_config.symbols.no_icons
|
||||
)
|
||||
-- Initialize highlight groups
|
||||
if self.options.colored then
|
||||
self.highlight_groups = {
|
||||
error = modules.highlight.create_component_highlight_group(
|
||||
self.options.diagnostics_color.error,
|
||||
'diagnostics_error',
|
||||
self.options
|
||||
),
|
||||
warn = modules.highlight.create_component_highlight_group(
|
||||
self.options.diagnostics_color.warn,
|
||||
'diagnostics_warn',
|
||||
self.options
|
||||
),
|
||||
info = modules.highlight.create_component_highlight_group(
|
||||
self.options.diagnostics_color.info,
|
||||
'diagnostics_info',
|
||||
self.options
|
||||
),
|
||||
hint = modules.highlight.create_component_highlight_group(
|
||||
self.options.diagnostics_color.hint,
|
||||
'diagnostics_hint',
|
||||
self.options
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
-- Error out no source
|
||||
if #self.options.sources < 1 then
|
||||
print 'no sources for diagnostics configured'
|
||||
return ''
|
||||
end
|
||||
-- Initialize variable to store last update so we can use it in insert
|
||||
-- mode for no update_in_insert
|
||||
self.last_update = ''
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
if not self.options.update_in_insert and vim.api.nvim_get_mode().mode:sub(1, 1) == 'i' then
|
||||
return self.last_update
|
||||
end
|
||||
local error_count, warning_count, info_count, hint_count = 0, 0, 0, 0
|
||||
local diagnostic_data = modules.sources.get_diagnostics(self.options.sources)
|
||||
for _, data in pairs(diagnostic_data) do
|
||||
error_count = error_count + data.error
|
||||
warning_count = warning_count + data.warn
|
||||
info_count = info_count + data.info
|
||||
hint_count = hint_count + data.hint
|
||||
end
|
||||
local result = {}
|
||||
local data = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
if self.options.colored then
|
||||
local colors = {}
|
||||
for name, hl in pairs(self.highlight_groups) do
|
||||
colors[name] = modules.highlight.component_format_highlight(hl)
|
||||
end
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, colors[section] .. self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, section in ipairs(self.options.sections) do
|
||||
if data[section] ~= nil and data[section] > 0 then
|
||||
table.insert(result, self.symbols[section] .. data[section])
|
||||
end
|
||||
end
|
||||
end
|
||||
self.last_update = ''
|
||||
if result[1] ~= nil then
|
||||
self.last_update = table.concat(result, ' ')
|
||||
end
|
||||
return self.last_update
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,73 @@
|
|||
local M = {}
|
||||
|
||||
M.sources = {
|
||||
nvim_lsp = function()
|
||||
local error_count = vim.lsp.diagnostic.get_count(0, 'Error')
|
||||
local warning_count = vim.lsp.diagnostic.get_count(0, 'Warning')
|
||||
local info_count = vim.lsp.diagnostic.get_count(0, 'Information')
|
||||
local hint_count = vim.lsp.diagnostic.get_count(0, 'Hint')
|
||||
return error_count, warning_count, info_count, hint_count
|
||||
end,
|
||||
nvim = function()
|
||||
local diagnostics = vim.diagnostic.get(0)
|
||||
local count = { 0, 0, 0, 0 }
|
||||
for _, diagnostic in ipairs(diagnostics) do
|
||||
count[diagnostic.severity] = count[diagnostic.severity] + 1
|
||||
end
|
||||
return count[vim.diagnostic.severity.ERROR],
|
||||
count[vim.diagnostic.severity.WARN],
|
||||
count[vim.diagnostic.severity.INFO],
|
||||
count[vim.diagnostic.severity.HINT]
|
||||
end,
|
||||
coc = function()
|
||||
local data = vim.b.coc_diagnostic_info
|
||||
if data then
|
||||
return data.error, data.warning, data.information, data.hint
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
ale = function()
|
||||
local ok, data = pcall(vim.fn['ale#statusline#Count'], vim.fn.bufnr())
|
||||
if ok then
|
||||
return data.error + data.style_error, data.warning + data.style_warning, data.info, 0
|
||||
else
|
||||
return 0, 0, 0, 0
|
||||
end
|
||||
end,
|
||||
vim_lsp = function()
|
||||
local ok, data = pcall(vim.fn['lsp#get_buffer_diagnostics_counts'])
|
||||
if ok then
|
||||
return data.error, data.warning, data.information
|
||||
else
|
||||
return 0, 0, 0
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
M.get_diagnostics = function(sources)
|
||||
local result = {}
|
||||
for index, source in ipairs(sources) do
|
||||
if type(source) == 'string' then
|
||||
local error_count, warning_count, info_count, hint_count = M.sources[source]()
|
||||
result[index] = {
|
||||
error = error_count,
|
||||
warn = warning_count,
|
||||
info = info_count,
|
||||
hint = hint_count,
|
||||
}
|
||||
elseif type(source) == 'function' then
|
||||
local source_result = source()
|
||||
source_result = type(source_result) == 'table' and source_result or {}
|
||||
result[index] = {
|
||||
error = source_result.error or 0,
|
||||
warn = source_result.warn or 0,
|
||||
info = source_result.info or 0,
|
||||
hint = source_result.hint or 0,
|
||||
}
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
return M
|
|
@ -1,244 +0,0 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require 'lualine_require'
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
highlight = 'lualine.highlight',
|
||||
Job = 'lualine.utils.job',
|
||||
}
|
||||
local Diff = lualine_require.require('lualine.component'):new()
|
||||
|
||||
local function check_deprecated_options(options)
|
||||
if options.color_added or options.color_modified or options.color_removed then
|
||||
options.diagnostics_color = options.diagnostics_color or {}
|
||||
require('lualine.utils.notices').add_notice(string.format [[
|
||||
### diff.options.colors
|
||||
Previously colors in diff section was set with color_added, color_modified..
|
||||
separate options . They've been unified under diff_color option.
|
||||
Now it should be something like:
|
||||
```lua
|
||||
{ 'diff',
|
||||
diff_color = {
|
||||
added = color_added,
|
||||
modified = color_modified,
|
||||
removed = color_removed,
|
||||
}
|
||||
}
|
||||
```
|
||||
]])
|
||||
options.diff_color.added = options.color_added
|
||||
options.diff_color.modified = options.color_modified
|
||||
options.diff_color.removed = options.color_removed
|
||||
end
|
||||
end
|
||||
|
||||
-- Vars
|
||||
-- variable to store git diff stats
|
||||
Diff.git_diff = nil
|
||||
-- accumulates output from diff process
|
||||
Diff.diff_output_cache = {}
|
||||
-- variable to store git_diff job
|
||||
Diff.diff_job = nil
|
||||
Diff.active_bufnr = '0'
|
||||
|
||||
local diff_cache = {} -- Stores last known value of diff of a buffer
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
symbols = { added = '+', modified = '~', removed = '-' },
|
||||
diff_color = {
|
||||
added = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffAdd', 'fg') or '#f0e130',
|
||||
},
|
||||
modified = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffChange', 'fg') or '#ff0038',
|
||||
},
|
||||
removed = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffDelete', 'fg') or '#ff0038',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
Diff.new = function(self, options, child)
|
||||
local new_instance = self._parent:new(options, child or Diff)
|
||||
new_instance.options = vim.tbl_deep_extend('keep', new_instance.options or {}, default_options)
|
||||
check_deprecated_options(new_instance.options)
|
||||
-- create highlights and save highlight_name in highlights table
|
||||
if new_instance.options.colored then
|
||||
new_instance.highlights = {
|
||||
added = modules.highlight.create_component_highlight_group(
|
||||
new_instance.options.diff_color.added,
|
||||
'diff_added',
|
||||
new_instance.options
|
||||
),
|
||||
modified = modules.highlight.create_component_highlight_group(
|
||||
new_instance.options.diff_color.modified,
|
||||
'diff_modified',
|
||||
new_instance.options
|
||||
),
|
||||
removed = modules.highlight.create_component_highlight_group(
|
||||
new_instance.options.diff_color.removed,
|
||||
'diff_removed',
|
||||
new_instance.options
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
Diff.diff_checker_enabled = type(new_instance.options.source) ~= 'function'
|
||||
|
||||
if Diff.diff_checker_enabled then
|
||||
-- setup internal source
|
||||
modules.utils.define_autocmd('BufEnter', "lua require'lualine.components.diff'.update_diff_args()")
|
||||
modules.utils.define_autocmd('BufWritePost', "lua require'lualine.components.diff'.update_git_diff()")
|
||||
Diff.update_diff_args()
|
||||
end
|
||||
|
||||
return new_instance
|
||||
end
|
||||
|
||||
-- Function that runs everytime statusline is updated
|
||||
Diff.update_status = function(self, is_focused)
|
||||
local git_diff
|
||||
if Diff.diff_checker_enabled then
|
||||
if Diff.active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
Diff.update_diff_args()
|
||||
end
|
||||
git_diff = Diff.git_diff
|
||||
else
|
||||
git_diff = self.options.source()
|
||||
end
|
||||
|
||||
if not is_focused then
|
||||
git_diff = diff_cache[vim.fn.bufnr()] or {}
|
||||
end
|
||||
if git_diff == nil then
|
||||
return ''
|
||||
end
|
||||
|
||||
local colors = {}
|
||||
if self.options.colored then
|
||||
-- load the highlights and store them in colors table
|
||||
for name, highlight_name in pairs(self.highlights) do
|
||||
colors[name] = modules.highlight.component_format_highlight(highlight_name)
|
||||
end
|
||||
end
|
||||
|
||||
local result = {}
|
||||
-- loop though data and load available sections in result table
|
||||
for _, name in ipairs { 'added', 'modified', 'removed' } do
|
||||
if git_diff[name] and git_diff[name] > 0 then
|
||||
if self.options.colored then
|
||||
table.insert(result, colors[name] .. self.options.symbols[name] .. git_diff[name])
|
||||
else
|
||||
table.insert(result, self.options.symbols[name] .. git_diff[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
-- Api to get git sign count
|
||||
-- scheme :
|
||||
-- {
|
||||
-- added = added_count,
|
||||
-- modified = modified_count,
|
||||
-- removed = removed_count,
|
||||
-- }
|
||||
-- error_code = { added = -1, modified = -1, removed = -1 }
|
||||
function Diff.get_sign_count()
|
||||
if Diff.diff_checker_enabled then
|
||||
Diff.update_diff_args()
|
||||
end
|
||||
return Diff.git_diff or { added = -1, modified = -1, removed = -1 }
|
||||
end
|
||||
|
||||
-- process diff data and update git_diff{ added, removed, modified }
|
||||
function Diff.process_diff(data)
|
||||
-- Adapted from https://github.com/wbthomason/nvim-vcs.lua
|
||||
local added, removed, modified = 0, 0, 0
|
||||
for _, line in ipairs(data) do
|
||||
if string.find(line, [[^@@ ]]) then
|
||||
local tokens = vim.fn.matchlist(line, [[^@@ -\v(\d+),?(\d*) \+(\d+),?(\d*)]])
|
||||
local line_stats = {
|
||||
mod_count = tokens[3] == nil and 0 or tokens[3] == '' and 1 or tonumber(tokens[3]),
|
||||
new_count = tokens[5] == nil and 0 or tokens[5] == '' and 1 or tonumber(tokens[5]),
|
||||
}
|
||||
|
||||
if line_stats.mod_count == 0 and line_stats.new_count > 0 then
|
||||
added = added + line_stats.new_count
|
||||
elseif line_stats.mod_count > 0 and line_stats.new_count == 0 then
|
||||
removed = removed + line_stats.mod_count
|
||||
else
|
||||
local min = math.min(line_stats.mod_count, line_stats.new_count)
|
||||
modified = modified + min
|
||||
added = added + line_stats.new_count - min
|
||||
removed = removed + line_stats.mod_count - min
|
||||
end
|
||||
end
|
||||
end
|
||||
Diff.git_diff = { added = added, modified = modified, removed = removed }
|
||||
end
|
||||
|
||||
-- Updates the job args
|
||||
function Diff.update_diff_args()
|
||||
-- Donn't show git diff when current buffer doesn't have a filename
|
||||
Diff.active_bufnr = tostring(vim.fn.bufnr())
|
||||
if #vim.fn.expand '%' == 0 then
|
||||
Diff.diff_args = nil
|
||||
Diff.git_diff = nil
|
||||
return
|
||||
end
|
||||
Diff.diff_args = {
|
||||
cmd = string.format(
|
||||
[[git -C %s --no-pager diff --no-color --no-ext-diff -U0 -- %s]],
|
||||
vim.fn.expand '%:h',
|
||||
vim.fn.expand '%:t'
|
||||
),
|
||||
on_stdout = function(_, data)
|
||||
if next(data) then
|
||||
Diff.diff_output_cache = vim.list_extend(Diff.diff_output_cache, data)
|
||||
end
|
||||
end,
|
||||
on_stderr = function(_, data)
|
||||
data = table.concat(data, '\n')
|
||||
if #data > 1 or (#data == 1 and #data[1] > 0) then
|
||||
Diff.git_diff = nil
|
||||
Diff.diff_output_cache = {}
|
||||
end
|
||||
end,
|
||||
on_exit = function()
|
||||
if #Diff.diff_output_cache > 0 then
|
||||
Diff.process_diff(Diff.diff_output_cache)
|
||||
else
|
||||
Diff.git_diff = { added = 0, modified = 0, removed = 0 }
|
||||
end
|
||||
diff_cache[vim.fn.bufnr()] = Diff.git_diff
|
||||
end,
|
||||
}
|
||||
Diff.update_git_diff()
|
||||
end
|
||||
|
||||
-- Update git_diff veriable
|
||||
function Diff.update_git_diff()
|
||||
if Diff.diff_args then
|
||||
Diff.diff_output_cache = {}
|
||||
if Diff.diff_job then
|
||||
Diff.diff_job:stop()
|
||||
end
|
||||
Diff.diff_job = modules.Job(Diff.diff_args)
|
||||
if Diff.diff_job then
|
||||
Diff.diff_job:start()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Diff
|
|
@ -0,0 +1,135 @@
|
|||
local lualine_require = require 'lualine_require'
|
||||
local modules = lualine_require.lazy_require {
|
||||
utils = 'lualine.utils.utils',
|
||||
Job = 'lualine.utils.job',
|
||||
}
|
||||
|
||||
local M = {}
|
||||
|
||||
-- Vars
|
||||
-- variable to store git diff stats
|
||||
local git_diff = nil
|
||||
-- accumulates output from diff process
|
||||
local diff_output_cache = {}
|
||||
-- variable to store git_diff job
|
||||
local diff_job = nil
|
||||
|
||||
local active_bufnr = '0'
|
||||
local diff_cache = {} -- Stores last known value of diff of a buffer
|
||||
|
||||
-- initialize the module
|
||||
function M.init(opts)
|
||||
if type(opts.source) == 'function' then
|
||||
M.src = opts.source
|
||||
else
|
||||
modules.utils.define_autocmd('BufEnter', "lua require'lualine.components.diff.git_diff'.update_diff_args()")
|
||||
modules.utils.define_autocmd('BufWritePost', "lua require'lualine.components.diff.git_diff'.update_git_diff()")
|
||||
M.update_diff_args()
|
||||
end
|
||||
end
|
||||
|
||||
-- Api to get git sign count
|
||||
-- scheme :
|
||||
-- {
|
||||
-- added = added_count,
|
||||
-- modified = modified_count,
|
||||
-- removed = removed_count,
|
||||
-- }
|
||||
-- error_code = { added = -1, modified = -1, removed = -1 }
|
||||
function M.get_sign_count(bufnr)
|
||||
if bufnr then
|
||||
return diff_cache[bufnr]
|
||||
end
|
||||
if M.src then
|
||||
git_diff = M.src()
|
||||
diff_cache[vim.fn.bufnr()] = git_diff
|
||||
elseif vim.g.actual_curbuf ~= nil and active_bufnr ~= vim.g.actual_curbuf then
|
||||
-- Workaround for https://github.com/hoob3rt/lualine.nvim/issues/286
|
||||
-- See upstream issue https://github.com/neovim/neovim/issues/15300
|
||||
-- Diff is out of sync re sync it.
|
||||
M.update_diff_args()
|
||||
end
|
||||
return git_diff
|
||||
end
|
||||
|
||||
-- process diff data and update git_diff{ added, removed, modified }
|
||||
local function process_diff(data)
|
||||
-- Adapted from https://github.com/wbthomason/nvim-vcs.lua
|
||||
local added, removed, modified = 0, 0, 0
|
||||
for _, line in ipairs(data) do
|
||||
if string.find(line, [[^@@ ]]) then
|
||||
local tokens = vim.fn.matchlist(line, [[^@@ -\v(\d+),?(\d*) \+(\d+),?(\d*)]])
|
||||
local line_stats = {
|
||||
mod_count = tokens[3] == nil and 0 or tokens[3] == '' and 1 or tonumber(tokens[3]),
|
||||
new_count = tokens[5] == nil and 0 or tokens[5] == '' and 1 or tonumber(tokens[5]),
|
||||
}
|
||||
|
||||
if line_stats.mod_count == 0 and line_stats.new_count > 0 then
|
||||
added = added + line_stats.new_count
|
||||
elseif line_stats.mod_count > 0 and line_stats.new_count == 0 then
|
||||
removed = removed + line_stats.mod_count
|
||||
else
|
||||
local min = math.min(line_stats.mod_count, line_stats.new_count)
|
||||
modified = modified + min
|
||||
added = added + line_stats.new_count - min
|
||||
removed = removed + line_stats.mod_count - min
|
||||
end
|
||||
end
|
||||
end
|
||||
git_diff = { added = added, modified = modified, removed = removed }
|
||||
end
|
||||
|
||||
-- Updates the job args
|
||||
function M.update_diff_args()
|
||||
-- Donn't show git diff when current buffer doesn't have a filename
|
||||
active_bufnr = tostring(vim.fn.bufnr())
|
||||
if #vim.fn.expand '%' == 0 then
|
||||
M.diff_args = nil
|
||||
git_diff = nil
|
||||
return
|
||||
end
|
||||
M.diff_args = {
|
||||
cmd = string.format(
|
||||
[[git -C %s --no-pager diff --no-color --no-ext-diff -U0 -- %s]],
|
||||
vim.fn.expand '%:h',
|
||||
vim.fn.expand '%:t'
|
||||
),
|
||||
on_stdout = function(_, data)
|
||||
if next(data) then
|
||||
diff_output_cache = vim.list_extend(diff_output_cache, data)
|
||||
end
|
||||
end,
|
||||
on_stderr = function(_, data)
|
||||
data = table.concat(data, '\n')
|
||||
if #data > 1 or (#data == 1 and #data[1] > 0) then
|
||||
git_diff = nil
|
||||
diff_output_cache = {}
|
||||
end
|
||||
end,
|
||||
on_exit = function()
|
||||
if #diff_output_cache > 0 then
|
||||
process_diff(diff_output_cache)
|
||||
else
|
||||
git_diff = { added = 0, modified = 0, removed = 0 }
|
||||
end
|
||||
diff_cache[vim.fn.bufnr()] = git_diff
|
||||
end,
|
||||
}
|
||||
M.update_git_diff()
|
||||
end
|
||||
|
||||
-- Update git_diff veriable
|
||||
function M.update_git_diff()
|
||||
if M.diff_args then
|
||||
diff_output_cache = {}
|
||||
if diff_job then
|
||||
diff_job:stop()
|
||||
end
|
||||
diff_job = modules.Job(M.diff_args)
|
||||
if diff_job then
|
||||
diff_job:start()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,88 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local lualine_require = require 'lualine_require'
|
||||
local modules = lualine_require.lazy_require {
|
||||
git_diff = 'lualine.components.diff.git_diff',
|
||||
utils = 'lualine.utils.utils',
|
||||
utils_notices = 'lualine.utils.notices',
|
||||
highlight = 'lualine.highlight',
|
||||
}
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
symbols = { added = '+', modified = '~', removed = '-' },
|
||||
diff_color = {
|
||||
added = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffAdd', 'fg') or '#f0e130',
|
||||
},
|
||||
modified = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffChange', 'fg') or '#ff0038',
|
||||
},
|
||||
removed = {
|
||||
fg = modules.utils.extract_highlight_colors('DiffDelete', 'fg') or '#ff0038',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
-- Initializer
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
-- create highlights and save highlight_name in highlights table
|
||||
if self.options.colored then
|
||||
self.highlights = {
|
||||
added = modules.highlight.create_component_highlight_group(
|
||||
self.options.diff_color.added,
|
||||
'diff_added',
|
||||
self.options
|
||||
),
|
||||
modified = modules.highlight.create_component_highlight_group(
|
||||
self.options.diff_color.modified,
|
||||
'diff_modified',
|
||||
self.options
|
||||
),
|
||||
removed = modules.highlight.create_component_highlight_group(
|
||||
self.options.diff_color.removed,
|
||||
'diff_removed',
|
||||
self.options
|
||||
),
|
||||
}
|
||||
end
|
||||
modules.git_diff.init(self.options)
|
||||
end
|
||||
|
||||
-- Function that runs everytime statusline is updated
|
||||
function M:update_status(is_focused)
|
||||
local git_diff = modules.git_diff.get_sign_count((not is_focused and vim.fn.bufnr()))
|
||||
if git_diff == nil then
|
||||
return ''
|
||||
end
|
||||
|
||||
local colors = {}
|
||||
if self.options.colored then
|
||||
-- load the highlights and store them in colors table
|
||||
for name, highlight_name in pairs(self.highlights) do
|
||||
colors[name] = modules.highlight.component_format_highlight(highlight_name)
|
||||
end
|
||||
end
|
||||
|
||||
local result = {}
|
||||
-- loop though data and load available sections in result table
|
||||
for _, name in ipairs { 'added', 'modified', 'removed' } do
|
||||
if git_diff[name] and git_diff[name] > 0 then
|
||||
if self.options.colored then
|
||||
table.insert(result, colors[name] .. self.options.symbols[name] .. git_diff[name])
|
||||
else
|
||||
table.insert(result, self.options.symbols[name] .. git_diff[name])
|
||||
end
|
||||
end
|
||||
end
|
||||
if #result > 0 then
|
||||
return table.concat(result, ' ')
|
||||
else
|
||||
return ''
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -1,9 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Encoding = require('lualine.component'):new()
|
||||
|
||||
Encoding.update_status = function()
|
||||
local function encoding()
|
||||
return [[%{strlen(&fenc)?&fenc:&enc}]]
|
||||
end
|
||||
|
||||
return Encoding
|
||||
return encoding
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local FileFormat = require('lualine.component'):new()
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
-- stylua: ignore
|
||||
FileFormat.icon = {
|
||||
M.icon = {
|
||||
unix = '', -- e712
|
||||
dos = '', -- e70f
|
||||
mac = '' -- e711
|
||||
}
|
||||
|
||||
FileFormat.update_status = function(self)
|
||||
M.update_status = function(self)
|
||||
if self.options.icons_enabled and not self.options.icon then
|
||||
local format = vim.bo.fileformat
|
||||
return FileFormat.icon[format] or format
|
||||
return M.icon[format] or format
|
||||
end
|
||||
return vim.bo.fileformat
|
||||
end
|
||||
|
||||
return FileFormat
|
||||
return M
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local FileName = require('lualine.component'):new()
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
symbols = { modified = '[+]', readonly = '[-]' },
|
||||
|
@ -18,13 +18,12 @@ local function shorten_path(path, sep)
|
|||
return path:gsub(string.format('([^%s])[^%s]+%%%s', sep, sep, sep), '%1' .. sep, 1)
|
||||
end
|
||||
|
||||
FileName.new = function(self, options, child)
|
||||
local new_instance = self._parent:new(options, child or FileName)
|
||||
new_instance.options = vim.tbl_deep_extend('keep', new_instance.options or {}, default_options)
|
||||
return new_instance
|
||||
M.init = function(self, options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
end
|
||||
|
||||
FileName.update_status = function(self)
|
||||
M.update_status = function(self)
|
||||
local data
|
||||
if self.options.path == 1 then
|
||||
-- relative path
|
||||
|
@ -63,4 +62,4 @@ FileName.update_status = function(self)
|
|||
return data
|
||||
end
|
||||
|
||||
return FileName
|
||||
return M
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):new()
|
||||
|
||||
M.update_status = function()
|
||||
local function filesize()
|
||||
local file = vim.fn.expand '%:p'
|
||||
if file == nil or #file == 0 then
|
||||
return ''
|
||||
|
@ -24,4 +22,4 @@ M.update_status = function()
|
|||
return string.format('%.1f%s', size, sufixes[i])
|
||||
end
|
||||
|
||||
return M
|
||||
return filesize
|
||||
|
|
|
@ -5,46 +5,23 @@ local modules = lualine_require.lazy_require {
|
|||
highlight = 'lualine.highlight',
|
||||
utils = 'lualine.utils.utils',
|
||||
}
|
||||
local FileType = lualine_require.require('lualine.component'):new()
|
||||
|
||||
local function check_deprecated_options(options)
|
||||
local function rename_notice(before, now)
|
||||
if options[before] then
|
||||
require('lualine.utils.notices').add_notice(string.format(
|
||||
[[
|
||||
### option.%s
|
||||
%s option has been renamed to `%s`. Please use `%s` instead in your config
|
||||
for filetype component.
|
||||
]],
|
||||
before,
|
||||
before,
|
||||
now,
|
||||
now
|
||||
))
|
||||
options[now] = options[before]
|
||||
options[before] = nil
|
||||
end
|
||||
end
|
||||
rename_notice('disable_text', 'icon_only')
|
||||
end
|
||||
local M = lualine_require.require('lualine.component'):extend()
|
||||
|
||||
local default_options = {
|
||||
colored = true,
|
||||
icon_only = false,
|
||||
}
|
||||
|
||||
function FileType:new(options, child)
|
||||
local new_instance = self._parent:new(options, child or FileType)
|
||||
new_instance.options = vim.tbl_deep_extend('keep', new_instance.options or {}, default_options)
|
||||
check_deprecated_options(new_instance.options)
|
||||
return new_instance
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
end
|
||||
|
||||
function FileType.update_status()
|
||||
function M.update_status()
|
||||
return vim.bo.filetype or ''
|
||||
end
|
||||
|
||||
function FileType:apply_icon()
|
||||
function M:apply_icon()
|
||||
if not self.options.icons_enabled then
|
||||
return
|
||||
end
|
||||
|
@ -87,4 +64,4 @@ function FileType:apply_icon()
|
|||
end
|
||||
end
|
||||
|
||||
return FileType
|
||||
return M
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local HostName = require('lualine.component'):new()
|
||||
local function hostname()
|
||||
return vim.loop.os_gethostname()
|
||||
end
|
||||
|
||||
HostName.update_status = vim.loop.os_gethostname
|
||||
|
||||
return HostName
|
||||
return hostname
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Location = require('lualine.component'):new()
|
||||
|
||||
Location.update_status = function()
|
||||
local function location()
|
||||
return [[%3l:%-2c]]
|
||||
end
|
||||
|
||||
return Location
|
||||
return location
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local Mode = require('lualine.component'):new()
|
||||
local get_mode = require('lualine.utils.mode').get_mode
|
||||
|
||||
Mode.update_status = get_mode
|
||||
|
||||
return Mode
|
||||
return get_mode
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
-- Copyright (c) 2020-2021 hoob3rt
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Progress = require('lualine.component'):new()
|
||||
|
||||
Progress.update_status = function()
|
||||
local function progress()
|
||||
return [[%3P]]
|
||||
end
|
||||
|
||||
return Progress
|
||||
return progress
|
||||
|
|
|
@ -1,36 +1,35 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
local EvalFuncComponent = require('lualine.component'):new()
|
||||
|
||||
EvalFuncComponent.update_status = function(self)
|
||||
function M:update_status()
|
||||
local component = self.options[1]
|
||||
local ok, status
|
||||
if self.options.type == nil then
|
||||
ok, status = pcall(EvalFuncComponent.lua_eval, component)
|
||||
ok, status = pcall(M.lua_eval, component)
|
||||
if not ok then
|
||||
status = EvalFuncComponent.vim_function(component)
|
||||
status = M.vim_function(component)
|
||||
end
|
||||
else
|
||||
if self.options.type == 'luae' then
|
||||
ok, status = pcall(EvalFuncComponent.lua_eval, component)
|
||||
if self.options.type == 'lua_expr' then
|
||||
ok, status = pcall(M.lua_eval, component)
|
||||
if not ok then
|
||||
status = nil
|
||||
end
|
||||
elseif self.options.type == 'vimf' then
|
||||
status = EvalFuncComponent.vim_function(component)
|
||||
elseif self.options.type == 'vim_fun' then
|
||||
status = M.vim_function(component)
|
||||
end
|
||||
end
|
||||
return status
|
||||
end
|
||||
|
||||
EvalFuncComponent.lua_eval = function(code)
|
||||
function M.lua_eval(code)
|
||||
local result = loadstring('return ' .. code)()
|
||||
assert(result, 'String expected got nil')
|
||||
return tostring(result)
|
||||
end
|
||||
|
||||
EvalFuncComponent.vim_function = function(name)
|
||||
function M.vim_function(name)
|
||||
-- vim function component
|
||||
local ok, return_val = pcall(vim.api.nvim_call_function, name, {})
|
||||
if not ok then
|
||||
|
@ -40,4 +39,4 @@ EvalFuncComponent.vim_function = function(name)
|
|||
return ok and return_val or ''
|
||||
end
|
||||
|
||||
return EvalFuncComponent
|
||||
return M
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local FunctionComponent = require('lualine.component'):new()
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
FunctionComponent.update_status = function(self, is_focused)
|
||||
M.update_status = function(self, is_focused)
|
||||
-- 1st element in options table is the function provided by config
|
||||
local ok, retval
|
||||
ok, retval = pcall(self.options[1], self, is_focused)
|
||||
|
@ -18,4 +18,4 @@ FunctionComponent.update_status = function(self, is_focused)
|
|||
return retval
|
||||
end
|
||||
|
||||
return FunctionComponent
|
||||
return M
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local VarComponent = require('lualine.component'):new()
|
||||
VarComponent.update_status = function(self)
|
||||
local M = require('lualine.component'):extend()
|
||||
|
||||
function M:update_status()
|
||||
local component = self.options[1]
|
||||
-- vim veriable component
|
||||
-- accepts g:, v:, t:, w:, b:, o, go:, vo:, to:, wo:, bo:
|
||||
|
@ -31,4 +32,4 @@ VarComponent.update_status = function(self)
|
|||
return ok and return_val or ''
|
||||
end
|
||||
|
||||
return VarComponent
|
||||
return M
|
||||
|
|
|
@ -1,217 +0,0 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local Tabs = require('lualine.component'):new()
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local default_options = {
|
||||
max_length = 0,
|
||||
mode = 0,
|
||||
tabs_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
}
|
||||
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and '_normal' or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
local Tab = {}
|
||||
|
||||
function Tab:new(tab)
|
||||
assert(tab.tabnr, 'Cannot create Tab without tabnr')
|
||||
local newObj = {
|
||||
tabnr = tab.tabnr,
|
||||
options = tab.options,
|
||||
highlights = tab.highlights,
|
||||
}
|
||||
self.__index = self
|
||||
newObj = setmetatable(newObj, self)
|
||||
return newObj
|
||||
end
|
||||
|
||||
function Tab:label()
|
||||
local buflist = vim.fn.tabpagebuflist(self.tabnr)
|
||||
local winnr = vim.fn.tabpagewinnr(self.tabnr)
|
||||
local bufnr = buflist[winnr]
|
||||
local file = vim.fn.bufname(bufnr)
|
||||
local buftype = vim.fn.getbufvar(bufnr, '&buftype')
|
||||
if buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(file, ':t:r')
|
||||
elseif buftype == 'terminal' then
|
||||
local match = string.match(vim.split(file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif vim.fn.isdirectory(file) == 1 then
|
||||
return vim.fn.fnamemodify(file, ':p:.')
|
||||
elseif file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
return vim.fn.fnamemodify(file, ':t')
|
||||
end
|
||||
|
||||
function Tab:render()
|
||||
local name
|
||||
if self.ellipse then
|
||||
name = '...'
|
||||
else
|
||||
if self.options.mode == 0 then
|
||||
name = string.format('%s%s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr))
|
||||
elseif self.options.mode == 1 then
|
||||
name = string.format('%s%s ', (self.last or not self.first) and ' ' or '', self:label())
|
||||
else
|
||||
name = string.format('%s%s %s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr), self:label())
|
||||
end
|
||||
end
|
||||
self.len = #name
|
||||
local line = string.format('%%%s@LualineSwitchTab@%s%%T', self.tabnr, name)
|
||||
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
|
||||
|
||||
if self.options.self.section < 'lualine_x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
function Tab:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%S{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
function Tab:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%s{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
function Tabs:new(options, child)
|
||||
local newObj = self._parent:new(options, child or Tabs)
|
||||
default_options.tabs_color = {
|
||||
active = get_hl(options.self.section, true),
|
||||
inactive = get_hl(options.self.section, false),
|
||||
}
|
||||
newObj.options = vim.tbl_deep_extend('keep', newObj.options or {}, default_options)
|
||||
-- stylua: ignore
|
||||
newObj.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
newObj.options.tabs_color.active,
|
||||
'tabs_active',
|
||||
newObj.options
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
newObj.options.tabs_color.inactive,
|
||||
'tabs_active',
|
||||
newObj.options
|
||||
),
|
||||
}
|
||||
return newObj
|
||||
end
|
||||
|
||||
function Tabs:update_status()
|
||||
local data = {}
|
||||
local tabs = {}
|
||||
for t = 1, vim.fn.tabpagenr '$' do
|
||||
tabs[#tabs + 1] = Tab:new { tabnr = t, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
local current = vim.fn.tabpagenr()
|
||||
tabs[1].first = true
|
||||
tabs[#tabs].last = true
|
||||
if tabs[current] then
|
||||
tabs[current].current = true
|
||||
end
|
||||
if tabs[current - 1] then
|
||||
tabs[current - 1].beforecurrent = true
|
||||
end
|
||||
if tabs[current + 1] then
|
||||
tabs[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, tab in pairs(tabs) do
|
||||
if tab.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
local current_tab = tabs[current]
|
||||
if current_tab == nil then
|
||||
local t = Tab:new { tabnr = vim.fn.tabpagenr(), options = self.options, highlights = self.highlights }
|
||||
t.current = true
|
||||
t.last = true
|
||||
data[#data + 1] = t:render()
|
||||
else
|
||||
data[#data + 1] = current_tab:render()
|
||||
total_length = current_tab.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = tabs[current - i]
|
||||
after = tabs[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
vim.cmd [[
|
||||
function! LualineSwitchTab(tabnr, mouseclicks, mousebutton, modifiers)
|
||||
execute a:tabnr . "tabnext"
|
||||
endfunction
|
||||
]]
|
||||
|
||||
return Tabs
|
|
@ -0,0 +1,140 @@
|
|||
-- Copyright (c) 2020-2021 shadmansaleh
|
||||
-- MIT license, see LICENSE for more details.
|
||||
local require = require('lualine_require').require
|
||||
local Tab = require 'lualine.components.tabs.tab'
|
||||
local M = require('lualine.component'):extend()
|
||||
local highlight = require 'lualine.highlight'
|
||||
|
||||
local default_options = {
|
||||
max_length = 0,
|
||||
mode = 0,
|
||||
tabs_color = {
|
||||
active = nil,
|
||||
inactive = nil,
|
||||
},
|
||||
}
|
||||
|
||||
local function get_hl(section, is_active)
|
||||
local suffix = is_active and '_normal' or '_inactive'
|
||||
local section_redirects = {
|
||||
lualine_x = 'lualine_c',
|
||||
lualine_y = 'lualine_b',
|
||||
lualine_z = 'lualine_a',
|
||||
}
|
||||
if section_redirects[section] then
|
||||
section = highlight.highlight_exists(section .. suffix) and section or section_redirects[section]
|
||||
end
|
||||
return section .. suffix
|
||||
end
|
||||
|
||||
function M:init(options)
|
||||
M.super.init(self, options)
|
||||
default_options.tabs_color = {
|
||||
active = get_hl(options.self.section, true),
|
||||
inactive = get_hl(options.self.section, false),
|
||||
}
|
||||
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||
-- stylua: ignore
|
||||
self.highlights = {
|
||||
active = highlight.create_component_highlight_group(
|
||||
self.options.tabs_color.active,
|
||||
'tabs_active',
|
||||
self.options
|
||||
),
|
||||
inactive = highlight.create_component_highlight_group(
|
||||
self.options.tabs_color.inactive,
|
||||
'tabs_active',
|
||||
self.options
|
||||
),
|
||||
}
|
||||
end
|
||||
|
||||
function M:update_status()
|
||||
local data = {}
|
||||
local tabs = {}
|
||||
for t = 1, vim.fn.tabpagenr '$' do
|
||||
tabs[#tabs + 1] = Tab { tabnr = t, options = self.options, highlights = self.highlights }
|
||||
end
|
||||
local current = vim.fn.tabpagenr()
|
||||
tabs[1].first = true
|
||||
tabs[#tabs].last = true
|
||||
if tabs[current] then
|
||||
tabs[current].current = true
|
||||
end
|
||||
if tabs[current - 1] then
|
||||
tabs[current - 1].beforecurrent = true
|
||||
end
|
||||
if tabs[current + 1] then
|
||||
tabs[current + 1].aftercurrent = true
|
||||
end
|
||||
|
||||
local max_length = self.options.max_length
|
||||
if max_length == 0 then
|
||||
max_length = math.floor(vim.o.columns / 3)
|
||||
end
|
||||
local total_length
|
||||
for i, tab in pairs(tabs) do
|
||||
if tab.current then
|
||||
current = i
|
||||
end
|
||||
end
|
||||
local current_tab = tabs[current]
|
||||
if current_tab == nil then
|
||||
local t = Tab { tabnr = vim.fn.tabpagenr(), options = self.options, highlights = self.highlights }
|
||||
t.current = true
|
||||
t.last = true
|
||||
data[#data + 1] = t:render()
|
||||
else
|
||||
data[#data + 1] = current_tab:render()
|
||||
total_length = current_tab.len
|
||||
local i = 0
|
||||
local before, after
|
||||
while true do
|
||||
i = i + 1
|
||||
before = tabs[current - i]
|
||||
after = tabs[current + i]
|
||||
local rendered_before, rendered_after
|
||||
if before == nil and after == nil then
|
||||
break
|
||||
end
|
||||
if before then
|
||||
rendered_before = before:render()
|
||||
total_length = total_length + before.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
table.insert(data, 1, rendered_before)
|
||||
end
|
||||
if after then
|
||||
rendered_after = after:render()
|
||||
total_length = total_length + after.len
|
||||
if total_length > max_length then
|
||||
break
|
||||
end
|
||||
data[#data + 1] = rendered_after
|
||||
end
|
||||
end
|
||||
if total_length > max_length then
|
||||
if before ~= nil then
|
||||
before.ellipse = true
|
||||
before.first = true
|
||||
table.insert(data, 1, before:render())
|
||||
end
|
||||
if after ~= nil then
|
||||
after.ellipse = true
|
||||
after.last = true
|
||||
data[#data + 1] = after:render()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return table.concat(data)
|
||||
end
|
||||
|
||||
vim.cmd [[
|
||||
function! LualineSwitchTab(tabnr, mouseclicks, mousebutton, modifiers)
|
||||
execute a:tabnr . "tabnext"
|
||||
endfunction
|
||||
]]
|
||||
|
||||
return M
|
|
@ -0,0 +1,75 @@
|
|||
local highlight = require 'lualine.highlight'
|
||||
local Tab = require('lualine.utils.class'):extend()
|
||||
|
||||
function Tab:init(opts)
|
||||
assert(opts.tabnr, 'Cannot create Tab without tabnr')
|
||||
self.tabnr = opts.tabnr
|
||||
self.options = opts.options
|
||||
self.highlights = opts.highlights
|
||||
end
|
||||
|
||||
function Tab:label()
|
||||
local buflist = vim.fn.tabpagebuflist(self.tabnr)
|
||||
local winnr = vim.fn.tabpagewinnr(self.tabnr)
|
||||
local bufnr = buflist[winnr]
|
||||
local file = vim.fn.bufname(bufnr)
|
||||
local buftype = vim.fn.getbufvar(bufnr, '&buftype')
|
||||
if buftype == 'help' then
|
||||
return 'help:' .. vim.fn.fnamemodify(file, ':t:r')
|
||||
elseif buftype == 'terminal' then
|
||||
local match = string.match(vim.split(file, ' ')[1], 'term:.*:(%a+)')
|
||||
return match ~= nil and match or vim.fn.fnamemodify(vim.env.SHELL, ':t')
|
||||
elseif vim.fn.isdirectory(file) == 1 then
|
||||
return vim.fn.fnamemodify(file, ':p:.')
|
||||
elseif file == '' then
|
||||
return '[No Name]'
|
||||
end
|
||||
return vim.fn.fnamemodify(file, ':t')
|
||||
end
|
||||
|
||||
function Tab:render()
|
||||
local name
|
||||
if self.ellipse then
|
||||
name = '...'
|
||||
else
|
||||
if self.options.mode == 0 then
|
||||
name = string.format('%s%s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr))
|
||||
elseif self.options.mode == 1 then
|
||||
name = string.format('%s%s ', (self.last or not self.first) and ' ' or '', self:label())
|
||||
else
|
||||
name = string.format('%s%s %s ', (self.last or not self.first) and ' ' or '', tostring(self.tabnr), self:label())
|
||||
end
|
||||
end
|
||||
self.len = #name
|
||||
local line = string.format('%%%s@LualineSwitchTab@%s%%T', self.tabnr, name)
|
||||
line = highlight.component_format_highlight(self.highlights[(self.current and 'active' or 'inactive')]) .. line
|
||||
|
||||
if self.options.self.section < 'lualine_x' and not self.first then
|
||||
local sep_before = self:separator_before()
|
||||
line = sep_before .. line
|
||||
self.len = self.len + vim.fn.strchars(sep_before)
|
||||
elseif self.options.self.section >= 'lualine_x' and not self.last then
|
||||
local sep_after = self:separator_after()
|
||||
line = line .. sep_after
|
||||
self.len = self.len + vim.fn.strchars(sep_after)
|
||||
end
|
||||
return line
|
||||
end
|
||||
|
||||
function Tab:separator_before()
|
||||
if self.current or self.aftercurrent then
|
||||
return '%S{' .. self.options.section_separators.left .. '}'
|
||||
else
|
||||
return self.options.component_separators.left
|
||||
end
|
||||
end
|
||||
|
||||
function Tab:separator_after()
|
||||
if self.current or self.beforecurrent then
|
||||
return '%s{' .. self.options.section_separators.right .. '}'
|
||||
else
|
||||
return self.options.component_separators.right
|
||||
end
|
||||
end
|
||||
|
||||
return Tab
|
|
@ -29,25 +29,11 @@ local config = {
|
|||
extensions = {},
|
||||
}
|
||||
|
||||
local function check_sep_format_deprecation(sep)
|
||||
if type(sep) == 'table' and vim.tbl_islist(sep) then
|
||||
require('lualine.utils.notices').add_persistent_notice(string.format [[
|
||||
### option.separator
|
||||
Using list for configuring separators has been deprecated. Please configure it
|
||||
with {left = left_sep, right = right_sep} like table.
|
||||
]])
|
||||
sep = { left = sep[1], right = sep[2] or sep[1] }
|
||||
end
|
||||
return sep
|
||||
end
|
||||
|
||||
-- change separator format 'x' to {left='x', right='x'}
|
||||
local function fix_separators(separators)
|
||||
if separators ~= nil then
|
||||
if type(separators) == 'string' then
|
||||
return { left = separators, right = separators }
|
||||
else
|
||||
return check_sep_format_deprecation(separators)
|
||||
end
|
||||
end
|
||||
return separators
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
-- Adapted from https://github.com/rxi/classic/blob/master/classic.lua
|
||||
local Object = {}
|
||||
|
||||
Object.__index = Object
|
||||
|
||||
-- luacheck: push no unused args
|
||||
-- Initializer
|
||||
function Object:init(...) end
|
||||
-- luacheck: pop
|
||||
|
||||
-- Extened base class to create a child class
|
||||
function Object:extend()
|
||||
local cls = {}
|
||||
for k, v in pairs(self) do
|
||||
if k:find '__' == 1 then
|
||||
cls[k] = v
|
||||
end
|
||||
end
|
||||
cls.__index = cls
|
||||
cls.super = self
|
||||
setmetatable(cls, self)
|
||||
return cls
|
||||
end
|
||||
|
||||
-- luacheck: push no unused args
|
||||
function Object:__tostring()
|
||||
return 'Object'
|
||||
end
|
||||
-- luacheck: pop
|
||||
|
||||
-- Creates a new object
|
||||
function Object:new(...)
|
||||
local obj = setmetatable({}, self)
|
||||
obj:init(...)
|
||||
return obj
|
||||
end
|
||||
|
||||
-- Creates a new object
|
||||
function Object:__call(...)
|
||||
return self:new(...)
|
||||
end
|
||||
|
||||
return Object
|
|
@ -11,14 +11,19 @@ local is_valid_filename = lualine_require.is_valid_filename
|
|||
local sep = lualine_require.sep
|
||||
|
||||
local component_types = {
|
||||
luaf = function(component)
|
||||
return require('lualine.components.special.function_component'):new(component)
|
||||
lua_fun = function(component)
|
||||
return require 'lualine.components.special.function_component'(component)
|
||||
end,
|
||||
mod = function(component)
|
||||
local ok, loaded_component = pcall(require, 'lualine.components.' .. component[1])
|
||||
if ok then
|
||||
component.component_name = component[1]
|
||||
loaded_component = loaded_component:new(component)
|
||||
if type(loaded_component) == 'table' then
|
||||
loaded_component = loaded_component(component)
|
||||
elseif type(loaded_component) == 'function' then
|
||||
component[1] = loaded_component
|
||||
loaded_component = require 'lualine.components.special.function_component'(component)
|
||||
end
|
||||
return loaded_component
|
||||
end
|
||||
end,
|
||||
|
@ -27,26 +32,26 @@ local component_types = {
|
|||
component[1] = function()
|
||||
return stl_expr
|
||||
end
|
||||
return require('lualine.components.special.function_component'):new(component)
|
||||
return require 'lualine.components.special.function_component'(component)
|
||||
end,
|
||||
var = function(component)
|
||||
return require('lualine.components.special.vim_var_component'):new(component)
|
||||
return require 'lualine.components.special.vim_var_component'(component)
|
||||
end,
|
||||
['_'] = function(component)
|
||||
return require('lualine.components.special.eval_func_component'):new(component)
|
||||
return require 'lualine.components.special.eval_func_component'(component)
|
||||
end,
|
||||
}
|
||||
|
||||
local function component_loader(component)
|
||||
if type(component[1]) == 'function' then
|
||||
return component_types.luaf(component)
|
||||
return component_types.lua_fun(component)
|
||||
end
|
||||
if type(component[1]) == 'string' then
|
||||
-- load the component
|
||||
if component.type ~= nil then
|
||||
if component_types[component.type] and component.type ~= 'luaf' then
|
||||
if component_types[component.type] and component.type ~= 'lua_fun' then
|
||||
return component_types[component.type](component)
|
||||
elseif component.type == 'vimf' or component.type == 'luae' then
|
||||
elseif component.type == 'vim_fun' or component.type == 'lua_expr' then
|
||||
return component_types['_'](component)
|
||||
else
|
||||
modules.notice.add_notice(string.format(
|
||||
|
@ -73,85 +78,39 @@ end
|
|||
|
||||
local function option_deprecatation_notice(component)
|
||||
local types = {
|
||||
case = function()
|
||||
local kind = component.upper ~= nil and 'upper' or 'lower'
|
||||
type_name = function()
|
||||
local changed_to = component.type == 'luae' and 'lua_expr' or 'vim_fun'
|
||||
modules.notice.add_notice(string.format(
|
||||
[[
|
||||
### option.%s
|
||||
### option.type.%s
|
||||
|
||||
Option `%s` has been deprecated.
|
||||
Please use `fmt` option if you need to change case of a component.
|
||||
type name `%s` has been deprecated.
|
||||
Please use `%s`.
|
||||
|
||||
You have some thing like this in your config:
|
||||
You have some thing like this in your config config for %s component:
|
||||
|
||||
```lua
|
||||
%s = true,
|
||||
type = %s,
|
||||
```
|
||||
|
||||
You'll have to change it to this to retain old behavior:
|
||||
|
||||
```lua
|
||||
fmt = string.%s
|
||||
type = %s
|
||||
```
|
||||
]],
|
||||
kind,
|
||||
kind,
|
||||
kind,
|
||||
kind
|
||||
component.type,
|
||||
component.type,
|
||||
changed_to,
|
||||
tostring(component[1]),
|
||||
component.type,
|
||||
changed_to
|
||||
))
|
||||
end,
|
||||
padding = function()
|
||||
local kind = component.left_padding ~= nil and 'left_padding' or 'right_padding'
|
||||
modules.notice.add_notice(string.format(
|
||||
[[
|
||||
### option.%s
|
||||
|
||||
Option `%s` has been deprecated.
|
||||
Please use `padding` option to set left/right padding.
|
||||
|
||||
You have some thing like this in your config:
|
||||
|
||||
```lua
|
||||
%s = %d,
|
||||
```
|
||||
|
||||
You'll have to change it to this to retain old behavior:
|
||||
|
||||
```lua
|
||||
padding = { %s = %d }
|
||||
```
|
||||
if you've set both left_padding and right_padding for a component
|
||||
you'll need to have something like
|
||||
```lua
|
||||
padding = { left = x, right = y }
|
||||
```
|
||||
When you set `padding = x` it's same as `padding = {left = x, right = x}`
|
||||
]],
|
||||
kind,
|
||||
kind,
|
||||
kind,
|
||||
component[kind],
|
||||
kind == 'left_padding' and 'left' or 'right',
|
||||
component[kind]
|
||||
))
|
||||
if component.left_padding and component.right_padding then
|
||||
component.padding = { left = component.left_padding, right = component.right_padding }
|
||||
component.left_padding = nil
|
||||
component.right_padding = nil
|
||||
elseif component.left_padding then
|
||||
component.padding = { left = component.left_padding, right = 1 }
|
||||
component.left_padding = nil
|
||||
else
|
||||
component.padding = { left = 1, right = component.right_padding }
|
||||
component.right_padding = nil
|
||||
end
|
||||
component.type = changed_to
|
||||
end,
|
||||
}
|
||||
if component.upper ~= nil or component.lower ~= nil then
|
||||
types.case()
|
||||
end
|
||||
if component.left_padding ~= nil or component.right_padding ~= nil then
|
||||
types.padding()
|
||||
if component.type == 'luae' or component.type == 'vimf' then
|
||||
types.type_name()
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -226,6 +185,10 @@ local function load_theme(theme_name)
|
|||
local retval
|
||||
local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' }
|
||||
local files = vim.api.nvim_get_runtime_file(path, true)
|
||||
if #files <= 0 then
|
||||
path = table.concat { 'lua/lualine/themes/', theme_name, '/init.lua' }
|
||||
files = vim.api.nvim_get_runtime_file(path, true)
|
||||
end
|
||||
local n_files = #files
|
||||
if n_files == 0 then
|
||||
-- No match found
|
||||
|
|
|
@ -24,19 +24,34 @@ function M.require(module)
|
|||
if package.loaded[module] then
|
||||
return package.loaded[module]
|
||||
end
|
||||
local pattern = module:gsub('%.', M.sep) .. '.lua'
|
||||
local pattern_dir = module:gsub('%.', M.sep)
|
||||
local pattern_path = pattern_dir .. '.lua'
|
||||
if M.plugin_dir then
|
||||
local path = M.plugin_dir .. pattern
|
||||
local path = M.plugin_dir .. pattern_path
|
||||
assert(M.is_valid_filename(module), 'Invalid filename')
|
||||
if vim.loop.fs_stat(path) then
|
||||
local file_stat, dir_stat
|
||||
file_stat = vim.loop.fs_stat(path)
|
||||
if not file_stat then
|
||||
path = M.plugin_dir .. pattern_dir
|
||||
dir_stat = vim.loop.fs_stat(path)
|
||||
if dir_stat and dir_stat.type == 'directory' then
|
||||
path = path .. M.sep .. 'init.lua'
|
||||
file_stat = vim.loop.fs_stat(path)
|
||||
end
|
||||
end
|
||||
if file_stat and file_stat.type == 'file' then
|
||||
local mod_result = dofile(path)
|
||||
package.loaded[module] = mod_result
|
||||
return mod_result
|
||||
end
|
||||
end
|
||||
|
||||
pattern = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' }
|
||||
local paths = vim.api.nvim_get_runtime_file(pattern, false)
|
||||
pattern_path = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' }
|
||||
local paths = vim.api.nvim_get_runtime_file(pattern_path, false)
|
||||
if #paths <= 0 then
|
||||
pattern_path = table.concat { 'lua/', module:gsub('%.', '/'), '/init.lua' }
|
||||
paths = vim.api.nvim_get_runtime_file(pattern_path, false)
|
||||
end
|
||||
if #paths > 0 then
|
||||
local mod_result = dofile(paths[1])
|
||||
package.loaded[module] = mod_result
|
||||
|
|
|
@ -16,8 +16,16 @@ M.assert_component = function(component, opts, result)
|
|||
-- for testing global options
|
||||
if component == nil then
|
||||
component = 'special.function_component'
|
||||
else
|
||||
opts.component_name = component
|
||||
end
|
||||
local comp = require('lualine.components.' .. component)
|
||||
if type(comp) == 'table' then
|
||||
comp = comp(opts)
|
||||
elseif type(comp) == 'function' then
|
||||
opts[1] = comp
|
||||
comp = require 'lualine.components.special.function_component'(opts)
|
||||
end
|
||||
local comp = require('lualine.components.' .. component):new(opts)
|
||||
eq(result, comp:draw(opts.hl))
|
||||
end
|
||||
|
||||
|
|
|
@ -12,20 +12,20 @@ local stub = require 'luassert.stub'
|
|||
describe('Component:', function()
|
||||
it('can select separators', function()
|
||||
local opts = build_component_opts()
|
||||
local comp = require('lualine.components.special.function_component'):new(opts)
|
||||
local comp = require 'lualine.components.special.function_component'(opts)
|
||||
-- correct for lualine_c
|
||||
eq('', comp.options.separator)
|
||||
local opts2 = build_component_opts { self = { section = 'lualine_y' } }
|
||||
local comp2 = require('lualine.components.special.function_component'):new(opts2)
|
||||
local comp2 = require 'lualine.components.special.function_component'(opts2)
|
||||
-- correct for lualine_u
|
||||
eq('', comp2.options.separator)
|
||||
end)
|
||||
|
||||
it('can provide unique identifier', function()
|
||||
local opts1 = build_component_opts()
|
||||
local comp1 = require('lualine.components.special.function_component'):new(opts1)
|
||||
local comp1 = require 'lualine.components.special.function_component'(opts1)
|
||||
local opts2 = build_component_opts()
|
||||
local comp2 = require('lualine.components.special.function_component'):new(opts2)
|
||||
local comp2 = require 'lualine.components.special.function_component'(opts2)
|
||||
neq(comp1.component_no, comp2.component_no)
|
||||
end)
|
||||
|
||||
|
@ -35,7 +35,7 @@ describe('Component:', function()
|
|||
local hl = require 'lualine.highlight'
|
||||
stub(hl, 'create_component_highlight_group')
|
||||
hl.create_component_highlight_group.returns 'MyCompHl'
|
||||
local comp1 = require('lualine.components.special.function_component'):new(opts1)
|
||||
local comp1 = require 'lualine.components.special.function_component'(opts1)
|
||||
eq('MyCompHl', comp1.options.color_highlight)
|
||||
-- color highlight wan't in options when create_comp_hl was
|
||||
-- called so remove it before assert
|
||||
|
@ -46,7 +46,7 @@ describe('Component:', function()
|
|||
local opts2 = build_component_opts { color = color }
|
||||
stub(hl, 'create_component_highlight_group')
|
||||
hl.create_component_highlight_group.returns 'MyCompLinkedHl'
|
||||
local comp2 = require('lualine.components.special.function_component'):new(opts2)
|
||||
local comp2 = require 'lualine.components.special.function_component'(opts2)
|
||||
eq('MyCompLinkedHl', comp2.options.color_highlight)
|
||||
-- color highlight wan't in options when create_comp_hl was
|
||||
-- called so remove it before assert
|
||||
|
@ -90,27 +90,6 @@ describe('Component:', function()
|
|||
end)
|
||||
|
||||
describe('Global options:', function()
|
||||
it('upper', function()
|
||||
local opts = build_component_opts {
|
||||
component_separators = { left = '', right = '' },
|
||||
padding = 0,
|
||||
upper = true,
|
||||
}
|
||||
assert_component(nil, opts, 'TEST')
|
||||
end)
|
||||
|
||||
it('lower', function()
|
||||
local opts = build_component_opts {
|
||||
function()
|
||||
return 'TeSt'
|
||||
end,
|
||||
component_separators = { left = '', right = '' },
|
||||
padding = 0,
|
||||
lower = true,
|
||||
}
|
||||
assert_component(nil, opts, 'test')
|
||||
end)
|
||||
|
||||
it('left_padding', function()
|
||||
local opts = build_component_opts {
|
||||
component_separators = { left = '', right = '' },
|
||||
|
@ -206,7 +185,7 @@ describe('Component:', function()
|
|||
padding = 0,
|
||||
color = 'MyHl',
|
||||
}
|
||||
local comp = require('lualine.components.special.function_component'):new(opts)
|
||||
local comp = require 'lualine.components.special.function_component'(opts)
|
||||
local custom_link_hl_name = 'lualine_' .. comp.options.component_name .. '_no_mode'
|
||||
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
|
||||
local opts2 = build_component_opts {
|
||||
|
@ -217,7 +196,7 @@ describe('Component:', function()
|
|||
local hl = require 'lualine.highlight'
|
||||
stub(hl, 'component_format_highlight')
|
||||
hl.component_format_highlight.returns '%#MyCompHl#'
|
||||
local comp2 = require('lualine.components.special.function_component'):new(opts2)
|
||||
local comp2 = require 'lualine.components.special.function_component'(opts2)
|
||||
assert_component(nil, opts2, '%#MyCompHl#test')
|
||||
assert.stub(hl.component_format_highlight).was_called_with(comp2.options.color_highlight)
|
||||
hl.component_format_highlight:revert()
|
||||
|
|
|
@ -63,11 +63,14 @@ describe('config parsing', function()
|
|||
end)
|
||||
it('table', function()
|
||||
local config = {
|
||||
options = { component_separators = { 'a' }, section_separators = { 'b' } },
|
||||
options = {
|
||||
component_separators = { left = 'a', right = 'b' },
|
||||
section_separators = { left = 'b', right = 'a' },
|
||||
},
|
||||
}
|
||||
config = config_module.apply_configuration(config)
|
||||
eq(config.options.component_separators, { left = 'a', right = 'a' })
|
||||
eq(config.options.section_separators, { left = 'b', right = 'b' })
|
||||
eq(config.options.component_separators, { left = 'a', right = 'b' })
|
||||
eq(config.options.section_separators, { left = 'b', right = 'a' })
|
||||
end)
|
||||
end)
|
||||
it('no seprarators', function()
|
||||
|
|
|
@ -59,8 +59,8 @@ describe('Section genarator', function()
|
|||
it('can draw', function()
|
||||
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
||||
local section = {
|
||||
require('lualine.components.special.function_component'):new(opts),
|
||||
require('lualine.components.special.function_component'):new(opts),
|
||||
require 'lualine.components.special.function_component'(opts),
|
||||
require 'lualine.components.special.function_component'(opts),
|
||||
}
|
||||
eq('%#lualine_MySection_normal# test %#lualine_MySection_normal# test ', sec.draw_section(section, 'MySection'))
|
||||
end)
|
||||
|
@ -78,9 +78,9 @@ describe('Section genarator', function()
|
|||
}
|
||||
require('lualine.highlight').create_highlight_groups(require 'lualine.themes.gruvbox')
|
||||
local section = {
|
||||
require('lualine.components.special.function_component'):new(opts),
|
||||
require('lualine.components.special.function_component'):new(opts_colored),
|
||||
require('lualine.components.special.function_component'):new(opts),
|
||||
require 'lualine.components.special.function_component'(opts),
|
||||
require 'lualine.components.special.function_component'(opts_colored),
|
||||
require 'lualine.components.special.function_component'(opts),
|
||||
}
|
||||
local highlight_name2 = 'lualine_' .. section[2].options.component_name .. '_no_mode'
|
||||
-- Removes separator on string color
|
||||
|
@ -88,14 +88,14 @@ describe('Section genarator', function()
|
|||
'%#lualine_MySection_normal# test %#' .. highlight_name2 .. '#' .. ' test %#lualine_MySection_normal# test ',
|
||||
sec.draw_section(section, 'MySection')
|
||||
)
|
||||
section[2] = require('lua.lualine.components.special.function_component'):new(opts_colored2)
|
||||
section[2] = require 'lua.lualine.components.special.function_component'(opts_colored2)
|
||||
local highlight_name = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||
-- Removes separator on color with bg
|
||||
eq(
|
||||
'%#lualine_MySection_normal# test ' .. highlight_name .. ' test %#lualine_MySection_normal# test ',
|
||||
sec.draw_section(section, 'MySection')
|
||||
)
|
||||
section[2] = require('lua.lualine.components.special.function_component'):new(opts_colored3)
|
||||
section[2] = require 'lua.lualine.components.special.function_component'(opts_colored3)
|
||||
highlight_name2 = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||
-- Doesn't remove separator on color without bg
|
||||
eq(
|
||||
|
|
Loading…
Reference in New Issue