Sublime Forum

Multi-Line Tabbar for ST2

#1

Hi folks,

I work with ST2 for one week now (coming from Notepad++) and the only thing really annoying me, is that the titles of the tabs are truncated when a lot of tabs are open and there is no multi row tab layout. So I used the ST layout to provide a hacky kind of multiple line tabs:

import sublime, sublime_plugin

multi_col_layout = 1
bar_height = 0.025

class MultiColumnTabBarCommand(sublime_plugin.EventListener):
  def on_activated(self, view):
    a = sublime.active_window()
    b = a.get_view_index(view)

    if (b[0] == 0) and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols":[0.0,1],"rows":[0.0,bar_height,bar_height*2,1],"cells":[0,2,1,3],[0,0,1,1],[0,1,1,2]]})

    if (b[0] == 1) and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols":[0.0,1],"rows":[0.0,bar_height,bar_height*2,1],"cells":[0,0,1,1],[0,2,1,3],[0,1,1,2]]})

    if (b[0] == 2) and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols":[0.0,1],"rows":[0.0,bar_height,bar_height*2,1],"cells":[0,0,1,1],[0,1,1,2],[0,2,1,3]]})

class ToggleMultiColLayoutCommand(sublime_plugin.TextCommand):
  def run(self,edit):
    global multi_col_layout
    if (multi_col_layout == 1):
      multi_col_layout = 0
      print "Multi Col Layout disabled"
    elif (multi_col_layout == 0):
      multi_col_layout = 1
      print "Multi Col Layout enabled"

https://docs.google.com/uc?export=download&id=0B6wrxUDLue4IWm9TS1hHVjkteEU

This is a quite static approach to provide a 3 row tab layout. The main idea is to set up a 3 row layout and only show one tab group whereas only the top of the other tabgroups is shown above. On click on a tab of another group, the active group is changed and shown whereas the others go to background.

Known issues are:

  • the height of a tab row is dependent on screen resolution and window size; can be manually adjusted using the bar_height variable
  • goto anything opens a file in the focussed tab group although it is already open in another group
  • 3 static rows
  • tabs have to be distributed to tab rows manually (i.e. drag and drop)
  • not compatible to own layouts (split column,…), therefore can be disabled by toggle_multi_col_layout command
    -…

For me it is fine like this and maybe it is helpful for someone else, but of course I would also appreciate if there is a Python/ST expert who can make this more flexible.

Best regards,
wwwweb

0 Likes

#2

Great work. I know it is not the complete solution, but I would take it as an interim solution. It allows me to view filenames easily. Heck…I use three rows as a way to sort files from three different projects too!!!

Thanks. It has crashed on me some times, but I am ok with that.

Thanks again.

0 Likes

#3

neat hack,
i guess by hooking EventListener.on_activate to detect the click on a tab and using Window.set_view_index to move the tab to lowest pane you should be able to mimic multiline tabbar behaviour really close

0 Likes

#4

Hi,

Thanks for the positive responses, nice to hear that it is useful to someone else. In combination with the “run multiple commands” plugin Run Multiple Commands.. Command , I created some keyboard shortcuts for tabline switching that you can find attached.

