Index: raster/Makefile
===================================================================
--- raster/Makefile	(revision 39934)
+++ raster/Makefile	(working copy)
@@ -110,7 +110,8 @@
 	r.what \
 	r.what.color \
 	simwe \
-	wildfire
+	wildfire \
+	r.prominence
 
 GDALBASED = r.in.gdal r.out.gdal
 
Index: gui/wxpython/gui_modules/goutput.py
===================================================================
--- gui/wxpython/gui_modules/goutput.py	(revision 39934)
+++ gui/wxpython/gui_modules/goutput.py	(working copy)
@@ -24,6 +24,8 @@
 import time
 import threading
 import Queue
+import shlex
+import keyword
 
 import wx
 import wx.stc
@@ -145,6 +147,10 @@
             self._notebook = self.parent.notebook
         self.lineWidth       = 80
         self.pageid          = pageid
+        
+        # dictionary of modules (description, keywords, ...)
+#        self.modules = self.parent.menudata.GetModules()
+                
         # remember position of line begining (used for '\r')
         self.linePos         = -1
         
@@ -269,7 +275,8 @@
         
         # p1 = self.cmd_output.GetCurrentPos()
         p1 = self.cmd_output.GetEndStyled()
-        self.cmd_output.GotoPos(p1)
+#        self.cmd_output.GotoPos(p1)
+        self.cmd_output.DocumentEnd()
         
         for line in text.splitlines():
             # fill space
@@ -590,7 +597,7 @@
 
         # set focus on prompt
         if self.parent.GetName() == "LayerManager":
-            self.parent.cmdinput.SetFocus()
+#            self.parent.cmdinput.SetFocus()
             self.btn_abort.Enable(False)
         else:
             # updated command dialog
@@ -756,14 +763,70 @@
     def __init__(self, parent, id, margin=False, wrap=None):
         wx.stc.StyledTextCtrl.__init__(self, parent, id)
         self.parent = parent
+        self.SetUndoCollection(True)
 
         #
         # styles
         #                
         self.SetStyle()
         
+        #
+        # create map lists for autocompletion
+        #
+        self.AutoCompSetIgnoreCase(False) 
+        self.datatypes = []
+        self.maplists = {}
+        self.maptype = ''
+        self.datatypes = ['rast',
+                        'rast3d',
+                        'vect',
+                        'oldvect',
+                        'asciivect',
+                        'labels',
+                        'region',
+                        'region3d',
+                        'group',
+                        '3dview']
 
+        self.drastcmd = ['d.rast',
+                        'd.rgb',
+                        'd.his',
+                        'd.rast.arrow',
+                        'd.rast.num']
+                    
+        self.dvectcmd = ['d.vect',
+                        'd.vect.chart'
+                        'd.thematic.area',
+                        'd.vect.thematic']
+        
+        self.rastargs = ['map',
+                        'input',
+                        'elevation',
+                        'color',
+                        'rast',
+                        'raster',
+                        'red',
+                        'green',
+                        'blue',
+                        'h_map',
+                        'i_map',
+                        's_map',
+                        'hue_input',
+                        'intensity_input',
+                        'saturation_input',
+                        'red_input',
+                        'green_input',
+                        'blue_input']
+                        
+        self.__getfiles()
+
         #
+        # command history buffer
+        #
+        self.cmdbuffer = []
+        self.cmdindex = 0
+
+        #
         # line margins
         #
         # TODO print number only from cmdlog
@@ -789,7 +852,14 @@
         # bindins
         #
         self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
         
+    def __getfiles(self):                                
+        for item in self.datatypes:
+            mlist = grass.read_command("g.mlist", "m", type=item).splitlines()
+            mlist.sort()
+            self.maplists[item] = mlist
+                                                    
     def SetStyle(self):
         """!Set styles for styled text output windows with type face 
         and point size selected by user (Courier New 10 is default)"""
@@ -830,8 +900,161 @@
         self.StyleSetSpec(self.StyleError,   self.StyleErrorSpec)
         self.StyleSetSpec(self.StyleWarning, self.StyleWarningSpec)
         self.StyleSetSpec(self.StyleMessage, self.StyleMessageSpec)
