Sublime Forum

Merging Buffers to Merge Different Windows

#1

On my mac, I work with a lot of tabs and windows in SublimeText 3. I often like to pull tabs out to create a new window but later, I want to be able to easily consolidate them all into one window WITHOUT using the mouse. I can have as many as 20+ tabs open at any one time spanning 3-6 windows.

Scenario: I have four SublimeText windows open, each with 5 tabs. Now, I’d like to merge all the tabs of windows 1, 2, 3 and 4 into window 1 so I only have one remaining window with 20 tabs.

Chrome has a fabulous extension called Merge Windows that demonstrates this behavior perfectly.

I posted a similar example on StackOverflow but the only viable answer was modifying buffers manually because Sublime did not support buffer merging functionality, thus, a plugin could not be created to do this.

I would like for sublime to support the merging of buffers, please!

0 Likes

#2

this is doing the trick. Save as Data/Packages/Mergewindows/mergewindows.py

import sublime, sublime_plugin
class mergewindows(sublime_plugin.ApplicationCommand):
  def run(self):
    window = sublime.active_window()
    for wnd in sublime.windows():
      if wnd is window:
        pass
      else:
        for oldview in wnd.views():
          fname = oldview.file_name()
          content = oldview.substr(sublime.Region(0,oldview.size()))
          oldview.set_scratch(True)
          wnd.focus_view(oldview)
          wnd.run_command('close_file')

          if fname is not None:
            newview = window.open_file(fname)
          else:
            newview = window.new_file()
          newview.run_command('placecontent', {"content": content})

class placecontent(sublime_plugin.TextCommand):
  def run(self, edit, content):
    region = sublime.Region(0,self.view.size())
    self.view.replace(edit, region, content)

Not that pretty, but works. You can then just add the “button” to the main menu by creating Data/Packages/Mergewindows/Main.sublime-menu

[{	"caption": "Merge Windows",
	"command": "mergewindows"
}]

and make it accesable from command palette by creating Data/Packages/Merewindows/Default.sublime-commands with same content

1 Like

#3

Wow Valerij!

You just don’t know how happy that just made me!! Works BEAUTIFULLY!! Thank you, thank you, thank you!! I also used bindings to configure this action to work with “alt+shift+control+m.”

The only thing I noticed that was a bit off was that the titles of the documents are lost in the merge. Every document not saved will revert back to “Untiled.” I guess that is to be expected? If there was a way to address this, it would be perfect.

Thanks again and let me know if I can buy you a drink! :smile:

God bless,

0 Likes

#4

The APIs needed for that are View.name() and View.set_name(new_name).

Here is what I came up with.

Note that this is untested, so don’t try it on sensible data!

import sublime
import sublime_plugin


class MergeWindowsCommand(sublime_plugin.WindowCommand):
    def run(self):
        for wnd in sublime.windows():
            if wnd.window_id == self.window.window_id:
                continue

            for oldview in wnd.views():
                fname = oldview.file_name()
                vname = oldview.name()
                content = oldview.substr(sublime.Region(0, oldview.size()))

                if fname is not None:
                    newview = self.window.open_file(fname)
                else:
                    newview = self.window.new_file()
                    newview.set_name(vname)
                    newview.set_syntax_file(oldview.settings().get('syntax'))
                    newview.run_command('insert', {"characters": content})

                if oldview.is_dirty() and fname is not None:
                    newview.run_command('select_all')
                    newview.run_command('left_delete')
                    newview.run_command('insert', {"characters": content})

                oldview.set_scratch(True)
                oldview.close()

I tried to get rid of the “placecontent” command, but I’m not sure if the “insert” command will behave the same here, especially regarding auto-indentation. There is also a lot more settings you can migrate, but for now the syntax for unsaved views will be enough.

1 Like

#5

FichteFoll,

Simply AMAZING! It worked like a charm! Very thankful for you guys!

Thanks again!

0 Likes

#6

Hi FichteFoll,

I’ve published a package on Github for with this code. One thing that came up was that when merging several windows, it appears that one of the windows will indent in a cascading manner, altering the state of the original document. In looking at the python logic, I can’t figure out why this is happening.

Any ideas? (Screenshot below)

0 Likes

View.insert changes indentation of inserted text
#7

What you ran into unfortunately is exactly what I mentioned in my first post and what I described further in this other thread.

You will need to do what I describe in the workaround and is sourced from my CSScheme package.

0 Likes