Overview:
This script adds a GoRelative
command.
-
GoRelative SIBLING=next
will jump you directly to the next sibling of the current folder.In other words, it is like going up one level, selecting the next (or previous) folder to where you were, then entering it. Or like pushing the up or down cursor key on the folder tree.
-
GoRelative SIBLING=prev
jumps to the previous sibling folder. -
Add the
WRAP
argument to loop back to the first folder when you reach the last one (or vice versa), instead of stopping at the ends. -
Add the
SKIPHIDDEN
argument to skip over hidden folders. -
Folders that you cannot access are skipped automatically. (e.g. So you don't get error messages when cycling through folders below C:\.)
Alternative:
A slightly different version of this, re-written in JScript and with some extra functionality, can be found in Julianon's Jan 3, 2017 reply below.
Installation:
- Download Go_to_Relative.vbs.txt (4.5 KB)
- Drag it to Preferences / Toolbars / Scripts.
- With the script installed, you can create toolbar buttons or hotkeys which use the
GoRelative
command, as described in the overview section above.
Here are two pre-made buttons you can drag to a toolbar:
- Previous Sibling.dcf (278 Bytes)
- Next Sibling.dcf (277 Bytes)
- See How to use buttons and scripts from this forum
History:
- 1.1 (15/May/2015): No longer skips empty folders.
- 1.0 (11/May/2015): Initial version.
Limitations:
- It decides the next or previous folder by listing the parent's folders in alphabetical order.
- Only real paths are currently used, not virtual paths or localised names. With localised names, the order you visit directories may not match the order you're used to seeing; for example, the My Documents folder is really called Documents behind the scenes, so it will appear earlier in the cycle than you might expect, if you have Opus configured to use localised names.
- If you are in the Desktop virtual folder, the script will act as if you are below C:\Users\<username>\Desktop instead, and cycle through the folders below C:\Users\<username>.
- If you are in a library, the script will act as if you are below the library's real path.
- Doesn't currently do anything at the root of a drive. It might cycle through drive letters in the future.
- May only currently consider the first ~65000 siblings. (This limitation may no longer apply, although the script will be very slow with that many folders to work through anyway.)
Script code:
The script code from the download above is reproduced below. This is for people browsing the forum for scripting techniques. You do not need to care about this code if you just want to use the script.
option explicit
' Go to Relative
' (C) 2015 Leo Davidson
'
' This is a script for Directory Opus.
' See http://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.
' Called by Directory Opus to initialize the script
Function OnInit(initData)
initData.name = "Go to Relative"
initData.desc = "Adds command to navigate to sibling folders."
initData.copyright = "(C) 2015 Leo Davidson"
initData.version = "1.1"
initData.default_enable = true
Dim cmd
Set cmd = initData.AddCommand
cmd.name = "GoRelative"
cmd.method = "OnGoRelative"
cmd.desc = "Go to the next or previous sibling of the current folder."
cmd.label = "GoRelative"
cmd.template = "SIBLING/K[next,prev],WRAP/S,SKIPHIDDEN/S"
End Function
' Implement the GoRelative command
Function OnGoRelative(scriptCmdData)
' Check arguments to see what we've been asked to do.
If (scriptCmdData.Func.args.got_arg.SIBLING) Then
OnGoSibling(scriptCmdData)
End If
' Other modes may be added here in the future.
End Function
Function OnGoSibling(scriptCmdData)
' Check arguments to see if we're going to the next or previous sibling.
Dim modeString, fNext, fWrap, fSkipHidden
modeString = UCase(scriptCmdData.Func.args.SIBLING)
If (modeString = "NEXT") Then
fNext = True
ElseIf (modeString = "PREV" Or modeString = "PREVIOUS") Then
fNext = False
Else
DOpus.Output "GoRelative: SIBLING argument used with invalid parameter """ & modeString & """.", True
Exit Function
End If
fWrap = scriptCmdData.Func.args.got_arg.WRAP
fSkipHidden = scriptCmdData.Func.args.got_arg.SKIPHIDDEN
' Get the parent folder, resolving aliases like /desktop while we're at it.
Dim pathParent, stringCurrentPath
Set pathParent = DOpus.FSUtil.Resolve(scriptCmdData.Func.sourcetab.path)
stringCurrentPath = pathParent
If (Not pathParent.test_parent) Then
' If we're on a drive letter, find the next/prev drive.
Dim driveNum
driveNum = CInt(pathParent.drive)
If (driveNum = 0) Then
' No parent, and not a drive letter, so we give up.
Exit Function
End If
' TODO: Hopping between drives not implemented yet.
Else
pathParent.Parent
' List the sibling folders, then sort the list.
Dim vecSiblings, folderEnum, folderItem, folderError
Set vecSiblings = DOpus.Create.Vector
Set folderEnum = DOpus.FSUtil.ReadDir(pathParent, False)
If (CLng(folderEnum.error) <> 0) Then
DOpus.Output "GoRelative: Error " & CLng(folderEnum.error) & " reading folder """ & pathParent & """.", True
Exit Function
End If
Do While (Not folderEnum.complete)
Set folderItem = folderEnum.Next
If (folderItem.is_dir) Then
vecSiblings.push_back(folderItem)
End If
Loop
vecSiblings.sort
' Find the current folder in the list.
Dim curIdx, origIdx, total, fFound
curIdx = CLng(0)
total = CLng(vecSiblings.count)
fFound = False
Do While (curIdx < total)
If (vecSiblings(curIdx) = stringCurrentPath) Then
fFound = True
Exit Do
End If
curIdx = curIdx + CLng(1)
Loop
If (Not fFound) Then
Exit Function
End If
origIdx = curIdx
Do While (True)
If (fNext) Then
curIdx = curIdx + CLng(1)
If (curIdx = total) Then
If (Not fWrap) Then
Exit Function
End If
curIdx = CLng(0)
End If
Else
If (curIdx = CLng(0)) Then
If (Not fWrap) Then
Exit Function
End If
curIdx = total - CLng(1)
Else
curIdx = curIdx - CLng(1)
End If
End If
If (origIdx = curIdx) Then
Exit Function ' We could not find another folder to go to.
End If
' Test we can access the folder, and skip it if not.
Set folderEnum = DOpus.FSUtil.ReadDir(vecSiblings(curIdx), False)
' If error is non-zero but complete is not set, it means we can read the dir
' but may be unable to get information about some of its children, which is fine.
folderError = CLng(folderEnum.error)
' Error 18 is ERROR_NO_MORE_FILES which just means the folder is empty.
If (folderError = CLng(0) Or folderError = CLng(18) Or Not folderEnum.complete) Then
If (Not fSkipHidden) Then
Exit Do ' This is the folder we want.
End If
' Check if the folder is hidden and skip it if it is.
If ((vecSiblings(curIdx).attr And 2) = 0) Then
Exit Do
End If
End If
Loop
scriptCmdData.func.command.RunCommand "Go PATH=""" & vecSiblings(curIdx) & """"
End If
End Function