-        self.StyleSetSpec(self.StyleUnknown, self.StyleUnknownSpec)        
+        self.StyleSetSpec(self.StyleUnknown, self.StyleUnknownSpec)    
+        
+    def OnKeyPressed(self, event):
+        """!Key press capture for autocompletion, tooltips, and command history"""
+        #keycodes used: <space> = 32, "=" = 61, "," = 44, up-arrow = 315, down-arrow = 317 
+        line = ''
+        
+        #Tooltips
+        if event.GetKeyCode() == 32 and event.ControlDown() and event.ShiftDown():
+            self.CallTipSetBackground("yellow")
+            self.CallTipShow(pos, 'lots of of text: blah, blah, blah\n\n'
+                             'show some suff, maybe parameters..\n\n'
+                             'fubar(param1, param2)')
+                             
+        #Autocompletion for map/data file name entry
+        elif (event.GetKeyCode() == 32 and event.ControlDown()) \
+            or event.GetKeyCode() == 61 or event.GetKeyCode() == 44:
+            # map/data entry autocompletion
 
+            #get all text left of cursor
+            pos = self.GetCurrentPos()
+            self.HomeExtend()
+            entry = self.GetSelectedText()
+            self.SetCurrentPos(pos)
+
+            #must be a command left of the cursor somewhere
+            try:
+                if '.' in entry:
+                    cmdtype, dot, rest = entry.partition('.')
+                    cmdname = rest.split()[0]
+                    cmd = cmdtype+dot+cmdname
+                    cmd = cmd.strip() 
+                elif 'nviz' in entry.lower():
+                    cmdtype = ''
+                    cmdname = cmd = 'nviz'
+                else:
+                    return
+                
+                cmdargs = entry.strip('=')
+                arg = cmdargs.rsplit(' ',1)[1]
+            except:
+                return
+
+
+            if event.GetKeyCode() == 61:
+                #insert the '=' and move to the end of the line, ready for a map name
+                self.InsertText(pos,'=')
+                self.LineEnd()
+                
+                #what kind of map/data type is desired?
+                maplist = []
+                if (((cmdtype=='r' or cmdtype=='i' or cmd in self.drastcmd) and arg in self.rastargs) or
+                  ((cmd=='nviz' or cmdtype=='r3') and (arg=='elevation' or arg=='color')) or
+                  arg=='rast' or arg=='raster'):
+                    self.maptype = 'rast'
+                elif (((cmdtype=='v' or cmd in self.dvectcmd) and (arg=='map' or arg=='input')) or
+                  (cmdtype=='r3' and arg=='input') or
+                  arg=='vect' or arg=='vector' or arg=='points'):
+                    self.maptype = 'vect'
+                elif ((cmdtype=='r3' and (arg=='map' or arg=='input')) or
+                  (cmdtype=='nviz' and arg=='volume') or arg=='rast3d'):
+                    self.maptype = 'rast3d'
+                elif arg=='labels':
+                    self.maptype ='labels'
+                elif arg=='region':
+                    self.maptype ='region'
+                elif arg=='region3d':
+                    self.maptype ='region3d'
+                elif arg=='group':
+                    self.maptype ='group'
+                elif arg=='3dview':
+                    self.maptype ='3dview'
+
+            elif event.GetKeyCode() == 44:
+                #if comma is pressed, use the same maptype as previous for multiple map entries
+                
+                # insert the comma and move to the end of the line ready for a map name
+                self.InsertText(pos,',')
+                self.LineEnd()
+                
+                #must apply to an entry where '=[string]' has already been entered
+                if '=' not in arg:
+                    return
+
+            else:
+                #map entries without arguments (as in r.info [mapname]) use ctrl-shift
+                maplist = []
+                if cmdtype=='r' or cmdtype=='i':
+                    self.maptype = 'rast'
+                elif cmdtype=='v':
+                    self.maptype = 'vect'
+                elif cmdtype=='r3':
+                    self.maptype = 'rast3d'
+                    
+            if self.maptype == '': 
+                return
+            else:
+                maplist = self.maplists[self.maptype]
+                self.AutoCompShow(0, " ".join(maplist))
+                        
+        #Command history    
+        elif event.GetKeyCode() in [315,317] and event.ControlDown():
+            
+            if self.cmdbuffer == []: return
+            txt = ''
+
+            self.DocumentEnd()
+            
+            if event.GetKeyCode() == 315:
+                self.cmdindex = self.cmdindex - 1
+            if event.GetKeyCode() == 317:
+                self.cmdindex = self.cmdindex + 1
+            if self.cmdindex < 0:
+                self.cmdindex = 0
+            if self.cmdindex > len(self.cmdbuffer) - 1:
+                self.cmdindex = len(self.cmdbuffer) - 1
+            
+            try:
+                txt = self.cmdbuffer[self.cmdindex]
+            except:
+                pass
+                
+            self.DelLineLeft()
+            self.DelLineRight()
+            pos = self.GetCurrentPos()            
+            self.InsertText(pos,txt)
+            self.LineEnd()
+            
+        #Run command on line when <return> is pressed    
+        elif event.GetKeyCode() == 13 and self.AutoCompActive() == False:
+            #find the command to run
+            line = str(self.GetCurLine()[0]).strip()
+            if line == '' or line == None or \
+                ('.' not in line and 'nviz' not in line.lower()): 
+                # must have some text and basic test for GRASS command
+                self.DocumentEnd()
+                return            
+                        
+            cmd = shlex.split(str(line))
+            
+            #send the command to the processor 
+            self.parent.RunCmd(cmd)
+                            
+            #add command to buffer    
+            self.cmdbuffer.append(line)
+            
+            #keep buffer to a managable size
+            if len(self.cmdbuffer) > 200:
+                del self.cmdbuffer[0]
+            self.cmdindex = len(self.cmdbuffer)
+            #TODO set focus back to terminal after command
+
+        else:
+            event.Skip()
+
     def OnDestroy(self, evt):
         """!The clipboard contents can be preserved after
         the app has exited"""
