vim-lion
vim-lion copied to clipboard
Inconsistent behavior in visual mode
First of all, I think this operator is great! I'm observing some strange behavior that I think we could improve. As an example, I have this:
If I select a region and I perform the alignment operator with the '(' character as target, I get his:
Which breaks the previous parts, which are not selected.
If I break the paragraph in two, then it works as I would expect:
Would it be possible to have the same behavior without having to break in blocks the paragraph? I don't want that the alignment of the unselected zone gets affected, so I can align part by part.
The text I'm playing around as test case:
static const Utils::UnorderedMap<test::BuiltinType, PortFunction> generate_port_map
{
{ test::UINT8, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint8_t>(_direction, _name, _description); }},
{ test::UINT16, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint16_t>(_direction, _name, _description); }},
{ test::UINT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint32_t>(_direction, _name, _description); }},
{ test::UINT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint64_t>(_direction, _name, _description); }},
{ test::BOOL, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<bool>(_direction, _name, _description); }},
{ test::BYTE, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int8_t>(_direction, _name, _description); }},
{ test::CHAR, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint8_t>(_direction, _name, _description); }},
{ test::INT8, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int8_t>(_direction, _name, _description); }},
{ test::INT16, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int16_t>(_direction, _name, _description); }},
{ test::INT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int32_t>(_direction, _name, _description); }},
{ test::INT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int64_t>(_direction, _name, _description); }},
{ test::FLOAT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<float>(_direction, _name, _description); }},
{ test::FLOAT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<double>(_direction, _name, _description); }},
{ test::STRING, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<std::string>(_direction, _name, _description); }},
};
Result objective:
static const Utils::UnorderedMap<test::BuiltinType, PortFunction> generate_port_map
{
{ test::UINT8, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint8_t> (_direction, _name, _description); }},
{ test::UINT16, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint16_t> (_direction, _name, _description); }},
{ test::UINT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint32_t> (_direction, _name, _description); }},
{ test::UINT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint64_t> (_direction, _name, _description); }},
{ test::BOOL, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<bool> (_direction, _name, _description); }},
{ test::BYTE, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int8_t> (_direction, _name, _description); }},
{ test::CHAR, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<uint8_t> (_direction, _name, _description); }},
{ test::INT8, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int8_t> (_direction, _name, _description); }},
{ test::INT16, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int16_t> (_direction, _name, _description); }},
{ test::INT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int32_t> (_direction, _name, _description); }},
{ test::INT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<int64_t> (_direction, _name, _description); }},
{ test::FLOAT32, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<float> (_direction, _name, _description); }},
{ test::FLOAT64, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<double> (_direction, _name, _description); }},
{ test::STRING, [] (const auto _direction, const auto& _name, const auto& _description) { return BT::fun<std::string>(_direction, _name, _description); }},
};
My only approach right now is to break with the block-visual mode and align each part, the objective would be to align it without having to break it down into pieces (breaking it down with the selection block)
Do you have let g:lion_squeeze_spaces = 1
in your vimrc? That's an option that's off by default, but it tells lion to effectively reset any alignment in the text. Setting it back to 0
(or not setting it at all) would address this.
That said, I think that feature needs some refinement. It shouldn't squeeze out spaces related to another alignment. I'll consider this a bug.
I do have that option set to 1. Setting it to 0, that solves the problem, but I do like that option. As you said it would be great if it would work with the option on. Thank you for the outstanding plugin once again.
@blasco did you try to align in visual block mode, only selecting the block you want to align?
Anyway, in my fork I added mappings to have both behaviours, without needing to set the option.
https://github.com/mg979/vim-lion/commit/305e038b345a94437f7d579b3ebde1355cbe4761
If there's interest from @tommcdo I could make a PR.
I changed the mappings, though:
g[ -> alignRight
g] -> alignLeft
g{ -> alignSqueezeRight
g} -> alignSqueezeLeft
I know g]
is a vim default, but I couldn't find better mappings, they're configurable though.
I actually just confirmed that even with a Visual Block selection that starts to the right of the aligned text, those spaces to the left will be squeezed when g:lion_squeeze_spaces
is enabled.
I think the expected behaviour would be that only spaces related to the targeted alignment character should be affected. If any spaces are skipped (either by Visual Block selection or by supplying a count), they should not be squeezed.
Replacing https://github.com/tommcdo/vim-lion/blob/75306ac1922952ca1a401aee43ddbb304029926d/plugin/lion.vim#L77
with
call setline(lnum, substitute(getline(lnum), '\%>'.pos[5].'c\(^\s*\)\@<! \{2,}', ' ', 'g'))
should fix it
Edit:
let pre = visualmode() ==# "\<C-v>" ? '\%>'.pos[5].'c' : ''
call setline(lnum, substitute(getline(lnum), pre.'\(^\s*\)\@<! \{2,}', ' ', 'g'))
Looking forward to the update :)