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