comparison mercurial/ui.py @ 28542:71e12fc53b80

ui: add new config flag for interface selection This patch introduces a new config flag ui.interface to select the interface for interactive commands. It currently only applies to chunks selection. The config can be overridden on a per feature basis with the flag ui.interface.<feature>. features for the moment can only be 'chunkselector', moving forward we expect to have 'histedit' and other commands there. If an incorrect value is given to ui.interface we print a warning and use the default interface: text. If HGPLAIN is specified we also use the default interface: text. Note that we fail quickly if a feature does not handle all the interfaces that we permit in ui.interface; in future, we could design a fallback path (e.g. blackpearl to curses, curses to text), but let's leave that until we need it.
author Simon Farnsworth <simonfar@fb.com>
date Mon, 14 Mar 2016 15:01:27 +0000
parents d09be0b8a3c6
children c30d5ca4945b
comparison
equal deleted inserted replaced
28541:4b81487a01d4 28542:71e12fc53b80
695 def _isatty(self, fh): 695 def _isatty(self, fh):
696 if self.configbool('ui', 'nontty', False): 696 if self.configbool('ui', 'nontty', False):
697 return False 697 return False
698 return util.isatty(fh) 698 return util.isatty(fh)
699 699
700 def interface(self, feature):
701 """what interface to use for interactive console features?
702
703 The interface is controlled by the value of `ui.interface` but also by
704 the value of feature-specific configuration. For example:
705
706 ui.interface.histedit = text
707 ui.interface.chunkselector = curses
708
709 Here the features are "histedit" and "chunkselector".
710
711 The configuration above means that the default interfaces for commands
712 is curses, the interface for histedit is text and the interface for
713 selecting chunk is crecord (the best curses interface available).
714
715 Consider the following exemple:
716 ui.interface = curses
717 ui.interface.histedit = text
718
719 Then histedit will use the text interface and chunkselector will use
720 the default curses interface (crecord at the moment).
721 """
722 alldefaults = frozenset(["text", "curses"])
723
724 featureinterfaces = {
725 "chunkselector": [
726 "text",
727 "curses",
728 ]
729 }
730
731 # Feature-specific interface
732 if feature not in featureinterfaces.keys():
733 # Programming error, not user error
734 raise ValueError("Unknown feature requested %s" % feature)
735
736 availableinterfaces = frozenset(featureinterfaces[feature])
737 if alldefaults > availableinterfaces:
738 # Programming error, not user error. We need a use case to
739 # define the right thing to do here.
740 raise ValueError(
741 "Feature %s does not handle all default interfaces" %
742 feature)
743
744 if self.plain():
745 return "text"
746
747 # Default interface for all the features
748 defaultinterface = "text"
749 i = self.config("ui", "interface", None)
750 if i in alldefaults:
751 defaultinterface = i
752
753 choseninterface = defaultinterface
754 f = self.config("ui", "interface.%s" % feature, None)
755 if f in availableinterfaces:
756 choseninterface = f
757
758 if i is not None and defaultinterface != i:
759 if f is not None:
760 self.warn(_("invalid value for ui.interface: %s\n") %
761 (i,))
762 else:
763 self.warn(_("invalid value for ui.interface: %s (using %s)\n") %
764 (i, choseninterface))
765 if f is not None and choseninterface != f:
766 self.warn(_("invalid value for ui.interface.%s: %s (using %s)\n") %
767 (feature, f, choseninterface))
768
769 return choseninterface
770
700 def interactive(self): 771 def interactive(self):
701 '''is interactive input allowed? 772 '''is interactive input allowed?
702 773
703 An interactive session is a session where input can be reasonably read 774 An interactive session is a session where input can be reasonably read
704 from `sys.stdin'. If this function returns false, any attempt to read 775 from `sys.stdin'. If this function returns false, any attempt to read