-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Adds completion for tab-focus. #1317
Conversation
try: | ||
index = int(index) | ||
except ValueError: | ||
raise cmdexc.CommandError("tab-focus takes an int or 'last' not: {}".format(index)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between checking this here and the way it was before (via the argument annotation, index: {'type': (int, 'last')}=None
)?
(I didn't actually check, but they should do the exact same thing, no?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I suppose it would do the same thing. Since typing until there is only one option left then pressing enter passes a string through I was going to add a title to index lookup there for one less keypress but that seems like way too much effort. I'll change it back.
Handling multiple windows obviously is the biggest problem here, yeah. The concept of a "current window" doesn't really exist when the completions are being rebuilt, and currently there's no mechanism for the completion to let the model know the current window when the completion is being invoked. Those are good ideas to keep in mind for #74 somewhen in the future though. I'd suggest a slightly different approach: Don't add a completion for Then you can iterate over all windows (e.g. via |
#32 is the related issue, by the way - a |
aye aye! ✨ 😃 👍 |
Alrighty. I changed the completion model to iterate over all windows, put |
So I played with this a bit - seems quite nice, but it seems the completion doesn't update correctly when I do I'll also add some line comments for some style things - thanks for this again, looking forward to it! |
index: The win_id/index of the tab to focus. Or a substring | ||
in which case the closest match will be focused. | ||
""" | ||
if not index or not len(index): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty strings are false in Python, so checking if not index:
here is enough.
On the other hand, why not just make index
mandatory by removing the =None
default?
Yeah ... coulda sworn that worked during testing. Looks like because there is no notification of new windows (or new |
I cleaned up commands:buffer() and added a signal |
I think that's the best solution - I'll leave some more line comments. |
idx = int(index) | ||
win_id = 0 | ||
active_win = objreg.get('app').activeWindow() | ||
if not active_win == None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be if active_win is not None:
Can you please also try writing some end-to-end tests for this? You can find some inspiration in |
Sorry for taking so long getting back to you. Writing tests is not very motivating. Hope this addresses your concerns. |
# Not sure how you enter a command without and active window... | ||
raise cmdexc.CommandError( | ||
"No window specified and couldn't find active window!") | ||
win_id = active_win.win_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add an else: raise AssertionError("Unexpected index length {}".format(len(index_parts)))
or so here, so there's a defined behaviour if that should ever happen (e.g. by someone changing the completion model in the future) rather than undefined behaviour?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well there is a index_parts = index.split('/', 1)
at the top of the method so there really isn't going to b more than 2 parts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, I missed that 😄
95b6229
to
7f86c61
Compare
fwiw, I've been @toofar 's tab-complete branch with no issues. If I try to access |
Thanks for letting me know! Now that the crowdfunding is up I can get back to coding and reviewing PRs, so I'll probably merge this in the coming few days. |
Using -m py.test seems to cause some issues, see e.g. #1317 (comment)
QTimer.singleShot(0, self.rebuild_cat) | ||
|
||
@pyqtSlot(str) | ||
def rebuild_cat(self, arg=None): # pylint: disable=unused-argument |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reason for the argument here? It seems to work fine when I use @pyqtSlot()
and drop the , arg=None
. Note slots can have less arguments than the signals they're connected to.
When I close a window, I still see the window category when typing Could you also fix the line comments and the few nitpicks found by the linters?
Can you also run After that, I think this is ready to merge - thanks a lot! |
Since I already added a tabbed_browser.new_window signal I suppose I could add a window_close signal too. |
Thanks for the quick reaction!
Sounds good - can you try if that helps? I'm not entirely sure (due to how What do you think about keybindings for |
`buffer` takes either a tab index or a string and focuses the specified tab. The index can be of the form [0-9]+ which will switch to the relevant tab in the current window or [0-9]+/[0-9]+ (that is win_id/index) which will focus the specified window before switching tabs. If a string is passed the list of open tabs across all windows is sorted based on title and url (just like in the completion widget) and the top result is selected.
The buffer_troubling_args tests may look a little un-intuitive but that is because they are testing the edge cases for the current behaviour. If these edge cases are encountered during normal usage you are doing something wrong.
Turns out the model was getting rebuilt after a window closed (due to the For the keybindings I am just using |
Merged - thanks for the great work, and sorry for the delays! |
Using -m py.test seems to cause some issues, see e.g. qutebrowser#1317 (comment)
It's been a couple of years - but since a long time, we can get the current |
Thanks for still being committed to PRs as old as this one! I understood that the PR backlog was a bit of hurdle, so good luck with the other ones you plan to do! |
This is so you can jump between tabs based on tab title or URL instead
of just index just like the
buffer
command in vim. Adds ab
aliasfor
tab-focus
to be more like vim too.The method of updating the completion model (rebuild the whole thing
every time a tab is created, removed or updated) is inefficient but is
still very fast for even unreasonable numbers of open tabs.
TODO: I did a quick test and it doesn't seem to work with multiple windows.
Probably because of how I am getting the
win_id
. Can anyone tell me howto get the current
win_id
?