Getting Started with Scripted Buttons

When you come to Directory Opus, the word script may cause some confusion because Opus has several kinds of scripts.

✱ On another page, we look at rename scripts, which give you fine-grain control over renaming operations.

✱ On another page, we look at script add-ins, which let you reach deep into Opus functionality, allowing you for instance to create custom columns or define what happens when you double-click a blank area of a lister.

✱ This page aims to introduce you to script functions, which can power the behavior of a button or keyboard shortcut.

An Introduction Using Barebone Scripts

In my view, the best way to get started with writing script functions for Opus buttons is to look at some barebone scripts. This is the time-honored Hello, World! tradition.

Once you have some simple near-empty "shells" in your hand, you can build them up to make them perform more complex tasks. In the case of Opus, having these hollow "shells" in your hand at the outset seems all the more important to me since each script requires a bit of scaffolding, i.e. lines of codes which are necessary for everything to work but whose deeper workings you may not need to master.

The scaffolding is the proverbial forest which may prevent you from seeing the trees—the trees being the actual functionality you want the script to perform. Or maybe the scaffolding is the fence around the forest. I don't know. It doesn't matter. I'm sure you got the point, so let's keep going.

Some coding required
This page is going to assume that you know very little Opus, so it will quickly explain how to create and edit a button, which will be basic for most of you. But it will assume that you know some coding, and in particular that you are familiar with at least one C-style language such as Java, C# or PHP.

If you know JavaScript, so much the better, but you don't need to. I know little about JavaScript apart from the intricacies of its crippled regex flavor, but still managed to throw together the simple scripts on this page by looking up the needed classes and methods in the Opus documentation.

Getting Ready to Script

In this section we get right to the point where we can start writing code. For many of you, the information will be old news, but I want to make sure that anyone who reads this page has everything they need to get started.

1. Set this preference
Before we get started, please do me a favor and set this preference in Opus so that you and I speak the same language. You can always unset it later on if you don't like it.

Opus Alt Click preference

With this preference set, when you Alt-Click a button on the toolbar (i.e. hold down Alt and click with the left button), Opus takes you right to the Edit dialog for that button. And when you Alt-Click an empty space on the toolbar, Opus enters the toolbar customizing mode.

2. Create a new button
Let's create a new button so we can place a script inside of it. To make the button easy to tweak, at first we'll place it on one of the toolbars where, to make changes, all we'll need to do is Alt-Click it. When you're done creating buttons, if you only want to use them via their hotkeys, you can move them into deep submenus, away from the main interface—or turn them into standalone hotkeys.

✱ Alt-click an empty space on any toolbar. If you followed step 1 above, Opus enters the toolbar customizing mode.

✱ Right-click an empty space on a toolbar, and select Insert New / New Button. A new button appears on the toolbar, with the label New Button

3. Set up the button
Double-click the new button. The button edit dialog opens.

Editing a button in Directory Opus

The basic version of this dialog allows you to create a traditional button that uses the built-in Opus command language. To create a scripted button instead (our goal with this page), press Advanced now.


In the advanced command editor, go straight to the Function pull-down and select Script Function. At this stage let me explain a bit what that pull-down menu does. If you don't care, just skip the next paragraph.

The Advanced mode is for three types of buttons: (i) the kind of scripted button this page is about, (ii) DOS batch commands, and (iii) regular Opus commands that may require more than one line. You choose between these three types of buttons in the Function pulldown. advanced-button-pref.jpg Since Advanced mode allows you to create every kind of button, consider setting it as a default. To do so, open Preferences, paste button_editor_advanced in the search box at the bottom left, and double-click the entry to set its value to True.

Okay, you've selected Script Function in the Function pull-down menu, right? At this stage, the command editor shows you three tabs: Modifiers, Script Code and Resources. The Script Code tab is selected.

At some stage in your learning journey you may want to study the default code and comments that now appear in the button's editor section, but for a gentle introduction it may be a bit overwhelming, which is why I'll soon have you replace all of that sample code with the code of the barebone scripts below.


Under Script Type, note that you can choose a language for the script. By default the pulldown shows JScript and VBScript, but you can use other scripting languages too.


Do you love Python? Use JavaScript
If you play with scripted buttons, in the documentation you will soon come across mentions that other scripting languages, such as Python, can be used. Even if you are a Python pro, resist the urge to try to write your Opus scripts in Python. It's not worth it. I love Python and have written programs whose printouts exceed a hundred pages, but I've come to accept that the most sane option for Opus scripting is JScript (followed by VBScript).

