##// END OF EJS Templates
demandimport: convert ignored modules from bytes -> str in extensions...
Matt Harbison -
r50445:5f22c92d stable
parent child Browse files
Show More
@@ -1,337 +1,337 b''
1 # bzr.py - bzr support for the convert extension
1 # bzr.py - bzr support for the convert extension
2 #
2 #
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> and others
3 # Copyright 2008, 2009 Marek Kubica <marek@xivilization.net> 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 # This module is for handling Breezy imports or `brz`, but it's also compatible
8 # This module is for handling Breezy imports or `brz`, but it's also compatible
9 # with Bazaar or `bzr`, that was formerly known as Bazaar-NG;
9 # with Bazaar or `bzr`, that was formerly known as Bazaar-NG;
10 # it cannot access `bar` repositories, but they were never used very much.
10 # it cannot access `bar` repositories, but they were never used very much.
11
11
12 import os
12 import os
13
13
14 from mercurial.i18n import _
14 from mercurial.i18n import _
15 from mercurial import (
15 from mercurial import (
16 demandimport,
16 demandimport,
17 error,
17 error,
18 util,
18 util,
19 )
19 )
20 from . import common
20 from . import common
21
21
22
22
23 # these do not work with demandimport, blacklist
23 # these do not work with demandimport, blacklist
24 demandimport.IGNORES.update(
24 demandimport.IGNORES.update(
25 [
25 [
26 b'breezy.transactions',
26 'breezy.transactions',
27 b'breezy.urlutils',
27 'breezy.urlutils',
28 b'ElementPath',
28 'ElementPath',
29 ]
29 ]
30 )
30 )
31
31
32 try:
32 try:
33 # bazaar imports
33 # bazaar imports
34 import breezy.bzr.bzrdir
34 import breezy.bzr.bzrdir
35 import breezy.errors
35 import breezy.errors
36 import breezy.revision
36 import breezy.revision
37 import breezy.revisionspec
37 import breezy.revisionspec
38
38
39 bzrdir = breezy.bzr.bzrdir
39 bzrdir = breezy.bzr.bzrdir
40 errors = breezy.errors
40 errors = breezy.errors
41 revision = breezy.revision
41 revision = breezy.revision
42 revisionspec = breezy.revisionspec
42 revisionspec = breezy.revisionspec
43 revisionspec.RevisionSpec
43 revisionspec.RevisionSpec
44 except ImportError:
44 except ImportError:
45 pass
45 pass
46
46
47 supportedkinds = ('file', 'symlink')
47 supportedkinds = ('file', 'symlink')
48
48
49
49
50 class bzr_source(common.converter_source):
50 class bzr_source(common.converter_source):
51 """Reads Bazaar repositories by using the Bazaar Python libraries"""
51 """Reads Bazaar repositories by using the Bazaar Python libraries"""
52
52
53 def __init__(self, ui, repotype, path, revs=None):
53 def __init__(self, ui, repotype, path, revs=None):
54 super(bzr_source, self).__init__(ui, repotype, path, revs=revs)
54 super(bzr_source, self).__init__(ui, repotype, path, revs=revs)
55
55
56 if not os.path.exists(os.path.join(path, b'.bzr')):
56 if not os.path.exists(os.path.join(path, b'.bzr')):
57 raise common.NoRepo(
57 raise common.NoRepo(
58 _(b'%s does not look like a Bazaar repository') % path
58 _(b'%s does not look like a Bazaar repository') % path
59 )
59 )
60
60
61 try:
61 try:
62 # access breezy stuff
62 # access breezy stuff
63 bzrdir
63 bzrdir
64 except NameError:
64 except NameError:
65 raise common.NoRepo(_(b'Bazaar modules could not be loaded'))
65 raise common.NoRepo(_(b'Bazaar modules could not be loaded'))
66
66
67 path = util.abspath(path)
67 path = util.abspath(path)
68 self._checkrepotype(path)
68 self._checkrepotype(path)
69 try:
69 try:
70 bzr_dir = bzrdir.BzrDir.open(path.decode())
70 bzr_dir = bzrdir.BzrDir.open(path.decode())
71 self.sourcerepo = bzr_dir.open_repository()
71 self.sourcerepo = bzr_dir.open_repository()
72 except errors.NoRepositoryPresent:
72 except errors.NoRepositoryPresent:
73 raise common.NoRepo(
73 raise common.NoRepo(
74 _(b'%s does not look like a Bazaar repository') % path
74 _(b'%s does not look like a Bazaar repository') % path
75 )
75 )
76 self._parentids = {}
76 self._parentids = {}
77 self._saverev = ui.configbool(b'convert', b'bzr.saverev')
77 self._saverev = ui.configbool(b'convert', b'bzr.saverev')
78
78
79 def _checkrepotype(self, path):
79 def _checkrepotype(self, path):
80 # Lightweight checkouts detection is informational but probably
80 # Lightweight checkouts detection is informational but probably
81 # fragile at API level. It should not terminate the conversion.
81 # fragile at API level. It should not terminate the conversion.
82 try:
82 try:
83 dir = bzrdir.BzrDir.open_containing(path.decode())[0]
83 dir = bzrdir.BzrDir.open_containing(path.decode())[0]
84 try:
84 try:
85 tree = dir.open_workingtree(recommend_upgrade=False)
85 tree = dir.open_workingtree(recommend_upgrade=False)
86 branch = tree.branch
86 branch = tree.branch
87 except (errors.NoWorkingTree, errors.NotLocalUrl):
87 except (errors.NoWorkingTree, errors.NotLocalUrl):
88 tree = None
88 tree = None
89 branch = dir.open_branch()
89 branch = dir.open_branch()
90 if (
90 if (
91 tree is not None
91 tree is not None
92 and tree.controldir.root_transport.base
92 and tree.controldir.root_transport.base
93 != branch.controldir.root_transport.base
93 != branch.controldir.root_transport.base
94 ):
94 ):
95 self.ui.warn(
95 self.ui.warn(
96 _(
96 _(
97 b'warning: lightweight checkouts may cause '
97 b'warning: lightweight checkouts may cause '
98 b'conversion failures, try with a regular '
98 b'conversion failures, try with a regular '
99 b'branch instead.\n'
99 b'branch instead.\n'
100 )
100 )
101 )
101 )
102 except Exception:
102 except Exception:
103 self.ui.note(_(b'bzr source type could not be determined\n'))
103 self.ui.note(_(b'bzr source type could not be determined\n'))
104
104
105 def before(self):
105 def before(self):
106 """Before the conversion begins, acquire a read lock
106 """Before the conversion begins, acquire a read lock
107 for all the operations that might need it. Fortunately
107 for all the operations that might need it. Fortunately
108 read locks don't block other reads or writes to the
108 read locks don't block other reads or writes to the
109 repository, so this shouldn't have any impact on the usage of
109 repository, so this shouldn't have any impact on the usage of
110 the source repository.
110 the source repository.
111
111
112 The alternative would be locking on every operation that
112 The alternative would be locking on every operation that
113 needs locks (there are currently two: getting the file and
113 needs locks (there are currently two: getting the file and
114 getting the parent map) and releasing immediately after,
114 getting the parent map) and releasing immediately after,
115 but this approach can take even 40% longer."""
115 but this approach can take even 40% longer."""
116 self.sourcerepo.lock_read()
116 self.sourcerepo.lock_read()
117
117
118 def after(self):
118 def after(self):
119 self.sourcerepo.unlock()
119 self.sourcerepo.unlock()
120
120
121 def _bzrbranches(self):
121 def _bzrbranches(self):
122 return self.sourcerepo.find_branches(using=True)
122 return self.sourcerepo.find_branches(using=True)
123
123
124 def getheads(self):
124 def getheads(self):
125 if not self.revs:
125 if not self.revs:
126 # Set using=True to avoid nested repositories (see issue3254)
126 # Set using=True to avoid nested repositories (see issue3254)
127 heads = sorted([b.last_revision() for b in self._bzrbranches()])
127 heads = sorted([b.last_revision() for b in self._bzrbranches()])
128 else:
128 else:
129 revid = None
129 revid = None
130 for branch in self._bzrbranches():
130 for branch in self._bzrbranches():
131 try:
131 try:
132 revspec = self.revs[0].decode()
132 revspec = self.revs[0].decode()
133 r = revisionspec.RevisionSpec.from_string(revspec)
133 r = revisionspec.RevisionSpec.from_string(revspec)
134 info = r.in_history(branch)
134 info = r.in_history(branch)
135 except errors.BzrError:
135 except errors.BzrError:
136 pass
136 pass
137 revid = info.rev_id
137 revid = info.rev_id
138 if revid is None:
138 if revid is None:
139 raise error.Abort(
139 raise error.Abort(
140 _(b'%s is not a valid revision') % self.revs[0]
140 _(b'%s is not a valid revision') % self.revs[0]
141 )
141 )
142 heads = [revid]
142 heads = [revid]
143 # Empty repositories return 'null:', which cannot be retrieved
143 # Empty repositories return 'null:', which cannot be retrieved
144 heads = [h for h in heads if h != b'null:']
144 heads = [h for h in heads if h != b'null:']
145 return heads
145 return heads
146
146
147 def getfile(self, name, rev):
147 def getfile(self, name, rev):
148 name = name.decode()
148 name = name.decode()
149 revtree = self.sourcerepo.revision_tree(rev)
149 revtree = self.sourcerepo.revision_tree(rev)
150
150
151 try:
151 try:
152 kind = revtree.kind(name)
152 kind = revtree.kind(name)
153 except breezy.errors.NoSuchFile:
153 except breezy.errors.NoSuchFile:
154 return None, None
154 return None, None
155 if kind not in supportedkinds:
155 if kind not in supportedkinds:
156 # the file is not available anymore - was deleted
156 # the file is not available anymore - was deleted
157 return None, None
157 return None, None
158 mode = self._modecache[(name.encode(), rev)]
158 mode = self._modecache[(name.encode(), rev)]
159 if kind == 'symlink':
159 if kind == 'symlink':
160 target = revtree.get_symlink_target(name)
160 target = revtree.get_symlink_target(name)
161 if target is None:
161 if target is None:
162 raise error.Abort(
162 raise error.Abort(
163 _(b'%s.%s symlink has no target') % (name, rev)
163 _(b'%s.%s symlink has no target') % (name, rev)
164 )
164 )
165 return target.encode(), mode
165 return target.encode(), mode
166 else:
166 else:
167 sio = revtree.get_file(name)
167 sio = revtree.get_file(name)
168 return sio.read(), mode
168 return sio.read(), mode
169
169
170 def getchanges(self, version, full):
170 def getchanges(self, version, full):
171 if full:
171 if full:
172 raise error.Abort(_(b"convert from cvs does not support --full"))
172 raise error.Abort(_(b"convert from cvs does not support --full"))
173 self._modecache = {}
173 self._modecache = {}
174 self._revtree = self.sourcerepo.revision_tree(version)
174 self._revtree = self.sourcerepo.revision_tree(version)
175 # get the parentids from the cache
175 # get the parentids from the cache
176 parentids = self._parentids.pop(version)
176 parentids = self._parentids.pop(version)
177 # only diff against first parent id
177 # only diff against first parent id
178 prevtree = self.sourcerepo.revision_tree(parentids[0])
178 prevtree = self.sourcerepo.revision_tree(parentids[0])
179 files, changes = self._gettreechanges(self._revtree, prevtree)
179 files, changes = self._gettreechanges(self._revtree, prevtree)
180 return files, changes, set()
180 return files, changes, set()
181
181
182 def getcommit(self, version):
182 def getcommit(self, version):
183 rev = self.sourcerepo.get_revision(version)
183 rev = self.sourcerepo.get_revision(version)
184 # populate parent id cache
184 # populate parent id cache
185 if not rev.parent_ids:
185 if not rev.parent_ids:
186 parents = []
186 parents = []
187 self._parentids[version] = (revision.NULL_REVISION,)
187 self._parentids[version] = (revision.NULL_REVISION,)
188 else:
188 else:
189 parents = self._filterghosts(rev.parent_ids)
189 parents = self._filterghosts(rev.parent_ids)
190 self._parentids[version] = parents
190 self._parentids[version] = parents
191
191
192 branch = rev.properties.get('branch-nick', 'default')
192 branch = rev.properties.get('branch-nick', 'default')
193 if branch == 'trunk':
193 if branch == 'trunk':
194 branch = 'default'
194 branch = 'default'
195 return common.commit(
195 return common.commit(
196 parents=parents,
196 parents=parents,
197 date=b'%d %d' % (rev.timestamp, -rev.timezone),
197 date=b'%d %d' % (rev.timestamp, -rev.timezone),
198 author=self.recode(rev.committer),
198 author=self.recode(rev.committer),
199 desc=self.recode(rev.message),
199 desc=self.recode(rev.message),
200 branch=branch.encode('utf8'),
200 branch=branch.encode('utf8'),
201 rev=version,
201 rev=version,
202 saverev=self._saverev,
202 saverev=self._saverev,
203 )
203 )
204
204
205 def gettags(self):
205 def gettags(self):
206 bytetags = {}
206 bytetags = {}
207 for branch in self._bzrbranches():
207 for branch in self._bzrbranches():
208 if not branch.supports_tags():
208 if not branch.supports_tags():
209 return {}
209 return {}
210 tagdict = branch.tags.get_tag_dict()
210 tagdict = branch.tags.get_tag_dict()
211 for name, rev in tagdict.items():
211 for name, rev in tagdict.items():
212 bytetags[self.recode(name)] = rev
212 bytetags[self.recode(name)] = rev
213 return bytetags
213 return bytetags
214
214
215 def getchangedfiles(self, rev, i):
215 def getchangedfiles(self, rev, i):
216 self._modecache = {}
216 self._modecache = {}
217 curtree = self.sourcerepo.revision_tree(rev)
217 curtree = self.sourcerepo.revision_tree(rev)
218 if i is not None:
218 if i is not None:
219 parentid = self._parentids[rev][i]
219 parentid = self._parentids[rev][i]
220 else:
220 else:
221 # no parent id, get the empty revision
221 # no parent id, get the empty revision
222 parentid = revision.NULL_REVISION
222 parentid = revision.NULL_REVISION
223
223
224 prevtree = self.sourcerepo.revision_tree(parentid)
224 prevtree = self.sourcerepo.revision_tree(parentid)
225 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
225 changes = [e[0] for e in self._gettreechanges(curtree, prevtree)[0]]
226 return changes
226 return changes
227
227
228 def _gettreechanges(self, current, origin):
228 def _gettreechanges(self, current, origin):
229 revid = current._revision_id
229 revid = current._revision_id
230 changes = []
230 changes = []
231 renames = {}
231 renames = {}
232 seen = set()
232 seen = set()
233
233
234 # Fall back to the deprecated attribute for legacy installations.
234 # Fall back to the deprecated attribute for legacy installations.
235 try:
235 try:
236 inventory = origin.root_inventory
236 inventory = origin.root_inventory
237 except AttributeError:
237 except AttributeError:
238 inventory = origin.inventory
238 inventory = origin.inventory
239
239
240 # Process the entries by reverse lexicographic name order to
240 # Process the entries by reverse lexicographic name order to
241 # handle nested renames correctly, most specific first.
241 # handle nested renames correctly, most specific first.
242
242
243 def key(c):
243 def key(c):
244 return c.path[0] or c.path[1] or ""
244 return c.path[0] or c.path[1] or ""
245
245
246 curchanges = sorted(
246 curchanges = sorted(
247 current.iter_changes(origin),
247 current.iter_changes(origin),
248 key=key,
248 key=key,
249 reverse=True,
249 reverse=True,
250 )
250 )
251 for change in curchanges:
251 for change in curchanges:
252 paths = change.path
252 paths = change.path
253 kind = change.kind
253 kind = change.kind
254 executable = change.executable
254 executable = change.executable
255 if paths[0] == u'' or paths[1] == u'':
255 if paths[0] == u'' or paths[1] == u'':
256 # ignore changes to tree root
256 # ignore changes to tree root
257 continue
257 continue
258
258
259 # bazaar tracks directories, mercurial does not, so
259 # bazaar tracks directories, mercurial does not, so
260 # we have to rename the directory contents
260 # we have to rename the directory contents
261 if kind[1] == 'directory':
261 if kind[1] == 'directory':
262 if kind[0] not in (None, 'directory'):
262 if kind[0] not in (None, 'directory'):
263 # Replacing 'something' with a directory, record it
263 # Replacing 'something' with a directory, record it
264 # so it can be removed.
264 # so it can be removed.
265 changes.append((self.recode(paths[0]), revid))
265 changes.append((self.recode(paths[0]), revid))
266
266
267 if kind[0] == 'directory' and None not in paths:
267 if kind[0] == 'directory' and None not in paths:
268 renaming = paths[0] != paths[1]
268 renaming = paths[0] != paths[1]
269 # neither an add nor an delete - a move
269 # neither an add nor an delete - a move
270 # rename all directory contents manually
270 # rename all directory contents manually
271 subdir = inventory.path2id(paths[0])
271 subdir = inventory.path2id(paths[0])
272 # get all child-entries of the directory
272 # get all child-entries of the directory
273 for name, entry in inventory.iter_entries(subdir):
273 for name, entry in inventory.iter_entries(subdir):
274 # hg does not track directory renames
274 # hg does not track directory renames
275 if entry.kind == 'directory':
275 if entry.kind == 'directory':
276 continue
276 continue
277 frompath = self.recode(paths[0] + '/' + name)
277 frompath = self.recode(paths[0] + '/' + name)
278 if frompath in seen:
278 if frompath in seen:
279 # Already handled by a more specific change entry
279 # Already handled by a more specific change entry
280 # This is important when you have:
280 # This is important when you have:
281 # a => b
281 # a => b
282 # a/c => a/c
282 # a/c => a/c
283 # Here a/c must not be renamed into b/c
283 # Here a/c must not be renamed into b/c
284 continue
284 continue
285 seen.add(frompath)
285 seen.add(frompath)
286 if not renaming:
286 if not renaming:
287 continue
287 continue
288 topath = self.recode(paths[1] + '/' + name)
288 topath = self.recode(paths[1] + '/' + name)
289 # register the files as changed
289 # register the files as changed
290 changes.append((frompath, revid))
290 changes.append((frompath, revid))
291 changes.append((topath, revid))
291 changes.append((topath, revid))
292 # add to mode cache
292 # add to mode cache
293 mode = (
293 mode = (
294 (entry.executable and b'x')
294 (entry.executable and b'x')
295 or (entry.kind == 'symlink' and b's')
295 or (entry.kind == 'symlink' and b's')
296 or b''
296 or b''
297 )
297 )
298 self._modecache[(topath, revid)] = mode
298 self._modecache[(topath, revid)] = mode
299 # register the change as move
299 # register the change as move
300 renames[topath] = frompath
300 renames[topath] = frompath
301
301
302 # no further changes, go to the next change
302 # no further changes, go to the next change
303 continue
303 continue
304
304
305 # we got unicode paths, need to convert them
305 # we got unicode paths, need to convert them
306 path, topath = paths
306 path, topath = paths
307 if path is not None:
307 if path is not None:
308 path = self.recode(path)
308 path = self.recode(path)
309 if topath is not None:
309 if topath is not None:
310 topath = self.recode(topath)
310 topath = self.recode(topath)
311 seen.add(path or topath)
311 seen.add(path or topath)
312
312
313 if topath is None:
313 if topath is None:
314 # file deleted
314 # file deleted
315 changes.append((path, revid))
315 changes.append((path, revid))
316 continue
316 continue
317
317
318 # renamed
318 # renamed
319 if path and path != topath:
319 if path and path != topath:
320 renames[topath] = path
320 renames[topath] = path
321 changes.append((path, revid))
321 changes.append((path, revid))
322
322
323 # populate the mode cache
323 # populate the mode cache
324 kind, executable = [e[1] for e in (kind, executable)]
324 kind, executable = [e[1] for e in (kind, executable)]
325 mode = (executable and b'x') or (kind == 'symlink' and b'l') or b''
325 mode = (executable and b'x') or (kind == 'symlink' and b'l') or b''
326 self._modecache[(topath, revid)] = mode
326 self._modecache[(topath, revid)] = mode
327 changes.append((topath, revid))
327 changes.append((topath, revid))
328
328
329 return changes, renames
329 return changes, renames
330
330
331 def _filterghosts(self, ids):
331 def _filterghosts(self, ids):
332 """Filters out ghost revisions which hg does not support, see
332 """Filters out ghost revisions which hg does not support, see
333 <http://bazaar-vcs.org/GhostRevision>
333 <http://bazaar-vcs.org/GhostRevision>
334 """
334 """
335 parentmap = self.sourcerepo.get_parent_map(ids)
335 parentmap = self.sourcerepo.get_parent_map(ids)
336 parents = tuple([parent for parent in ids if parent in parentmap])
336 parents = tuple([parent for parent in ids if parent in parentmap])
337 return parents
337 return parents
@@ -1,100 +1,100 b''
1 # highlight.py - highlight extension implementation file
1 # highlight.py - highlight extension implementation file
2 #
2 #
3 # Copyright 2007-2009 Adam Hupp <adam@hupp.org> and others
3 # Copyright 2007-2009 Adam Hupp <adam@hupp.org> 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 # The original module was split in an interface and an implementation
8 # The original module was split in an interface and an implementation
9 # file to defer pygments loading and speedup extension setup.
9 # file to defer pygments loading and speedup extension setup.
10
10
11
11
12 from mercurial import demandimport
12 from mercurial import demandimport
13
13
14 demandimport.IGNORES.update([b'pkgutil', b'pkg_resources', b'__main__'])
14 demandimport.IGNORES.update(['pkgutil', 'pkg_resources', '__main__'])
15
15
16 from mercurial import (
16 from mercurial import (
17 encoding,
17 encoding,
18 pycompat,
18 pycompat,
19 )
19 )
20
20
21 from mercurial.utils import stringutil
21 from mercurial.utils import stringutil
22
22
23 with demandimport.deactivated():
23 with demandimport.deactivated():
24 import pygments
24 import pygments
25 import pygments.formatters
25 import pygments.formatters
26 import pygments.lexers
26 import pygments.lexers
27 import pygments.plugin
27 import pygments.plugin
28 import pygments.util
28 import pygments.util
29
29
30 for unused in pygments.plugin.find_plugin_lexers():
30 for unused in pygments.plugin.find_plugin_lexers():
31 pass
31 pass
32
32
33 highlight = pygments.highlight
33 highlight = pygments.highlight
34 ClassNotFound = pygments.util.ClassNotFound
34 ClassNotFound = pygments.util.ClassNotFound
35 guess_lexer = pygments.lexers.guess_lexer
35 guess_lexer = pygments.lexers.guess_lexer
36 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
36 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
37 TextLexer = pygments.lexers.TextLexer
37 TextLexer = pygments.lexers.TextLexer
38 HtmlFormatter = pygments.formatters.HtmlFormatter
38 HtmlFormatter = pygments.formatters.HtmlFormatter
39
39
40 SYNTAX_CSS = (
40 SYNTAX_CSS = (
41 b'\n<link rel="stylesheet" href="{url}highlightcss" type="text/css" />'
41 b'\n<link rel="stylesheet" href="{url}highlightcss" type="text/css" />'
42 )
42 )
43
43
44
44
45 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
45 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
46
46
47 # append a <link ...> to the syntax highlighting css
47 # append a <link ...> to the syntax highlighting css
48 tmpl.load(b'header')
48 tmpl.load(b'header')
49 old_header = tmpl.cache[b'header']
49 old_header = tmpl.cache[b'header']
50 if SYNTAX_CSS not in old_header:
50 if SYNTAX_CSS not in old_header:
51 new_header = old_header + SYNTAX_CSS
51 new_header = old_header + SYNTAX_CSS
52 tmpl.cache[b'header'] = new_header
52 tmpl.cache[b'header'] = new_header
53
53
54 text = fctx.data()
54 text = fctx.data()
55 if stringutil.binary(text):
55 if stringutil.binary(text):
56 return
56 return
57
57
58 # str.splitlines() != unicode.splitlines() because "reasons"
58 # str.splitlines() != unicode.splitlines() because "reasons"
59 for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
59 for c in b"\x0c", b"\x1c", b"\x1d", b"\x1e":
60 if c in text:
60 if c in text:
61 text = text.replace(c, b'')
61 text = text.replace(c, b'')
62
62
63 # Pygments is best used with Unicode strings:
63 # Pygments is best used with Unicode strings:
64 # <http://pygments.org/docs/unicode/>
64 # <http://pygments.org/docs/unicode/>
65 text = text.decode(pycompat.sysstr(encoding.encoding), 'replace')
65 text = text.decode(pycompat.sysstr(encoding.encoding), 'replace')
66
66
67 # To get multi-line strings right, we can't format line-by-line
67 # To get multi-line strings right, we can't format line-by-line
68 try:
68 try:
69 path = pycompat.sysstr(fctx.path())
69 path = pycompat.sysstr(fctx.path())
70 lexer = guess_lexer_for_filename(path, text[:1024], stripnl=False)
70 lexer = guess_lexer_for_filename(path, text[:1024], stripnl=False)
71 except (ClassNotFound, ValueError):
71 except (ClassNotFound, ValueError):
72 # guess_lexer will return a lexer if *any* lexer matches. There is
72 # guess_lexer will return a lexer if *any* lexer matches. There is
73 # no way to specify a minimum match score. This can give a high rate of
73 # no way to specify a minimum match score. This can give a high rate of
74 # false positives on files with an unknown filename pattern.
74 # false positives on files with an unknown filename pattern.
75 if guessfilenameonly:
75 if guessfilenameonly:
76 return
76 return
77
77
78 try:
78 try:
79 lexer = guess_lexer(text[:1024], stripnl=False)
79 lexer = guess_lexer(text[:1024], stripnl=False)
80 except (ClassNotFound, ValueError):
80 except (ClassNotFound, ValueError):
81 # Don't highlight unknown files
81 # Don't highlight unknown files
82 return
82 return
83
83
84 # Don't highlight text files
84 # Don't highlight text files
85 if isinstance(lexer, TextLexer):
85 if isinstance(lexer, TextLexer):
86 return
86 return
87
87
88 formatter = HtmlFormatter(nowrap=True, style=pycompat.sysstr(style))
88 formatter = HtmlFormatter(nowrap=True, style=pycompat.sysstr(style))
89
89
90 colorized = highlight(text, lexer, formatter)
90 colorized = highlight(text, lexer, formatter)
91 coloriter = (
91 coloriter = (
92 s.encode(pycompat.sysstr(encoding.encoding), 'replace')
92 s.encode(pycompat.sysstr(encoding.encoding), 'replace')
93 for s in colorized.splitlines()
93 for s in colorized.splitlines()
94 )
94 )
95
95
96 tmpl._filters[b'colorize'] = lambda x: next(coloriter)
96 tmpl._filters[b'colorize'] = lambda x: next(coloriter)
97
97
98 oldl = tmpl.cache[field]
98 oldl = tmpl.cache[field]
99 newl = oldl.replace(b'line|escape', b'line|colorize')
99 newl = oldl.replace(b'line|escape', b'line|colorize')
100 tmpl.cache[field] = newl
100 tmpl.cache[field] = newl
General Comments 0
You need to be logged in to leave comments. Login now