vim-lion icon indicating copy to clipboard operation
vim-lion copied to clipboard

Inconsistent behavior in visual mode

Open blasco opened this issue 5 years ago • 9 comments

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:

Screenshot_2019-10-07_23-56-07

If I select a region and I perform the alignment operator with the '(' character as target, I get his:

Screenshot_2019-10-07_23-56-48

Which breaks the previous parts, which are not selected.

If I break the paragraph in two, then it works as I would expect:

Screenshot_2019-10-07_23-57-18

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.

blasco avatar Oct 07 '19 22:10 blasco

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); }},
};

blasco avatar Oct 07 '19 22:10 blasco

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)

blasco avatar Oct 07 '19 22:10 blasco

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.

tommcdo avatar Oct 09 '19 13:10 tommcdo

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.

tommcdo avatar Oct 09 '19 18:10 tommcdo

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 avatar Oct 10 '19 11:10 blasco

@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.

mg979 avatar Oct 13 '19 09:10 mg979

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.

tommcdo avatar Oct 14 '19 12:10 tommcdo

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'))

mg979 avatar Oct 14 '19 12:10 mg979

Looking forward to the update :)

blasco avatar Oct 19 '19 18:10 blasco