103 self.re_kw = re.compile(r'\$(%s)[^$]*?\$' % |
103 self.re_kw = re.compile(r'\$(%s)[^$]*?\$' % |
104 '|'.join(re.escape(k) for k in self.templates.keys())) |
104 '|'.join(re.escape(k) for k in self.templates.keys())) |
105 templater.common_filters['utcdate'] = utcdate |
105 templater.common_filters['utcdate'] = utcdate |
106 self.t = cmdutil.changeset_templater(ui, repo, False, '', False) |
106 self.t = cmdutil.changeset_templater(ui, repo, False, '', False) |
107 |
107 |
108 def expand(self, mobj, path, node): |
108 def kwsub(self, mobj, path, node): |
109 '''Expands keyword using corresponding template.''' |
109 '''Substitutes keyword using corresponding template.''' |
110 kw = mobj.group(1) |
110 kw = mobj.group(1) |
111 template = templater.parsestring(self.templates[kw], quoted=False) |
111 template = templater.parsestring(self.templates[kw], quoted=False) |
112 self.t.use_template(template) |
112 self.t.use_template(template) |
113 self.ui.pushbuffer() |
113 self.ui.pushbuffer() |
114 self.t.show(changenode=node, root=self.repo.root, file=path) |
114 self.t.show(changenode=node, root=self.repo.root, file=path) |
115 kwsub = templater.firstline(self.ui.popbuffer()) |
115 keywordsub = templater.firstline(self.ui.popbuffer()) |
116 return '$%s: %s $' % (kw, kwsub) |
116 return '$%s: %s $' % (kw, keywordsub) |
|
117 |
|
118 def expand(self, path, node, data): |
|
119 '''Returns data with expanded keywords.''' |
|
120 if util.binary(data): |
|
121 return data |
|
122 return self.re_kw.sub(lambda m: self.kwsub(m, path, node), data) |
|
123 |
|
124 def expandn(self, path, node, data): |
|
125 '''Returns data with expanded keywords and number of expansions.''' |
|
126 if util.binary(data): |
|
127 return data, None |
|
128 return self.re_kw.subn(lambda m: self.kwsub(m, path, node), data) |
117 |
129 |
118 def shrink(self, text): |
130 def shrink(self, text): |
119 '''Returns text with all keyword substitutions removed.''' |
131 '''Returns text with all keyword substitutions removed.''' |
|
132 if util.binary(text): |
|
133 return text |
120 return self.re_kw.sub(r'$\1$', text) |
134 return self.re_kw.sub(r'$\1$', text) |
121 |
135 |
122 |
136 |
123 def reposetup(ui, repo): |
137 def reposetup(ui, repo): |
124 '''Sets up repo, and filelog especially, as kwrepo and kwfilelog |
138 '''Sets up repo, and filelog especially, as kwrepo and kwfilelog |
165 |
179 |
166 kwt = kwtemplater(self.ui, self) |
180 kwt = kwtemplater(self.ui, self) |
167 overwrite = [] |
181 overwrite = [] |
168 for f in candidates: |
182 for f in candidates: |
169 data = self.wfile(f).read() |
183 data = self.wfile(f).read() |
170 if not util.binary(data): |
184 data, kwct = kwt.expandn(f, node, data) |
171 data, kwct = kwt.re_kw.subn(lambda m: |
185 if kwct: |
172 kwt.expand(m, f, node), data) |
186 ui.debug(_('overwriting %s expanding keywords\n' % f)) |
173 if kwct: |
187 self.wfile(f, 'w').write(data) |
174 ui.debug(_('overwriting %s expanding keywords\n' % f)) |
188 overwrite.append(f) |
175 self.wfile(f, 'w').write(data) |
189 if overwrite: |
176 overwrite.append(f) |
190 self.dirstate.update(overwrite, 'n') |
177 self.dirstate.update(overwrite, 'n') |
|
178 return node |
191 return node |
179 |
192 |
180 class kwfilelog(filelog.filelog): |
193 class kwfilelog(filelog.filelog): |
181 ''' |
194 ''' |
182 Superclass over filelog to customize it's read, add, cmp methods. |
195 Superclass over filelog to customize it's read, add, cmp methods. |
191 if not isinstance(repo, int) and repo.kwfmatcher(path): |
204 if not isinstance(repo, int) and repo.kwfmatcher(path): |
192 self.kwt = kwtemplater(repo.ui, repo) |
205 self.kwt = kwtemplater(repo.ui, repo) |
193 else: |
206 else: |
194 self.kwt = None |
207 self.kwt = None |
195 |
208 |
196 def iskwcandidate(self, data): |
|
197 '''Decides whether to act on keywords.''' |
|
198 return self.kwt is not None and not util.binary(data) |
|
199 |
|
200 def read(self, node): |
209 def read(self, node): |
201 '''Substitutes keywords when reading filelog.''' |
210 '''Substitutes keywords when reading filelog.''' |
202 data = super(kwfilelog, self).read(node) |
211 data = super(kwfilelog, self).read(node) |
203 if self.iskwcandidate(data): |
212 if self.kwt: |
204 c = context.filectx(self._repo, self._path, |
213 c = context.filectx(self._repo, self._path, |
205 fileid=node, filelog=self) |
214 fileid=node, filelog=self) |
206 return self.kwt.re_kw.sub(lambda m: |
215 data = self.kwt.expand(self._path, c.node(), data) |
207 self.kwt.expand(m, self._path, c.node()), data) |
|
208 return data |
216 return data |
209 |
217 |
210 def add(self, text, meta, tr, link, p1=None, p2=None): |
218 def add(self, text, meta, tr, link, p1=None, p2=None): |
211 '''Removes keyword substitutions when adding to filelog.''' |
219 '''Removes keyword substitutions when adding to filelog.''' |
212 if self.iskwcandidate(text): |
220 if self.kwt: |
213 text = self.kwt.shrink(text) |
221 text = self.kwt.shrink(text) |
214 return super(kwfilelog, self).add(text, |
222 return super(kwfilelog, self).add(text, |
215 meta, tr, link, p1=p1, p2=p2) |
223 meta, tr, link, p1=p1, p2=p2) |
216 |
224 |
217 def cmp(self, node, text): |
225 def cmp(self, node, text): |
218 '''Removes keyword substitutions for comparison.''' |
226 '''Removes keyword substitutions for comparison.''' |
219 if self.iskwcandidate(text): |
227 if self.kwt: |
220 text = self.kwt.shrink(text) |
228 text = self.kwt.shrink(text) |
221 return super(kwfilelog, self).cmp(node, text) |
229 return super(kwfilelog, self).cmp(node, text) |
222 |
230 |
223 filelog.filelog = kwfilelog |
231 filelog.filelog = kwfilelog |
224 repo.__class__ = kwrepo |
232 repo.__class__ = kwrepo |