DeDuplicateTabs: Auto-close duplicate tabs when new windows open

Overview

This script runs whenever a new lister (main window) opens, and will automatically close all tabs for folders which are already open in the same window.

For dual-display listers, a tab is only considered a duplicate if it is on the same side as another with the same path. (It is easy to change if you want de-duplication across both sides, however.)

Download:

History

v1.0 (31-Oct-2020):

  • Initial version.

Script code

If you just want to use this thing, see above for the download.

The script code is reproduced here to help people browsing the forum for scripting techniques.

function OnInit(initData)
{
	initData.name = "DeDuplicateTabs";
	initData.version = "1.0";
	initData.copyright = "(c) 2020 Leo Davidson";
	initData.url = "https://resource.dopus.com/t/deduplicatetabs-auto-close-duplicate-tabs-when-new-windows-open/37050/1";
	initData.desc = "Automatically closes duplicate folder tabs in new windows.";
	initData.default_enable = true;
	initData.min_version = "12.22";
}

// Called when a new Lister is opened
function OnOpenLister(openListerData)
{
	if (!openListerData.after)
	{
		// The tabs aren't open yet. Ask to be called again when they are.
		return true;
	}

	var cmd = DOpus.Create.Command();
	cmd.SetSourceTab(openListerData.lister.activetab);
	closeDuplicateTabs(cmd, openListerData.lister.tabsleft);
	closeDuplicateTabs(cmd, openListerData.lister.tabsright);

	return false; // Don't call us again for this lister.
}

function closeDuplicateTabs(cmd, tabList)
{
	var mapPaths = DOpus.Create.Map();
	var vecTabsToClose = DOpus.Create.Vector();
	var tabIndex = 0;

	for (var eTabs = new Enumerator(tabList); !eTabs.atEnd(); eTabs.moveNext())
	{
		var tab = eTabs.item();
		var tabPath = tab.path;
		
		if (mapPaths.exists(tabPath))
		{
			vecTabsToClose.push_back(tab);
			if (tab.visible)
			{
				cmd.RunCommand("Go TABSELECT=" + mapPaths(tabPath));
			}
		}
		else
		{
			mapPaths(tabPath) = tabIndex;
		}
		
		tabIndex = tabIndex + 1;
	}

	if (vecTabsToClose.empty)
		return;

	cmd.Clear();

	for (var eTabs = new Enumerator(vecTabsToClose); !eTabs.atEnd(); eTabs.moveNext())
	{
		var tab = eTabs.item();
		cmd.AddLine("Go TABCLOSE=" + tab);
	}

	cmd.Run();
}

On-Demand Version:

If you only want duplicate tabs to be cleaned up when you click a button or hotkey, not automatically, use this button:

Script Code (on-demand version):

function OnClick(clickData)
{
	var cmd = clickData.func.command;
	cmd.deselect = false; // Prevent automatic deselection
	cmd.ClearFiles();

	var lister = clickData.func.sourcetab.lister;
	closeDuplicateTabs(cmd, lister.tabsleft);
	closeDuplicateTabs(cmd, lister.tabsright);

}

function closeDuplicateTabs(cmd, tabList)
{
	var mapPaths = DOpus.Create.Map();
	var vecTabsToClose = DOpus.Create.Vector();
	var tabIndex = 0;

	for (var eTabs = new Enumerator(tabList); !eTabs.atEnd(); eTabs.moveNext())
	{
		var tab = eTabs.item();
		var tabPath = tab.path;
		
		if (mapPaths.exists(tabPath))
		{
			vecTabsToClose.push_back(tab);
			if (tab.visible)
			{
				cmd.RunCommand("Go TABSELECT=" + mapPaths(tabPath));
			}
		}
		else
		{
			mapPaths(tabPath) = tabIndex;
		}
		
		tabIndex = tabIndex + 1;
	}

	if (vecTabsToClose.empty)
		return;

	cmd.Clear();

	for (var eTabs = new Enumerator(vecTabsToClose); !eTabs.atEnd(); eTabs.moveNext())
	{
		var tab = eTabs.item();
		cmd.AddLine("Go TABCLOSE=" + tab);
	}

	cmd.Run();
	cmd.Clear();
}
2 Likes

Doesn't work here.

OnOpenLister gets called once before the tabs are open, but script execution never returns.

Tried with a Layout that contains duplicate tabs. Not aware of other scripts that might interfere.

Strange. It's definitely working here, on two machines.

Have you tried disabling any other scripts?

Yes. Turned out the add-in

was active. It also contains OnOpenLister. After disabling it this thread's script works just fine.

I don't need either of these scripts, but what would be the preferred way if I did? Have one add-in that integrates the two functionalities?

That would probably be needed right now. That or just them both ask to be called the second time, which should also work. The issue is the "should the scripts be called the second time" state is not per-script currently.

But we're going to fix this, so two scripts handling the event can't cause problems for each other. So in the next beta it should no longer be an issue.

Thanks for reporting the issue!

What has to be changed for de-duplication on both sides?

Seems not to be a simple switch already existing in the script, right?

I think as "backstop" the script can be useful. :slight_smile:

you could try this script that has an flag to close dupes in each of the two panes

I noticed that many users have asked for this. Would you consider integrating it into the tab settings as a built-in feature of dopus in future releases rather than through JS scripts, so that new users don't have to ask questions repeatedly in the forum

If built in, an option should be available to to turn deduplication on of off. Next, I suppose folks would ask for that option on a per-folder basis. :wink:

Close Duplicate Tabs.dcf

It should not close locked tabs, so further improvement is needed