Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

Add node holding and swapping feature #14

Merged
merged 15 commits into from
Mar 18, 2023

Conversation

spiderforrest
Copy link
Contributor

I found myself needing to swap two nodes a far enough distance apart that sibling swapping was tedious, so I wrote small functions to 'hold' a node and then swap it with the focused node.
Notes:

  • I chose the time the extmark exists arbitrarily and it may be better changed
  • If you decide to merge this you may want to rerecord the demo because my vim is aesthetically jarringly different from the other demos

@bew
Copy link

bew commented Mar 17, 2023

Do you know about the vimscript-based plugin vim-exchange ?
I'm wondering: is this is a tree-sitter-aware variant, allowing to swap any TS nodes?

@spiderforrest
Copy link
Contributor Author

I did not know about vim-exchange, that looks cool, thanks.

This does allow swapping any TS nodes. The hold key just grabs the current node, and the swap key calls ts_utils.swap_nodes() on the held node and the current node.

@bew
Copy link

bew commented Mar 17, 2023

FYI vim-exchange uses the same key for hold and swap, Basically it works like this:
cx i) to hold the area inside braces, that area is now highlighted in some way
Move around and then
cx ap to swap the paragraph with the held area.
(ok maybe it's a weird example ^^)

(And other variants for different modes)

@spiderforrest
Copy link
Contributor Author

Oh, that makes sense. I'll implement that when I have a minute.

@spiderforrest
Copy link
Contributor Author

@bew, I added that as :STSSwapOrHold-that does what you suggested, right? I switched my personal bindings to that, it's much nicer. Thanks for the suggestion.

I ended up having it clear the held node when it's swapped, as it behaved poorly when swapped twice. I'm considering removing :STSHoldFocusedNode and :STSSwapHeldAndFocusedNodes. It doesn't make much sense to have them now that the held node is cleared when it's swapped and with :STSSwapOrHold available.

@ziontee113
Copy link
Owner

Hi @spiderforrest , thank you for opening the PR.
I've tried out the feature and I think it's great 👍

I wonder if you can add Visual Mode support for the feature as well. I ran into this example upon testing the PR:
Let's say we're in a Lua file, with this sample code:

vim.keymap.set("n", "vx", "<cmd>STSSelectMasterNode<cr>")

local something = "something else"

vim.keymap.set("n", "vd", function()
     vim.opt.opfunc = "v:lua.STSSwapCurrentNodeNextNormal_Dot"
     return "g@l"
end, { silent = true, expr = true })

If the user wants to swap the vim.keymap.set nodes, they can't, since the node under cursor is only vim, not the entire vim.keymap.set.... call.
Either with or without supporting Visual Mode, I'm curious to hear your thoughts on this use case.

@spiderforrest
Copy link
Contributor Author

I'd really like that functionality, I think it'd expand a lot on the use cases. This would be a really quick way to restructure code arbitrarily. I'm looking into implementing it now.

@spiderforrest
Copy link
Contributor Author

spiderforrest commented Mar 18, 2023

That seems to work mostly alright. I just moved the other visual code from M.surf into a function that returns a single node. The one bug I found was it triggers three undo events, instead of one. I think that's from the vim.cmd("normal! o") calls? Honestly I don't completely understand the chunk of code I copied into get_visual_node(), so I'm not sure why that doesn't happen with STSSwapNextVisual.

@ziontee113
Copy link
Owner

It works just fine on my end. I'll merge the PR for now, then I'll format with stylua and add "exit visual mode" after using STSSwapOrHoldVisual"

@ziontee113 ziontee113 merged commit 98a6d56 into ziontee113:master Mar 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants