ui: get readline and prompt to behave better depending on interactivity
authorBryan O'Sullivan <bos@serpentine.com>
Tue, 31 Jul 2007 16:28:05 -0700
changeset 5036 ca0d02222d6a
parent 5035 a675f6d5d069
child 5037 b2607267236d
ui: get readline and prompt to behave better depending on interactivity
mercurial/ui.py
--- a/mercurial/ui.py	Tue Jul 31 16:28:05 2007 -0700
+++ b/mercurial/ui.py	Tue Jul 31 16:28:05 2007 -0700
@@ -24,6 +24,8 @@
             dest.set(section, name, value)
 
 class ui(object):
+    _isatty = None
+
     def __init__(self, verbose=False, debug=False, quiet=False,
                  interactive=True, traceback=False, report_untrusted=True,
                  parentui=None):
@@ -62,6 +64,11 @@
     def __getattr__(self, key):
         return getattr(self.parentui, key)
 
+    def isatty(self):
+        if ui._isatty is None:
+            ui._isatty = os.isatty(sys.stdin.fileno())
+        return ui._isatty
+
     def updateopts(self, verbose=False, debug=False, quiet=False,
                    interactive=True, traceback=False, config=[]):
         for section, name, value in config:
@@ -204,7 +211,9 @@
             if name is None or name in ('quiet', 'verbose', 'debug'):
                 self.verbosity_constraints()
             if name is None or name == 'interactive':
-                self.interactive = self.configbool("ui", "interactive", True)
+                self.interactive = self.configbool("ui", "interactive", None)
+                if self.interactive is None:
+                    self.interactive = self.isatty()
             if name is None or name == 'report_untrusted':
                 self.report_untrusted = (
                     self.configbool("ui", "report_untrusted", True))
@@ -382,17 +391,29 @@
         try: sys.stderr.flush()
         except: pass
 
-    def readline(self):
-        return sys.stdin.readline()[:-1]
+    def readline(self, prompt=''):
+        if self.isatty():
+            try:
+                # magically add command line editing support, where
+                # available
+                import readline
+                # force demandimport to really load the module
+                readline.read_history_file
+            except ImportError:
+                pass
+        return raw_input(prompt)
+
     def prompt(self, msg, pat=None, default="y"):
         if not self.interactive: return default
-        while 1:
-            self.write(msg, " ")
-            r = self.readline()
+        try:
+            r = self.readline(msg + ' ')
             if not pat or re.match(pat, r):
                 return r
             else:
                 self.write(_("unrecognized response\n"))
+        except EOFError:
+            raise util.Abort(_('response expected'))
+
     def getpass(self, prompt=None, default=None):
         if not self.interactive: return default
         return getpass.getpass(prompt or _('password: '))