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
|
modified, removed in diff_color table option
|
||||||
- color_error, color_warning, color_info, color_hint are now available
|
- color_error, color_warning, color_info, color_hint are now available
|
||||||
as error, warn, info, hint in diagnostics_color table option
|
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.
|
-- When type is omitted lualine will guess it.
|
||||||
-- Available types [format: type_name(example)]
|
-- Available types [format: type_name(example)]
|
||||||
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
||||||
-- luae(lua expressions), vimf(viml function name)
|
-- lua_expr(lua expressions), vim_fun(viml function name)
|
||||||
-- luae is short for lua-expression and vimf is short fror vim-function
|
-- lua_expr is short for lua-expression and vim_fun is short fror vim-function
|
||||||
type = nil,
|
type = nil,
|
||||||
padding = 1, -- adds padding to the left and right of components
|
padding = 1, -- adds padding to the left and right of components
|
||||||
-- padding can be specified to left or right separately like
|
-- 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.
|
-- When type is omitted lualine will guess it.
|
||||||
-- Available types [format: type_name(example)]
|
-- Available types [format: type_name(example)]
|
||||||
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
-- mod(branch/filename), stl(%f/%m), var(g:coc_status/bo:modifiable),
|
||||||
-- luae(lua expressions), vimf(viml function name)
|
-- lua_expr(lua expressions), vim_fun(viml function name)
|
||||||
-- luae is short for lua-expression and vimf is short fror vim-function
|
-- lua_expr is short for lua-expression and vim_fun is short fror vim-function
|
||||||
type = nil,
|
type = nil,
|
||||||
padding = 1, -- adds padding to the left and right of components
|
padding = 1, -- adds padding to the left and right of components
|
||||||
-- padding can be specified to left or right separately like
|
-- padding can be specified to left or right separately like
|
||||||
|
|
|
@ -1,54 +1,33 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
|
local require = require('lualine_require').require
|
||||||
local highlight = require 'lualine.highlight'
|
local highlight = require 'lualine.highlight'
|
||||||
|
local M = require('lualine.utils.class'):extend()
|
||||||
|
|
||||||
-- Used to provide a unique id for each component
|
-- Used to provide a unique id for each component
|
||||||
local component_no = 1
|
local component_no = 1
|
||||||
|
|
||||||
local function check_deprecated_options(options)
|
function M:__tostring()
|
||||||
local function rename_notice(before, now)
|
local str = 'Component: ' .. self.options.component_name
|
||||||
if options[before] then
|
if self.debug then
|
||||||
require('lualine.utils.notices').add_notice(string.format(
|
str = str .. '\n---------------------\n' .. vim.inspect(self)
|
||||||
[[
|
|
||||||
### 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
|
|
||||||
end
|
end
|
||||||
|
return str
|
||||||
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)
|
|
||||||
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)
|
-- 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.separator == nil then
|
||||||
if self.options.component_separators then
|
if self.options.component_separators then
|
||||||
if self.options.self.section < 'lualine_x' then
|
if self.options.self.section < 'lualine_x' then
|
||||||
|
@ -58,9 +37,9 @@ local Component = {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
create_option_highlights = function(self)
|
function M:create_option_highlights()
|
||||||
-- set custom highlights
|
-- set custom highlights
|
||||||
if self.options.color then
|
if self.options.color then
|
||||||
self.options.color_highlight = highlight.create_component_highlight_group(
|
self.options.color_highlight = highlight.create_component_highlight_group(
|
||||||
|
@ -69,23 +48,10 @@ local Component = {
|
||||||
self.options
|
self.options
|
||||||
)
|
)
|
||||||
end
|
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
|
|
||||||
return
|
|
||||||
end
|
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,
|
|
||||||
|
|
||||||
-- Adds spaces to left and right of a component
|
-- Adds spaces to left and right of a component
|
||||||
apply_padding = function(self)
|
function M:apply_padding()
|
||||||
local padding = self.options.padding
|
local padding = self.options.padding
|
||||||
local l_padding, r_padding
|
local l_padding, r_padding
|
||||||
if padding == nil then
|
if padding == nil then
|
||||||
|
@ -109,10 +75,10 @@ local Component = {
|
||||||
if r_padding then
|
if r_padding then
|
||||||
self.status = self.status .. string.rep(' ', r_padding)
|
self.status = self.status .. string.rep(' ', r_padding)
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- Applies custom highlights for component
|
-- Applies custom highlights for component
|
||||||
apply_highlights = function(self, default_highlight)
|
function M:apply_highlights(default_highlight)
|
||||||
if self.options.color_highlight then
|
if self.options.color_highlight then
|
||||||
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
self.status = highlight.component_format_highlight(self.options.color_highlight) .. self.status
|
||||||
end
|
end
|
||||||
|
@ -129,18 +95,18 @@ local Component = {
|
||||||
if not self.status:find '^%%#' then
|
if not self.status:find '^%%#' then
|
||||||
self.status = default_highlight .. self.status
|
self.status = default_highlight .. self.status
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- Apply icon in front of component
|
-- Apply icon in front of component
|
||||||
apply_icon = function(self)
|
function M:apply_icon()
|
||||||
if self.options.icons_enabled and self.options.icon then
|
if self.options.icons_enabled and self.options.icon then
|
||||||
self.status = self.options.icon .. ' ' .. self.status
|
self.status = self.options.icon .. ' ' .. self.status
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- Apply separator at end of component only when
|
-- Apply separator at end of component only when
|
||||||
-- custom highlights haven't affected background
|
-- custom highlights haven't affected background
|
||||||
apply_separator = function(self)
|
function M:apply_separator()
|
||||||
local separator = self.options.separator
|
local separator = self.options.separator
|
||||||
if type(separator) == 'table' then
|
if type(separator) == 'table' then
|
||||||
if self.options.separator[2] == '' then
|
if self.options.separator[2] == '' then
|
||||||
|
@ -157,9 +123,9 @@ local Component = {
|
||||||
self.status = self.status .. separator
|
self.status = self.status .. separator
|
||||||
self.applied_separator = self.applied_separator .. separator
|
self.applied_separator = self.applied_separator .. separator
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
apply_section_separators = function(self)
|
function M:apply_section_separators()
|
||||||
if type(self.options.separator) ~= 'table' then
|
if type(self.options.separator) ~= 'table' then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -170,26 +136,26 @@ local Component = {
|
||||||
if self.options.separator.right ~= nil and self.options.separator.right ~= '' then
|
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)
|
self.status = string.format('%s%%S{%s}', self.status, self.options.separator.right)
|
||||||
end
|
end
|
||||||
end,
|
end
|
||||||
|
|
||||||
strip_separator = function(self)
|
function M:strip_separator()
|
||||||
if not self.applied_separator then
|
if not self.applied_separator then
|
||||||
self.applied_separator = ''
|
self.applied_separator = ''
|
||||||
end
|
end
|
||||||
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
self.status = self.status:sub(1, (#self.status - #self.applied_separator))
|
||||||
self.applied_separator = nil
|
self.applied_separator = nil
|
||||||
return self.status
|
return self.status
|
||||||
end,
|
end
|
||||||
|
|
||||||
-- variable to store component output for manipulation
|
-- variable to store component output for manipulation
|
||||||
status = '',
|
M.status = ''
|
||||||
-- Actual function that updates a component. Must be overwritten with component functionality
|
-- Actual function that updates a component. Must be overwritten with component functionality
|
||||||
-- luacheck: push no unused args
|
-- luacheck: push no unused args
|
||||||
update_status = function(self, is_focused) end,
|
function M:update_status(is_focused) end
|
||||||
-- luacheck: pop
|
-- luacheck: pop
|
||||||
|
|
||||||
-- Driver code of the class
|
-- Driver code of the class
|
||||||
draw = function(self, default_highlight, is_focused)
|
function M:draw(default_highlight, is_focused)
|
||||||
self.status = ''
|
self.status = ''
|
||||||
self.applied_separator = ''
|
self.applied_separator = ''
|
||||||
|
|
||||||
|
@ -203,14 +169,12 @@ local Component = {
|
||||||
if type(status) == 'string' and #status > 0 then
|
if type(status) == 'string' and #status > 0 then
|
||||||
self.status = status
|
self.status = status
|
||||||
self:apply_icon()
|
self:apply_icon()
|
||||||
self:apply_case()
|
|
||||||
self:apply_padding()
|
self:apply_padding()
|
||||||
self:apply_highlights(default_highlight)
|
self:apply_highlights(default_highlight)
|
||||||
self:apply_section_separators()
|
self:apply_section_separators()
|
||||||
self:apply_separator()
|
self:apply_separator()
|
||||||
end
|
end
|
||||||
return self.status
|
return self.status
|
||||||
end,
|
end
|
||||||
}
|
|
||||||
|
|
||||||
return Component
|
return M
|
||||||
|
|
|
@ -1,51 +1,64 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
local M = {}
|
||||||
-- MIT license, see LICENSE for more details.
|
|
||||||
local Branch = require('lualine.component'):new()
|
local require = require('lualine_require').require
|
||||||
local modules = require('lualine_require').lazy_require {
|
local utils = require 'lualine.utils.utils'
|
||||||
utils = 'lualine.utils.utils',
|
|
||||||
}
|
|
||||||
-- vars
|
-- vars
|
||||||
Branch.git_branch = ''
|
local current_git_branch = ''
|
||||||
Branch.git_dir = ''
|
local current_git_dir = ''
|
||||||
|
local branch_cache = {} -- stores last known branch for a buffer
|
||||||
|
local active_bufnr = '0'
|
||||||
-- os specific path separator
|
-- os specific path separator
|
||||||
Branch.sep = package.config:sub(1, 1)
|
local sep = package.config:sub(1, 1)
|
||||||
-- event watcher to watch head file
|
-- event watcher to watch head file
|
||||||
-- Use file wstch for non windows and poll for windows.
|
-- Use file wstch for non windows and poll for windows.
|
||||||
-- windows doesn't like file watch for some reason.
|
-- 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()
|
local file_changed = 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 git_dir_cache = {} -- Stores git paths that we already know of
|
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
|
-- 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 root_dir = file_dir
|
||||||
local git_dir
|
local git_dir
|
||||||
-- Search upward for .git file or folder
|
-- Search upward for .git file or folder
|
||||||
|
@ -54,7 +67,7 @@ function Branch.find_git_dir()
|
||||||
git_dir = git_dir_cache[root_dir]
|
git_dir = git_dir_cache[root_dir]
|
||||||
break
|
break
|
||||||
end
|
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)
|
local git_file_stat = vim.loop.fs_stat(git_path)
|
||||||
if git_file_stat then
|
if git_file_stat then
|
||||||
if git_file_stat.type == 'directory' then
|
if git_file_stat.type == 'directory' then
|
||||||
|
@ -66,12 +79,12 @@ function Branch.find_git_dir()
|
||||||
git_dir = git_dir:match 'gitdir: (.+)$'
|
git_dir = git_dir:match 'gitdir: (.+)$'
|
||||||
file:close()
|
file:close()
|
||||||
-- submodule / relative file path
|
-- 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
|
git_dir = git_path:match '(.*).git' .. git_dir
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if git_dir then
|
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
|
if head_file_stat and head_file_stat.type == 'file' then
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
|
@ -79,54 +92,34 @@ function Branch.find_git_dir()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
root_dir = root_dir:match('(.*)' .. Branch.sep .. '.-')
|
root_dir = root_dir:match('(.*)' .. sep .. '.-')
|
||||||
end
|
end
|
||||||
|
|
||||||
git_dir_cache[file_dir] = git_dir
|
git_dir_cache[file_dir] = git_dir
|
||||||
if Branch.git_dir ~= git_dir then
|
if dir_path == nil and current_git_dir ~= git_dir then
|
||||||
Branch.git_dir = git_dir
|
current_git_dir = git_dir
|
||||||
Branch.update_branch()
|
update_branch()
|
||||||
end
|
end
|
||||||
return git_dir
|
return git_dir
|
||||||
end
|
end
|
||||||
|
|
||||||
-- sets git_branch veriable to branch name or commit hash if not on branch
|
function M.init()
|
||||||
function Branch.get_git_head(head_file)
|
-- run watch head on load so branch is present when component is loaded
|
||||||
local f_head = io.open(head_file)
|
M.find_git_dir()
|
||||||
if f_head then
|
-- update branch state of BufEnter as different Buffer may be on different repos
|
||||||
local HEAD = f_head:read()
|
utils.define_autocmd('BufEnter', "lua require'lualine.components.branch.git_branch'.find_git_dir()")
|
||||||
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
|
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
|
end
|
||||||
return nil
|
if bufnr then
|
||||||
|
return branch_cache[bufnr] or ''
|
||||||
|
end
|
||||||
|
return current_git_branch
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Update branch
|
return M
|
||||||
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
|
|
|
@ -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
|
-- Copyright (c) 2020-2021 hoob3rt
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local Encoding = require('lualine.component'):new()
|
local function encoding()
|
||||||
|
|
||||||
Encoding.update_status = function()
|
|
||||||
return [[%{strlen(&fenc)?&fenc:&enc}]]
|
return [[%{strlen(&fenc)?&fenc:&enc}]]
|
||||||
end
|
end
|
||||||
|
|
||||||
return Encoding
|
return encoding
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local FileFormat = require('lualine.component'):new()
|
local M = require('lualine.component'):extend()
|
||||||
|
|
||||||
-- stylua: ignore
|
-- stylua: ignore
|
||||||
FileFormat.icon = {
|
M.icon = {
|
||||||
unix = '', -- e712
|
unix = '', -- e712
|
||||||
dos = '', -- e70f
|
dos = '', -- e70f
|
||||||
mac = '' -- e711
|
mac = '' -- e711
|
||||||
}
|
}
|
||||||
|
|
||||||
FileFormat.update_status = function(self)
|
M.update_status = function(self)
|
||||||
if self.options.icons_enabled and not self.options.icon then
|
if self.options.icons_enabled and not self.options.icon then
|
||||||
local format = vim.bo.fileformat
|
local format = vim.bo.fileformat
|
||||||
return FileFormat.icon[format] or format
|
return M.icon[format] or format
|
||||||
end
|
end
|
||||||
return vim.bo.fileformat
|
return vim.bo.fileformat
|
||||||
end
|
end
|
||||||
|
|
||||||
return FileFormat
|
return M
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local FileName = require('lualine.component'):new()
|
local M = require('lualine.component'):extend()
|
||||||
|
|
||||||
local default_options = {
|
local default_options = {
|
||||||
symbols = { modified = '[+]', readonly = '[-]' },
|
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)
|
return path:gsub(string.format('([^%s])[^%s]+%%%s', sep, sep, sep), '%1' .. sep, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
FileName.new = function(self, options, child)
|
M.init = function(self, options)
|
||||||
local new_instance = self._parent:new(options, child or FileName)
|
M.super.init(self, options)
|
||||||
new_instance.options = vim.tbl_deep_extend('keep', new_instance.options or {}, default_options)
|
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||||
return new_instance
|
|
||||||
end
|
end
|
||||||
|
|
||||||
FileName.update_status = function(self)
|
M.update_status = function(self)
|
||||||
local data
|
local data
|
||||||
if self.options.path == 1 then
|
if self.options.path == 1 then
|
||||||
-- relative path
|
-- relative path
|
||||||
|
@ -63,4 +62,4 @@ FileName.update_status = function(self)
|
||||||
return data
|
return data
|
||||||
end
|
end
|
||||||
|
|
||||||
return FileName
|
return M
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local M = require('lualine.component'):new()
|
local function filesize()
|
||||||
|
|
||||||
M.update_status = function()
|
|
||||||
local file = vim.fn.expand '%:p'
|
local file = vim.fn.expand '%:p'
|
||||||
if file == nil or #file == 0 then
|
if file == nil or #file == 0 then
|
||||||
return ''
|
return ''
|
||||||
|
@ -24,4 +22,4 @@ M.update_status = function()
|
||||||
return string.format('%.1f%s', size, sufixes[i])
|
return string.format('%.1f%s', size, sufixes[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return filesize
|
||||||
|
|
|
@ -5,46 +5,23 @@ local modules = lualine_require.lazy_require {
|
||||||
highlight = 'lualine.highlight',
|
highlight = 'lualine.highlight',
|
||||||
utils = 'lualine.utils.utils',
|
utils = 'lualine.utils.utils',
|
||||||
}
|
}
|
||||||
local FileType = lualine_require.require('lualine.component'):new()
|
local M = lualine_require.require('lualine.component'):extend()
|
||||||
|
|
||||||
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 default_options = {
|
local default_options = {
|
||||||
colored = true,
|
colored = true,
|
||||||
icon_only = false,
|
icon_only = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
function FileType:new(options, child)
|
function M:init(options)
|
||||||
local new_instance = self._parent:new(options, child or FileType)
|
M.super.init(self, options)
|
||||||
new_instance.options = vim.tbl_deep_extend('keep', new_instance.options or {}, default_options)
|
self.options = vim.tbl_deep_extend('keep', self.options or {}, default_options)
|
||||||
check_deprecated_options(new_instance.options)
|
|
||||||
return new_instance
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function FileType.update_status()
|
function M.update_status()
|
||||||
return vim.bo.filetype or ''
|
return vim.bo.filetype or ''
|
||||||
end
|
end
|
||||||
|
|
||||||
function FileType:apply_icon()
|
function M:apply_icon()
|
||||||
if not self.options.icons_enabled then
|
if not self.options.icons_enabled then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -87,4 +64,4 @@ function FileType:apply_icon()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return FileType
|
return M
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
-- Copyright (c) 2020-2021 hoob3rt
|
-- Copyright (c) 2020-2021 hoob3rt
|
||||||
-- MIT license, see LICENSE for more details.
|
-- 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
|
-- Copyright (c) 2020-2021 hoob3rt
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local Location = require('lualine.component'):new()
|
local function location()
|
||||||
|
|
||||||
Location.update_status = function()
|
|
||||||
return [[%3l:%-2c]]
|
return [[%3l:%-2c]]
|
||||||
end
|
end
|
||||||
|
|
||||||
return Location
|
return location
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
-- Copyright (c) 2020-2021 hoob3rt
|
-- Copyright (c) 2020-2021 hoob3rt
|
||||||
-- MIT license, see LICENSE for more details.
|
-- 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
|
local get_mode = require('lualine.utils.mode').get_mode
|
||||||
|
return get_mode
|
||||||
Mode.update_status = get_mode
|
|
||||||
|
|
||||||
return Mode
|
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
-- Copyright (c) 2020-2021 hoob3rt
|
-- Copyright (c) 2020-2021 hoob3rt
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local Progress = require('lualine.component'):new()
|
local function progress()
|
||||||
|
|
||||||
Progress.update_status = function()
|
|
||||||
return [[%3P]]
|
return [[%3P]]
|
||||||
end
|
end
|
||||||
|
|
||||||
return Progress
|
return progress
|
||||||
|
|
|
@ -1,36 +1,35 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
|
local M = require('lualine.component'):extend()
|
||||||
|
|
||||||
local EvalFuncComponent = require('lualine.component'):new()
|
function M:update_status()
|
||||||
|
|
||||||
EvalFuncComponent.update_status = function(self)
|
|
||||||
local component = self.options[1]
|
local component = self.options[1]
|
||||||
local ok, status
|
local ok, status
|
||||||
if self.options.type == nil then
|
if self.options.type == nil then
|
||||||
ok, status = pcall(EvalFuncComponent.lua_eval, component)
|
ok, status = pcall(M.lua_eval, component)
|
||||||
if not ok then
|
if not ok then
|
||||||
status = EvalFuncComponent.vim_function(component)
|
status = M.vim_function(component)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if self.options.type == 'luae' then
|
if self.options.type == 'lua_expr' then
|
||||||
ok, status = pcall(EvalFuncComponent.lua_eval, component)
|
ok, status = pcall(M.lua_eval, component)
|
||||||
if not ok then
|
if not ok then
|
||||||
status = nil
|
status = nil
|
||||||
end
|
end
|
||||||
elseif self.options.type == 'vimf' then
|
elseif self.options.type == 'vim_fun' then
|
||||||
status = EvalFuncComponent.vim_function(component)
|
status = M.vim_function(component)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return status
|
return status
|
||||||
end
|
end
|
||||||
|
|
||||||
EvalFuncComponent.lua_eval = function(code)
|
function M.lua_eval(code)
|
||||||
local result = loadstring('return ' .. code)()
|
local result = loadstring('return ' .. code)()
|
||||||
assert(result, 'String expected got nil')
|
assert(result, 'String expected got nil')
|
||||||
return tostring(result)
|
return tostring(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
EvalFuncComponent.vim_function = function(name)
|
function M.vim_function(name)
|
||||||
-- vim function component
|
-- vim function component
|
||||||
local ok, return_val = pcall(vim.api.nvim_call_function, name, {})
|
local ok, return_val = pcall(vim.api.nvim_call_function, name, {})
|
||||||
if not ok then
|
if not ok then
|
||||||
|
@ -40,4 +39,4 @@ EvalFuncComponent.vim_function = function(name)
|
||||||
return ok and return_val or ''
|
return ok and return_val or ''
|
||||||
end
|
end
|
||||||
|
|
||||||
return EvalFuncComponent
|
return M
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- 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
|
-- 1st element in options table is the function provided by config
|
||||||
local ok, retval
|
local ok, retval
|
||||||
ok, retval = pcall(self.options[1], self, is_focused)
|
ok, retval = pcall(self.options[1], self, is_focused)
|
||||||
|
@ -18,4 +18,4 @@ FunctionComponent.update_status = function(self, is_focused)
|
||||||
return retval
|
return retval
|
||||||
end
|
end
|
||||||
|
|
||||||
return FunctionComponent
|
return M
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
-- Copyright (c) 2020-2021 shadmansaleh
|
-- Copyright (c) 2020-2021 shadmansaleh
|
||||||
-- MIT license, see LICENSE for more details.
|
-- MIT license, see LICENSE for more details.
|
||||||
local VarComponent = require('lualine.component'):new()
|
local M = require('lualine.component'):extend()
|
||||||
VarComponent.update_status = function(self)
|
|
||||||
|
function M:update_status()
|
||||||
local component = self.options[1]
|
local component = self.options[1]
|
||||||
-- vim veriable component
|
-- vim veriable component
|
||||||
-- accepts g:, v:, t:, w:, b:, o, go:, vo:, to:, wo:, bo:
|
-- 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 ''
|
return ok and return_val or ''
|
||||||
end
|
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 = {},
|
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'}
|
-- change separator format 'x' to {left='x', right='x'}
|
||||||
local function fix_separators(separators)
|
local function fix_separators(separators)
|
||||||
if separators ~= nil then
|
if separators ~= nil then
|
||||||
if type(separators) == 'string' then
|
if type(separators) == 'string' then
|
||||||
return { left = separators, right = separators }
|
return { left = separators, right = separators }
|
||||||
else
|
|
||||||
return check_sep_format_deprecation(separators)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return separators
|
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 sep = lualine_require.sep
|
||||||
|
|
||||||
local component_types = {
|
local component_types = {
|
||||||
luaf = function(component)
|
lua_fun = function(component)
|
||||||
return require('lualine.components.special.function_component'):new(component)
|
return require 'lualine.components.special.function_component'(component)
|
||||||
end,
|
end,
|
||||||
mod = function(component)
|
mod = function(component)
|
||||||
local ok, loaded_component = pcall(require, 'lualine.components.' .. component[1])
|
local ok, loaded_component = pcall(require, 'lualine.components.' .. component[1])
|
||||||
if ok then
|
if ok then
|
||||||
component.component_name = component[1]
|
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
|
return loaded_component
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -27,26 +32,26 @@ local component_types = {
|
||||||
component[1] = function()
|
component[1] = function()
|
||||||
return stl_expr
|
return stl_expr
|
||||||
end
|
end
|
||||||
return require('lualine.components.special.function_component'):new(component)
|
return require 'lualine.components.special.function_component'(component)
|
||||||
end,
|
end,
|
||||||
var = function(component)
|
var = function(component)
|
||||||
return require('lualine.components.special.vim_var_component'):new(component)
|
return require 'lualine.components.special.vim_var_component'(component)
|
||||||
end,
|
end,
|
||||||
['_'] = function(component)
|
['_'] = function(component)
|
||||||
return require('lualine.components.special.eval_func_component'):new(component)
|
return require 'lualine.components.special.eval_func_component'(component)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local function component_loader(component)
|
local function component_loader(component)
|
||||||
if type(component[1]) == 'function' then
|
if type(component[1]) == 'function' then
|
||||||
return component_types.luaf(component)
|
return component_types.lua_fun(component)
|
||||||
end
|
end
|
||||||
if type(component[1]) == 'string' then
|
if type(component[1]) == 'string' then
|
||||||
-- load the component
|
-- load the component
|
||||||
if component.type ~= nil then
|
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)
|
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)
|
return component_types['_'](component)
|
||||||
else
|
else
|
||||||
modules.notice.add_notice(string.format(
|
modules.notice.add_notice(string.format(
|
||||||
|
@ -73,85 +78,39 @@ end
|
||||||
|
|
||||||
local function option_deprecatation_notice(component)
|
local function option_deprecatation_notice(component)
|
||||||
local types = {
|
local types = {
|
||||||
case = function()
|
type_name = function()
|
||||||
local kind = component.upper ~= nil and 'upper' or 'lower'
|
local changed_to = component.type == 'luae' and 'lua_expr' or 'vim_fun'
|
||||||
modules.notice.add_notice(string.format(
|
modules.notice.add_notice(string.format(
|
||||||
[[
|
[[
|
||||||
### option.%s
|
### option.type.%s
|
||||||
|
|
||||||
Option `%s` has been deprecated.
|
type name `%s` has been deprecated.
|
||||||
Please use `fmt` option if you need to change case of a component.
|
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
|
```lua
|
||||||
%s = true,
|
type = %s,
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll have to change it to this to retain old behavior:
|
You'll have to change it to this to retain old behavior:
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
fmt = string.%s
|
type = %s
|
||||||
```
|
```
|
||||||
]],
|
]],
|
||||||
kind,
|
component.type,
|
||||||
kind,
|
component.type,
|
||||||
kind,
|
changed_to,
|
||||||
kind
|
tostring(component[1]),
|
||||||
|
component.type,
|
||||||
|
changed_to
|
||||||
))
|
))
|
||||||
end,
|
component.type = changed_to
|
||||||
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
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
if component.upper ~= nil or component.lower ~= nil then
|
if component.type == 'luae' or component.type == 'vimf' then
|
||||||
types.case()
|
types.type_name()
|
||||||
end
|
|
||||||
if component.left_padding ~= nil or component.right_padding ~= nil then
|
|
||||||
types.padding()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -226,6 +185,10 @@ local function load_theme(theme_name)
|
||||||
local retval
|
local retval
|
||||||
local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' }
|
local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' }
|
||||||
local files = vim.api.nvim_get_runtime_file(path, true)
|
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
|
local n_files = #files
|
||||||
if n_files == 0 then
|
if n_files == 0 then
|
||||||
-- No match found
|
-- No match found
|
||||||
|
|
|
@ -24,19 +24,34 @@ function M.require(module)
|
||||||
if package.loaded[module] then
|
if package.loaded[module] then
|
||||||
return package.loaded[module]
|
return package.loaded[module]
|
||||||
end
|
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
|
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')
|
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)
|
local mod_result = dofile(path)
|
||||||
package.loaded[module] = mod_result
|
package.loaded[module] = mod_result
|
||||||
return mod_result
|
return mod_result
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
pattern = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' }
|
pattern_path = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' }
|
||||||
local paths = vim.api.nvim_get_runtime_file(pattern, false)
|
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
|
if #paths > 0 then
|
||||||
local mod_result = dofile(paths[1])
|
local mod_result = dofile(paths[1])
|
||||||
package.loaded[module] = mod_result
|
package.loaded[module] = mod_result
|
||||||
|
|
|
@ -16,8 +16,16 @@ M.assert_component = function(component, opts, result)
|
||||||
-- for testing global options
|
-- for testing global options
|
||||||
if component == nil then
|
if component == nil then
|
||||||
component = 'special.function_component'
|
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
|
end
|
||||||
local comp = require('lualine.components.' .. component):new(opts)
|
|
||||||
eq(result, comp:draw(opts.hl))
|
eq(result, comp:draw(opts.hl))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,20 @@ local stub = require 'luassert.stub'
|
||||||
describe('Component:', function()
|
describe('Component:', function()
|
||||||
it('can select separators', function()
|
it('can select separators', function()
|
||||||
local opts = build_component_opts()
|
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
|
-- correct for lualine_c
|
||||||
eq('', comp.options.separator)
|
eq('', comp.options.separator)
|
||||||
local opts2 = build_component_opts { self = { section = 'lualine_y' } }
|
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
|
-- correct for lualine_u
|
||||||
eq('', comp2.options.separator)
|
eq('', comp2.options.separator)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('can provide unique identifier', function()
|
it('can provide unique identifier', function()
|
||||||
local opts1 = build_component_opts()
|
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 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)
|
neq(comp1.component_no, comp2.component_no)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ describe('Component:', function()
|
||||||
local hl = require 'lualine.highlight'
|
local hl = require 'lualine.highlight'
|
||||||
stub(hl, 'create_component_highlight_group')
|
stub(hl, 'create_component_highlight_group')
|
||||||
hl.create_component_highlight_group.returns 'MyCompHl'
|
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)
|
eq('MyCompHl', comp1.options.color_highlight)
|
||||||
-- color highlight wan't in options when create_comp_hl was
|
-- color highlight wan't in options when create_comp_hl was
|
||||||
-- called so remove it before assert
|
-- called so remove it before assert
|
||||||
|
@ -46,7 +46,7 @@ describe('Component:', function()
|
||||||
local opts2 = build_component_opts { color = color }
|
local opts2 = build_component_opts { color = color }
|
||||||
stub(hl, 'create_component_highlight_group')
|
stub(hl, 'create_component_highlight_group')
|
||||||
hl.create_component_highlight_group.returns 'MyCompLinkedHl'
|
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)
|
eq('MyCompLinkedHl', comp2.options.color_highlight)
|
||||||
-- color highlight wan't in options when create_comp_hl was
|
-- color highlight wan't in options when create_comp_hl was
|
||||||
-- called so remove it before assert
|
-- called so remove it before assert
|
||||||
|
@ -90,27 +90,6 @@ describe('Component:', function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('Global options:', function()
|
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()
|
it('left_padding', function()
|
||||||
local opts = build_component_opts {
|
local opts = build_component_opts {
|
||||||
component_separators = { left = '', right = '' },
|
component_separators = { left = '', right = '' },
|
||||||
|
@ -206,7 +185,7 @@ describe('Component:', function()
|
||||||
padding = 0,
|
padding = 0,
|
||||||
color = 'MyHl',
|
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'
|
local custom_link_hl_name = 'lualine_' .. comp.options.component_name .. '_no_mode'
|
||||||
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
|
eq('%#' .. custom_link_hl_name .. '#test', comp:draw(opts.hl))
|
||||||
local opts2 = build_component_opts {
|
local opts2 = build_component_opts {
|
||||||
|
@ -217,7 +196,7 @@ describe('Component:', function()
|
||||||
local hl = require 'lualine.highlight'
|
local hl = require 'lualine.highlight'
|
||||||
stub(hl, 'component_format_highlight')
|
stub(hl, 'component_format_highlight')
|
||||||
hl.component_format_highlight.returns '%#MyCompHl#'
|
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_component(nil, opts2, '%#MyCompHl#test')
|
||||||
assert.stub(hl.component_format_highlight).was_called_with(comp2.options.color_highlight)
|
assert.stub(hl.component_format_highlight).was_called_with(comp2.options.color_highlight)
|
||||||
hl.component_format_highlight:revert()
|
hl.component_format_highlight:revert()
|
||||||
|
|
|
@ -63,11 +63,14 @@ describe('config parsing', function()
|
||||||
end)
|
end)
|
||||||
it('table', function()
|
it('table', function()
|
||||||
local config = {
|
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)
|
config = config_module.apply_configuration(config)
|
||||||
eq(config.options.component_separators, { left = 'a', right = 'a' })
|
eq(config.options.component_separators, { left = 'a', right = 'b' })
|
||||||
eq(config.options.section_separators, { left = 'b', right = 'b' })
|
eq(config.options.section_separators, { left = 'b', right = 'a' })
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
it('no seprarators', function()
|
it('no seprarators', function()
|
||||||
|
|
|
@ -59,8 +59,8 @@ describe('Section genarator', function()
|
||||||
it('can draw', function()
|
it('can draw', function()
|
||||||
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
local opts = build_component_opts { section_separators = { left = '', right = '' } }
|
||||||
local section = {
|
local section = {
|
||||||
require('lualine.components.special.function_component'):new(opts),
|
require 'lualine.components.special.function_component'(opts),
|
||||||
require('lualine.components.special.function_component'):new(opts),
|
require 'lualine.components.special.function_component'(opts),
|
||||||
}
|
}
|
||||||
eq('%#lualine_MySection_normal# test %#lualine_MySection_normal# test ', sec.draw_section(section, 'MySection'))
|
eq('%#lualine_MySection_normal# test %#lualine_MySection_normal# test ', sec.draw_section(section, 'MySection'))
|
||||||
end)
|
end)
|
||||||
|
@ -78,9 +78,9 @@ describe('Section genarator', function()
|
||||||
}
|
}
|
||||||
require('lualine.highlight').create_highlight_groups(require 'lualine.themes.gruvbox')
|
require('lualine.highlight').create_highlight_groups(require 'lualine.themes.gruvbox')
|
||||||
local section = {
|
local section = {
|
||||||
require('lualine.components.special.function_component'):new(opts),
|
require 'lualine.components.special.function_component'(opts),
|
||||||
require('lualine.components.special.function_component'):new(opts_colored),
|
require 'lualine.components.special.function_component'(opts_colored),
|
||||||
require('lualine.components.special.function_component'):new(opts),
|
require 'lualine.components.special.function_component'(opts),
|
||||||
}
|
}
|
||||||
local highlight_name2 = 'lualine_' .. section[2].options.component_name .. '_no_mode'
|
local highlight_name2 = 'lualine_' .. section[2].options.component_name .. '_no_mode'
|
||||||
-- Removes separator on string color
|
-- Removes separator on string color
|
||||||
|
@ -88,14 +88,14 @@ describe('Section genarator', function()
|
||||||
'%#lualine_MySection_normal# test %#' .. highlight_name2 .. '#' .. ' test %#lualine_MySection_normal# test ',
|
'%#lualine_MySection_normal# test %#' .. highlight_name2 .. '#' .. ' test %#lualine_MySection_normal# test ',
|
||||||
sec.draw_section(section, 'MySection')
|
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#'
|
local highlight_name = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||||
-- Removes separator on color with bg
|
-- Removes separator on color with bg
|
||||||
eq(
|
eq(
|
||||||
'%#lualine_MySection_normal# test ' .. highlight_name .. ' test %#lualine_MySection_normal# test ',
|
'%#lualine_MySection_normal# test ' .. highlight_name .. ' test %#lualine_MySection_normal# test ',
|
||||||
sec.draw_section(section, 'MySection')
|
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#'
|
highlight_name2 = '%#lualine_c_' .. section[2].options.component_name .. '_normal#'
|
||||||
-- Doesn't remove separator on color without bg
|
-- Doesn't remove separator on color without bg
|
||||||
eq(
|
eq(
|
||||||
|
|
Loading…
Reference in New Issue