vimium icon indicating copy to clipboard operation
vimium copied to clipboard

Design UX for moving a tab to an existing window

Open philc opened this issue 10 months ago • 3 comments

See #2407 for the initial feature request and discussion.

To organize the discussion, I'm splitting off the UX discussion and proposal for this feature into this separate issue.

UX requirements

  • One should be able to move multiple tabs quickly. This can be supported with a count prefix. If we had a "dot" (repeat) command, that could be another way to quickly move many tabs.
  • The moved tab should be focused after the move. We can add a parameter on the command to leave the focus in the source window.
  • Tabs should only be movable to windows with the same privacy state (normal vs. incognito).

Not requirements

  • Undoing a tab move via a specific command or a general "undo" command (Vimium doesn't currently have an undo command). The undo would put the tab back exactly where it came from.
  • Handling tab groups. I don't use tab groups and don't know how this command should interact with them, but I did notice that the MoveTabToNextWindow extension will preserve the tab group across window moves.

UX options

1) Show a window picker

  • Show the Vomnibar with a list of windows, sorted by most recently used, and pick the destination window.
  • This is implemented in PR #3925.
  • Highlight the target window: it would be nice, maybe essential, to highlight the target window that's selected in the Vomnibar (e.g. with a outline around the target window's active tab).
  • Chrome has this UX already: if you right click on a tab > Move to another window, it shows a list of windows of the form "'name of active tab' and N other tabs", ordered by most-recently-accessed. Moving a tab automatically switches to it.

2) Move to a window in a direction

  • Implemented in PR #4417.
  • If windows are stacked, it's unclear how to disambiguate which one is in a given direction, or how to allow the user to move a tab to a window which isn't the topmost.

3) Move the tab to the "next" window, AKA moveTabToNextWindow

  • Implemented in PR #4168.
  • "Next" could mean the next most recently accessed window, or the next window sorted by creation time. Vimium C implements the latter.
  • You can get a window to its destination by repeating this command (ideally via a dot operator) until the tab lands in the correct window, similar to Vim's split swapping commands.
  • This is laborious if there's many windows, and it's unclear how to handle windows which are stopped on top of each other, especially if we allow the source window to stay focused, rather than focusing the destination window.

4) Cut-and-paste

  • Do one cut command, switch to the destination window, and then perform a paste command.
  • Mentioned in this comment.
  • This is powerful, in that you can schedule one or more tabs to be moved, then switch to where precisely where where you want them pasted, and then paste. This is a similar workflow to cutting and pasting text across files/splits in Vim.
  • We could implement this as a stack, such that issuing several cut commands queues up all of those tabs to be moved. However, this might be surprising, and is more complicated -- if you made a mistake and want to start over, how do you cancel the current stack?
  • It's conceptually more involved, and less approachable, than a single command.

