Overview:
This script adds a new command, GoParallel
, which you can use in buttons, hotkeys, etc.
The GoParallel
command lets you jump between two folder hierarchies while maintaining the same relative position, and optionally keeping the same things selected.
For example, say you have ==Pre-Release==
and ==Live==
areas, below which are different versions of the same files and folders.
You might be here, below the ==Pre-Release==
branch:
C:\Euro Cat Simulator 2019\==Pre-Release==\Assets\3D Objects
With the click of a button, you can jump to the same place in the ==Live==
branch:
C:\Euro Cat Simulator 2019\==Live==\Assets\3D Objects
Clicking the button again could take you back again.
If you had files or folders selected before jumping to the other branch, they can be selected for you automatically after the jump (as long as they exist in both places).
Video Example:
This video shows it in action, using POST
and PROD
as the two branches:
Installation:
Requires Directory Opus Pro 12.9 or above.
- Download: GoParallel.js.txt (3.0 KB) [v1.2 26/Aug/2018]
- Open Settings > Preferences / Toolbars / Scripts.
- Drag GoParallel.js.txt to the list of scripts.
After doing that, you will now be able to use the GoParallel
command in buttons, hotkeys, menu items, and so on.
Command Arguments:
FIND
(keyword)
REPLACE
(keyword)
-
The FIND and REPLACE arguments work together and apply a basic find-and-replace operation on the current folder path.
Example 1:
GoParallel FIND="John" REPLACE="Jane"
:If you are in
C:\Folder for John Doe
, you will go toC:\Folder for Jane Doe
.If you want to make sure you match a whole folder component, not just part of one, be sure to put
\
at the start and end of both strings.Example 2:
GoParallel FIND="\John\" REPLACE="\Jane\"
:Nothing will happen if you are under
C:\John Doe
.
But if you are underC:\John
then you will go toC:\Jane
.(You don't have to worry about whether or not there is a
\
on the very end of the path. The script takes care of that.)If the FIND / REPLACE arguments do not apply to the path you are in then the command will fail, causing any other commands after it to be skipped.
The arguments are not case-sensitive by default. If you want them to be, edit the script and change
caseSensitive = false
totrue
.
TOGGLE
(switch)
-
Include the
TOGGLE
argument if you want the command to work as a toggle, going back and forth between two folders.Leave out the argument if you want the jump to be one-way.
When toggling, the FIND > REPLACE conversion is tried first.
Only if that fails will it try the reverse REPLACE > FIND conversion.That may be important if one folder name is a substring of the other.
Example 3:
GoParallel FIND="Pre-Release" REPLACE="Release" TOGGLE
That will work for toggling between paths containing ...
Pre-Release
... and ...Release
....Example 4:
GoParallel FIND="Release" REPLACE="Pre-Release" TOGGLE
The above example won't work properly. With the find and replace parameters the other way around, if you are below ...
Pre-Release
..., it will find and replaceRelease
withPre-Release
, and try to take you to ...Pre-Pre-Release
.... This is why I said above that the order may be important, but only in special cases like this.
PARENT
(switch)
-
Include the
PARENT
argument to change what happens if the parallel folder does not exist. By default, the command will fail if the result of the find-and-replace is a path that doesn't exist. IfPARENT
is specified, the command will try the parent folder, then the parent of that, and so on, until it reaches a folder that exists.Example 5:
GoParallel FIND="POST" REPLACE="PROD" TOGGLE PARENT
If you are in
C:\Project\PROD\Obj_X\Mod
, the button will try going to these folders until it finds one that exists, instead of failing if the first one does not exist:C:\Project\POST\Obj_X\Mod
C:\Project\POST\Obj_X
C:\Project\POST
C:\Project
C:\
SELECT
(switch)
-
Include the
SELECT
argument if you would like the command to look at what you had selected in the folder you started in and try to select the same things in the folder you end up in.The example button, just below, demonstrates the
SELECT
switch being used, along with the other arguments.
Example Button:
Here is the button which is shown in the video above:
The last line is the important one, and you should be able to understand it if you've read everything above:
GoParallel find="\PROD\" replace="\POST\" TOGGLE SELECT
The first line is something extra:
@hideifpathr:!\\(PROD|POST)($|\\)
It uses @hideifpathr
to hide the button, saving space on the toolbar, when you are not in a folder which matches the regular expression after the !
. Since the button toggles between \PROD\
and \POST\
branches, it will be useless if the path does not include either of those, so the button is only visible when in a suitable location.
The ($|\\)
on the end of the regular expression ensures that it works both when directly below either folder, and when in a child folder, without accidentally matching folder names which start with PROD or POST (e.g. PRODUCE).
In case you want to paste the example button straight to your toolbar, here is the same button again, as an XML Button Definition:
<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
<label>Prod / Post</label>
<icon1>#getsizes</icon1>
<function type="normal">
<instruction>@hideifpathr:!\\(PROD|POST)($|\\)</instruction>
<instruction />
<instruction>// Button is hidden unless in a path with</instruction>
<instruction>// a component named PROD or POST.</instruction>
<instruction />
<instruction>// Toggle between the PROD and POST trees,</instruction>
<instruction>// maintaining any selection.</instruction>
<instruction />
<instruction>GoParallel find="\PROD\" replace="\POST\" TOGGLE SELECT</instruction>
</function>
</button>
(Remember, you still need to install the add-in, as per the Installation section above. If you don't, the GoParallel
command won't be recognized.)
History:
- v1.2 (26/Aug/2018): Find and replace no longer case-sensitive by default.
- v1.1 (14/Aug/2018): Added
PARENT
switch. - v1.0 (13/Aug/2018): Initial version.
Script Code:
If you just want to use the script, grab the download from the Installation section above.
The script code is reproduced below so people browsing the forum can find scripting techniques without having to download every script:
// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.
function OnInit(initData)
{
initData.name = "GoParallel";
initData.version = "1.2";
initData.copyright = "(c) 2018 Leo Davidson";
initData.url = "https://resource.dopus.com/t/goparallel-jump-between-related-folder-trees/29608";
initData.desc = "Go to a path by replacing part of the current one.";
initData.default_enable = true;
initData.min_version = "12.9";
var cmd = initData.AddCommand();
cmd.name = "GoParallel";
cmd.method = "OnGoParallel";
cmd.desc = "Go to a path by replacing part of the current one.";
cmd.label = "GoParallel";
cmd.template = "FIND/K,REPLACE/K,TOGGLE/S,SELECT/S,PARENT/S";
cmd.hide = false;
cmd.icon = "getsizes";
}
function OnGoParallel(scriptCmdData)
{
var caseSensitive = false; // Change if needed.
var cmd = scriptCmdData.func.Command;
cmd.deselect = false;
var args = scriptCmdData.func.args;
if (!args.got_arg.find || !args.got_arg.replace)
return true; // Block further commands.
var findStr = args.find;
var replaceStr = args.replace;
var curPath = endSlash( DOpus.FSUtil.Resolve(scriptCmdData.func.sourcetab.path) );
if (!caseSensitive)
{
curPath = curPath.toUpperCase();
findStr = findStr.toUpperCase();
replaceStr = replaceStr.toUpperCase();
}
var newPath = endSlash( curPath.replace(findStr, replaceStr) );
if (curPath == newPath && args.toggle)
newPath = endSlash( curPath.replace(replaceStr, findStr) );
if (curPath == newPath)
return true; // Block further commands.
while ( !DOpus.FSUtil.Exists(newPath) )
{
var newPathObj = DOpus.FSUtil.NewPath(newPath);
if (!args.parent || !newPathObj.Parent())
return true; // Block further commands.
newPath = endSlash( newPathObj );
if (curPath == newPath)
return true; // Block further commands.
}
// Snapshot selections before changing folders.
var selFiles = scriptCmdData.func.sourcetab.selected_files;
var selDirs = scriptCmdData.func.sourcetab.selected_dirs;
cmd.RunCommand('Go PATH="' + newPath + '"');
if (args.select)
{
selectItems(cmd, newPath, selFiles, false);
selectItems(cmd, newPath, selDirs, true);
}
return false; // Allow further commands.
}
function selectItems(cmd, newPath, sel, isDirs)
{
if (sel.count == 0)
return;
cmd.ClearFiles();
for (var eSel = new Enumerator(sel); !eSel.atEnd(); eSel.moveNext())
{
var selItem = eSel.item();
var selPath = newPath + eSel.item().name;
cmd.AddFile(selPath);
}
cmd.RunCommand("Select FROMSCRIPT MAKEVISIBLE TYPE=" + (isDirs ? "dirs" : "files"));
}
function endSlash(pathString)
{
// In case pathString is an Opus path object, ensure conversion to JSCript string.
var res = pathString + "";
// Add a backslash to the end of the path if there isn't one already.
res = res.replace(/([^\\])$/, '$1\\');
return res;
}