notomo / gesture.nvim

Mouse gesture plugin for neovim
MIT License
527 stars 2 forks source link

Gesture with window context #40

Closed m3at closed 1 year ago

m3at commented 1 year ago

Hi, thank you for building this interesting plugin. I'm not sure how to build a gesture that would depend on window location, would something like the following be possible?

Example if I have the following window layout:

    │     │  C  
 A  │  B  │─────
    │     │  D

I'd like to click and drag from A to D, and end up with:

    │     │  C  
 D  │  B  │─────
    │     │  A
notomo commented 1 year ago

Thanks for interesting question.

Unfortunately, it is not supported currently. But I may add functions so that the following gestures are possible.

📝 not implemented yet

local swap = function(first_window_id, last_window_id) -- this implements by user side
  local first_window_view = vim.api.nvim_win_call(first_window_id, function()
    return vim.fn.winsaveview()
  end)
  local first_bufnr = vim.api.nvim_win_get_buf(first_window_id)

  local last_window_view = vim.api.nvim_win_call(last_window_id, function()
    return vim.fn.winsaveview()
  end)
  local last_bufnr = vim.api.nvim_win_get_buf(last_window_id)

  vim.api.nvim_win_set_buf(first_window_id, last_bufnr)
  vim.api.nvim_win_call(first_window_id, function()
    vim.fn.winrestview(last_window_view)
  end)

  vim.api.nvim_win_set_buf(last_window_id, first_bufnr)
  vim.api.nvim_win_call(last_window_id, function()
    vim.fn.winrestview(first_window_view)
  end)
end

local gesture = require("gesture")
gesture.register({
  name = "swap",
  match = function(ctx) -- should avoid heavy operation because called every gesture.draw()
    if ctx.inputs[1] ~= gesture.up() then -- optional prefix
      return false
    end
    local tab_number = vim.api.nvim_tabpage_get_number(ctx.tabpage)
    return vim.fn.tabpagewinnr(tab_number, "$") >= 2 and ctx.first_window_id ~= ctx:last_window_id()
  end,
  action = function(ctx)
    local first_window_id = ctx.first_window_id
    local last_window_id = ctx:last_window_id()
    swap(first_window_id, last_window_id)
    vim.api.nvim_set_current_win(last_window_id)
  end,
})
m3at commented 1 year ago

Thanks for considering this! I can't get the snippet above to work (fail with attempt to call method 'last_window_id' (a nil value)), I assume this is the part that would need to be implemented?

notomo commented 1 year ago

I assume this is the part that would need to be implemented?

Yes.

ctx has only last_position now.

https://github.com/notomo/gesture.nvim/blob/a0782e18c020ecbb60e4fc7214aef2cb92fe8838/doc/gesture.nvim.txt#L88-L91