From 013c637c2ea7b4f2a91fd981aa789f9242ae3f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Bar=C3=A3o?= Date: Tue, 9 May 2023 21:18:42 +0100 Subject: [PATCH 1/2] fix(selectioncount) wrong sizes with multibyte, widechars and tabs. --- lua/lualine/components/selectioncount.lua | 34 +++++++++++++++++------ 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lua/lualine/components/selectioncount.lua b/lua/lualine/components/selectioncount.lua index f08bde0c9..1c2e0d3ee 100644 --- a/lua/lualine/components/selectioncount.lua +++ b/lua/lualine/components/selectioncount.lua @@ -1,13 +1,29 @@ local function selectioncount() - local mode = vim.fn.mode(true) - local line_start, col_start = vim.fn.line('v'), vim.fn.col('v') - local line_end, col_end = vim.fn.line('.'), vim.fn.col('.') - if mode:match('') then - return string.format('%dx%d', math.abs(line_start - line_end) + 1, math.abs(col_start - col_end) + 1) - elseif mode:match('V') or line_start ~= line_end then - return math.abs(line_start - line_end) + 1 - elseif mode:match('v') then - return math.abs(col_start - col_end) + 1 + local mode = vim.fn.mode() + local lines = math.abs(vim.fn.line('v') - vim.fn.line('.')) + 1 + if mode == 'v' or mode == 'V' then + local wc = vim.fn.wordcount() + local bytecount, linecount = '', '' + if wc.visual_chars ~= wc.visual_bytes then + bytecount = string.format('-%d', wc.visual_bytes) + end + if lines > 1 then + linecount = string.format(' / %d', lines) + end + return string.format('[%d%s%s]', wc.visual_chars, bytecount, linecount) + elseif mode == '' then + local cols = vim.fn.virtcol('.') - vim.fn.virtcol('v') + local line, col + if cols >= 0 then + line = vim.fn.getline('v') + col = vim.fn.charcol('v') - 1 + else + line = vim.fn.getline('.') + col = vim.fn.charcol('.') - 1 + cols = -cols + end + local char1width = vim.fn.strwidth(vim.fn.strcharpart(line, col, 1)) + return string.format('[%dx%d]', lines, cols + char1width) else return '' end From 88a9cc89fb0beaa24399605262385ce000502daa Mon Sep 17 00:00:00 2001 From: dmyTRUEk <25669613+dmyTRUEk@users.noreply.github.com> Date: Tue, 17 Oct 2023 16:30:43 +0300 Subject: [PATCH 2/2] feat: `selectioncount` formatting options --- README.md | 20 ++++++++ lua/lualine/components/selectioncount.lua | 56 +++++++++++++++++++---- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 6d988d5ac..f13ad9a8d 100644 --- a/README.md +++ b/README.md @@ -658,6 +658,26 @@ sections = { } ``` +#### selectioncount component options + +```lua +sections = { + lualine_a = { + { + 'selectioncount', + format = { + -- `%b`: bytes, `%c`: chars, `%l`: lines + single_line_no_multibyte = '[%c]', + single_line_multibyte = '[%c-%b]', + multi_line_no_multibyte = '[%c / %l]', + multi_line_multibyte = '[%c-%b / %l]', + visual_block_mode = '[%cx%l]', + } + } + } +} +``` + #### searchcount component options ```lua diff --git a/lua/lualine/components/selectioncount.lua b/lua/lualine/components/selectioncount.lua index 1c2e0d3ee..fdf6adbe1 100644 --- a/lua/lualine/components/selectioncount.lua +++ b/lua/lualine/components/selectioncount.lua @@ -1,16 +1,49 @@ -local function selectioncount() +local M = require('lualine.component'):extend() + +local default_format = { + single_line_no_multibyte = '[%c]', + single_line_multibyte = '[%c-%b]', + multi_line_no_multibyte = '[%c / %l]', + multi_line_multibyte = '[%c-%b / %l]', + visual_block_mode = '[%cx%l]', +} + +function M:init(options) + M.super.init(self, options) + self.format = vim.tbl_extend('keep', self.options.format or {}, default_format) +end + +function M:update_status() local mode = vim.fn.mode() local lines = math.abs(vim.fn.line('v') - vim.fn.line('.')) + 1 if mode == 'v' or mode == 'V' then local wc = vim.fn.wordcount() - local bytecount, linecount = '', '' - if wc.visual_chars ~= wc.visual_bytes then - bytecount = string.format('-%d', wc.visual_bytes) - end - if lines > 1 then - linecount = string.format(' / %d', lines) + local is_multibyte = wc.visual_chars ~= wc.visual_bytes + local is_multiline = lines > 1 + local chars = wc.visual_chars + if is_multiline then + if is_multibyte then + local bytes = wc.visual_bytes + return self.format.multi_line_multibyte + :gsub("^%%b", bytes):gsub("([^%%])%%b", "%1"..bytes) + :gsub("^%%c", chars):gsub("([^%%])%%c", "%1"..chars) + :gsub("^%%l", lines):gsub("([^%%])%%l", "%1"..lines) + else + return self.format.multi_line_no_multibyte + :gsub("^%%c", chars):gsub("([^%%])%%c", "%1"..chars) + :gsub("^%%l", lines):gsub("([^%%])%%l", "%1"..lines) + end + else + if is_multibyte then + local bytes = wc.visual_bytes + return self.format.single_line_multibyte + :gsub("^%%b", bytes):gsub("([^%%])%%b", "%1"..bytes) + :gsub("^%%c", chars):gsub("([^%%])%%c", "%1"..chars) + else + return self.format.single_line_no_multibyte + :gsub("^%%c", chars):gsub("([^%%])%%c", "%1"..chars) + end end - return string.format('[%d%s%s]', wc.visual_chars, bytecount, linecount) elseif mode == '' then local cols = vim.fn.virtcol('.') - vim.fn.virtcol('v') local line, col @@ -23,10 +56,13 @@ local function selectioncount() cols = -cols end local char1width = vim.fn.strwidth(vim.fn.strcharpart(line, col, 1)) - return string.format('[%dx%d]', lines, cols + char1width) + local chars = cols+char1width + return self.format.visual_block_mode + :gsub("^%%c", chars):gsub("([^%%])%%c", "%1"..chars) + :gsub("^%%l", lines):gsub("([^%%])%%l", "%1"..lines) else return '' end end -return selectioncount +return M