This is because JScript and VBScript work out of the box on any Windows machine. To get Python to work requires a lot of fiddling. And if you succeed, you'll have something that works on that particular machine, but not on your other machines.

Apart from that, if you use Python to script Opus, you are unlikely to get helpful answers on the forum. Most Opus scripters use JScript, so that's where you'll get the most help, and for me that's the number one reason to use JScript. Some people (fewer) use VBScript, so that's another option if you're fluent in VBScript. On this page, we'll only use JScript.

To finish setting up the button, you'll have to click OK twice. The first OK takes you out of the Command Editor window. The second OK button appears on the Customize window. If that window isn't right there after you click the first OK, look for it on your Windows taskbar.

4. Use the Button
new-button.jpg You should now have a new button on your toolbar.

✱ Click the button: nothing happens. That's normal, the code inside the button is just general scaffolding.

✱ Alt-Click the button: this takes you directly to the Script Code tab, where you can tweak to your heart's content.

5. Decide where you will edit the script
Viewed a certain way, the work of creating and tweaking a script button merely consists in replacing the code that appears in the Script Code tab.


You can do that directly in the tab, and that may be a viable option for small tweaks. It's nice that the simple editor in the Script Code knows some things about JavaScript syntax, such as unbalanced braces. But for real work, it just isn't a comfortable workspace with all the bells and whistles you expect from a code editor.

In my view, your preferred workflow should be to write the JScript code in a code-aware editor, then to paste that code into the Script Code tab. Apart from having access to advanced editing functions, one benefit is that this protects you from accidentally losing your code, which is easy to do if it only lives inside the button. Keeping your code outside of Opus also allows you to use git or other version control tools to manage your scripts.


I tend to use an IDE called WebStorm (that's what's on the picture) because I like JetBrains products, but you don't need an IDE—all you need is an advanced text editor, such as EditPad Pro (my favorite) or NotePad++ (the freeware favorite).

That being said, if you're adventurous and insist on editing your script straight in the built-in editor, make sure you save your button often, and have a look at the Run button (mentioned in the Additional Tips section).

How to Learn from the Three Scripts Below

From this point forward, I will present three small but functioning scripts which you can directly paste into the button we created in the previous section. The idea is not just to copy and paste, but to provide you with a crash-course in scripted buttons.

How to learn from these scripts?

Examine the scripts in the order presented.

Read the scripts from top to bottom. They are self-documenting, so you shouldn't have trouble reading them—I've assumed that you know nothing about Opus scripting.

Perform basic tweaks based on the syntax you immediately understand, for instance playing with the logic or the literals.

Perform deeper tweaks by diving into the classes and methods Opus makes available to you.

Use a script as a template to start your own script. It's always helpful to start from a working point.

Barebones Script #1: Hello, World

What This Does
Although I'm calling this script Hello, World, it does a bit more than your single-message program. The script plays with several ways that Opus scripts can show you information: alerts, dialogs and the "Other Logs" utility panel. So doing, it introduces you to the important Func object.

How to Use
✱ Alt-click the button, paste the code, click OK twice.
✱ Click the button. Note the two messages: a pop-up alert, and a message inside the Utility Panel.
✱ Click OK on the "Hello, World!" dialog.
✱ Click through the next dialog.

// Every script that lives in a button or hotkey needs // the OnClick function below. // It is the script's main entry point. // The function has one argument: clickData. // clickData is an object that Opus passes to the function. // clickData has a func property: a Func object which has useful // attributes and methods. // When done reading, explore the Func object in the // documentation (see the link below) function OnClick(clickData) { // 1. Let's create an Alert in the Output Log // This is a convenient way to examine variables when // debugging a script, or to output a lot of text. // First open the log clickData.func.command.RunCommand("Set UTILITY=otherlog") // Clear the output log DOpus.ClearOutput() // Display the text DOpus.Output("Hello, World in the Output Log") // 2. Let's create a simple alert var dlg = clickData.func.Dlg; // creates a dialog object // nothing happens until you invoke the Show() method dlg.message = "Hello, World!" dlg.buttons = "OK" dlg.Show() // 3. Let's create a multi-button dialog dlg.message = "Pick a Color" // recycle the dialog object dlg.buttons = "Red|Black" if (dlg.Show() == 1) { // test which button was clicked dlg.message = "You picked red" } else { dlg.message = "You picked black" } // recycle the dialog object again. dlg.buttons = "Please shut up already" dlg.title = "== One More Box ==" dlg.icon = "Info" dlg.Show() }

