comparison hgext/highlight/__init__.py @ 26249:3166bcc0c538

highlight: add highlightfiles config option which takes a fileset (issue3005) Highlight extension lacked a way to limit files by size, by extension, and/or by any other part of file path. A good solution would be to use a fileset, since it can check file path, extension and size (and more) in one expression. So this change introduces such an option, highlighfiles, which takes a fileset and on each request decides if the requested file should be highlighted. The default "size('<5M')" is, in a way, suggested in issue3005. checkfctx() limits the amount of work to just one file (subset kwarg in fileset.matchctx()). Monkey-patching works around issue4568, otherwise using filesets here while running hgweb in directory mode would say, for example, "Abort: **.py not under root", but this fix is very local and probably far from ideal. I suspect there to be a way to fix this for the whole hgweb and resolve the issue, but I don't know how to do it.
author Anton Shestakov <av6@dwimlabs.net>
date Wed, 16 Sep 2015 22:30:36 +0800
parents 85fb416f2fa7
children e7cb19b1ef2b
comparison
equal deleted inserted replaced
26248:99b6afff09ae 26249:3166bcc0c538
11 """syntax highlighting for hgweb (requires Pygments) 11 """syntax highlighting for hgweb (requires Pygments)
12 12
13 It depends on the Pygments syntax highlighting library: 13 It depends on the Pygments syntax highlighting library:
14 http://pygments.org/ 14 http://pygments.org/
15 15
16 There is a single configuration option:: 16 There are two configuration options::
17 17
18 [web] 18 [web]
19 pygments_style = <style> 19 pygments_style = <style> (default: colorful)
20 20 highlightfiles = <fileset> (default: size('<5M'))
21 The default is 'colorful'.
22 """ 21 """
23 22
24 import highlight 23 import highlight
25 from mercurial.hgweb import webcommands, webutil, common 24 from mercurial.hgweb import webcommands, webutil, common
26 from mercurial import extensions, encoding 25 from mercurial import extensions, encoding, fileset
27 # Note for extension authors: ONLY specify testedwith = 'internal' for 26 # Note for extension authors: ONLY specify testedwith = 'internal' for
28 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should 27 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
29 # be specifying the version(s) of Mercurial they are tested with, or 28 # be specifying the version(s) of Mercurial they are tested with, or
30 # leave the attribute unspecified. 29 # leave the attribute unspecified.
31 testedwith = 'internal' 30 testedwith = 'internal'
31
32 def checkfctx(fctx, expr):
33 ctx = fctx.changectx()
34 tree = fileset.parse(expr)
35 mctx = fileset.matchctx(ctx, subset=[fctx.path()], status=None)
36 repo = ctx.repo()
37 # To allow matching file names in the fileset in hgweb directory mode.
38 # See issue4568.
39 object.__setattr__(repo, 'getcwd', lambda: repo.root)
40 return fctx.path() in fileset.getset(mctx, tree)
32 41
33 def filerevision_highlight(orig, web, req, tmpl, fctx): 42 def filerevision_highlight(orig, web, req, tmpl, fctx):
34 mt = ''.join(tmpl('mimetype', encoding=encoding.encoding)) 43 mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
35 # only pygmentize for mimetype containing 'html' so we both match 44 # only pygmentize for mimetype containing 'html' so we both match
36 # 'text/html' and possibly 'application/xhtml+xml' in the future 45 # 'text/html' and possibly 'application/xhtml+xml' in the future
39 # raw file is sent using rawfile() and doesn't call us, so we 48 # raw file is sent using rawfile() and doesn't call us, so we
40 # can't clash with the file's content-type here in case we 49 # can't clash with the file's content-type here in case we
41 # pygmentize a html file 50 # pygmentize a html file
42 if 'html' in mt: 51 if 'html' in mt:
43 style = web.config('web', 'pygments_style', 'colorful') 52 style = web.config('web', 'pygments_style', 'colorful')
44 highlight.pygmentize('fileline', fctx, style, tmpl) 53 expr = web.config('web', 'highlightfiles', "size('<5M')")
54 if checkfctx(fctx, expr):
55 highlight.pygmentize('fileline', fctx, style, tmpl)
45 return orig(web, req, tmpl, fctx) 56 return orig(web, req, tmpl, fctx)
46 57
47 def annotate_highlight(orig, web, req, tmpl): 58 def annotate_highlight(orig, web, req, tmpl):
48 mt = ''.join(tmpl('mimetype', encoding=encoding.encoding)) 59 mt = ''.join(tmpl('mimetype', encoding=encoding.encoding))
49 if 'html' in mt: 60 if 'html' in mt:
50 fctx = webutil.filectx(web.repo, req) 61 fctx = webutil.filectx(web.repo, req)
51 style = web.config('web', 'pygments_style', 'colorful') 62 style = web.config('web', 'pygments_style', 'colorful')
52 highlight.pygmentize('annotateline', fctx, style, tmpl) 63 expr = web.config('web', 'highlightfiles', "size('<5M')")
64 if checkfctx(fctx, expr):
65 highlight.pygmentize('annotateline', fctx, style, tmpl)
53 return orig(web, req, tmpl) 66 return orig(web, req, tmpl)
54 67
55 def generate_css(web, req, tmpl): 68 def generate_css(web, req, tmpl):
56 pg_style = web.config('web', 'pygments_style', 'colorful') 69 pg_style = web.config('web', 'pygments_style', 'colorful')
57 fmter = highlight.HtmlFormatter(style=pg_style) 70 fmter = highlight.HtmlFormatter(style=pg_style)