balta2ar / brotab

Control your browser's tabs from the command line
MIT License
389 stars 27 forks source link

Moving tabs programmatically (move all tabs into a single window.) #56

Closed bjohas closed 2 years ago

bjohas commented 3 years ago

Hello - brotab is amazing, thank you!

I am looking for a way to move tabs between windows programmatically. brotab move is great for manual reordering, but what if I want to do this programatically? The use case is to move all tabs into a single window.

Obviously, one could archive this with bt close and bt open, but the 'move' is actually a move: I.e., the tab isn't reloaded.

My questions are:

(1) Is it possible to do moving (and reordering) using direct bt commands?

(2) Is it possible intercept the action of bt move? I.e., let bt move write the temp file, edit it outside the editor, and then tell bt move that I'm done?

I guess, Item (2) would be possible by passing EDITOR=my-brotab-editor to brotab, but that's a somewhat roundabout way of doing things...

Many thanks!

bjohas commented 3 years ago

When moving, brotab seems to use an object like this:

MOVE [(575, 184, 2), (248, 184, 3), (296, 184, 4), (492, 184, 5), (497, 184, 6), (481, 184, 7), (580, 184, 8), (583, 184, 9), (586, 184, 10)]

which is tab number, window number and tab position. Is it possible to issue such a command directly, e.g.,

brotab MOVE "[(575, 184, 2), (248, 184, 3), (296, 184, 4), (492, 184, 5), (497, 184, 6), (481, 184, 7), (580, 184, 8), (583, 184, 9), (586, 184, 10)]"

or similar?

balta2ar commented 3 years ago

Hi! Thanks for the nice words :)

one way

would be possible by passing EDITOR=my-brotab-editor to brotab, but that's a somewhat roundabout way of doing things

You're actually close to what I wanted to suggest. Depending on the details of your use case you could write a tiny script to collapse all the tabs into a single window and assign it to a shortcut. E.g. if you have a list of tabs:

$ cat list.txt
a.1.1   Gmail   https://mail.google.com/mail/u/0/#inbox
a.10.3  Translations of https://www.lingvolive.com/en-us/translate/en-r>
a.20.2  Google Keep     https://keep.google.com/
a.528.533       title1  url1
a.528.534       title2  url2

What you need to do is to replace all prefixes and windows with a.1, e.g.:

$ /tmp/1/move.py list.txt
a.1.1   Gmail   https://mail.google.com/mail/u/0/#inbox
a.1.3   Translations of https://www.lingvolive.com/en-us/translate/en-r>
a.1.2   Google Keep     https://keep.google.com/
a.1.533 title1  url1
a.1.534 title2  url2

EDIT: Forgot to mention that this script is basically an "editor", so you should do:

EDITOR=/tmp/1/move.py bt move

Note that currently move between different browser instances (or between different brotab mediators) is not supported, because it's not just a move, it's "close" + "open new tab with a URL".

EDIT2: here's a sample move.py

#!/bin/env python3

import fileinput

class TabId:
    def __init__(self, prefix: str, window: str, index: str):
        self.prefix = prefix
        self.window = window
        self.index = index
    def __repr__(self):
        return f'{self.prefix}.{self.window}.{self.index}'

class Line:
    @staticmethod
    def parse(string: str):
        id, title, url = string.split('\t', 3)
        prefix, window, index = id.split('.', 3)
        return Line(TabId(prefix, window, index), title, url)
    def __init__(self, id: TabId, title: str, url: str):
        self.id = id
        self.title = title
        self.url = url
    def __repr__(self):
        return f'{self.id}\t{self.title}\t{self.url}'

first = None
for string in fileinput.input():
    line = Line.parse(string)
    first = first or line.id
    line.id = TabId(line.id.prefix, first.window, line.id.index)
    print(line, end='')

another way

possible to issue such a command directly

Yes it is possible! First figure out the port of the corresponding brotab mediator:

bt clients
a.      localhost:4625  3910886 firefox
b.      localhost:4626  1732320 chrome/chromium

Then send a move request directly (move triples are " "):

curl 'http://localhost:4625/move_tabs/2 1 20'

This will move tab id "2" into window "1" with position "20".

There are more commands available if you need them, but they are pretty low level:

$ curl 'http://localhost:4625/'                    
get_active_tabs /get_active_tabs
get_browser     /get_browser
list_tabs       /list_tabs
open_urls       /open_urls
get_words       /get_words/
shutdown        /shutdown
get_text        /get_text/
get_html        /get_html/
get_pid /get_pid
root_handler    /
activate_tab    /activate_tab/<int:tab_id>
query_tabs      /query_tabs/<query_info>
close_tabs      /close_tabs/<tab_ids>
open_urls       /open_urls/<int:window_id>
move_tabs       /move_tabs/<move_triplets>
get_words       /get_words/<string:tab_id>/
new_tab /new_tab/<query>
static  /static/<path:filename>
bjohas commented 3 years ago

@balta2ar - that's amazing, thank you for the detailed response! Works for me, thanks! This didn't work for me:

curl 'http://localhost:4625/move_tabs/2 1 20'

I had to url encode:

curl http://localhost:4625/move_tabs/2%201%2020

Very cool - thanks again!