The Func object
The Func object is probably your first entry key into the methods and properties Opus makes available to you. Here is a link to online documentation for Func in DO12. You can learn a lot by drilling into the tree of methods and attributes.

Since you may be using a different Opus version, you may like to see the documentation for your version. In Opus, press F1, select the Index tab, type fu, and select Func from the list.

Barebones Script #2: Names of Selected Files

What This Does
This script shows you how to start interacting with files in the Opus lister panes. If files are selected, when you click the button, the names of the files are shown in the Other Logs utility panel. In addition, if more than five files are selected, a dialog appears telling you that only the first five will be shown.

The script introduces you to the important Tab object and shows you how to iterate through files.

// The point of this script is to show how you can access the // files selected in the tab and start to do something with them. // The script just outputs some text to the Other Log. // Main script entry point. DO passes the ClickData object to // the function. function OnClick(clickData) { // sourcetab is a Tab object (see the link below // for documentation) // Here we use the Tab object's selected_files property // The Tab object also has selected_dirs and many more goodies var selected_files = clickData.func.sourcetab.selected_files // Start to setup a simple alert -- displayed later // with dlg.Show() var dlg = clickData.func.Dlg; dlg.buttons = "OK" // Note that numbers of files and more info can be obtained in // sourcetab.stats or sourcetab.selstats (see Tab object) var num_files = selected_files.count if (num_files > 5) { dlg.message = "There are " + num_files.toString() + " files, only the first five will be shown." dlg.Show() } // Create an enumerator object to enumerate the selected files // JS enumerators: // var enumFiles = new Enumerator(selected_files) // The details of outputting to the Other Logs utility pane // are covered in the previous script clickData.func.command.RunCommand("Set UTILITY=otherlog") DOpus.ClearOutput() // clears the output log // enumerate the files in the tab var counter = 1 var currentFile while ( (! enumFiles.atEnd()) && counter < 6) { currentFile = enumFiles.item() DOpus.Output( enumFiles.moveNext() counter++ } }

The Tab object
The Tab object is your main key to the listers. Here is a link to online documentation for Tab in DO12. You can learn a lot by drilling into the tree of methods and attributes.

Since you may be using a different Opus version, you may like to see the documentation for your version. In Opus, press F1, select the Index tab, type t, and select Tab from the list.

Tip: showing not just Files, but Folders also
This script plays with files. What if you also want to enumerate selected folders?

Instead of
var selected_files = clickData.func.sourcetab.selected_files
use something like
var selected_files_and_folders = clickData.func.sourcetab.selected

(direct link)

Barebones Script #3: Custom Sort and (optionally) Rename

What This Does
This script introduces you to file manipulation, leading up to a powerful custom renaming operation.

Note that Opus also offers a dedicated type of script just for file renaming (this site has a page just about rename scripts).

What makes this particular script powerful is that in traditional rename scripting, file names are considered one by one, whereas here, a file's final name depends on all the files being considered.

✱ In its simplest form, the script outputs a list of the selected file names sorted in a custom order: the length of the file's name, and, secondarily, the name itself in reverse order.

✱ If you uncomment one of the lines, the files are also renamed.

✱ To rename files, we learn about the Command object.

Test #1: show sorted names without renaming
Create files with the names below.
(Tip: if you were creating not just four files but many, you could use this button to copy the file names above and create them with a single click.)

        New Text Document.txt

When you select the files and click the button, the Other Logs displays this:

output of custom sort

Test #2: also rename the files
Uncomment this line:
// cmd.Run()

When you click the button, the files are renamed like so:

custom rename

