diff --git a/README.md b/README.md index 8463761..fd1a94d 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ for `lualine.nvim` with additional components. - [🧩 Provided components](#provided-components) - [ex.spellcheck](#exspellcheck) - [ex.cwd](#excwd) + - [ex.location](#exlocation) - [ex.relative_filename](#exrelative_filename) - [ex.git.branch](#exgitbranch) - [ex.lsp.single](#exlspsingle) @@ -137,6 +138,34 @@ sections = { The absolute value of the {depth} will be decreased until the length of the path becomes less then {max_length}. +### ex.location + +This component shows the current cursor position in configurable format. Comparing to the default +`location` component, this component can show total number of lines, and may be flexibly configured. + +| pattern | example | +|:---:|:---:| +| `'%2C:%-3L/%T'` | ex location | +| `'%3L:%-2C'` | ex location-2 | + + +```lua +sections = { + lualine_a = { + { + 'ex.location', + + -- The pattern to show the cursor position. Here three possible specifiers: + -- 'L' means 'line' - the number of the line where is the cursor now; + -- 'C' means 'column' - the number of the virtual column where is the cursor now; + -- 'T' means 'total' - the total count of lines in the current buffer; + -- Every specifier can be used in similar maner to %d in the {string.format} function. + -- The pattern similar to the default 'location' component is '%3L:%-2C' + pattern = '%2C:%-3L/%T' + } + } +} +``` ### ex.relative_filename diff --git a/lua/lualine/components/ex/location.lua b/lua/lualine/components/ex/location.lua new file mode 100644 index 0000000..f128857 --- /dev/null +++ b/lua/lualine/components/ex/location.lua @@ -0,0 +1,31 @@ +local log = require('plenary.log').new({ plugin = 'ex.location' }) + +local Location = require('lualine.ex.component'):extend({ + pattern = '%2C:%-3L/%T', +}) + +function Location:post_init() + self.__substitutions = {} + self.__pattern = string.gsub(self.options.pattern, '(%%%-?%d*[LCT]+)', function(template) + return string.gsub(template, '([LCT])', function(value) + table.insert(self.__substitutions, value) + return 'd' + end) + end) + log.debug(self.__substitutions) + log.debug(self.__pattern) +end + +function Location:update_status() + local values = { + L = vim.fn.line('.'), + C = vim.fn.virtcol('.'), + T = vim.fn.line('$'), + } + local substitutions = vim.tbl_map(function(key) + return values[key] + end, self.__substitutions) + return string.format(self.__pattern, unpack(substitutions)) +end + +return Location diff --git a/tests/components/location_spec.lua b/tests/components/location_spec.lua new file mode 100644 index 0000000..f929082 --- /dev/null +++ b/tests/components/location_spec.lua @@ -0,0 +1,47 @@ +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, + virtcol = vim.fn.virtcol, +} +local mock = { + line = {}, + virtcol = {}, +} + +local component_name = 'ex.location' +describe(component_name, function() + before_each(function() + vim.fn.line = function(arg) + return mock.line[arg] + end + vim.fn.virtcol = function(arg) + return mock.virtcol[arg] + end + end) + + after_each(function() + vim.fn.line = orig.line + vim.fn.virtcol = orig.virtcol + end) + + describe('default patter', function() + it('should show {line}:{column}/{total}', function() + mock.virtcol['.'] = 11 + mock.line['.'] = 222 + mock.line['$'] = 3333 + local component = l.render_component(component_name) + eq('11:222/3333', component) + end) + it('should fill numbers by space', function() + mock.virtcol['.'] = 1 + mock.line['.'] = 2 + mock.line['$'] = 3 + local component = l.render_component(component_name) + eq(' 1:2 /3', component) + end) + end) +end)