diff --git a/twander.py b/twander.py index 8932100..bf249cd 100755 --- a/twander.py +++ b/twander.py @@ -6,7 +6,7 @@ # Program Information PROGNAME = "twander" -RCSID = "$Id: twander.py,v 3.104 2003/02/25 00:08:23 tundra Exp $" +RCSID = "$Id: twander.py,v 3.105 2003/02/25 08:28:27 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -259,10 +259,8 @@ AUTOREFRESH = TRUE # Automatically refresh the directory display CMDSHELL = "" # No CMDSHELL processing DEBUGLEVEL = 0 # No debug output -MAXDIR = 32 # Maximum number of directories to track -MAXDIRBUF = 250 # Maximum size of UI.AllDirs -MAXHIST = 32 # Maximum length of Command History -MAXHISTBUF = 250 # Maximum size of UI.CmdHist +MAXMENU = 32 # Maximum length of displayed menu +MAXMENUBUF = 250 # Maximum size of internal menu buffer MAXNESTING = 32 # Maximum depth of nested variable definitions NODETAILS = FALSE # TRUE means details can never be displayed NONAVIGATE = FALSE # TRUE means that all directory navigation is prevented @@ -476,6 +474,7 @@ # Variable Name Pattern Matching Stuff DIRSC = "DIRSC" # Directory Shortcut naming +WILDCARD = "WILDCARD" # Wildcard naming reDIRSC = r'^' + DIRSC + r'([1-9]|1[0-2])$' # Regex describing Directory Shortcut names reVAR = r"\[.+?\]" # Regex describing variable notation @@ -527,8 +526,10 @@ COMMANDMENU = 'Commands' # Title for Command Menu button DIRMENU = 'Directories' # Title for Directory Menu button HISTMENU = 'History' # Title for History Menu button +WILDMENU = 'Wildcards' # Title for Wildcard Menu button HELPMENU = 'Help' # Title for Help Menu button + # Help Menu-Related ABOUT = "%s %s\n\nCopyright %s %s\n%s\n\n%s" % (PROGNAME, VERSION, CPRT, DATE, OWNER, RIGHTS) @@ -603,13 +604,13 @@ DEBUGCMDS = (1<<4) # Dump command execution string DEBUGDIRS = (1<<5) # Dump directory stack contents as it changes -DEBUGHIST = (1<<6) # Dump contents of Command History stack after command execution +DEBUGHIST = (1<<6) # Dump contents of command history stack after command execution DEBUGMEM = (1<<7) # Dump contents of program memories as they change # Nibble #3 -DEBUGRSRV1 = (1<<8) # Reserved for future use -DEBUGRSRV2 = (1<<9) +DEBUGWILD = (1<<8) # Dump contents of wildcard stack as it changes +DEBUGRSRV2 = (1<<9) # Reserved for future use DEBUGRSRV3 = (1<<10) DEBUGQUIT = (1<<11) # Dump debug info and quit program @@ -628,6 +629,7 @@ dNULL = "None" dOPTVAR = hOPTVBLS dSYMTBL = hUSERVBLS +dWILDSTK = "WILDCARD STACK" # Debug Formatting @@ -663,7 +665,7 @@ " 5 - Dump Directory Stack As It Changes (0x020)", " 6 - Dump Command History Stack After Command Executes (0x040)", " 7 - Dump Contents Of Program Memories As They Change (0x080)", - " 8 - Reserved", + " 8 - Dump Contents Of Wildcard Stack As It Changes (0x100)", " 9 - Reserved", " 10 - Reserved", " 11 - Dump Requested Debug Information And Exit Immediately (0x800)", @@ -1017,32 +1019,38 @@ WrnMsg(wBADSCNUM % (num, line)) return - # Process any option variables + # Process any wildcard definitions + + elif name == WILDCARD: + if val and (val not in UI.WildHist): + UpdateMenu(UI.WildBtn, UI.WildHist, MAXMENU, MAXMENUBUF, KeySelWild, newentry=val, fakeevent=TRUE) + + # Process any option variables - blank RHS is OK and means to leave + # option set to its default value. elif name in UI.OptionsBoolean.keys(): - val = val.upper() - if val == 'TRUE' or val == 'FALSE': - globals()[name] = eval(val) # !!! Cheater's way to get to global variables. - else: - WrnMsg(wBADRHS % (num, line)) - return + if val: + val = val.upper() + if val == 'TRUE' or val == 'FALSE': + globals()[name] = eval(val) # !!! Cheater's way to get to global variables. + else: + WrnMsg(wBADRHS % (num, line)) + return elif name in UI.OptionsNumeric.keys(): - try: - val = StringToNum(val) - if val >= 0: - globals()[name] = val - else: - WrnMsg(wBADRHS % (num, line)) - except: - WrnMsg(wBADRHS % (num, line)) - return + if val: + try: + val = StringToNum(val) + if val >= 0: + globals()[name] = val + else: + WrnMsg(wBADRHS % (num, line)) + except: + WrnMsg(wBADRHS % (num, line)) + return elif name in UI.OptionsString.keys(): - # RHS null means line ignored - option left set to default value - if not val: - pass - else: + if val: globals()[name] = val @@ -1140,7 +1148,7 @@ # Any user-set options have now been read, set the GUI - for i in (UI.CmdBtn, UI.DirBtn, UI.HistBtn, UI.HelpBtn): + for i in (UI.CmdBtn, UI.DirBtn, UI.HistBtn, UI.WildBtn, UI.HelpBtn): i.config(foreground=MFCOLOR, background=MBCOLOR, font=(MFNAME, MFSZ, MFWT)) i.menu.config(foreground=MFCOLOR, background=MBCOLOR, font=(MFNAME, MFSZ, MFWT)) @@ -1153,8 +1161,9 @@ # Make sure menus conform to max lengths (which may have changed). - UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, MAXDIRBUF, LoadDirList, sort=TRUE) - UpdateMenu(UI.HistBtn, UI.CmdHist, MAXHIST, MAXHISTBUF, KeyRunCommand, fakeevent=TRUE) + UpdateMenu(UI.DirBtn, UI.AllDirs, MAXMENU, MAXMENUBUF, LoadDirList, sort=TRUE) + UpdateMenu(UI.HistBtn, UI.CmdHist, MAXMENU, MAXMENUBUF, KeyRunCommand, fakeevent=TRUE) + UpdateMenu(UI.WildBtn, UI.WildHist, MAXMENU, MAXMENUBUF, KeySelWild, fakeevent=TRUE) ##### # Initialize Help Menu with latest information @@ -1316,6 +1325,12 @@ self.HistBtn.menu = Menu(self.HistBtn) self.HistBtn.pack(side=LEFT, padx=MENUPADX) + # Setup the Wildcard Menu + + self.WildBtn = Menubutton(self.mBar, text=WILDMENU, underline=0, state=DISABLED) + self.WildBtn.menu = Menu(self.WildBtn) + self.WildBtn.pack(side=LEFT, padx=MENUPADX) + # Setup the Help Menu self.HelpBtn = Menubutton(self.mBar, text=HELPMENU, underline=2, state=DISABLED) @@ -1688,6 +1703,10 @@ x, y = UI.DirList.winfo_pointerxy() # Position near mouse PopupMenu(UI.HistBtn.menu, x, y) # Display History Menu + elif event.state == (Button3Mask | AltMask | ControlMask): # Alt-Control-Button-3 + x, y = UI.DirList.winfo_pointerxy() # Position near mouse + PopupMenu(UI.WildBtn.menu, x, y) # Display Wildcard Menu + elif event.state == (Button3Mask | ShiftMask): # Shift-Button-3 x, y = UI.DirList.winfo_pointerxy() # Position near mouse PopupMenu(UI.DirBtn.menu, x, y) # Display Directory Menu @@ -1726,14 +1745,15 @@ def ClearHistory(event): global UI - UI.AllDirs = [] - UI.CmdHist = [] - UI.LastCmd = "" - UI.LastDir = [] + UI.AllDirs = [] + UI.CmdHist = [] + UI.WildHist = [] + UI.LastCmd = "" + UI.LastDir = [] UI.LastPathEntered = "" UI.LastSelWildcard = "" - for x in [UI.HistBtn, UI.DirBtn]: + for x in [UI.DirBtn, UI.HistBtn, UI.WildBtn]: x.menu.delete(0,END) x['menu'] = x.menu x.config(state=DISABLED) @@ -1805,6 +1825,10 @@ elif event.char == 'h': button = UI.HistBtn + # Wildcard Menu + elif event.char == 'w': + button = UI.WildBtn + # Help Menu elif event.char == 'l': button = UI.HelpBtn @@ -1907,7 +1931,7 @@ newpath = askstring(pCHPATH, pENPATH, initialvalue=UI.LastPathEntered) if newpath: - if MAXDIR > 0: + if MAXMENU > 0: UI.LastPathEntered = newpath LoadDirList(newpath) KeySelTop(event) @@ -2150,31 +2174,28 @@ # Event Handler: Select Using Wildcard ##### -def KeySelWild(event): +def KeySelWild(event, initial=""): - # Ask the user for the wildcard pattern - wc = askstring(pWILDSEL, pENWILD, initialvalue=UI.LastSelWildcard) + # Ask the user for the wildcard pattern, using initial string, if any + if initial: + uwc = askstring(pWILDSEL, pENWILD, initialvalue=initial) + else: + uwc = askstring(pWILDSEL, pENWILD, initialvalue=UI.LastSelWildcard) # Return focus to the main interface UI.DirList.focus() # Blank value means to abort - if not wc: + if not uwc: return - # Save the input - even if it turns out to be - # bogus, its better to have it available for - # subsequent edits since regex's get complicated - - UI.LastSelWildcard = wc - # Unless the user indicates otherwise, cook the regex so # a match can occur anywhere on the line - if wc[0] == STRICTMATCH: - wc = wc[1:] + if uwc[0] == STRICTMATCH: + wc = uwc[1:] else: - wc = r".*" + wc + wc = r".*" + uwc # Compile it - abort if compilation fails try: @@ -2198,6 +2219,24 @@ if matches: UI.SetSelection(matches, matches[0]) + # Save the wildcard only if dynamic menus are enabled (MAXMENU > 0) + # AND one of two conditions exist: + # + # 1) No initial string was provided (The user entered a command manually). + # 2) An initial string was provided, but the user edited it. + + if (MAXMENU > 0) and ((not initial) or (uwc != initial)): + UI.LastSelWildcard = uwc + + # Add this wildcard to the menu if its not there alread + if uwc not in UI.WildHist: + UpdateMenu(UI.WildBtn, UI.WildHist, MAXMENU, MAXMENUBUF, KeySelWild, newentry=uwc, fakeevent=TRUE) + + # Dump wildcard stack if debug requested it + if DEBUGLEVEL & DEBUGWILD: + PrintDebug(dWILDSTK, UI.WildHist) + + return 'break' # End of 'KeySelWild()' @@ -2279,13 +2318,9 @@ if initial: cmd = askstring(pRUNCMD, pENCMD, initialvalue=initial) - # Prompt with last manually entered command - elif UI.LastCmd: - cmd = askstring(pRUNCMD, pENCMD, initialvalue=UI.LastCmd ) - - # Prompt with no initial string + # Prompt with last manually entered command - doesn't matter if it's null else: - cmd = askstring(pRUNCMD, pENCMD) + cmd = askstring(pRUNCMD, pENCMD, initialvalue=UI.LastCmd ) # Execute command (if any) - Blank entry means do nothing/return if cmd: @@ -2301,13 +2336,13 @@ ExecuteCommand(mycmd, pMANUALCMD, ResolveVars=TRUE, SaveUnresolved=TRUE) - # Save the command only if Command History is enabled (MAXHIST > 0) + # Save the command only if Command History is enabled (MAXMENU > 0) # AND one of two conditions exist: # # 1) No initial string was provided (The user entered a command manually). # 2) An initial string was provided, but the user edited it. - if (MAXHIST > 0) and ((not initial) or (cmd != initial)): + if (MAXMENU > 0) and ((not initial) or (cmd != initial)): UI.LastCmd = cmd UI.DirList.focus() @@ -2544,7 +2579,7 @@ WrnMsg(wBADEXE % newcmd) - # Update the Command History observing MAXHIST + # Update the Command History observing MAXMENU # In most cases, we want to save the command with all the # variables (Built-In, Environment, User-Defined) resolved (dereferenced). # However, sometimes (e.g. manual command entry via KeyRunCommand()) we @@ -2555,7 +2590,7 @@ else: savecmd = newcmd - UpdateMenu(UI.HistBtn, UI.CmdHist, MAXHIST, MAXHISTBUF, KeyRunCommand, newentry=savecmd, fakeevent=TRUE) + UpdateMenu(UI.HistBtn, UI.CmdHist, MAXMENU, MAXMENUBUF, KeyRunCommand, newentry=savecmd, fakeevent=TRUE) # Dump Command History stack if requested @@ -3331,7 +3366,7 @@ ##### # Add An Entry To The List Of All Directories Visited # Do this only if it is not already on the list and -# observe the MAXDIR variable to keep list length bounded. +# observe the MAXMENU variable to keep list length bounded. ##### def UpdateDirMenu(newdir): @@ -3362,10 +3397,10 @@ elif newdir not in UI.AllDirs: addentry = TRUE - # Now add the entry if we decided it was necessary. observing MAXDIR value. + # Now add the entry if we decided it was necessary. observing MAXMENU value. if addentry: - UpdateMenu(UI.DirBtn, UI.AllDirs, MAXDIR, MAXDIRBUF, LoadDirList, sort=TRUE, newentry=newdir) + UpdateMenu(UI.DirBtn, UI.AllDirs, MAXMENU, MAXMENUBUF, LoadDirList, sort=TRUE, newentry=newdir) # End of 'UpdateDirMenu()' @@ -3584,9 +3619,8 @@ "USETHREADS":USETHREADS, "USEWIN32ALL":USEWIN32ALL, "WARN":WARN} UI.OptionsNumeric = {"DEBUGLEVEL":DEBUGLEVEL, "FSZ":FSZ, "MFSZ":MFSZ, "HFSZ":HFSZ, "HEIGHT":HEIGHT, - "MAXDIR":MAXDIR, "MAXDIRBUF":MAXDIRBUF, "MAXHIST":MAXHIST, "MAXHISTBUF":MAXHISTBUF, - "MAXNESTING":MAXNESTING, "REFRESHINT":REFRESHINT, "STARTX":STARTX, "STARTY":STARTY, - "WIDTH":WIDTH} + "MAXMENU":MAXMENU, "MAXMENUBUF":MAXMENUBUF, "MAXNESTING":MAXNESTING, + "REFRESHINT":REFRESHINT, "STARTX":STARTX, "STARTY":STARTY, "WIDTH":WIDTH} UI.OptionsString = {"BCOLOR":BCOLOR, "FCOLOR":FCOLOR, "FNAME":FNAME, "FWT":FWT, # Main Font/Colors "MBCOLOR":MBCOLOR, "MFCOLOR":MFCOLOR, "MFNAME":MFNAME, "MFWT":MFWT, # Menu Font/Colors @@ -3611,7 +3645,7 @@ # And current location UI.CurrentDir = "" -# Initialize Command History data structures +# Initialize various menu data structures ClearHistory(None) # Initialize Storage For Program Memories