Best regards,
wwwweb

  //layout: enable/disable multi line tabbar switching
  { "keys": "ctrl+u","ctrl+r"], "command": "toggle_multi_col_layout" },
      
  //disable multiline tabbar and show single tabline only
  {
    "keys": "ctrl+alt+b"],
    "command": "run_multiple_commands",
    "args": {
      "commands": 
      {"command": "disable_multi_col_layout", "context": "window"},
      {"command": "set_layout", "context": "window","args":{"cols": [0.0, 1.0],"rows": [0.0, 1.0],"cells": [0, 0, 1, 1]]}}      
    ]}},
    
  //split screen
  {
  "keys": "ctrl+alt+n"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "disable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0, 0.5, 1.0],
          "rows": [0.0, 1.0],
          "cells": [0, 0, 1, 1], [1, 0, 2, 1]]
        }}
  ]}},
  
  //move current file to other row
  { "keys": "ctrl+alt+,"], "command": "move_to_group", "args": { "group": 0 } },
  { "keys": "ctrl+alt+."], "command": "move_to_group", "args": { "group": 1 } },
  { "keys": "ctrl+alt+-"], "command": "move_to_group", "args": { "group": 2 } },

  //first group to foreground
  {
  "keys": "ctrl+,"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "enable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 2, 1, 3],[0, 0, 1, 1],[0, 1, 1, 2]]
        }}
  ]}},
  
  //second group to foreground
  {
  "keys": "ctrl+."],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "enable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 0, 1, 1],[0, 2, 1, 3],[0, 1, 1, 2]]
        }}
  ]}},
  
  //third group to foreground
  {
  "keys": "ctrl+-"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "enable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 0, 1, 1],[0, 1, 1, 2], [0, 2, 1, 3]]
        }}
  ]}},
  
  //disable multi tabline view and show first row only
    {
  "keys": "ctrl+b"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "disable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 0, 1, 3],[0, 0, 0, 0],[0, 0, 0, 0]]
        }}
  ]}},

  //disable multi tabline view and show second row only
    {
  "keys": "ctrl+n"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "disable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 0, 0, 0],[0, 0, 1, 3],[0, 0, 0, 0]]
        }}
  ]}},
  
  //disable multi tabline view and show third row only
    {
  "keys": "ctrl+m"],
  "command": "run_multiple_commands",
  "args": {
    "commands": 
      {"command": "disable_multi_col_layout", "context": "window"},
      {
        "command": "set_layout",
        "context":"window",
        "args":
        {
          "cols": [0.0 ,1],
          "rows": [0.0, 0.025, 0.05, 1.0],
          "cells": [0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 1, 3]]
        }}
  ]}}
0 Likes

#5

hi, can you build a plugin for this pls?

0 Likes

#6

This actually IS a plugin. Just copy the code into a file named multicolumntabbar.py and put this file into the Packages/User folder (go there by clicking Preferences -> Browse Packages). Then it works.

I just noticed that the indents in the code in the first post are not correct (maybe because of the new forum layout?). Unfortunately, for Python the indents are quite important ;-). Anyway, here the code again with correct indents.

import sublime, sublime_plugin

multi_col_layout = 1

class MultiColumnTabBarCommand(sublime_plugin.EventListener):
  def on_activated(self,view):
    a=sublime.active_window()
    b=a.get_view_index(view)
    if (b[0] == 0) and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 2, 1, 3],[0, 0, 1, 1],[0, 1, 1, 2]]})
    
    if b[0] == 1 and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 0, 1, 1],[0, 2, 1, 3],[0, 1, 1, 2]]})
    
    if b[0] == 2 and (multi_col_layout == 1):
      a.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 0, 1, 1],[0, 1, 1, 2], [0, 2, 1, 3]]})
            
class ToggleMultiColLayoutCommand(sublime_plugin.TextCommand):
  def run(self,edit):
    global multi_col_layout    
    if (multi_col_layout == 1):
      multi_col_layout = 0
      print "Multi Column switch disabled"
    elif (multi_col_layout == 0):
      multi_col_layout = 1
      print "Multi Column switch enabled"
      
class DisableMultiColLayoutCommand(sublime_plugin.TextCommand):
  def run(self,edit):
    global multi_col_layout
    multi_col_layout = 0
    print "Multi Column switch disabled"

class EnableMultiColLayoutCommand(sublime_plugin.TextCommand):
  def run(self,edit):
    global multi_col_layout
    multi_col_layout = 1
    print "Multi Column switch enabled"
0 Likes

#7

I think @XIIZQ was asking for a “package” with this included.

0 Likes

#8

and we can i activate this?
when i activate this with multiline command, have i blackscreen in sublime…

0 Likes

#9

You do not need to activate something. If you have a file open, just click somewhere in sublime text and the three rows should appear with the file in the first row.

What do you mean with multiline command? You used one of the keyboard shortcuts? A black screen sounds like you disabled the layout by a command and are currently at one of the 3 layers with no file open. Also note, that this plugin is for Sublime Text 2 only, I think it will show unexpected behavior on ST3 (not tested yet).

I think a package for this quite static and only-ST2-specific layout is somehow oversized.

0 Likes

#10

thank you =)

0 Likes

#11

Thank wwwweb. Could you port this to Sublime 3? I’m not very familiar with making packages or extensions for Sublime, but I tried copying the code into a .py file, saved it the packages directory, then restarted Sublime. No noticeable change or effect.

I know you designed it for Sublime 2, but I thought that if it was loading, I should get some effect or feedback in Sublime 3, so I might be doing something wrong.

Thanks

0 Likes

#12

