Patchwork [3,of,4,V2] templater: introduce word function

login
register
mail settings
Submitter Ryan McElroy
Date June 30, 2014, 8:16 a.m.
Message ID <ef4d286cea6073a99bc1.1404116181@nexus.gateway.2wire.net>
Download mbox | patch
Permalink /patch/5080/
State Superseded
Commit 8f23f80966062bf29e07f8b6c3dc86d7a618286a
Headers show

Comments

Ryan McElroy - June 30, 2014, 8:16 a.m.
# HG changeset patch
# User Ryan McElroy <rmcelroy@fb.com>
# Date 1402621343 25200
#      Thu Jun 12 18:02:23 2014 -0700
# Node ID ef4d286cea6073a99bc1b6196dc35627ee89ad8e
# Parent  761db1c368e2765cb485789eb4d237dad32c76c4
templater: introduce word function

This function allows returning only the nth "word" from a string. By default
a string is split as by Python's split() function default, but an optional
third parameter can also override what string the string is split by.
Pierre-Yves David - July 1, 2014, 11:43 a.m.
On 06/30/2014 10:16 AM, Ryan McElroy wrote:
> # HG changeset patch
> # User Ryan McElroy <rmcelroy@fb.com>
> # Date 1402621343 25200
> #      Thu Jun 12 18:02:23 2014 -0700
> # Node ID ef4d286cea6073a99bc1b6196dc35627ee89ad8e
> # Parent  761db1c368e2765cb485789eb4d237dad32c76c4
> templater: introduce word function

I've pushed 1-2 and 4. But I've some feedback on this one that could 
justify a V3.

(queued)

>
> This function allows returning only the nth "word" from a string. By default
> a string is split as by Python's split() function default, but an optional
> third parameter can also override what string the string is split by.
>
> diff -r 761db1c368e2 -r ef4d286cea60 mercurial/help/templates.txt
> --- a/mercurial/help/templates.txt	Thu Jun 12 17:53:37 2014 -0700
> +++ b/mercurial/help/templates.txt	Thu Jun 12 18:02:23 2014 -0700
> @@ -72,6 +72,8 @@
>
>   - sub(pat, repl, expr)
>
> +- word(number, text[, separator])
> +
>   Also, for any expression that returns a list, there is a list operator:
>
>   - expr % "{template}"
> @@ -130,3 +132,7 @@
>   - Show only commit descriptions that start with "template"::
>
>      $ hg log --template "{startswith(\"template\", firstline(desc))}\n"
> +
> +- Print the first word of each line of a commit message::
> +
> +   $ hg log --template "{word(\"0\", desc)}\n"
> diff -r 761db1c368e2 -r ef4d286cea60 mercurial/templater.py
> --- a/mercurial/templater.py	Thu Jun 12 17:53:37 2014 -0700
> +++ b/mercurial/templater.py	Thu Jun 12 18:02:23 2014 -0700
> @@ -477,6 +477,24 @@
>       return ''
>
>
> +def word(context, mapping, args):
> +    """return nth word from a string"""
> +    if len(args) != 2 and len(args) != 3:

(small nit) Could be `if len(args) not in (2, 3):` or `if not 2 <= 
len(args) <= 3:`

> +        raise error.ParseError(_("word expects two or three arguments"))

We could adds "(got %i)" in this message to help people spotting the error.

The error message does not seems tested.

Patch

diff -r 761db1c368e2 -r ef4d286cea60 mercurial/help/templates.txt
--- a/mercurial/help/templates.txt	Thu Jun 12 17:53:37 2014 -0700
+++ b/mercurial/help/templates.txt	Thu Jun 12 18:02:23 2014 -0700
@@ -72,6 +72,8 @@ 
 
 - sub(pat, repl, expr)
 
+- word(number, text[, separator])
+
 Also, for any expression that returns a list, there is a list operator:
 
 - expr % "{template}"
@@ -130,3 +132,7 @@ 
 - Show only commit descriptions that start with "template"::
 
    $ hg log --template "{startswith(\"template\", firstline(desc))}\n"
+
+- Print the first word of each line of a commit message::
+
+   $ hg log --template "{word(\"0\", desc)}\n"
diff -r 761db1c368e2 -r ef4d286cea60 mercurial/templater.py
--- a/mercurial/templater.py	Thu Jun 12 17:53:37 2014 -0700
+++ b/mercurial/templater.py	Thu Jun 12 18:02:23 2014 -0700
@@ -477,6 +477,24 @@ 
     return ''
 
 
+def word(context, mapping, args):
+    """return nth word from a string"""
+    if len(args) != 2 and len(args) != 3:
+        raise error.ParseError(_("word expects two or three arguments"))
+
+    num = int(stringify(args[0][0](context, mapping, args[0][1])))
+    text = stringify(args[1][0](context, mapping, args[1][1]))
+    if len(args) == 3:
+        splitter = stringify(args[2][0](context, mapping, args[2][1]))
+    else:
+        splitter = None
+
+    tokens = text.split(splitter)
+    if num >= len(tokens):
+        return ''
+    else:
+        return tokens[num]
+
 methods = {
     "string": lambda e, c: (runstring, e[1]),
     "rawstring": lambda e, c: (runrawstring, e[1]),
@@ -504,6 +522,7 @@ 
     "startswith": startswith,
     "strip": strip,
     "sub": sub,
+    "word": word,
 }
 
 # template engine
diff -r 761db1c368e2 -r ef4d286cea60 tests/test-command-template.t
--- a/tests/test-command-template.t	Thu Jun 12 17:53:37 2014 -0700
+++ b/tests/test-command-template.t	Thu Jun 12 18:02:23 2014 -0700
@@ -1911,3 +1911,51 @@ 
   |
   o  line 1
      line 2
+
+Test word function (including index out of bounds graceful failure)
+
+  $ hg log -Gv -R a --template "{word('1', desc)}"
+  @
+  |
+  o
+  |
+  o
+  
+  o
+  |\
+  | o  head
+  | |
+  o |  branch
+  |/
+  o  user,
+  |
+  o  person
+  |
+  o  1
+  |
+  o  1
+  
+
+Test word third parameter used as splitter
+
+  $ hg log -Gv -R a --template "{word('0', desc, 'o')}"
+  @  future
+  |
+  o  third
+  |
+  o  sec
+  
+  o    merge
+  |\
+  | o  new head
+  | |
+  o |  new branch
+  |/
+  o  n
+  |
+  o  n
+  |
+  o
+  |
+  o  line 1
+     line 2