[PATCH] hgweb: code selection in file view without line numbers

Mads Kiilerich mads at kiilerich.com
Wed Apr 17 09:43:08 CDT 2013


On 04/17/2013 04:07 PM, Alexander Plavin wrote:
> # HG changeset patch
> # User Alexander Plavin <me at aplavin.ru>
> # Date 1366205259 -14400
> #      Wed Apr 17 17:27:39 2013 +0400
> # Node ID 1933896b16c821ba1e54e397f15e3f521aaf8909
> # Parent  4d32c86be3fad13cbe42ce3f51b0fdacf295f30f
> hgweb: code selection in file view without line numbers
>
> Only single file views changed, and only default templates set ('paper')

Some questions that it might make sense to answer in the commit description:

What was the problem - both the user experience and the technical 
explanation?

Will the patch remove the line numbers completely or what trick will it 
use to make sure they don't get selected?

Will this for instance change how huge text files will be transmitted 
and rendered on the fly? Is using a method that is similar to what 
similar tools and sites use?

/Mads


>
> diff -r 4d32c86be3fa -r 1933896b16c8 mercurial/templates/paper/filerevision.tmpl
> --- a/mercurial/templates/paper/filerevision.tmpl	Wed Apr 10 20:45:10 2013 +0400
> +++ b/mercurial/templates/paper/filerevision.tmpl	Wed Apr 17 17:27:39 2013 +0400
> @@ -68,7 +68,8 @@
>   
>   <div class="overflow">
>   <div class="sourcefirst"> line source</div>
> -{text%fileline}
> +<pre class="sourcenumbers">{text%filelinenum}</pre>
> +<pre class="source">{text%fileline}</pre>
>   <div class="sourcelast"></div>
>   </div>
>   </div>
> diff -r 4d32c86be3fa -r 1933896b16c8 mercurial/templates/paper/map
> --- a/mercurial/templates/paper/map	Wed Apr 10 20:45:10 2013 +0400
> +++ b/mercurial/templates/paper/map	Wed Apr 17 17:27:39 2013 +0400
> @@ -72,7 +72,9 @@
>   filecomparison = filecomparison.tmpl
>   filelog = filelog.tmpl
>   fileline = '
> -  <div class="source"><a href="#{lineid}" id="{lineid}">{linenumber}</a> {line|escape}</div>'
> +  {line|escape|strip}'
> +filelinenum = '
> +  <a href="#{lineid}" id="{lineid}">{linenumber} </a>'
>   filelogentry = filelogentry.tmpl
>   
>   annotateline = '
> diff -r 4d32c86be3fa -r 1933896b16c8 mercurial/templates/static/style-paper.css
> --- a/mercurial/templates/static/style-paper.css	Wed Apr 10 20:45:10 2013 +0400
> +++ b/mercurial/templates/static/style-paper.css	Wed Apr 17 17:27:39 2013 +0400
> @@ -198,7 +198,7 @@
>   .bigtable td.annotate { font-size: smaller; }
>   .bigtable td.source { font-size: inherit; }
>   
> -.source, .sourcefirst, .sourcelast {
> +.source, .sourcefirst, .sourcelast, .sourcenumbers {
>     font-family: monospace;
>     white-space: pre;
>     padding: 1px 4px;
> @@ -206,7 +206,8 @@
>   }
>   .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
>   .sourcelast { border-top: 1px solid #999; }
> -.source a { color: #999; font-size: smaller; font-family: monospace;}
> +.sourcenumbers { float: left; }
> +.sourcenumbers a { color: #999; font-size: smaller; font-family: monospace; }
>   .bottomline { border-bottom: 1px solid #999; }
>   
>   .fileline { font-family: monospace; }
> diff -r 4d32c86be3fa -r 1933896b16c8 tests/test-hgweb-commands.t
> --- a/tests/test-hgweb-commands.t	Wed Apr 10 20:45:10 2013 +0400
> +++ b/tests/test-hgweb-commands.t	Wed Apr 17 17:27:39 2013 +0400
> @@ -668,9 +668,10 @@
>     
>     <div class="overflow">
>     <div class="sourcefirst"> line source</div>
> -
> -  <div class="source"><a href="#l1" id="l1">     1</a> foo
> -  </div>
> +  <pre class="sourcenumbers">
> +  <a href="#l1" id="l1">     1 </a></pre>
> +  <pre class="source">
> +  foo</pre>
>     <div class="sourcelast"></div>
>     </div>
>     </div>
> diff -r 4d32c86be3fa -r 1933896b16c8 tests/test-highlight.t
> --- a/tests/test-highlight.t	Wed Apr 10 20:45:10 2013 +0400
> +++ b/tests/test-highlight.t	Wed Apr 17 17:27:39 2013 +0400
> @@ -137,39 +137,72 @@
>     
>     <div class="overflow">
>     <div class="sourcefirst"> line source</div>
> +  <pre class="sourcenumbers">
> +  <a href="#l1" id="l1">     1 </a>
> +  <a href="#l2" id="l2">     2 </a>
> +  <a href="#l3" id="l3">     3 </a>
> +  <a href="#l4" id="l4">     4 </a>
> +  <a href="#l5" id="l5">     5 </a>
> +  <a href="#l6" id="l6">     6 </a>
> +  <a href="#l7" id="l7">     7 </a>
> +  <a href="#l8" id="l8">     8 </a>
> +  <a href="#l9" id="l9">     9 </a>
> +  <a href="#l10" id="l10">    10 </a>
> +  <a href="#l11" id="l11">    11 </a>
> +  <a href="#l12" id="l12">    12 </a>
> +  <a href="#l13" id="l13">    13 </a>
> +  <a href="#l14" id="l14">    14 </a>
> +  <a href="#l15" id="l15">    15 </a>
> +  <a href="#l16" id="l16">    16 </a>
> +  <a href="#l17" id="l17">    17 </a>
> +  <a href="#l18" id="l18">    18 </a>
> +  <a href="#l19" id="l19">    19 </a>
> +  <a href="#l20" id="l20">    20 </a>
> +  <a href="#l21" id="l21">    21 </a>
> +  <a href="#l22" id="l22">    22 </a>
> +  <a href="#l23" id="l23">    23 </a>
> +  <a href="#l24" id="l24">    24 </a>
> +  <a href="#l25" id="l25">    25 </a>
> +  <a href="#l26" id="l26">    26 </a>
> +  <a href="#l27" id="l27">    27 </a>
> +  <a href="#l28" id="l28">    28 </a>
> +  <a href="#l29" id="l29">    29 </a>
> +  <a href="#l30" id="l30">    30 </a>
> +  <a href="#l31" id="l31">    31 </a>
> +  <a href="#l32" id="l32">    32 </a></pre>
> +  <pre class="source">
> +  <span class="c">#!/usr/bin/env python</span>
>     
> -  <div class="source"><a href="#l1" id="l1">     1</a> <span class="c">#!/usr/bin/env python</span></div>
> -  <div class="source"><a href="#l2" id="l2">     2</a> </div>
> -  <div class="source"><a href="#l3" id="l3">     3</a> <span class="sd">"""Fun with generators. Corresponding Haskell implementation:</span></div>
> -  <div class="source"><a href="#l4" id="l4">     4</a> </div>
> -  <div class="source"><a href="#l5" id="l5">     5</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></div>
> -  <div class="source"><a href="#l6" id="l6">     6</a> <span class="sd">    where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]</span></div>
> -  <div class="source"><a href="#l7" id="l7">     7</a> <span class="sd">"""</span></div>
> -  <div class="source"><a href="#l8" id="l8">     8</a> </div>
> -  <div class="source"><a href="#l9" id="l9">     9</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></div>
> -  <div class="source"><a href="#l10" id="l10">    10</a> </div>
> -  <div class="source"><a href="#l11" id="l11">    11</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></div>
> -  <div class="source"><a href="#l12" id="l12">    12</a>     <span class="sd">"""Generate all primes."""</span></div>
> -  <div class="source"><a href="#l13" id="l13">    13</a>     <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div>
> -  <div class="source"><a href="#l14" id="l14">    14</a>         <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></div>
> -  <div class="source"><a href="#l15" id="l15">    15</a>         <span class="c"># It is important to yield *here* in order to stop the</span></div>
> -  <div class="source"><a href="#l16" id="l16">    16</a>         <span class="c"># infinite recursion.</span></div>
> -  <div class="source"><a href="#l17" id="l17">    17</a>         <span class="kn">yield</span> <span class="n">p</span></div>
> -  <div class="source"><a href="#l18" id="l18">    18</a>         <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></div>
> -  <div class="source"><a href="#l19" id="l19">    19</a>         <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></div>
> -  <div class="source"><a href="#l20" id="l20">    20</a>             <span class="kn">yield</span> <span class="n">n</span></div>
> -  <div class="source"><a href="#l21" id="l21">    21</a> </div>
> -  <div class="source"><a href="#l22" id="l22">    22</a>     <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></div>
> -  <div class="source"><a href="#l23" id="l23">    23</a>     <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o"><</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></div>
> -  <div class="source"><a href="#l24" id="l24">    24</a> </div>
> -  <div class="source"><a href="#l25" id="l25">    25</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span></div>
> -  <div class="source"><a href="#l26" id="l26">    26</a>     <span class="kn">import</span> <span class="nn">sys</span></div>
> -  <div class="source"><a href="#l27" id="l27">    27</a>     <span class="kn">try</span><span class="p">:</span></div>
> -  <div class="source"><a href="#l28" id="l28">    28</a>         <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div>
> -  <div class="source"><a href="#l29" id="l29">    29</a>     <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></div>
> -  <div class="source"><a href="#l30" id="l30">    30</a>         <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></div>
> -  <div class="source"><a href="#l31" id="l31">    31</a>     <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></div>
> -  <div class="source"><a href="#l32" id="l32">    32</a>     <span class="kn">print</span> <span class="s">"The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></div>
> +  <span class="sd">"""Fun with generators. Corresponding Haskell implementation:</span>
> +
> +  <span class="sd">primes = 2 : sieve [3, 5..]</span>
> +  <span class="sd">    where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]</span>
> +  <span class="sd">"""</span>
> +
> +  <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span>
> +
> +  <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span>
> +  <span class="sd">"""Generate all primes."""</span>
> +  <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span>
> +  <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
> +  <span class="c"># It is important to yield *here* in order to stop the</span>
> +  <span class="c"># infinite recursion.</span>
> +  <span class="kn">yield</span> <span class="n">p</span>
> +  <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span>
> +  <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span>
> +  <span class="kn">yield</span> <span class="n">n</span>
> +
> +  <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span>
> +  <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o"><</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span>
> +
> +  <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
> +  <span class="kn">import</span> <span class="nn">sys</span>
> +  <span class="kn">try</span><span class="p">:</span>
> +  <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
> +  <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span>
> +  <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span>
> +  <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span>
> +  <span class="kn">print</span> <span class="s">"The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">"</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></pre>
>     <div class="sourcelast"></div>
>     </div>
>     </div>
> @@ -586,24 +619,27 @@
>     >
>     >     echo % hgweb filerevision, html
>     >     "$TESTDIR/get-with-headers.py" localhost:$HGPORT "file/tip/$2" \
> -  >         | grep '<div class="source">'
> +  >         | grep -A 1 '<pre class="source">'
>     >     echo % errors encountered
>     >     cat errors.log
>     > }
>     $ hgserveget euc-jp eucjp.txt
>     % HGENCODING=euc-jp hg serve
>     % hgweb filerevision, html
> -  <div class="source"><a href="#l1" id="l1">     1</a> \xb5\xfe</div> (esc)
> +  <pre class="source">
> +  \xb5\xfe</pre> (esc)
>     % errors encountered
>     $ hgserveget utf-8 eucjp.txt
>     % HGENCODING=utf-8 hg serve
>     % hgweb filerevision, html
> -  <div class="source"><a href="#l1" id="l1">     1</a> \xef\xbf\xbd\xef\xbf\xbd</div> (esc)
> +  <pre class="source">
> +  \xef\xbf\xbd\xef\xbf\xbd</pre> (esc)
>     % errors encountered
>     $ hgserveget us-ascii eucjp.txt
>     % HGENCODING=us-ascii hg serve
>     % hgweb filerevision, html
> -  <div class="source"><a href="#l1" id="l1">     1</a> ??</div>
> +  <pre class="source">
> +  ??</pre>
>     % errors encountered
>   
>     $ cd ..
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list