diff --git a/lua/lualine/components/buffers/buffer.lua b/lua/lualine/components/buffers/buffer.lua new file mode 100644 index 0000000..2fd811d --- /dev/null +++ b/lua/lualine/components/buffers/buffer.lua @@ -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 diff --git a/lua/lualine/components/buffers.lua b/lua/lualine/components/buffers/init.lua similarity index 51% rename from lua/lualine/components/buffers.lua rename to lua/lualine/components/buffers/init.lua index 86ec797..a2f0f87 100644 --- a/lua/lualine/components/buffers.lua +++ b/lua/lualine/components/buffers/init.lua @@ -1,5 +1,7 @@ -- 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' @@ -33,107 +35,6 @@ local function get_hl(section, is_active) 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 M:init(options) M.super.init(self, options) default_options.buffers_color = { @@ -160,7 +61,7 @@ function M:update_status() 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 } + buffers[#buffers + 1] = Buffer { bufnr = b, options = self.options, highlights = self.highlights } end end local current_bufnr = vim.fn.bufnr() @@ -195,7 +96,7 @@ function M:update_status() end end if current == -2 then - local b = Buffer:new { bufnr = vim.fn.bufnr(), options = self.options, highlights = self.highlights } + 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 diff --git a/lua/lualine/components/tabs.lua b/lua/lualine/components/tabs/init.lua similarity index 55% rename from lua/lualine/components/tabs.lua rename to lua/lualine/components/tabs/init.lua index 57e5495..6a521ef 100644 --- a/lua/lualine/components/tabs.lua +++ b/lua/lualine/components/tabs/init.lua @@ -1,5 +1,7 @@ -- 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' @@ -25,84 +27,6 @@ local function get_hl(section, is_active) 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 M:init(options) M.super.init(self, options) default_options.tabs_color = { @@ -129,7 +53,7 @@ function M: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 } + tabs[#tabs + 1] = Tab { tabnr = t, options = self.options, highlights = self.highlights } end local current = vim.fn.tabpagenr() tabs[1].first = true @@ -156,7 +80,7 @@ function M:update_status() 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 } + local t = Tab { tabnr = vim.fn.tabpagenr(), options = self.options, highlights = self.highlights } t.current = true t.last = true data[#data + 1] = t:render() diff --git a/lua/lualine/components/tabs/tab.lua b/lua/lualine/components/tabs/tab.lua new file mode 100644 index 0000000..70d1c89 --- /dev/null +++ b/lua/lualine/components/tabs/tab.lua @@ -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 diff --git a/lua/lualine/utils/loader.lua b/lua/lualine/utils/loader.lua index ed0788a..175008f 100644 --- a/lua/lualine/utils/loader.lua +++ b/lua/lualine/utils/loader.lua @@ -231,6 +231,10 @@ local function load_theme(theme_name) local retval local path = table.concat { 'lua/lualine/themes/', theme_name, '.lua' } local files = vim.api.nvim_get_runtime_file(path, true) + if #files <= 0 then + path = table.concat { 'lua/lualine/themes/', theme_name, '/init.lua' } + files = vim.api.nvim_get_runtime_file(path, true) + end local n_files = #files if n_files == 0 then -- No match found diff --git a/lua/lualine_require.lua b/lua/lualine_require.lua index 6aa35f7..6126104 100644 --- a/lua/lualine_require.lua +++ b/lua/lualine_require.lua @@ -24,19 +24,34 @@ function M.require(module) if package.loaded[module] then return package.loaded[module] end - local pattern = module:gsub('%.', M.sep) .. '.lua' + local pattern_dir = module:gsub('%.', M.sep) + local pattern_path = pattern_dir .. '.lua' if M.plugin_dir then - local path = M.plugin_dir .. pattern + local path = M.plugin_dir .. pattern_path assert(M.is_valid_filename(module), 'Invalid filename') - if vim.loop.fs_stat(path) then + local file_stat, dir_stat + file_stat = vim.loop.fs_stat(path) + if not file_stat then + path = M.plugin_dir .. pattern_dir + dir_stat = vim.loop.fs_stat(path) + if dir_stat and dir_stat.type == 'directory' then + path = path .. M.sep .. 'init.lua' + file_stat = vim.loop.fs_stat(path) + end + end + if file_stat and file_stat.type == 'file' then local mod_result = dofile(path) package.loaded[module] = mod_result return mod_result end end - pattern = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' } - local paths = vim.api.nvim_get_runtime_file(pattern, false) + pattern_path = table.concat { 'lua/', module:gsub('%.', '/'), '.lua' } + local paths = vim.api.nvim_get_runtime_file(pattern_path, false) + if #paths <= 0 then + pattern_path = table.concat { 'lua/', module:gsub('%.', '/'), '/init.lua' } + paths = vim.api.nvim_get_runtime_file(pattern_path, false) + end if #paths > 0 then local mod_result = dofile(paths[1]) package.loaded[module] = mod_result