comparison mercurial/ui.py @ 32872:9fcb6df413c9

ui: add support for a tweakdefaults knob We've been talking for years about a one-stop config knob to opt in to better behavior. There have been a lot of ideas thrown around, but they all seem to be too complicated to get anyone to actually do the work.. As such, this patch is the stupidest thing that can possibly work in the name of getting a good feature to users. Right now it's just three config settings that I think are generally uncontroversial, but I expect to add more soon. That will likely include adding new config knobs for the express purpose of adding them to tweakdefaults.
author Augie Fackler <augie@google.com>
date Wed, 14 Jun 2017 20:56:34 -0400
parents 012e0da5b759
children 4a3f1d362e5f
comparison
equal deleted inserted replaced
32871:6fa245f80b6f 32872:9fcb6df413c9
40 urlreq = util.urlreq 40 urlreq = util.urlreq
41 41
42 # for use with str.translate(None, _keepalnum), to keep just alphanumerics 42 # for use with str.translate(None, _keepalnum), to keep just alphanumerics
43 _keepalnum = ''.join(c for c in map(pycompat.bytechr, range(256)) 43 _keepalnum = ''.join(c for c in map(pycompat.bytechr, range(256))
44 if not c.isalnum()) 44 if not c.isalnum())
45
46 # The config knobs that will be altered (if unset) by ui.tweakdefaults.
47 tweakrc = """
48 [ui]
49 # The rollback command is dangerous. As a rule, don't use it.
50 rollback = False
51
52 [commands]
53 # Make `hg status` emit cwd-relative paths by default.
54 status.relative = yes
55
56 [diff]
57 git = 1
58 """
45 59
46 samplehgrcs = { 60 samplehgrcs = {
47 'user': 61 'user':
48 """# example user config (see 'hg help config' for more info) 62 """# example user config (see 'hg help config' for more info)
49 [ui] 63 [ui]
180 self.fout = src.fout 194 self.fout = src.fout
181 self.ferr = src.ferr 195 self.ferr = src.ferr
182 self.fin = src.fin 196 self.fin = src.fin
183 self.pageractive = src.pageractive 197 self.pageractive = src.pageractive
184 self._disablepager = src._disablepager 198 self._disablepager = src._disablepager
199 self._tweaked = src._tweaked
185 200
186 self._tcfg = src._tcfg.copy() 201 self._tcfg = src._tcfg.copy()
187 self._ucfg = src._ucfg.copy() 202 self._ucfg = src._ucfg.copy()
188 self._ocfg = src._ocfg.copy() 203 self._ocfg = src._ocfg.copy()
189 self._trustusers = src._trustusers.copy() 204 self._trustusers = src._trustusers.copy()
203 self.fout = util.stdout 218 self.fout = util.stdout
204 self.ferr = util.stderr 219 self.ferr = util.stderr
205 self.fin = util.stdin 220 self.fin = util.stdin
206 self.pageractive = False 221 self.pageractive = False
207 self._disablepager = False 222 self._disablepager = False
223 self._tweaked = False
208 224
209 # shared read-only environment 225 # shared read-only environment
210 self.environ = encoding.environ 226 self.environ = encoding.environ
211 227
212 self.httppasswordmgrdb = httppasswordmgrdbproxy() 228 self.httppasswordmgrdb = httppasswordmgrdbproxy()
239 sections.add(section) 255 sections.add(section)
240 for section in sections: 256 for section in sections:
241 u.fixconfig(section=section) 257 u.fixconfig(section=section)
242 else: 258 else:
243 raise error.ProgrammingError('unknown rctype: %s' % t) 259 raise error.ProgrammingError('unknown rctype: %s' % t)
260 u._maybetweakdefaults()
244 return u 261 return u
262
263 def _maybetweakdefaults(self):
264 if not self.configbool('ui', 'tweakdefaults'):
265 return
266 if self._tweaked or self.plain('tweakdefaults'):
267 return
268
269 # Note: it is SUPER IMPORTANT that you set self._tweaked to
270 # True *before* any calls to setconfig(), otherwise you'll get
271 # infinite recursion between setconfig and this method.
272 #
273 # TODO: We should extract an inner method in setconfig() to
274 # avoid this weirdness.
275 self._tweaked = True
276 tmpcfg = config.config()
277 tmpcfg.parse('<tweakdefaults>', tweakrc)
278 for section in tmpcfg:
279 for name, value in tmpcfg.items(section):
280 if not self.hasconfig(section, name):
281 self.setconfig(section, name, value, "<tweakdefaults>")
245 282
246 def copy(self): 283 def copy(self):
247 return self.__class__(self) 284 return self.__class__(self)
248 285
249 def resetstate(self): 286 def resetstate(self):
385 422
386 def setconfig(self, section, name, value, source=''): 423 def setconfig(self, section, name, value, source=''):
387 for cfg in (self._ocfg, self._tcfg, self._ucfg): 424 for cfg in (self._ocfg, self._tcfg, self._ucfg):
388 cfg.set(section, name, value, source) 425 cfg.set(section, name, value, source)
389 self.fixconfig(section=section) 426 self.fixconfig(section=section)
427 self._maybetweakdefaults()
390 428
391 def _data(self, untrusted): 429 def _data(self, untrusted):
392 return untrusted and self._ucfg or self._tcfg 430 return untrusted and self._ucfg or self._tcfg
393 431
394 def configsource(self, section, name, untrusted=False): 432 def configsource(self, section, name, untrusted=False):