Sublime Forum

Toggle Switch Recent Tabs in Sublime

#1

Hello everyone,

I’ve searched for something like this and can’t find if it exists. I’m looking for a way to toggle back and forth between the last and current tab of a given window in sublime. I know sublime has a way to go back and forth in the queue of opened files, but I’m looking for just a way to toggle back and forth.

The functionality would be exactly like this google chrome plugin: https://chrome.google.com/webstore/detail/toggle-switch-recent-last/odhjcgnlbagjllfbilicalpigimhdcll

Thanks in advance for any help.

1 Like

#2

If you do ctrl+p, the very first option will be the last opened file. So you can hit ctrl+p, enter and that will allow you to toggle back and forth.

0 Likes

#3

Thanks a lot @rslee That is quite helpful, I didn’t realize you could press enter immediately, I thought you had to select something in the quick find menu.

I know this may sound silly, but I would find it really worth it productivity wise to combine this into a single keybinding, instead of pressing 3 keys (ctrl+p, then enter).

I just tried recording a macro, of ctrl+p, then enter. But it seems the macro doesn’t save right when you switch to a different file. Another idea I had was to have a keybinding, (preferable alt+q, just like chrome) that maps to a keybinding [ctrl+p+enter]. But since the enter key has to be pressed after the ctrl+p I’m not sure how to do this.

Thanks so much for any help.

0 Likes

#4

You could potentially create a plugin that does this. Here’s a first draft of something that works (mostly; see below):

import sublime, sublime_plugin

# The last view we were in, which is None if there isn't one yet
# or it was closed
lastSeenView = None

class ToggleToLastViewCommand(sublime_plugin.WindowCommand):
    def run(self):
        # Jump to last seen view, if any
        if lastSeenView != None:
            self.window.focus_view (lastSeenView)

class ToggleEventListener(sublime_plugin.EventListener):
    def on_close(self, view):
        global lastSeenView

        # If the view being closed is the view we're toggling to, don't try
        # to toggle there any more.
        if view == lastSeenView:
            lastSeenView = None;

    def on_deactivated(self, view):
        global lastSeenView

        # If the view being deactivated isn't a file, do nothing
        if view.file_name () == None:
            return

        # If the view being deactivated is the view that we already think is 
        # the last view, then do nothing.
        if lastSeenView == view:
            return

        # Save this view as the last seen view
        lastSeenView = view;

Saving in (for example) Packages/User/toggle_to_last_view.py, you can bind it with something similar to:

    { "keys": ["alt+q"], "command": "toggle_to_last_view"}

(Note: The command name is derived from the name of the method that implements the command, not the name of the file that you save the code in).

As I mentioned above, this only “mostly” works. In particular, it gets confused if you open up the command panel or if you give the focus a panel (e.g. the console). As such, this is more of a proof of concept.

Also, this (crudely) checks if a view represents a file by checking if view.file_name () returns a value, which means that this only works for files that have been saved to disk at some point.

Replacing that test with some code that can accurately detect if a view represents a file (saved or otherwise) and not a panel or an input widget would make this more robust.

2 Likes

#5

Thank you so much @OdatNurd! I really appreciate the help. Your code should work for the vast majority of times I would use it. Just what I needed.

I don’t have much experience with Python scripts but something I definitely want to learn. I guess that really opens up more possibilities for sublime customization. I’ll try tweaking your code to make it ignore views anywhere other than the current sublime pane.

Anyways, thanks again!

0 Likes

#6

Glad you find it somewhat helpful! I’m fairly new to sublime so I’m still learning the API and its various ins and outs, so I like the chance to dig a little into things for the experience. :slightly_smiling:

0 Likes

#7

 
Here’s a workaround for that:

if view.settings().get( "is_widget" ):
	return

 
Anything that makes it through should be a legit view ( both saved & unsaved ).

2 Likes

#8

Unless I’m misunderstanding, ctrl+tab does this out of the box

0 Likes

#9

I thought so too initially, but he wants a key that will switch between the current tab and the most recently active tab, with those two items switching places (e.g. just always flipping between a .c file and its associated .h file.

The command bound to Ctrl+Tab seems to cycle through all of the tabs in the tab stack in their MRU order, so if you have 4 tabs open it cycles through all of them instead of just flipping between the two.

0 Likes

#10

ctrl+tab works the same as alt+tab / command+tab do at the application level: if you press ctrl+tab, then release ctrl, you can toggle between two files. If you hold down ctrl, and press tab multiple times, than you can visit the last N files.

On a tangent, for the .h/.c case, you likely want to use the key binding associated with the “Goto/Switch File/Switch Header/Implementation” menu

2 Likes

#11

You know, I would swear that I tried that very thing earlier when I saw that was the key that the next_view_in_stack key was bound to, because that sounded like how it should work. Clearly I was being a bozo and not letting go of ctrl. Sorry for the noise.

1 Like

#12

Thanks all for the input everyone! I can’t believe I wasn’t aware that ctrl+tab could toggle back and forth (I was always holding down ctrl while doing it, which meant it cycled through the stack). I do still prefer the python script solution because it would be great if I didn’t have to release the key for it to toggle back and forth.

Next thing I’ll dig into is how to include logic like:

if view.pane () != lastSeenPane
   return;

I’ve never dug into sublime API… or even written python… (pure full stack JS but I know I need to get good with another language) so I’m sure that is nonsense… but I’ll figure it out, unless someone is bored :slight_smile: would be great to have these events ignore views in different panes than original pane toggle was fired in. It would be even cooler if each pane was treated as a separate entity, so that toggling could “remember” the last view for each separate pane. But that might be a bit much

0 Likes

#13

Ok I just discovered how it works but I almost raged on the forum.

For readers, press Ctrl + Tab, then release both keys, then press Ctrl + Tab again and you will go back to the previous tab.

0 Likes