##// END OF EJS Templates
templatekw: change default value of 'requires' to ()...
Yuya Nishihara -
r42535:de65ae32 default
parent child Browse files
Show More
@@ -1,503 +1,501 b''
1 # registrar.py - utilities to register function for specific purpose
1 # registrar.py - utilities to register function for specific purpose
2 #
2 #
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
3 # Copyright FUJIWARA Katsunori <foozy@lares.dti.ne.jp> and others
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from . import (
10 from . import (
11 configitems,
11 configitems,
12 error,
12 error,
13 pycompat,
13 pycompat,
14 util,
14 util,
15 )
15 )
16
16
17 # unlike the other registered items, config options are neither functions or
17 # unlike the other registered items, config options are neither functions or
18 # classes. Registering the option is just small function call.
18 # classes. Registering the option is just small function call.
19 #
19 #
20 # We still add the official API to the registrar module for consistency with
20 # We still add the official API to the registrar module for consistency with
21 # the other items extensions want might to register.
21 # the other items extensions want might to register.
22 configitem = configitems.getitemregister
22 configitem = configitems.getitemregister
23
23
24 class _funcregistrarbase(object):
24 class _funcregistrarbase(object):
25 """Base of decorator to register a function for specific purpose
25 """Base of decorator to register a function for specific purpose
26
26
27 This decorator stores decorated functions into own dict 'table'.
27 This decorator stores decorated functions into own dict 'table'.
28
28
29 The least derived class can be defined by overriding 'formatdoc',
29 The least derived class can be defined by overriding 'formatdoc',
30 for example::
30 for example::
31
31
32 class keyword(_funcregistrarbase):
32 class keyword(_funcregistrarbase):
33 _docformat = ":%s: %s"
33 _docformat = ":%s: %s"
34
34
35 This should be used as below:
35 This should be used as below:
36
36
37 keyword = registrar.keyword()
37 keyword = registrar.keyword()
38
38
39 @keyword('bar')
39 @keyword('bar')
40 def barfunc(*args, **kwargs):
40 def barfunc(*args, **kwargs):
41 '''Explanation of bar keyword ....
41 '''Explanation of bar keyword ....
42 '''
42 '''
43 pass
43 pass
44
44
45 In this case:
45 In this case:
46
46
47 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
47 - 'barfunc' is stored as 'bar' in '_table' of an instance 'keyword' above
48 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
48 - 'barfunc.__doc__' becomes ":bar: Explanation of bar keyword"
49 """
49 """
50 def __init__(self, table=None):
50 def __init__(self, table=None):
51 if table is None:
51 if table is None:
52 self._table = {}
52 self._table = {}
53 else:
53 else:
54 self._table = table
54 self._table = table
55
55
56 def __call__(self, decl, *args, **kwargs):
56 def __call__(self, decl, *args, **kwargs):
57 return lambda func: self._doregister(func, decl, *args, **kwargs)
57 return lambda func: self._doregister(func, decl, *args, **kwargs)
58
58
59 def _doregister(self, func, decl, *args, **kwargs):
59 def _doregister(self, func, decl, *args, **kwargs):
60 name = self._getname(decl)
60 name = self._getname(decl)
61
61
62 if name in self._table:
62 if name in self._table:
63 msg = 'duplicate registration for name: "%s"' % name
63 msg = 'duplicate registration for name: "%s"' % name
64 raise error.ProgrammingError(msg)
64 raise error.ProgrammingError(msg)
65
65
66 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
66 if func.__doc__ and not util.safehasattr(func, '_origdoc'):
67 doc = pycompat.sysbytes(func.__doc__).strip()
67 doc = pycompat.sysbytes(func.__doc__).strip()
68 func._origdoc = doc
68 func._origdoc = doc
69 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
69 func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc))
70
70
71 self._table[name] = func
71 self._table[name] = func
72 self._extrasetup(name, func, *args, **kwargs)
72 self._extrasetup(name, func, *args, **kwargs)
73
73
74 return func
74 return func
75
75
76 def _merge(self, registrarbase):
76 def _merge(self, registrarbase):
77 """Merge the entries of the given registrar object into this one.
77 """Merge the entries of the given registrar object into this one.
78
78
79 The other registrar object must not contain any entries already in the
79 The other registrar object must not contain any entries already in the
80 current one, or a ProgrammmingError is raised. Additionally, the types
80 current one, or a ProgrammmingError is raised. Additionally, the types
81 of the two registrars must match.
81 of the two registrars must match.
82 """
82 """
83 if not isinstance(registrarbase, type(self)):
83 if not isinstance(registrarbase, type(self)):
84 msg = "cannot merge different types of registrar"
84 msg = "cannot merge different types of registrar"
85 raise error.ProgrammingError(msg)
85 raise error.ProgrammingError(msg)
86
86
87 dups = set(registrarbase._table).intersection(self._table)
87 dups = set(registrarbase._table).intersection(self._table)
88
88
89 if dups:
89 if dups:
90 msg = 'duplicate registration for names: "%s"' % '", "'.join(dups)
90 msg = 'duplicate registration for names: "%s"' % '", "'.join(dups)
91 raise error.ProgrammingError(msg)
91 raise error.ProgrammingError(msg)
92
92
93 self._table.update(registrarbase._table)
93 self._table.update(registrarbase._table)
94
94
95 def _parsefuncdecl(self, decl):
95 def _parsefuncdecl(self, decl):
96 """Parse function declaration and return the name of function in it
96 """Parse function declaration and return the name of function in it
97 """
97 """
98 i = decl.find('(')
98 i = decl.find('(')
99 if i >= 0:
99 if i >= 0:
100 return decl[:i]
100 return decl[:i]
101 else:
101 else:
102 return decl
102 return decl
103
103
104 def _getname(self, decl):
104 def _getname(self, decl):
105 """Return the name of the registered function from decl
105 """Return the name of the registered function from decl
106
106
107 Derived class should override this, if it allows more
107 Derived class should override this, if it allows more
108 descriptive 'decl' string than just a name.
108 descriptive 'decl' string than just a name.
109 """
109 """
110 return decl
110 return decl
111
111
112 _docformat = None
112 _docformat = None
113
113
114 def _formatdoc(self, decl, doc):
114 def _formatdoc(self, decl, doc):
115 """Return formatted document of the registered function for help
115 """Return formatted document of the registered function for help
116
116
117 'doc' is '__doc__.strip()' of the registered function.
117 'doc' is '__doc__.strip()' of the registered function.
118 """
118 """
119 return self._docformat % (decl, doc)
119 return self._docformat % (decl, doc)
120
120
121 def _extrasetup(self, name, func):
121 def _extrasetup(self, name, func):
122 """Execute exra setup for registered function, if needed
122 """Execute exra setup for registered function, if needed
123 """
123 """
124
124
125 class command(_funcregistrarbase):
125 class command(_funcregistrarbase):
126 """Decorator to register a command function to table
126 """Decorator to register a command function to table
127
127
128 This class receives a command table as its argument. The table should
128 This class receives a command table as its argument. The table should
129 be a dict.
129 be a dict.
130
130
131 The created object can be used as a decorator for adding commands to
131 The created object can be used as a decorator for adding commands to
132 that command table. This accepts multiple arguments to define a command.
132 that command table. This accepts multiple arguments to define a command.
133
133
134 The first argument is the command name (as bytes).
134 The first argument is the command name (as bytes).
135
135
136 The `options` keyword argument is an iterable of tuples defining command
136 The `options` keyword argument is an iterable of tuples defining command
137 arguments. See ``mercurial.fancyopts.fancyopts()`` for the format of each
137 arguments. See ``mercurial.fancyopts.fancyopts()`` for the format of each
138 tuple.
138 tuple.
139
139
140 The `synopsis` argument defines a short, one line summary of how to use the
140 The `synopsis` argument defines a short, one line summary of how to use the
141 command. This shows up in the help output.
141 command. This shows up in the help output.
142
142
143 There are three arguments that control what repository (if any) is found
143 There are three arguments that control what repository (if any) is found
144 and passed to the decorated function: `norepo`, `optionalrepo`, and
144 and passed to the decorated function: `norepo`, `optionalrepo`, and
145 `inferrepo`.
145 `inferrepo`.
146
146
147 The `norepo` argument defines whether the command does not require a
147 The `norepo` argument defines whether the command does not require a
148 local repository. Most commands operate against a repository, thus the
148 local repository. Most commands operate against a repository, thus the
149 default is False. When True, no repository will be passed.
149 default is False. When True, no repository will be passed.
150
150
151 The `optionalrepo` argument defines whether the command optionally requires
151 The `optionalrepo` argument defines whether the command optionally requires
152 a local repository. If no repository can be found, None will be passed
152 a local repository. If no repository can be found, None will be passed
153 to the decorated function.
153 to the decorated function.
154
154
155 The `inferrepo` argument defines whether to try to find a repository from
155 The `inferrepo` argument defines whether to try to find a repository from
156 the command line arguments. If True, arguments will be examined for
156 the command line arguments. If True, arguments will be examined for
157 potential repository locations. See ``findrepo()``. If a repository is
157 potential repository locations. See ``findrepo()``. If a repository is
158 found, it will be used and passed to the decorated function.
158 found, it will be used and passed to the decorated function.
159
159
160 The `intents` argument defines a set of intended actions or capabilities
160 The `intents` argument defines a set of intended actions or capabilities
161 the command is taking. These intents can be used to affect the construction
161 the command is taking. These intents can be used to affect the construction
162 of the repository object passed to the command. For example, commands
162 of the repository object passed to the command. For example, commands
163 declaring that they are read-only could receive a repository that doesn't
163 declaring that they are read-only could receive a repository that doesn't
164 have any methods allowing repository mutation. Other intents could be used
164 have any methods allowing repository mutation. Other intents could be used
165 to prevent the command from running if the requested intent could not be
165 to prevent the command from running if the requested intent could not be
166 fulfilled.
166 fulfilled.
167
167
168 If `helpcategory` is set (usually to one of the constants in the help
168 If `helpcategory` is set (usually to one of the constants in the help
169 module), the command will be displayed under that category in the help's
169 module), the command will be displayed under that category in the help's
170 list of commands.
170 list of commands.
171
171
172 The following intents are defined:
172 The following intents are defined:
173
173
174 readonly
174 readonly
175 The command is read-only
175 The command is read-only
176
176
177 The signature of the decorated function looks like this:
177 The signature of the decorated function looks like this:
178 def cmd(ui[, repo] [, <args>] [, <options>])
178 def cmd(ui[, repo] [, <args>] [, <options>])
179
179
180 `repo` is required if `norepo` is False.
180 `repo` is required if `norepo` is False.
181 `<args>` are positional args (or `*args`) arguments, of non-option
181 `<args>` are positional args (or `*args`) arguments, of non-option
182 arguments from the command line.
182 arguments from the command line.
183 `<options>` are keyword arguments (or `**options`) of option arguments
183 `<options>` are keyword arguments (or `**options`) of option arguments
184 from the command line.
184 from the command line.
185
185
186 See the WritingExtensions and MercurialApi documentation for more exhaustive
186 See the WritingExtensions and MercurialApi documentation for more exhaustive
187 descriptions and examples.
187 descriptions and examples.
188 """
188 """
189
189
190 # Command categories for grouping them in help output.
190 # Command categories for grouping them in help output.
191 # These can also be specified for aliases, like:
191 # These can also be specified for aliases, like:
192 # [alias]
192 # [alias]
193 # myalias = something
193 # myalias = something
194 # myalias:category = repo
194 # myalias:category = repo
195 CATEGORY_REPO_CREATION = 'repo'
195 CATEGORY_REPO_CREATION = 'repo'
196 CATEGORY_REMOTE_REPO_MANAGEMENT = 'remote'
196 CATEGORY_REMOTE_REPO_MANAGEMENT = 'remote'
197 CATEGORY_COMMITTING = 'commit'
197 CATEGORY_COMMITTING = 'commit'
198 CATEGORY_CHANGE_MANAGEMENT = 'management'
198 CATEGORY_CHANGE_MANAGEMENT = 'management'
199 CATEGORY_CHANGE_ORGANIZATION = 'organization'
199 CATEGORY_CHANGE_ORGANIZATION = 'organization'
200 CATEGORY_FILE_CONTENTS = 'files'
200 CATEGORY_FILE_CONTENTS = 'files'
201 CATEGORY_CHANGE_NAVIGATION = 'navigation'
201 CATEGORY_CHANGE_NAVIGATION = 'navigation'
202 CATEGORY_WORKING_DIRECTORY = 'wdir'
202 CATEGORY_WORKING_DIRECTORY = 'wdir'
203 CATEGORY_IMPORT_EXPORT = 'import'
203 CATEGORY_IMPORT_EXPORT = 'import'
204 CATEGORY_MAINTENANCE = 'maintenance'
204 CATEGORY_MAINTENANCE = 'maintenance'
205 CATEGORY_HELP = 'help'
205 CATEGORY_HELP = 'help'
206 CATEGORY_MISC = 'misc'
206 CATEGORY_MISC = 'misc'
207 CATEGORY_NONE = 'none'
207 CATEGORY_NONE = 'none'
208
208
209 def _doregister(self, func, name, options=(), synopsis=None,
209 def _doregister(self, func, name, options=(), synopsis=None,
210 norepo=False, optionalrepo=False, inferrepo=False,
210 norepo=False, optionalrepo=False, inferrepo=False,
211 intents=None, helpcategory=None, helpbasic=False):
211 intents=None, helpcategory=None, helpbasic=False):
212 func.norepo = norepo
212 func.norepo = norepo
213 func.optionalrepo = optionalrepo
213 func.optionalrepo = optionalrepo
214 func.inferrepo = inferrepo
214 func.inferrepo = inferrepo
215 func.intents = intents or set()
215 func.intents = intents or set()
216 func.helpcategory = helpcategory
216 func.helpcategory = helpcategory
217 func.helpbasic = helpbasic
217 func.helpbasic = helpbasic
218 if synopsis:
218 if synopsis:
219 self._table[name] = func, list(options), synopsis
219 self._table[name] = func, list(options), synopsis
220 else:
220 else:
221 self._table[name] = func, list(options)
221 self._table[name] = func, list(options)
222 return func
222 return func
223
223
224 INTENT_READONLY = b'readonly'
224 INTENT_READONLY = b'readonly'
225
225
226 class revsetpredicate(_funcregistrarbase):
226 class revsetpredicate(_funcregistrarbase):
227 """Decorator to register revset predicate
227 """Decorator to register revset predicate
228
228
229 Usage::
229 Usage::
230
230
231 revsetpredicate = registrar.revsetpredicate()
231 revsetpredicate = registrar.revsetpredicate()
232
232
233 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
233 @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
234 def mypredicatefunc(repo, subset, x):
234 def mypredicatefunc(repo, subset, x):
235 '''Explanation of this revset predicate ....
235 '''Explanation of this revset predicate ....
236 '''
236 '''
237 pass
237 pass
238
238
239 The first string argument is used also in online help.
239 The first string argument is used also in online help.
240
240
241 Optional argument 'safe' indicates whether a predicate is safe for
241 Optional argument 'safe' indicates whether a predicate is safe for
242 DoS attack (False by default).
242 DoS attack (False by default).
243
243
244 Optional argument 'takeorder' indicates whether a predicate function
244 Optional argument 'takeorder' indicates whether a predicate function
245 takes ordering policy as the last argument.
245 takes ordering policy as the last argument.
246
246
247 Optional argument 'weight' indicates the estimated run-time cost, useful
247 Optional argument 'weight' indicates the estimated run-time cost, useful
248 for static optimization, default is 1. Higher weight means more expensive.
248 for static optimization, default is 1. Higher weight means more expensive.
249 Usually, revsets that are fast and return only one revision has a weight of
249 Usually, revsets that are fast and return only one revision has a weight of
250 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
250 0.5 (ex. a symbol); revsets with O(changelog) complexity and read only the
251 changelog have weight 10 (ex. author); revsets reading manifest deltas have
251 changelog have weight 10 (ex. author); revsets reading manifest deltas have
252 weight 30 (ex. adds); revset reading manifest contents have weight 100
252 weight 30 (ex. adds); revset reading manifest contents have weight 100
253 (ex. contains). Note: those values are flexible. If the revset has a
253 (ex. contains). Note: those values are flexible. If the revset has a
254 same big-O time complexity as 'contains', but with a smaller constant, it
254 same big-O time complexity as 'contains', but with a smaller constant, it
255 might have a weight of 90.
255 might have a weight of 90.
256
256
257 'revsetpredicate' instance in example above can be used to
257 'revsetpredicate' instance in example above can be used to
258 decorate multiple functions.
258 decorate multiple functions.
259
259
260 Decorated functions are registered automatically at loading
260 Decorated functions are registered automatically at loading
261 extension, if an instance named as 'revsetpredicate' is used for
261 extension, if an instance named as 'revsetpredicate' is used for
262 decorating in extension.
262 decorating in extension.
263
263
264 Otherwise, explicit 'revset.loadpredicate()' is needed.
264 Otherwise, explicit 'revset.loadpredicate()' is needed.
265 """
265 """
266 _getname = _funcregistrarbase._parsefuncdecl
266 _getname = _funcregistrarbase._parsefuncdecl
267 _docformat = "``%s``\n %s"
267 _docformat = "``%s``\n %s"
268
268
269 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
269 def _extrasetup(self, name, func, safe=False, takeorder=False, weight=1):
270 func._safe = safe
270 func._safe = safe
271 func._takeorder = takeorder
271 func._takeorder = takeorder
272 func._weight = weight
272 func._weight = weight
273
273
274 class filesetpredicate(_funcregistrarbase):
274 class filesetpredicate(_funcregistrarbase):
275 """Decorator to register fileset predicate
275 """Decorator to register fileset predicate
276
276
277 Usage::
277 Usage::
278
278
279 filesetpredicate = registrar.filesetpredicate()
279 filesetpredicate = registrar.filesetpredicate()
280
280
281 @filesetpredicate('mypredicate()')
281 @filesetpredicate('mypredicate()')
282 def mypredicatefunc(mctx, x):
282 def mypredicatefunc(mctx, x):
283 '''Explanation of this fileset predicate ....
283 '''Explanation of this fileset predicate ....
284 '''
284 '''
285 pass
285 pass
286
286
287 The first string argument is used also in online help.
287 The first string argument is used also in online help.
288
288
289 Optional argument 'callstatus' indicates whether a predicate
289 Optional argument 'callstatus' indicates whether a predicate
290 implies 'matchctx.status()' at runtime or not (False, by
290 implies 'matchctx.status()' at runtime or not (False, by
291 default).
291 default).
292
292
293 Optional argument 'weight' indicates the estimated run-time cost, useful
293 Optional argument 'weight' indicates the estimated run-time cost, useful
294 for static optimization, default is 1. Higher weight means more expensive.
294 for static optimization, default is 1. Higher weight means more expensive.
295 There are predefined weights in the 'filesetlang' module.
295 There are predefined weights in the 'filesetlang' module.
296
296
297 ====== =============================================================
297 ====== =============================================================
298 Weight Description and examples
298 Weight Description and examples
299 ====== =============================================================
299 ====== =============================================================
300 0.5 basic match patterns (e.g. a symbol)
300 0.5 basic match patterns (e.g. a symbol)
301 10 computing status (e.g. added()) or accessing a few files
301 10 computing status (e.g. added()) or accessing a few files
302 30 reading file content for each (e.g. grep())
302 30 reading file content for each (e.g. grep())
303 50 scanning working directory (ignored())
303 50 scanning working directory (ignored())
304 ====== =============================================================
304 ====== =============================================================
305
305
306 'filesetpredicate' instance in example above can be used to
306 'filesetpredicate' instance in example above can be used to
307 decorate multiple functions.
307 decorate multiple functions.
308
308
309 Decorated functions are registered automatically at loading
309 Decorated functions are registered automatically at loading
310 extension, if an instance named as 'filesetpredicate' is used for
310 extension, if an instance named as 'filesetpredicate' is used for
311 decorating in extension.
311 decorating in extension.
312
312
313 Otherwise, explicit 'fileset.loadpredicate()' is needed.
313 Otherwise, explicit 'fileset.loadpredicate()' is needed.
314 """
314 """
315 _getname = _funcregistrarbase._parsefuncdecl
315 _getname = _funcregistrarbase._parsefuncdecl
316 _docformat = "``%s``\n %s"
316 _docformat = "``%s``\n %s"
317
317
318 def _extrasetup(self, name, func, callstatus=False, weight=1):
318 def _extrasetup(self, name, func, callstatus=False, weight=1):
319 func._callstatus = callstatus
319 func._callstatus = callstatus
320 func._weight = weight
320 func._weight = weight
321
321
322 class _templateregistrarbase(_funcregistrarbase):
322 class _templateregistrarbase(_funcregistrarbase):
323 """Base of decorator to register functions as template specific one
323 """Base of decorator to register functions as template specific one
324 """
324 """
325 _docformat = ":%s: %s"
325 _docformat = ":%s: %s"
326
326
327 class templatekeyword(_templateregistrarbase):
327 class templatekeyword(_templateregistrarbase):
328 """Decorator to register template keyword
328 """Decorator to register template keyword
329
329
330 Usage::
330 Usage::
331
331
332 templatekeyword = registrar.templatekeyword()
332 templatekeyword = registrar.templatekeyword()
333
333
334 # new API (since Mercurial 4.6)
334 # new API (since Mercurial 4.6)
335 @templatekeyword('mykeyword', requires={'repo', 'ctx'})
335 @templatekeyword('mykeyword', requires={'repo', 'ctx'})
336 def mykeywordfunc(context, mapping):
336 def mykeywordfunc(context, mapping):
337 '''Explanation of this template keyword ....
337 '''Explanation of this template keyword ....
338 '''
338 '''
339 pass
339 pass
340
340
341 The first string argument is used also in online help.
341 The first string argument is used also in online help.
342
342
343 Optional argument 'requires' should be a collection of resource names
343 Optional argument 'requires' should be a collection of resource names
344 which the template keyword depends on. This also serves as a flag to
344 which the template keyword depends on.
345 switch to the new API. If 'requires' is unspecified, all template
346 keywords and resources are expanded to the function arguments.
347
345
348 'templatekeyword' instance in example above can be used to
346 'templatekeyword' instance in example above can be used to
349 decorate multiple functions.
347 decorate multiple functions.
350
348
351 Decorated functions are registered automatically at loading
349 Decorated functions are registered automatically at loading
352 extension, if an instance named as 'templatekeyword' is used for
350 extension, if an instance named as 'templatekeyword' is used for
353 decorating in extension.
351 decorating in extension.
354
352
355 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
353 Otherwise, explicit 'templatekw.loadkeyword()' is needed.
356 """
354 """
357
355
358 def _extrasetup(self, name, func, requires=None):
356 def _extrasetup(self, name, func, requires=()):
359 func._requires = requires
357 func._requires = requires
360
358
361 class templatefilter(_templateregistrarbase):
359 class templatefilter(_templateregistrarbase):
362 """Decorator to register template filer
360 """Decorator to register template filer
363
361
364 Usage::
362 Usage::
365
363
366 templatefilter = registrar.templatefilter()
364 templatefilter = registrar.templatefilter()
367
365
368 @templatefilter('myfilter', intype=bytes)
366 @templatefilter('myfilter', intype=bytes)
369 def myfilterfunc(text):
367 def myfilterfunc(text):
370 '''Explanation of this template filter ....
368 '''Explanation of this template filter ....
371 '''
369 '''
372 pass
370 pass
373
371
374 The first string argument is used also in online help.
372 The first string argument is used also in online help.
375
373
376 Optional argument 'intype' defines the type of the input argument,
374 Optional argument 'intype' defines the type of the input argument,
377 which should be (bytes, int, templateutil.date, or None for any.)
375 which should be (bytes, int, templateutil.date, or None for any.)
378
376
379 'templatefilter' instance in example above can be used to
377 'templatefilter' instance in example above can be used to
380 decorate multiple functions.
378 decorate multiple functions.
381
379
382 Decorated functions are registered automatically at loading
380 Decorated functions are registered automatically at loading
383 extension, if an instance named as 'templatefilter' is used for
381 extension, if an instance named as 'templatefilter' is used for
384 decorating in extension.
382 decorating in extension.
385
383
386 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
384 Otherwise, explicit 'templatefilters.loadkeyword()' is needed.
387 """
385 """
388
386
389 def _extrasetup(self, name, func, intype=None):
387 def _extrasetup(self, name, func, intype=None):
390 func._intype = intype
388 func._intype = intype
391
389
392 class templatefunc(_templateregistrarbase):
390 class templatefunc(_templateregistrarbase):
393 """Decorator to register template function
391 """Decorator to register template function
394
392
395 Usage::
393 Usage::
396
394
397 templatefunc = registrar.templatefunc()
395 templatefunc = registrar.templatefunc()
398
396
399 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3',
397 @templatefunc('myfunc(arg1, arg2[, arg3])', argspec='arg1 arg2 arg3',
400 requires={'ctx'})
398 requires={'ctx'})
401 def myfuncfunc(context, mapping, args):
399 def myfuncfunc(context, mapping, args):
402 '''Explanation of this template function ....
400 '''Explanation of this template function ....
403 '''
401 '''
404 pass
402 pass
405
403
406 The first string argument is used also in online help.
404 The first string argument is used also in online help.
407
405
408 If optional 'argspec' is defined, the function will receive 'args' as
406 If optional 'argspec' is defined, the function will receive 'args' as
409 a dict of named arguments. Otherwise 'args' is a list of positional
407 a dict of named arguments. Otherwise 'args' is a list of positional
410 arguments.
408 arguments.
411
409
412 Optional argument 'requires' should be a collection of resource names
410 Optional argument 'requires' should be a collection of resource names
413 which the template function depends on.
411 which the template function depends on.
414
412
415 'templatefunc' instance in example above can be used to
413 'templatefunc' instance in example above can be used to
416 decorate multiple functions.
414 decorate multiple functions.
417
415
418 Decorated functions are registered automatically at loading
416 Decorated functions are registered automatically at loading
419 extension, if an instance named as 'templatefunc' is used for
417 extension, if an instance named as 'templatefunc' is used for
420 decorating in extension.
418 decorating in extension.
421
419
422 Otherwise, explicit 'templatefuncs.loadfunction()' is needed.
420 Otherwise, explicit 'templatefuncs.loadfunction()' is needed.
423 """
421 """
424 _getname = _funcregistrarbase._parsefuncdecl
422 _getname = _funcregistrarbase._parsefuncdecl
425
423
426 def _extrasetup(self, name, func, argspec=None, requires=()):
424 def _extrasetup(self, name, func, argspec=None, requires=()):
427 func._argspec = argspec
425 func._argspec = argspec
428 func._requires = requires
426 func._requires = requires
429
427
430 class internalmerge(_funcregistrarbase):
428 class internalmerge(_funcregistrarbase):
431 """Decorator to register in-process merge tool
429 """Decorator to register in-process merge tool
432
430
433 Usage::
431 Usage::
434
432
435 internalmerge = registrar.internalmerge()
433 internalmerge = registrar.internalmerge()
436
434
437 @internalmerge('mymerge', internalmerge.mergeonly,
435 @internalmerge('mymerge', internalmerge.mergeonly,
438 onfailure=None, precheck=None,
436 onfailure=None, precheck=None,
439 binary=False, symlink=False):
437 binary=False, symlink=False):
440 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
438 def mymergefunc(repo, mynode, orig, fcd, fco, fca,
441 toolconf, files, labels=None):
439 toolconf, files, labels=None):
442 '''Explanation of this internal merge tool ....
440 '''Explanation of this internal merge tool ....
443 '''
441 '''
444 return 1, False # means "conflicted", "no deletion needed"
442 return 1, False # means "conflicted", "no deletion needed"
445
443
446 The first string argument is used to compose actual merge tool name,
444 The first string argument is used to compose actual merge tool name,
447 ":name" and "internal:name" (the latter is historical one).
445 ":name" and "internal:name" (the latter is historical one).
448
446
449 The second argument is one of merge types below:
447 The second argument is one of merge types below:
450
448
451 ========== ======== ======== =========
449 ========== ======== ======== =========
452 merge type precheck premerge fullmerge
450 merge type precheck premerge fullmerge
453 ========== ======== ======== =========
451 ========== ======== ======== =========
454 nomerge x x x
452 nomerge x x x
455 mergeonly o x o
453 mergeonly o x o
456 fullmerge o o o
454 fullmerge o o o
457 ========== ======== ======== =========
455 ========== ======== ======== =========
458
456
459 Optional argument 'onfailure' is the format of warning message
457 Optional argument 'onfailure' is the format of warning message
460 to be used at failure of merging (target filename is specified
458 to be used at failure of merging (target filename is specified
461 at formatting). Or, None or so, if warning message should be
459 at formatting). Or, None or so, if warning message should be
462 suppressed.
460 suppressed.
463
461
464 Optional argument 'precheck' is the function to be used
462 Optional argument 'precheck' is the function to be used
465 before actual invocation of internal merge tool itself.
463 before actual invocation of internal merge tool itself.
466 It takes as same arguments as internal merge tool does, other than
464 It takes as same arguments as internal merge tool does, other than
467 'files' and 'labels'. If it returns false value, merging is aborted
465 'files' and 'labels'. If it returns false value, merging is aborted
468 immediately (and file is marked as "unresolved").
466 immediately (and file is marked as "unresolved").
469
467
470 Optional argument 'binary' is a binary files capability of internal
468 Optional argument 'binary' is a binary files capability of internal
471 merge tool. 'nomerge' merge type implies binary=True.
469 merge tool. 'nomerge' merge type implies binary=True.
472
470
473 Optional argument 'symlink' is a symlinks capability of inetrnal
471 Optional argument 'symlink' is a symlinks capability of inetrnal
474 merge function. 'nomerge' merge type implies symlink=True.
472 merge function. 'nomerge' merge type implies symlink=True.
475
473
476 'internalmerge' instance in example above can be used to
474 'internalmerge' instance in example above can be used to
477 decorate multiple functions.
475 decorate multiple functions.
478
476
479 Decorated functions are registered automatically at loading
477 Decorated functions are registered automatically at loading
480 extension, if an instance named as 'internalmerge' is used for
478 extension, if an instance named as 'internalmerge' is used for
481 decorating in extension.
479 decorating in extension.
482
480
483 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
481 Otherwise, explicit 'filemerge.loadinternalmerge()' is needed.
484 """
482 """
485 _docformat = "``:%s``\n %s"
483 _docformat = "``:%s``\n %s"
486
484
487 # merge type definitions:
485 # merge type definitions:
488 nomerge = None
486 nomerge = None
489 mergeonly = 'mergeonly' # just the full merge, no premerge
487 mergeonly = 'mergeonly' # just the full merge, no premerge
490 fullmerge = 'fullmerge' # both premerge and merge
488 fullmerge = 'fullmerge' # both premerge and merge
491
489
492 def _extrasetup(self, name, func, mergetype,
490 def _extrasetup(self, name, func, mergetype,
493 onfailure=None, precheck=None,
491 onfailure=None, precheck=None,
494 binary=False, symlink=False):
492 binary=False, symlink=False):
495 func.mergetype = mergetype
493 func.mergetype = mergetype
496 func.onfailure = onfailure
494 func.onfailure = onfailure
497 func.precheck = precheck
495 func.precheck = precheck
498
496
499 binarycap = binary or mergetype == self.nomerge
497 binarycap = binary or mergetype == self.nomerge
500 symlinkcap = symlink or mergetype == self.nomerge
498 symlinkcap = symlink or mergetype == self.nomerge
501
499
502 # actual capabilities, which this internal merge tool has
500 # actual capabilities, which this internal merge tool has
503 func.capabilities = {"binary": binarycap, "symlink": symlinkcap}
501 func.capabilities = {"binary": binarycap, "symlink": symlinkcap}
General Comments 0
You need to be logged in to leave comments. Login now