// The point of this script is to establish a custom-sort // for a set of files before passing files // to Run() or RunCommand() // This could be useful for AddFilesFromFolders // As it stands, the script writes to the Other Log, sorting // files by name length ASC + name DESC // If you uncomment Run(), the files are renamed one by one. // You could also do a bulk rename by adding files one by one // before running Run() // Main script entry point. DO passes the ClickData object // to the function. function OnClick(clickData) { // Open the Other Logs clickData.func.command.RunCommand("Set UTILITY=otherlog") // selected_files is a set. It cannot be sorted. var selected_files = clickData.func.sourcetab.selected_files // In order to sort the files, create an array var fileList = [] var enumFiles = new Enumerator(selected_files) var currentFile while (!enumFiles.atEnd()) { currentFile = enumFiles.item() fileList.push(currentFile) // if you want an array with the files and some // custom computed item, do something like // fileList.push( {item:currentFile, // custom:something} ) enumFiles.moveNext() } // Establish a custom sort fileList.sort(function (a, b) { if ( - != 0) { return > ? 1 : -1 } else { return b.name_stem.toLowerCase() > a.name_stem.toLowerCase() ? 1 : -1 } }) // cmd is a Command object (see the link below // for documentation) var cmd = DOpus.Create.Command() DOpus.Output("\nCustom sort: name length ASC + name DESC") // Rename files one by one // To actually rename, uncomment the cmd.Run() line for (var i = 0; i < fileList.length; i++) { cmd.AddLine('Rename PATTERN ^(.*)$ TO "' + i.toString() + ' \\1" REGEXP') cmd.AddFile(fileList[i]) // cmd.Run() cmd.Clear() cmd.ClearFiles() DOpus.Output((i+1).toString() + " - " + fileList[i].name) } }

The Command object
The Command object is your main key to operating on files and manipulating the listers. Here is a link to online documentation for Command in DO12. You can learn a lot by drilling into the tree of methods and attributes.

Since you may be using a different Opus version, you may like to see the documentation for your version. In Opus, press F1, select the Index tab, type comm, and select Command from the list.

Other Examples of Script Functions written in JScript

To deepen your understanding of script functions, I recommend you explore scripts in the Scripts section of the Opus forum. There are many wonderful examples contributed by the community.

If you are overwhelmed by the choice, I suggest the following script because, having written it, I am intimate with it. It is no indicator of power or quality—there are far more complex scripts on the forum.

Cycle Dimensions & Duration Columns
Opus has some built-in facilities for buttons that quickly toggle between two states. In my view, this button is interesting in that it is a simple example that demonstrates how you can cycle between multiple states (not just two).

Additional Tips

Here are some additional tips which you may want to consider when working with scripted functions.

My script has an endless loop and runs forever
Try exiting and restarting Opus via Help / Exit Directory Opus if you're using my toolbars, or File / Exit Directory Opus on the standard toolbars. Sad to say, but I often have to kill Opus manually via my task manager. I use Process Hacker, but any task manager (including the Windows default) should do. Incidentally, the CPU meter of your task manager might alert you to endless loops.

The Run button
script-run-button.jpg Earlier, I mentioned that my preferred workflow is to edit scripts in a standalone IDE or editor, then to paste the entire code in the Opus button. However, there may be times when you want to tweak buttons directly within the Opus button editor—perhaps for quick debugging or testing. In those situations, the Run button at the bottom left of the script editor comes in handy as it lets you test the script without going in and out of Customize mode.

Setting a default script for new buttons
When you create a new scripted function, Opus supplies some vanilla code and comments. You may like to replace that default with something you've worked with and fully understood, such as one of the barebones scripts on this page, or, better, one of our own, with helpful comments to remind you of features you'd like to remember. This can be done directly in the script editor via the Default pulldown.


Learning more about Script Functions

I'm no expert of Opus script functions, so from here I'll probably be spending more time looking at:

✱ The documentation (press F1, select the Index tab, select Script Functions)
✱ The Buttons / Scripts section of the forum.

(direct link)
Useful Scripts written in VBScript
If you're more into VBScript than JScript, here are a couple of useful examples.

Merge Folders. This script by Leo allows you to select multiple folders and merge them to a single folder, whose name you specify. You could accomplish the same in Flat view, but that would be more fiddly. On my toolbars, this button lives under Folder / Merge Folders.

Paste Empty File & Folder List. This script by Leo allows you to copy a list of file names from a file or a web page and to paste them in a lister, which creates empty files bearing these names. File names that terminate with a \ are pasted as folders. On my toolbars, this button lives under Copy / Paste File & Folder List.

Other Types of Scripts in Directory Opus

There are Three types of scripts in Directory Opus

Each has its own page on the DearOpus website:

1. Scripted Buttons / Script Functions (this page)
2. Script Add-Ins
3. Rename Scripts

You may like to check out the other two.

Be the First to Leave a Comment

All comments are moderated.
Link spammers, this won't work for you.

Kindly note that I will not reply to general Opus tech support questions (but feel free to ask about issues directly related to my toolbars).

To prevent automatic spam, we require that you type the two words below before you submit your comment.