diff --git a/twander.py b/twander.py index c97df59..22fd5be 100755 --- a/twander.py +++ b/twander.py @@ -4,7 +4,7 @@ # For Updates See: http://www.tundraware.com/Software/twander PROGNAME = "twander" -RCSID = "$Id: twander.py,v 2.60 2003/01/16 01:15:08 tundra Exp $" +RCSID = "$Id: twander.py,v 2.61 2003/01/16 17:26:03 tundra Exp $" VERSION = RCSID.split()[2] @@ -319,10 +319,10 @@ # Prompts pCHPATH = "Change Path" -pENPATH = "Enter New Path Desired:" -pRUNCMD = "Run Command" pENCMD = "Enter Command To Run:" - +pENPATH = "Enter New Path Desired:" +pMANUALCMD = "Manual Command Entry" +pRUNCMD = "Run Command" # Warnings @@ -1366,55 +1366,8 @@ # Otherwise, replace config tokens with actual file/dir names if cmd: - # Replace runtime-determined tokens - - # First do any prompting required - - for promptvar, handler, replace in ((YESNO, askyesno, FALSE), (PROMPT, askstring, TRUE)): - - for x in range(cmd.count(promptvar)): - b = cmd.find(promptvar) - e = cmd.find("]", b) - prompt = cmd[b + len(promptvar):e] - val = handler(name, prompt) - - # Make sure our program gets focus back - UI.DirList.focus() - - if val: - if replace: - cmd = cmd.replace(cmd[b:e+1], QUOTECHAR + val + QUOTECHAR) - else: - cmd = cmd.replace(cmd[b:e+1], '') - - # Null input means the command is being aborted - else: - return - - # Now do files & directories - # Strip trailing path separators in each case to - # give the command author the maximum flexibility possible - - selection = StripPSEP(UI.LastInSelection()) - - selections = "" - dselections = "" - for selected in UI.AllSelection(): - selected = StripPSEP(selected) - dselections += QUOTECHAR + UI.CurrentDir + selected + QUOTECHAR + " " - selections += QUOTECHAR + selected + QUOTECHAR + " " - - cmd = cmd.replace(DIR, QUOTECHAR + StripPSEP(UI.CurrentDir) + QUOTECHAR) - cmd = cmd.replace(DSELECTION, QUOTECHAR + UI.CurrentDir + selection + QUOTECHAR) - cmd = cmd.replace(DSELECTIONS, dselections) - cmd = cmd.replace(HASH, COMMENT) - cmd = cmd.replace(SELECTION, QUOTECHAR + selection + QUOTECHAR) - cmd = cmd.replace(SELECTIONS, selections) - - # Run the command - ExecuteCommand(cmd) - - + ExecuteCommand(cmd, name) + # end of 'KeystrokeHandler()' @@ -1726,7 +1679,7 @@ # Execute command (if any) - Blank entry means do nothing/return if cmd: - ExecuteCommand(cmd) + ExecuteCommand(cmd, pMANUALCMD) # Save the command only if Command History is enabled (MAXHIST > 0) # AND one of two conditions exist: @@ -1827,10 +1780,10 @@ # the selection elsewhere. elif OSNAME == 'nt': - ExecuteCommand(os.path.join(os.path.abspath(UI.CurrentDir), selected), UseStartDir=TRUE) + ExecuteCommand(os.path.join(os.path.abspath(UI.CurrentDir), selected), '', UseStartDir=TRUE) elif OSNAME == 'posix': - ExecuteCommand(os.path.join(os.path.abspath(UI.CurrentDir), selected)) + ExecuteCommand(os.path.join(os.path.abspath(UI.CurrentDir), selected), '') # End of 'DirListHandler()' @@ -1872,30 +1825,34 @@ # Execute A Command ##### -def ExecuteCommand(cmd, UseStartDir=FALSE): +def ExecuteCommand(cmd, name, UseStartDir=FALSE): global UI + # Process any unresolved variables + + newcmd = ProcessCommand(cmd, name) + # Just dump command if we're debugging if int(DEBUGLEVEL) & DEBUGCMDS: - PrintDebug(dCMD, [cmd,]) + PrintDebug(dCMD, [newcmd,]) # Otherwise,actually execute the command - else: + elif newcmd: # Run the command on Win32 using filename associations if UseStartDir: try: - os.startfile(cmd) + os.startfile(newcmd) except: - WrnMsg(wBADEXE % cmd) + WrnMsg(wBADEXE % newcmd) # Normal command execution for both Unix and Win32 else: try: - thread.start_new_thread(os.system, (cmd,)) + thread.start_new_thread(os.system, (newcmd,)) except: - WrnMsg(wBADEXE % cmd) + WrnMsg(wBADEXE % newcmd) # Update the Command History observing MAXHIST @@ -2243,6 +2200,60 @@ ##### +# Process A Command Line Containing Unresolved Vatriables +##### + +def ProcessCommand(cmd, name): + + # First do any prompting required + + for promptvar, handler, replace in ((YESNO, askyesno, FALSE), (PROMPT, askstring, TRUE)): + + for x in range(cmd.count(promptvar)): + b = cmd.find(promptvar) + e = cmd.find("]", b) + prompt = cmd[b + len(promptvar):e] + val = handler(name, prompt) + + # Make sure our program gets focus back + UI.DirList.focus() + + if val: + if replace: + cmd = cmd.replace(cmd[b:e+1], QUOTECHAR + val + QUOTECHAR) + else: + cmd = cmd.replace(cmd[b:e+1], '') + + # Null input means the command is being aborted + else: + return + + # Now do files & directories + # Strip trailing path separators in each case to + # give the command author the maximum flexibility possible + + selection = StripPSEP(UI.LastInSelection()) + + selections = "" + dselections = "" + for selected in UI.AllSelection(): + selected = StripPSEP(selected) + dselections += QUOTECHAR + UI.CurrentDir + selected + QUOTECHAR + " " + selections += QUOTECHAR + selected + QUOTECHAR + " " + + cmd = cmd.replace(DIR, QUOTECHAR + StripPSEP(UI.CurrentDir) + QUOTECHAR) + cmd = cmd.replace(DSELECTION, QUOTECHAR + UI.CurrentDir + selection + QUOTECHAR) + cmd = cmd.replace(DSELECTIONS, dselections) + cmd = cmd.replace(HASH, COMMENT) + cmd = cmd.replace(SELECTION, QUOTECHAR + selection + QUOTECHAR) + cmd = cmd.replace(SELECTIONS, selections) + + return cmd + +# End of 'ProcessCommand()' + + +##### # Refresh contents of directory listing to stay in sync with reality ##### @@ -2341,7 +2352,7 @@ # Now add the entry if we decided it was necessary. observing MAXDIR value. if addentry: - UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, LoadDirList, newentry=newdir) + UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, LoadDirList, sort=TRUE, newentry=newdir) # End of 'UpdateDirMenu()' @@ -2350,7 +2361,7 @@ # Generic Menu Update Routine ##### -def UpdateMenu(menubtn, datastore, max, func, newentry="", sort=TRUE, fakeevent=FALSE): +def UpdateMenu(menubtn, datastore, max, func, sort=FALSE, newentry="", fakeevent=FALSE): # First add the new data, if any, to the specified data storage stucture. @@ -2359,7 +2370,11 @@ # Now trim it to requested maximum length - this only changes how many # entries are display on the menu - nothing is actually removed - # from the data storage for this menu. + # from the data storage for this menu. We also do not sort the + # actual data storage itself if sorting has been requested. + # We sort the *copy*. That way we get the 'last _max_ items in + # sorted order.' (If we sorted the master copy, we would lose + # track of the order in which things were placed there.) data = datastore[:] if not max: @@ -2420,7 +2435,7 @@ # Make sure menus conform to max lengths (which may have changed). - UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, LoadDirList) + UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, LoadDirList, sort=TRUE) UpdateMenu(UI.HistBtn, UI.CmdHist, MAXHIST, KeyRunCommand, fakeevent=TRUE)