Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mini.move: less intrusive blockwise movement #838

Open
2 tasks done
matu3ba opened this issue Apr 24, 2024 · 1 comment
Open
2 tasks done

mini.move: less intrusive blockwise movement #838

matu3ba opened this issue Apr 24, 2024 · 1 comment
Labels

Comments

@matu3ba
Copy link

matu3ba commented Apr 24, 2024

Contributing guidelines

Module(s)

mini.move

Description

Use case
Drawing block selections up and down breaks right-wards indentation, which can make virtual edits for adjusting graphics unnecessary painful. I hope below drawings show the problem. Any kind of ideas would be appreciated.

Problem Description

got

                           ┌──────────────┐
                           │              │
                           │              │
          ┌────────────┐   │              │
          │    upsii   │   │              │
          │     123    │   │              │
          │            │   └──────────────┘
          │            │
          │            │
          └────────────┘

want without redundant steps
1 box selection copy
2 selection replace whitespace
3 selection wanted position and paste

                           ┌──────────────┐
                           │              │
                           │              │
          ┌────────────┐   │              │
          │            │   │              │
          │            │   │              │
          │    upsii   │   └──────────────┘
          │     123    │
          │            │
          └────────────┘

current behavior:
1 line selection movements dont work for multiple lines
2 minimove.move_selection up/down breaks right-hand intendation

                           ┌──────────────┐
                           │              │
                           │              │
          ┌────────────┐   │              │
          │       │   │              │
          │       │   │              │
          │    upsii        │   └──────────────┘
          │     123         │
          │            │
          └────────────┘

It would be nice, if move_selection would have another mode
so that a move is an actual swap of text elements freely
into the buffer positions, so moving 1 upwards does

                           ┌──────────────┐
                           │              │
                           │              │
          ┌────upsii───┐   │              │
          │     123    │   │              │
          │    ─────   │   │              │
          │            │   └──────────────┘
          │            │
          │            │
          └────────────┘

and moving 1 more upwards does

                           ┌──────────────┐
                           │              │
               upsii       │              │
          ┌──── 123 ───┐   │              │
          │    ─────   │   │              │
          │            │   │              │
          │            │   └──────────────┘
          │            │
          │            │
          └────────────┘

until

               upsii       ┌──────────────┐
                123        │              │
                           │              │
          ┌────────────┐   │              │
          │            │   │              │
          │            │   │              │
          │            │   └──────────────┘
          │            │
          │            │
          └────────────┘

with the internal position of the collision range be kept.
To me it looks like you have implemented collision detection,
but nothing to keep track of correct fixups after nothig collides.
For example, left and right movements have the same behavior:

                           ┌──────────────┐
                           │              │
                           │              │
          ┌────────────┐   │              │
  upsii        │       │   │              │
   123         │       │   │              │
          │            │   └──────────────┘
          │            │
          │            │
          └────────────┘
local selmove_hint = [[
 Arrow^^^^^^
 ^ ^ _k_ ^ ^
 _h_ ^ ^ _l_
 ^ ^ _j_ ^ ^                      _<C-c>_
]]

local ok_minimove, minimove = pcall(require, 'mini.move')
assert(ok_minimove)
if ok_minimove == true then
  local opts = {
    mappings = {
      left = '',
      right = '',
      down = '',
      up = '',
      line_left = '',
      line_right = '',
      line_down = '',
      line_up = '',
    },
  }
  minimove.setup(opts)
  -- setup here prevents needless global vars for opts required by `move_selection()/moveline()`
  M.minimove_box_hydra = Hydra {
    name = 'Move Box Selection',
    hint = selmove_hint,
    config = {
      color = 'pink',
      invoke_on_body = true,
    },
    mode = 'v',
    body = '<leader>vb',
    heads = {
      {
        'h',
        function() minimove.move_selection('left', opts) end,
      },
      {
        'j',
        function() minimove.move_selection('down', opts) end,
      },
      {
        'k',
        function() minimove.move_selection('up', opts) end,
      },
      {
        'l',
        function() minimove.move_selection('right', opts) end,
      },
      { '<C-c>', nil, { exit = true } },
    },
  }
  M.minimove_line_hydra = Hydra {
    name = 'Move Line Selection',
    hint = selmove_hint,
    config = {
      color = 'pink',
      invoke_on_body = true,
    },
    mode = 'n',
    body = '<leader>vl',
    heads = {
      {
        'h',
        function() minimove.move_line('left', opts) end,
      },
      {
        'j',
        function() minimove.move_line('down', opts) end,
      },
      {
        'k',
        function() minimove.move_line('up', opts) end,
      },
      {
        'l',
        function() minimove.move_line('right', opts) end,
      },
      { '<C-c>', nil, { exit = true } },
    },
  }
end
@matu3ba matu3ba added the feature-request Feature request label Apr 24, 2024
@echasnovski echasnovski changed the title mini.move: Movements and block movements as virtual edits with collision detection and fixups mini.move: less intrusive blockwise movement Apr 24, 2024
@echasnovski
Copy link
Owner

Thanks for the suggestion!

I can reproduce. At first glance, it is indeed not a very good behavior. However, blockwise movement is kind of lesser tier of support for 'mini.move' because of how complicated it is to implement.

I'll look more into why this happens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants