Patchwork [v3] templater: add separate() template function

login
register
mail settings
Submitter via Mercurial-devel
Date May 5, 2016, 8:52 p.m.
Message ID <9a9fd3c8c8434c52e642.1462481546@martinvonz.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/14931/
State Accepted
Delegated to: Yuya Nishihara
Headers show

Comments

via Mercurial-devel - May 5, 2016, 8:52 p.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1462294194 25200
#      Tue May 03 09:49:54 2016 -0700
# Node ID 9a9fd3c8c8434c52e642cb5f32d423e09800e607
# Parent  8eba4cdcfd810d80785c94d770a442c5bd1f9d0f
templater: add separate() template function

A pretty common pattern in templates is adding conditional separators
like so:

  {node}{if(bookmarks, " {bookmarks}")}{if(tags, " {tags}")}

With this patch, the above can be simplified to:

  {separate(" ", node, bookmarks, tags)}

The function is similar to the already existing join(), but with a few
differences:

 * separate() skips empty arguments

 * join() expects a single list argument, while separate() expects
   each item as a separate argument

 * separate() takes the separator first in order to allow a variable
   number of arguments after it
Yuya Nishihara - May 6, 2016, 2:43 a.m.
On Thu, 05 May 2016 13:52:26 -0700, Martin von Zweigbergk via Mercurial-devel wrote:
> # HG changeset patch
> # User Martin von Zweigbergk <martinvonz@google.com>
> # Date 1462294194 25200
> #      Tue May 03 09:49:54 2016 -0700
> # Node ID 9a9fd3c8c8434c52e642cb5f32d423e09800e607
> # Parent  8eba4cdcfd810d80785c94d770a442c5bd1f9d0f
> templater: add separate() template function

Looks good and simple as a start. I'll push to the committed repo, thanks.

> +@templatefunc('separate(sep, args)')
> +def separate(context, mapping, args):
> +    """Add a separator between non-empty arguments."""
> +    if not args:
> +        # i18n: "separate" is a keyword
> +        raise error.ParseError(_("separate expects at least one argument"))
> +
> +    sep = evalstring(context, mapping, args[0])
> +    first = True
> +    for arg in args[1:]:
> +        argstr = evalstring(context, mapping, arg)
> +        if not argstr:
> +            continue
> +        if first:
> +            first = False
> +        else:
> +            yield sep
> +        yield argstr
> +
>  @templatefunc('label(label, expr)')

Moved the definition next to rstdoc().

Patch

diff -r 8eba4cdcfd81 -r 9a9fd3c8c843 mercurial/help/templates.txt
--- a/mercurial/help/templates.txt	Sun Apr 17 12:31:06 2016 +0900
+++ b/mercurial/help/templates.txt	Tue May 03 09:49:54 2016 -0700
@@ -81,6 +81,10 @@ 
 
    $ hg log -r 0 --template "files: {join(files, ', ')}\n"
 
+- Separate non-empty arguments by a " "::
+
+   $ hg log -r 0 --template "{separate(' ', node, bookmarks, tags}\n"
+
 - Modify each line of a commit description::
 
    $ hg log --template "{splitlines(desc) % '**** {line}\n'}"
diff -r 8eba4cdcfd81 -r 9a9fd3c8c843 mercurial/templater.py
--- a/mercurial/templater.py	Sun Apr 17 12:31:06 2016 +0900
+++ b/mercurial/templater.py	Tue May 03 09:49:54 2016 -0700
@@ -621,6 +621,25 @@ 
             yield joiner
         yield x
 
+@templatefunc('separate(sep, args)')
+def separate(context, mapping, args):
+    """Add a separator between non-empty arguments."""
+    if not args:
+        # i18n: "separate" is a keyword
+        raise error.ParseError(_("separate expects at least one argument"))
+
+    sep = evalstring(context, mapping, args[0])
+    first = True
+    for arg in args[1:]:
+        argstr = evalstring(context, mapping, arg)
+        if not argstr:
+            continue
+        if first:
+            first = False
+        else:
+            yield sep
+        yield argstr
+
 @templatefunc('label(label, expr)')
 def label(context, mapping, args):
     """Apply a label to generated content. Content with
diff -r 8eba4cdcfd81 -r 9a9fd3c8c843 tests/test-command-template.t
--- a/tests/test-command-template.t	Sun Apr 17 12:31:06 2016 +0900
+++ b/tests/test-command-template.t	Tue May 03 09:49:54 2016 -0700
@@ -3320,6 +3320,15 @@ 
   hg: parse error: pad() expects an integer width
   [255]
 
+Test separate function
+
+  $ hg log -r 0 -T '{separate("-", "", "a", "b", "", "", "c", "")}\n'
+  a-b-c
+  $ hg log -r 0 -T '{separate(" ", "{rev}:{node|short}", author|user, branch)}\n'
+  0:f7769ec2ab97 test default
+  $ hg log -r 0 --color=always -T '{separate(" ", "a", label(red, "b"), "c", label(red, ""), "d")}\n'
+  a \x1b[0;31mb\x1b[0m c d (esc)
+
 Test ifcontains function
 
   $ hg log --template '{rev} {ifcontains(rev, "2 two 0", "is in the string", "is not")}\n'