Index: macosx/bundle.make
===================================================================
--- macosx/bundle.make	(revision 39934)
+++ macosx/bundle.make	(working copy)
@@ -20,5 +20,14 @@
 #	${INSTALL} /usr/local/pgsql/lib/libpq.5.1.dylib ${INST_DIR_TARGET}/lib
 #	${LN} libpq.5.1.dylib ${INST_DIR_TARGET}/lib/libpq.5.dylib
 
+WXPREFIX=/usr/local/lib/wxPython-unicode-2.8.10.1
 bundle-macosx:
-	@# add custom bundle commands here:
+	${INSTALL} ${WXPREFIX}/lib/libwx_macud-2.8.0.dylib ${INST_DIR_TARGET}/lib
+	${INSTALL} ${WXPREFIX}/lib/libwx_macud_gl-2.8.0.dylib ${INST_DIR_TARGET}/lib
+	${INSTALL} ${WXPREFIX}/lib/libwx_macud_stc-2.8.0.dylib ${INST_DIR_TARGET}/lib
+	${INSTALL} ${WXPREFIX}/lib/libwx_macud_gizmos-2.8.0.dylib ${INST_DIR_TARGET}/lib
+	${INSTALL} ${WXPREFIX}/lib/libwx_macud_gizmos_xrc-2.8.0.dylib ${INST_DIR_TARGET}/lib
+	cp -Rfp ${WXPREFIX}/lib/python2.5/site-packages/wx-2.8-mac-unicode/wx ${INST_DIR_TARGET}/etc/python
+	cp -Rfp ${WXPREFIX}/lib/python2.5/site-packages/wx-2.8-mac-unicode/wxPython ${INST_DIR_TARGET}/etc/python
+	cp -fp ${WXPREFIX}/lib/python2.5/site-packages/wxversion.py ${INST_DIR_TARGET}/etc/python
+	sed -i '' -e 's/^GRASS_WXBUNDLED=.*/GRASS_WXBUNDLED=1/' ${INST_DIR_TARGET}/grass.sh