I tried some time ago and came to the same result: the plugin does not work for ST3 ;-). As I use ST2 only, I am not familiar with the ST3 API and I do not plan to use ST3 in the near future.
Maybe someone else here knows which functions to replace and could do it in five minutes?

0 Likes

#13

Thanks for the response. I understand Python pretty well and will take a look at Sublime 3’s API when (if) I get the time. Will post here if I can get it working.

0 Likes

#14

This should work, although I didn’t test.

from collections import defaultdict

import sublime_plugin

enabled_map = defaultdict(lambda: False)


class MultiColumnTabBarCommand(sublime_plugin.EventListener):
    def on_activated(self, view):
        id_ = self.window.id()
        if not enabled_map[id_]:
            return
        window = view.window()
        group, _ = window.get_view_index(view)
        id_ = self.window.id()
        if group == 0:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 2, 1, 3],[0, 0, 1, 1],[0, 1, 1, 2]]})
        elif group == 1:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 0, 1, 1],[0, 2, 1, 3],[0, 1, 1, 2]]})
        elif group == 2:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 0.025, 0.05, 1.0],"cells": [[0, 0, 1, 1],[0, 1, 1, 2],[0, 2, 1, 3]]})
              
                        
class ToggleMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] ^= True
        if enabled_map[id_]:
            print("Multi Column switch enabled")
        else:
            print("Multi Column switch disabled")
           
            
class DisableMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] = False
        print("Multi Column switch disabled")


class EnableMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] = True
        print("Multi Column switch enabled")
2 Likes

#15

 
What does ^= do?

0 Likes

#16

The ^ is the exclusive-or operator; it works like or except that it only returns true if one of the two values being tested is true and the other one is false.

Using it in this manner makes the value toggle between True and False:

  • If the value you’re checking is True, then True XOR True return False because both values are the same
  • If the value you’re checking is False, then False XOR True returns True because both values are different
3 Likes

#17

Thank you for the porting, FichteFoll. Just because I am curious, I tried your code in ST3. It almost works ;-). And just because of personal ambition, I had a look into the ST3 API now. It seems, the EventListener has no self.window, so this just has to be replaced by view.window().id(). Here the corrected code. I also added the bar_height from the first post for tab row height configuration again. And I added a command ResetLayout which resets the layout to the standard one-column sublime layout in case someone tries this plugin and does not know how to get back to standard layout again.

from collections import defaultdict

import sublime_plugin

enabled_map = defaultdict(lambda: True)

#modify this parameter to configure height of tab rows
bar_height = 0.025

class MultiColumnTabBarCommand(sublime_plugin.EventListener):
    def on_activated(self, view):        
        id_ = view.window().id()
        if not enabled_map[id_]:
            return
        window = view.window()
        group, _ = window.get_view_index(view)
        if group == 0:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, bar_height, bar_height*2, 1.0],"cells": [[0, 2, 1, 3],[0, 0, 1, 1],[0, 1, 1, 2]]})
        elif group == 1:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, bar_height, bar_height*2, 1.0],"cells": [[0, 0, 1, 1],[0, 2, 1, 3],[0, 1, 1, 2]]})
        elif group == 2:
            window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, bar_height, bar_height*2, 1.0],"cells": [[0, 0, 1, 1],[0, 1, 1, 2],[0, 2, 1, 3]]})
              
                        
class ToggleMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] ^= True
        if enabled_map[id_]:
            print("Multi Column switch enabled")
        else:
            print("Multi Column switch disabled")
           
            
class DisableMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] = False
        print("Multi Column switch disabled")


class EnableMultiColLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] = True
        print("Multi Column switch enabled")


class ResetLayoutCommand(sublime_plugin.WindowCommand):
    def run(self):
        id_ = self.window.id()
        enabled_map[id_] = False
        self.window.run_command("set_layout",{"cols": [0.0 ,1],"rows": [0.0, 1.0],"cells": [[0, 0, 1, 1]]})
        print("Multi Column disabled and layout reset to standard")
3 Likes

#18

New to Sublime … I got this working but it wasn’t as i expected. How do I remove it from my project?

0 Likes

#19

@eDaddi
Just remove the file from the User/Package folder and then click on View -> Layout -> Single.
Alternatively leave the file and use the defined ResetLayout command.

0 Likes

#20

Btw. there is an animated gif linked in the first post to see if it looks like you expect before installing.

0 Likes