lualine.nvim
lualine.nvim copied to clipboard
Bug: selectioncount component gives the wrong size
It's not working correctly for visual block mode with
vim.opt.virtualedit = { 'block', 'onemore' }
neovim 0.9 on linux
Should be fixed now
Not yet fixed. It's also reporting wrong sizes when there are tabs, multibyte or wide characters.
Looking at the code, in the formula abs(start-end)+1
, the +1
is assuming chars to be 1 byte which may not be the case.
In visual-block mode, the columns could be reported with the vim.fn.virtcol()
function to fix the issue reported above. It almost works but still fails when the 1st char of the selected area starts is a wide character (e.g. emoji).
In visual mode, single line, the sizes should probably be reported by vim.fn.strchars()
and vim.fn.strlen()
functions to report the selected area size in chars and bytes.
Just to mention (to keep things in one place) there is also #1032.
I can confirm that #1042 works fine, but there are few things that i think should discussed:
- Should there be rectangular brackets?
- Maybe we should provide a user an option to configure formatting?
I'm using brackets to group and easily distinguish the output from other information shown, but it's just personal preference. A configuration option would be great.
Then I think we need 5 "things" for formatting this 5 cases:
- Single line, no multi-byte chars
- Single line, multi-byte chars
- Multi line, no multi-byte chars
- Multi line, multi-byte chars
- Visual block mode
As of what can be used as mentioned "things" i see three options:
- Simplest: strings for separators. Then config may look something like this (for the same result as now in your PR):
{
'selectioncount',
symbols = {
first = '[',
last = ']',
bytecount_separator = '-',
lines_separator = ' / ',
visual_block_line_symbols_separator = 'x',
},
}
- Cumbersome: functions, which will be pretty bulky for users, but (i think) pretty easy to implement. Config example:
{
'selectioncount',
format_functions = {
single_line_no_multibyte = {
function(chars)
return string.format('[%i]', chars)
end
},
single_line_multibyte = {
function(chars, bytes)
return string.format('[%i-%i]', chars, bytes)
end
},
multi_line_no_multibyte = {
function(chars, lines)
return string.format('[%i / %i]', chars, lines)
end
},
multi_line_multibyte = {
function(chars, bytes, lines)
return string.format('[%i-%i / %i]', chars, bytes, lines)
end
},
visual_block_mode = {
function(chars, lines)
return string.format('[%ix%i]', chars, lines)
end
},
},
}
- Perfect: user provides only format strings with named fields. But i understand that its pretty hard to implement. Config example:
{
'selectioncount',
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]',
},
}
Here %c
stands for chars
, %b
— bytes
, %l
— lines
.
Also, if we go this way, should we use %
to indicate formatting or perhaps some other symbol, like $
(used in kotlin) or {varname}
as used in python, c#, rust, or even something else?
I think would vote for the 1st one, for simplicity. The 3rd would be perfect, and is my preferred one for its customizability, but requiring some kind of parsing is a bit overkill for such a simple feature. Maybe in a later version?