Skip to content

Commit

Permalink
feat(ex.progress): the new component to show the progress in differen…
Browse files Browse the repository at this point in the history
…t modes

.
  • Loading branch information
vladimir-popov committed Dec 28, 2023
1 parent 35aad95 commit efb0738
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 0 deletions.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ for `lualine.nvim` with additional components.
- [ex.spellcheck](#exspellcheck)
- [ex.cwd](#excwd)
- [ex.location](#exlocation)
- [ex.progress](#exprogress)
- [ex.relative_filename](#exrelative_filename)
- [ex.git.branch](#exgitbranch)
- [ex.lsp.single](#exlspsingle)
Expand Down Expand Up @@ -167,6 +168,42 @@ sections = {
}
```

### ex.progress

This component shows the progress in the file. It has two pre-build modes: 'percent' and 'bar'. The first
one is similar to the default `progress` component, but in the second 'bar' mode the progress is
shown as a progress bar.

| mode | example |
|:---:|:---:|
| `'percent'` | <img height=18 alt="ex progress-percent" src="https://github.com/dokwork/lualine-ex/assets/6939832/fa2413c7-dd03-474f-8152-d9b8f4d026ef"> |
| `'bar'` | <img height=18 alt="ex progress-bar" src="https://github.com/dokwork/lualine-ex/assets/6939832/df29650a-3fa9-422b-940f-956079f3a8bb"> |

```lua
sections = {
lualine_a = {
{
'ex.progress',

-- How to show the progress. It may be the one of two string constants:
-- 'percent' or 'bar'. In the 'percent' mode the progress is shown as percent of the file.
-- In the 'bar' mode it's shown as the vertical bar. Also, it can be a table with symbols
-- which will be taken to show according to the progress, or a function, which receive three
-- arguments: the component itself, the cursor line and total lines count in the file.
mode = 'percent',

-- This string will be shown when the cursor is on the first line of the file. Set `false`
-- to turn this logic off.
top = 'Top',

-- This string will be shown when the cursor is on the last line of the file. Set `false`
-- to turn this logic off.
bottom = 'Bot'
}
}
}
```

### ex.relative_filename

This component shows a `filename`: a file name and a path to the current file relative to the
Expand Down
48 changes: 48 additions & 0 deletions lua/lualine/components/ex/progress.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-- stylua: ignore start
local progress_bar = { '', '', '', '', '', '', '', '', ' ' }
-- stylua: ignore end

local Progress = require('lualine.ex.component'):extend({
mode = 'percent',
top = 'Top',
bottom = 'Bot',
})

local function mode_percent(self, line, total)
if (line == total) and self.options.bottom then
return self.options.bottom
end
if (line == 1) and self.options.top then
return self.options.top
end
return string.format('%3d%%%%', 99 * line / total + 1)
end

local function mode_table(t)
return function(self, line, total)
if (line == total) and self.options.bottom then
return self.options.bottom
end
if (line == 1) and self.options.top then
return self.options.top
end
local idx = math.floor(line * (#t - 1) / total) + 1
return t[idx]
end
end

function Progress:post_init()
if type(self.options.mode) == 'string' then
self.options.mode = (self.options.mode == 'bar') and mode_table(progress_bar)
or mode_percent
end
if type(self.options.mode) == 'table' then
self.options.mode = mode_table(self.options.mode)
end
end

function Progress:update_status()
return self.options.mode(self, vim.fn.line('.'), vim.fn.line('$'))
end

return Progress
92 changes: 92 additions & 0 deletions tests/components/progress_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
local l = require('tests.ex.lualine')
local t = require('tests.ex.busted') --:ignore_all_tests()

local eq = assert.are.equal

local orig = {
line = vim.fn.line,
}
local mock = {
line = {},
}

local component_name = 'ex.progress'

describe(component_name, function()
before_each(function()
vim.fn.line = function(arg)
return mock.line[arg]
end
end)

after_each(function()
vim.fn.line = orig.line
end)

describe('in "percent" (default) mode', function()
it('should show "Top" when the cursor is on bottom of the buffer', function()
-- { line, total, expected percent }
local cases = {
{ 1, 100, 'Top' },
{ 1, 1000, 'Top' },
{ 2, 1000, ' 1%%' },
}
for _, case in ipairs(cases) do
mock.line['.'] = case[1]
mock.line['$'] = case[2]
local c = l.render_component(component_name)
eq(case[3], c, vim.inspect(case))
end
end)
it('should show "Bot" when the cursor is on bottom of the buffer', function()
-- { line, total, expected percent }
local cases = {
{ 100, 100, 'Bot' },
{ 1000, 1000, 'Bot' },
{ 999, 1000, ' 99%%' },
}
for _, case in ipairs(cases) do
mock.line['.'] = case[1]
mock.line['$'] = case[2]
local c = l.render_component(component_name)
eq(case[3], c, vim.inspect(case))
end
end)
it('should show expected persentage of the buffer', function()
-- { line, total, expected percent }
local cases = {
{ 1, 100, 1 },
{ 100, 100, 100 },
{ 17, 111, 16 },
}
for _, case in ipairs(cases) do
mock.line['.'] = case[1]
mock.line['$'] = case[2]
local c = l.render_component(component_name, { top = false, bottom = false })
eq(string.format('%3d%%%%', case[3]), c, vim.inspect(case))
end
end)
end)

describe('in "bar" mode, or "tabe" mode', function()
it('should show appropriate symbol', function()
-- { line, total, expected percent }
local cases = {
{ 1, 100, '' },
{ 100, 100, ' ' },
{ 99, 100, '' },
{ 7, 9, '' },
{ 19, 31, '' },
}
for _, case in ipairs(cases) do
mock.line['.'] = case[1]
mock.line['$'] = case[2]
local c = l.render_component(
component_name,
{ top = false, bottom = false, mode = 'bar' }
)
eq(case[3], c, vim.inspect(case))
end
end)
end)
end)

0 comments on commit efb0738

Please sign in to comment.