msteen

RememberLayout Sublime Text 3 Plugin

Jul 16th, 2013
97
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import sublime, sublime_plugin
  2. from collections import defaultdict
  3.  
  4. class RememberLayout(sublime_plugin.EventListener):
  5.     """Remembers where views are located in a layout,
  6.     so they can be restored correctly when you revert to that specific layout."""
  7.  
  8.     # Per window, per layout, which view as active.
  9.     active_view_cache = defaultdict(dict)
  10.  
  11.     # Per window, per layout, per group, the views.
  12.     views_cache = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
  13.  
  14.     def on_window_command(self, window, command_name, args):
  15.         if command_name == 'set_layout':
  16.             # Before the layout changes.
  17.             self.remember_views(window)
  18.            
  19.             # After the layout changes.
  20.             sublime.set_timeout(lambda: self.restore_views(window), 0)
  21.  
  22.     def get_layout_repr(self, window):
  23.         # We need some kind of identifier for layouts, and the cells attribute seems a safe choice.
  24.         return repr(window.get_layout()['cells'])
  25.  
  26.     def remember_views(self, window):
  27.         layout = self.get_layout_repr(window)
  28.        
  29.         self.active_view_cache[window.id()][layout] = window.active_view().id()
  30.        
  31.         groups = self.views_cache[window.id()][layout]
  32.         for v in window.views():
  33.             self.update_view(groups, v)
  34.  
  35.     def update_view(self, groups, view):
  36.         # The group and view index can potentially be -1 according to the API.
  37.         window = view.window()
  38.         group_idx, view_idx = window.get_view_index(view)
  39.         if group_idx == -1 or view_idx == -1:
  40.             return
  41.  
  42.         # Only alter if necessary.
  43.         view_ids = groups[group_idx]
  44.         view_id = view.id()
  45.         if view_id in view_ids and view_ids.index(view_id) == view_idx:
  46.             return
  47.        
  48.         self.remove_view_id(groups, view_id)
  49.         view_ids.insert(view_idx, view_id)
  50.  
  51.     def remove_view_id(self, groups, view_id):
  52.         for group_idx in groups:
  53.             if view_id in groups[group_idx]:
  54.                 groups[group_idx].remove(view_id)
  55.                 return
  56.  
  57.     def restore_views(self, window):
  58.         # There might be nothing to restore from.
  59.         layout = self.get_layout_repr(window)
  60.         if layout not in self.views_cache[window.id()]:
  61.             return
  62.  
  63.         view_lookup = dict([(v.id(), v) for v in window.views()])
  64.        
  65.         groups = self.views_cache[window.id()][layout]
  66.         for group_idx in groups:
  67.             for view_idx, view_id in enumerate(groups[group_idx]):
  68.                 window.set_view_index(view_lookup[view_id], group_idx, view_idx)
  69.        
  70.         window.focus_view(view_lookup[self.active_view_cache[window.id()][layout]])
RAW Paste Data