Other references

  • There's a small Chrome extension which implements just this feature and has some interesting UX choices.
  • If we support performing actions on tabs from the Vomnibar (#4611), "move to another window" would be a natural one.

Comments

Of these options, I think (1) is the simplest: it doesn't have any difficult UX drawbacks, and it takes direct inspiration from the way tab moving already works in Chrome, which is a general design goal for Vimium.

What do you think?

philc avatar Feb 24 '25 06:02 philc

Thank you for starting this discussion. A few thoughts:

  • I do like option 1 as it is simple to implement and understand. It also has virtually infinite UX flexibility/design complexity.
  • There might not be a reason that we can't have multiple solutions. Moving to the window in a direction seems like a nice complement to any other solutions.
  • Any solution (if not based on window position) must also be easily expandable in the future to other kinds of moving. The next obvious feature request we will get is moving tabs to groups, if we can move them to a window. We want to be able to do all of this in a consistent way.
  • Personally I think I would be most likely to use a cut and paste feature. However, it would be hard to use/understand as described above if I need to switch to each tab to cut it and it gets added to some invisible cut buffer. See my proposal for my preferred way to implement cutting/pasting tabs.
  • No matter which of those options we use, the expected functionality would be that the action applies to all selected tabs, not only the currently open one. If I select some tabs in the tab switching bar of my browser then push whatever the move command is, it should apply to all of those tabs. This would be the "natural" way I expect a user to try to move multiple tabs, and seems non-negotiable to fulfill user expectations/avoid frustration. This might be a new conversation though, since existing commands like ">>" to move a tab do not respect tab selection. We may want a feature to change this.

Far beyond the scope of the basic tab window mover, it would be very nice to have a better general tab management solution. In Neovim I use two plugins with a UX that I really like: oil.nvim and harpoon, that allows manipulating files or quick switcher in a text buffer. This means that I very easily cut and paste lines wherever I want them with the commands I already know. That UX is a bit complicated/unintuitive for most people, so it would be better as below:

My proposal: build a generalized "tab manipulator" overlay.

With only a few functions, this could be extremely useful for reordering tabs, moving them to windows, closing them, or any functions we want in the future. I would propose a similar shortcut/UX design to ranger and lf file browsers, as described (note this is a "full-featured" description, we could build a simpler MVP):

  • List all tabs in a scrolling list.
  • Must be sorted by window order (at least by default) to support reordering tabs.
  • j/k to navigate up and down the list
  • space to add/remove a tab from the selection
  • x to close all selected (or current hovered)
  • d to cut all selected (or hovered)
  • y to yank all selected (or hovered)
  • p/P to paste cut/yanked tabs
  • / to filter the list
  • esc to clear filter
  • v/V to select all/none currently shown tabs
  • c to clear clipboard/selection
  • o or enter to open hovered tab
  • We could also support Firefox hidden tabs here, or any other future functionality we want.

Something like this is probably far beyond the scope of main fork vimium, but it would provide an easy, quite understandable way to perform powerful and fast mass (or single) tab manipulation. I think I could implement this if people do want it in main. It would look something like:

  • Window 1
    • Dev group - Dev tab 1 - Dev tab 2 - Dev tab 3
    • Group 1 - G1 tab 1 - G1 tab 2
    • Other tab 1
    • Other tab 2
  • Window 2
    • W2 tab 1
    • W2 tab 2
    • W2 tab 3

If I wanted to move, for example, all tab 1s to Window 2, I could type "/ 1" so the list looks like:

  • Window 1
    • Dev group - Dev tab 1
    • Group 1 - G1 tab 1
    • Other tab 1
  • Window 2
    • W2 tab 1

Then press "v" (or "V", depending our shortcut choice) to select all, then "d" to cut. All tabs would be highlighted as in the cut buffer. then I can move cursor to Window 2 and push "p" to paste.

Note that windows and groups stay visible even on filter, allowing for them to still be paste targets. So if I want to just move one tab I could do that with this UX as well by filtering until I find it, pressing d, then p on the window. So if I filtered by "Other 1" it would look like:

  • Window 1
    • Dev group >
    • Group 1 >
    • Other tab 1
  • Window 2

There are a lot of nuances here, but a workflow for conveniently moving tabs based on name, and reordering tabs, and also allowing for moving to other windows, and moving to other groups, seems best supported by some sort of "tab manipulation window," even if the UX is quite different from that proposed here. We could do something very similar if we added actions to the tab picker #4611 if we allow performing the action on all or "most" of the search results, in some way (although it wouldn't be quite as flexible).

Summary: In my opinion we need a better flexible way to perform actions on many tabs, like closing many, anyway. To me, it makes sense to either 1) build this into the tab picker or 2) build some sort of tab manipulator. Either of these could then be used for move to window/group.

UncleSnail avatar Mar 08 '25 08:03 UncleSnail

I'm not sure if this is still actively being worked on or looked into, but one consideration that is essential for my use-case is that, along with being able to move individual or selected tabs to a specified window, there should also be a simple way to effectively merge an entire window (all tabs) to another window - at the very least the window it was detached from (if it still exists). I often find myself detaching a tab into its own window, creating more tabs in that window, and then wanting to merge that window back to the window it was detached from; i.e., W -> t (n times) -> <reattach-tab>. It would be cumbersome to execute something like <moveTabToWindow> on all tabs, as would your proposed option 4 of yanking all tabs and moving back to the other window and pasting them. I agree that option 1 is the most sensible and provides the most flexibility. I think something like <Vomnibar.moveTabToWindow> along with <Vomnibar.mergeWindows> would make the most sense. So if you wanted to move a single tab, you could invoke the vomnibar method to move that tab to a specified window, or you could invoke a method to merge the current window with all its tabs to the specified window.

ASong5 avatar Nov 11 '25 15:11 ASong5

If we come to a consensus on UX, I am willing to work on a PR or work on updating one of the existing PRs to work with modern Vimium code.

UncleSnail avatar Nov 11 '25 20:11 UncleSnail