33 |
33 |
34 Keywords are only expanded in local repositories and not stored in the |
34 Keywords are only expanded in local repositories and not stored in the |
35 change history. The mechanism can be regarded as a convenience for the |
35 change history. The mechanism can be regarded as a convenience for the |
36 current user or for archive distribution. |
36 current user or for archive distribution. |
37 |
37 |
38 Configuration is done in the [keyword] and [keywordmaps] sections of |
38 Configuration is done in the [keyword], [keywordset] and [keywordmaps] |
39 hgrc files. |
39 sections of hgrc files. |
40 |
40 |
41 Example:: |
41 Example:: |
42 |
42 |
43 [keyword] |
43 [keyword] |
44 # expand keywords in every python file except those matching "x*" |
44 # expand keywords in every python file except those matching "x*" |
45 **.py = |
45 **.py = |
46 x* = ignore |
46 x* = ignore |
|
47 |
|
48 [keywordset] |
|
49 # prefer svn- over cvs-like default keywordmaps |
|
50 svn = True |
47 |
51 |
48 NOTE: the more specific you are in your filename patterns the less you |
52 NOTE: the more specific you are in your filename patterns the less you |
49 lose speed in huge repositories. |
53 lose speed in huge repositories. |
50 |
54 |
51 For [keywordmaps] template mapping and expansion demonstration and |
55 For [keywordmaps] template mapping and expansion demonstration and |
106 |
110 |
107 # make keyword tools accessible |
111 # make keyword tools accessible |
108 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
112 kwtools = {'templater': None, 'hgcmd': '', 'inc': [], 'exc': ['.hg*']} |
109 |
113 |
110 |
114 |
111 class kwtemplater(object): |
115 def _defaultkwmaps(ui): |
112 ''' |
116 '''Returns default keywordmaps according to keywordset configuration.''' |
113 Sets up keyword templates, corresponding keyword regex, and |
|
114 provides keyword substitution functions. |
|
115 ''' |
|
116 templates = { |
117 templates = { |
117 'Revision': '{node|short}', |
118 'Revision': '{node|short}', |
118 'Author': '{author|user}', |
119 'Author': '{author|user}', |
|
120 } |
|
121 kwsets = ({ |
119 'Date': '{date|utcdate}', |
122 'Date': '{date|utcdate}', |
120 'RCSfile': '{file|basename},v', |
123 'RCSfile': '{file|basename},v', |
121 'RCSFile': '{file|basename},v', # kept for backwards compatibility |
124 'RCSFile': '{file|basename},v', # kept for backwards compatibility |
122 # with hg-keyword |
125 # with hg-keyword |
123 'Source': '{root}/{file},v', |
126 'Source': '{root}/{file},v', |
124 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
127 'Id': '{file|basename},v {node|short} {date|utcdate} {author|user}', |
125 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
128 'Header': '{root}/{file},v {node|short} {date|utcdate} {author|user}', |
126 } |
129 }, { |
|
130 'Date': '{date|svnisodate}', |
|
131 'Id': '{file|basename},v {node|short} {date|svnutcdate} {author|user}', |
|
132 'LastChangedRevision': '{node|short}', |
|
133 'LastChangedBy': '{author|user}', |
|
134 'LastChangedDate': '{date|svnisodate}', |
|
135 }) |
|
136 templates.update(kwsets[ui.configbool('keywordset', 'svn')]) |
|
137 return templates |
|
138 |
|
139 class kwtemplater(object): |
|
140 ''' |
|
141 Sets up keyword templates, corresponding keyword regex, and |
|
142 provides keyword substitution functions. |
|
143 ''' |
127 |
144 |
128 def __init__(self, ui, repo): |
145 def __init__(self, ui, repo): |
129 self.ui = ui |
146 self.ui = ui |
130 self.repo = repo |
147 self.repo = repo |
131 self.match = match.match(repo.root, '', [], |
148 self.match = match.match(repo.root, '', [], |
135 |
152 |
136 kwmaps = self.ui.configitems('keywordmaps') |
153 kwmaps = self.ui.configitems('keywordmaps') |
137 if kwmaps: # override default templates |
154 if kwmaps: # override default templates |
138 self.templates = dict((k, templater.parsestring(v, False)) |
155 self.templates = dict((k, templater.parsestring(v, False)) |
139 for k, v in kwmaps) |
156 for k, v in kwmaps) |
|
157 else: |
|
158 self.templates = _defaultkwmaps(self.ui) |
140 escaped = map(re.escape, self.templates.keys()) |
159 escaped = map(re.escape, self.templates.keys()) |
141 kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped) |
160 kwpat = r'\$(%s)(: [^$\n\r]*? )??\$' % '|'.join(escaped) |
142 self.re_kw = re.compile(kwpat) |
161 self.re_kw = re.compile(kwpat) |
143 |
162 |
144 templatefilters.filters['utcdate'] = utcdate |
163 templatefilters.filters['utcdate'] = utcdate |
320 fp.close() |
339 fp.close() |
321 ui.readconfig(repo.join('hgrc')) |
340 ui.readconfig(repo.join('hgrc')) |
322 kwmaps = dict(ui.configitems('keywordmaps')) |
341 kwmaps = dict(ui.configitems('keywordmaps')) |
323 elif opts.get('default'): |
342 elif opts.get('default'): |
324 ui.status(_('\n\tconfiguration using default keyword template maps\n')) |
343 ui.status(_('\n\tconfiguration using default keyword template maps\n')) |
325 kwmaps = kwtemplater.templates |
344 kwmaps = _defaultkwmaps(ui) |
326 if uikwmaps: |
345 if uikwmaps: |
327 ui.status(_('\tdisabling current template maps\n')) |
346 ui.status(_('\tdisabling current template maps\n')) |
328 for k, v in kwmaps.iteritems(): |
347 for k, v in kwmaps.iteritems(): |
329 ui.setconfig('keywordmaps', k, v) |
348 ui.setconfig('keywordmaps', k, v) |
330 else: |
349 else: |
331 ui.status(_('\n\tconfiguration using current keyword template maps\n')) |
350 ui.status(_('\n\tconfiguration using current keyword template maps\n')) |
332 kwmaps = dict(uikwmaps) or kwtemplater.templates |
351 kwmaps = dict(uikwmaps) or _defaultkwmaps(ui) |
333 |
352 |
334 uisetup(ui) |
353 uisetup(ui) |
335 reposetup(ui, repo) |
354 reposetup(ui, repo) |
336 ui.write('[extensions]\nkeyword =\n') |
355 ui.write('[extensions]\nkeyword =\n') |
337 demoitems('keyword', ui.configitems('keyword')) |
356 demoitems('keyword', ui.configitems('keyword')) |