##// END OF EJS Templates
highlight: eagerly discover plugin lexers while demandimport is off...
Augie Fackler -
r35330:169d66db default
parent child Browse files
Show More
@@ -1,89 +1,93 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 from __future__ import absolute_import
11 from __future__ import absolute_import
12
12
13 from mercurial import demandimport
13 from mercurial import demandimport
14 demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__'])
14 demandimport.ignore.extend(['pkgutil', 'pkg_resources', '__main__'])
15
15
16 from mercurial import (
16 from mercurial import (
17 encoding,
17 encoding,
18 util,
18 util,
19 )
19 )
20
20
21 with demandimport.deactivated():
21 with demandimport.deactivated():
22 import pygments
22 import pygments
23 import pygments.formatters
23 import pygments.formatters
24 import pygments.lexers
24 import pygments.lexers
25 import pygments.plugin
25 import pygments.util
26 import pygments.util
26
27
28 for unused in pygments.plugin.find_plugin_lexers():
29 pass
30
27 highlight = pygments.highlight
31 highlight = pygments.highlight
28 ClassNotFound = pygments.util.ClassNotFound
32 ClassNotFound = pygments.util.ClassNotFound
29 guess_lexer = pygments.lexers.guess_lexer
33 guess_lexer = pygments.lexers.guess_lexer
30 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
34 guess_lexer_for_filename = pygments.lexers.guess_lexer_for_filename
31 TextLexer = pygments.lexers.TextLexer
35 TextLexer = pygments.lexers.TextLexer
32 HtmlFormatter = pygments.formatters.HtmlFormatter
36 HtmlFormatter = pygments.formatters.HtmlFormatter
33
37
34 SYNTAX_CSS = ('\n<link rel="stylesheet" href="{url}highlightcss" '
38 SYNTAX_CSS = ('\n<link rel="stylesheet" href="{url}highlightcss" '
35 'type="text/css" />')
39 'type="text/css" />')
36
40
37 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
41 def pygmentize(field, fctx, style, tmpl, guessfilenameonly=False):
38
42
39 # append a <link ...> to the syntax highlighting css
43 # append a <link ...> to the syntax highlighting css
40 old_header = tmpl.load('header')
44 old_header = tmpl.load('header')
41 if SYNTAX_CSS not in old_header:
45 if SYNTAX_CSS not in old_header:
42 new_header = old_header + SYNTAX_CSS
46 new_header = old_header + SYNTAX_CSS
43 tmpl.cache['header'] = new_header
47 tmpl.cache['header'] = new_header
44
48
45 text = fctx.data()
49 text = fctx.data()
46 if util.binary(text):
50 if util.binary(text):
47 return
51 return
48
52
49 # str.splitlines() != unicode.splitlines() because "reasons"
53 # str.splitlines() != unicode.splitlines() because "reasons"
50 for c in "\x0c\x1c\x1d\x1e":
54 for c in "\x0c\x1c\x1d\x1e":
51 if c in text:
55 if c in text:
52 text = text.replace(c, '')
56 text = text.replace(c, '')
53
57
54 # Pygments is best used with Unicode strings:
58 # Pygments is best used with Unicode strings:
55 # <http://pygments.org/docs/unicode/>
59 # <http://pygments.org/docs/unicode/>
56 text = text.decode(encoding.encoding, 'replace')
60 text = text.decode(encoding.encoding, 'replace')
57
61
58 # To get multi-line strings right, we can't format line-by-line
62 # To get multi-line strings right, we can't format line-by-line
59 try:
63 try:
60 lexer = guess_lexer_for_filename(fctx.path(), text[:1024],
64 lexer = guess_lexer_for_filename(fctx.path(), text[:1024],
61 stripnl=False)
65 stripnl=False)
62 except (ClassNotFound, ValueError):
66 except (ClassNotFound, ValueError):
63 # guess_lexer will return a lexer if *any* lexer matches. There is
67 # guess_lexer will return a lexer if *any* lexer matches. There is
64 # no way to specify a minimum match score. This can give a high rate of
68 # no way to specify a minimum match score. This can give a high rate of
65 # false positives on files with an unknown filename pattern.
69 # false positives on files with an unknown filename pattern.
66 if guessfilenameonly:
70 if guessfilenameonly:
67 return
71 return
68
72
69 try:
73 try:
70 lexer = guess_lexer(text[:1024], stripnl=False)
74 lexer = guess_lexer(text[:1024], stripnl=False)
71 except (ClassNotFound, ValueError):
75 except (ClassNotFound, ValueError):
72 # Don't highlight unknown files
76 # Don't highlight unknown files
73 return
77 return
74
78
75 # Don't highlight text files
79 # Don't highlight text files
76 if isinstance(lexer, TextLexer):
80 if isinstance(lexer, TextLexer):
77 return
81 return
78
82
79 formatter = HtmlFormatter(nowrap=True, style=style)
83 formatter = HtmlFormatter(nowrap=True, style=style)
80
84
81 colorized = highlight(text, lexer, formatter)
85 colorized = highlight(text, lexer, formatter)
82 coloriter = (s.encode(encoding.encoding, 'replace')
86 coloriter = (s.encode(encoding.encoding, 'replace')
83 for s in colorized.splitlines())
87 for s in colorized.splitlines())
84
88
85 tmpl.filters['colorize'] = lambda x: next(coloriter)
89 tmpl.filters['colorize'] = lambda x: next(coloriter)
86
90
87 oldl = tmpl.cache[field]
91 oldl = tmpl.cache[field]
88 newl = oldl.replace('line|escape', 'line|colorize')
92 newl = oldl.replace('line|escape', 'line|colorize')
89 tmpl.cache[field] = newl
93 tmpl.cache[field] = newl
General Comments 0
You need to be logged in to leave comments. Login now