[PATCH] Add line anchors to annotate, changeset, diff, file views for hgweb

Edward Lee edilee at mozilla.com
Tue Sep 4 23:41:11 CDT 2007


I'm having issues today. :( File attached.

On 9/4/07, Edward Lee <edilee at mozilla.com> wrote:
> This patch makes the line numbers into anchor tags with an id to link
> to itself. The default and gitweb templates are updated to have
> clickable line numbers for annotate, changeset, diff, and file views.
>
> hgweb's ability to show the whole repository for any given changeset
> is really useful, but it would be nice if we could refer to a
> particular line of a file or changeset (such as for a bug report or
> discussing a patch). This patch adds a couple new template-vars such
> as lineid and linenumber.
>
> -- Patch comments --
>
> Refactored the |yield self.t()| do save on duplicate calls with the
> same arguments.
> http://74.136.196.179:8080/rev/5447b7e5ba45#l1.25
>
> For changesets (and single file diffs), it'll only use the
> "block.line" notation for the second block on. This makes single file
> diffs nicer while keeping changeset views clean.
> http://74.136.196.179:8080/rev/5447b7e5ba45#l1.21
>
> I renamed the l variable to lineno to keep it consistent with the
> other code blocks.
> http://74.136.196.179:8080/rev/5447b7e5ba45#l1.48
>
> Both the default and gitweb templates are edited in the patch, but
> they can be easily removed if we want to leave it to the end user to
> decide if they want linkable line numbers for diffs/changesets and
> annotate. I would recommend it on by default for file views though.
> http://74.136.196.179:8080/rev/5447b7e5ba45#l3.1
> http://74.136.196.179:8080/rev/5447b7e5ba45#l2.1
>
> Ed
>


-- 
Ed
-------------- next part --------------
# HG changeset patch
# User Edward Lee <edward.lee at engineering.uiuc.edu>
# Date 1188962737 18000
# Node ID 5447b7e5ba45915da3aa86fb23bf86476e25142b
# Parent  4fe04b183fd83ec6ba9b8c8f014329064761e36c
Add line anchors to annotate, changeset, diff, file views for hgweb

diff --git a/mercurial/hgweb/common.py b/mercurial/hgweb/common.py
--- a/mercurial/hgweb/common.py
+++ b/mercurial/hgweb/common.py
@@ -76,3 +76,9 @@ def paritygen(stripecount, offset=0):
             parity = 1 - parity
             count = 0
 
+def countgen(start=0, step=1):
+    """count forever -- useful for line numbers"""
+    while True:
+        yield start
+        start += step
+
diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py
--- a/mercurial/hgweb/hgweb_mod.py
+++ b/mercurial/hgweb/hgweb_mod.py
@@ -12,7 +12,7 @@ from mercurial.i18n import gettext as _
 from mercurial.i18n import gettext as _
 from mercurial import mdiff, ui, hg, util, archival, streamclone, patch
 from mercurial import revlog, templater
-from common import get_mtime, staticfile, style_map, paritygen
+from common import get_mtime, staticfile, style_map, paritygen, countgen
 
 def _up(p):
     if p[0] != "/":
@@ -166,16 +166,25 @@ class hgweb(object):
                          file=f,
                          filenode=hex(fn or nullid))
 
+        blockcount = countgen()
         def prettyprintlines(diff):
-            for l in diff.splitlines(1):
+            blockno = blockcount.next()
+            for lineno, l in enumerate(diff.splitlines(1)):
+                if blockno == 0:
+                    lineno = lineno + 1
+                else:
+                    lineno = "%d.%d" % (blockno, lineno + 1)
+                type = "diffline"
                 if l.startswith('+'):
-                    yield self.t("difflineplus", line=l)
+                    type = "difflineplus"
                 elif l.startswith('-'):
-                    yield self.t("difflineminus", line=l)
+                    type = "difflineminus"
                 elif l.startswith('@'):
-                    yield self.t("difflineat", line=l)
-                else:
-                    yield self.t("diffline", line=l)
+                    type = "difflineat"
+                yield self.t(type,
+                             line=l,
+                             lineid="l%s" % lineno,
+                             linenumber="% 8s" % lineno)
 
         r = self.repo
         c1 = r.changectx(node1)
@@ -394,9 +403,10 @@ class hgweb(object):
         mt = mt or 'text/plain'
 
         def lines():
-            for l, t in enumerate(text.splitlines(1)):
+            for lineno, t in enumerate(text.splitlines(1)):
                 yield {"line": t,
-                       "linenumber": "% 6d" % (l + 1),
+                       "lineid": "l%d" % (lineno + 1),
+                       "linenumber": "% 6d" % (lineno + 1),
                        "parity": parity.next()}
 
         yield self.t("filerevision",
@@ -423,7 +433,7 @@ class hgweb(object):
 
         def annotate(**map):
             last = None
-            for f, l in fctx.annotate(follow=True):
+            for lineno, (f, l) in enumerate(fctx.annotate(follow=True)):
                 fnode = f.filenode()
                 name = self.repo.ui.shortuser(f.user())
 
@@ -435,7 +445,9 @@ class hgweb(object):
                        "rev": f.rev(),
                        "author": name,
                        "file": f.path(),
-                       "line": l}
+                       "line": l,
+                       "lineid": "l%d" % (lineno + 1),
+                       "linenumber": "% 6d" % (lineno + 1)}
 
         yield self.t("fileannotate",
                      file=f,
diff --git a/templates/gitweb/map b/templates/gitweb/map
--- a/templates/gitweb/map
+++ b/templates/gitweb/map
@@ -22,12 +22,12 @@ fileannotate = fileannotate.tmpl
 fileannotate = fileannotate.tmpl
 filediff = filediff.tmpl
 filelog = filelog.tmpl
-fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><span class="linenr">   #linenumber#</span> #line|escape#</pre></div>'
-annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
-difflineplus = '<div style="color:#008800;">#line|escape#</div>'
-difflineminus = '<div style="color:#cc0000;">#line|escape#</div>'
-difflineat = '<div style="color:#990099;">#line|escape#</div>'
-diffline = '<div>#line|escape#</div>'
+fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</pre></div>'
+annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a></pre></td><td><pre>#line|escape#</pre></td></tr>'
+difflineplus = '<div style="color:#008800;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</div>'
+difflineminus = '<div style="color:#cc0000;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</div>'
+difflineat = '<div style="color:#990099;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</div>'
+diffline = '<div><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</div>'
 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
 changesetparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
 filerevparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
diff --git a/templates/map b/templates/map
--- a/templates/map
+++ b/templates/map
@@ -21,13 +21,13 @@ fileannotate = fileannotate.tmpl
 fileannotate = fileannotate.tmpl
 filediff = filediff.tmpl
 filelog = filelog.tmpl
-fileline = '<div class="parity#parity#"><span class="lineno">#linenumber#</span>#line|escape#</div>'
+fileline = '<div class="parity#parity#"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</div>'
 filelogentry = filelogentry.tmpl
-annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><pre>#line|escape#</pre></td></tr>'
-difflineplus = '<span class="plusline">#line|escape#</span>'
-difflineminus = '<span class="minusline">#line|escape#</span>'
-difflineat = '<span class="atline">#line|escape#</span>'
-diffline = '#line|escape#'
+annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#author|obfuscate#@#rev#</a></td><td><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a></td><td><pre>#line|escape#</pre></td></tr>'
+difflineplus = '<span class="plusline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
+difflineminus = '<span class="minusline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
+difflineat = '<span class="atline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
+diffline = '<a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#'
 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
 changesetparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'


More information about the Mercurial-devel mailing list