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.
This commit is contained in:
Ryan McElroy 2014-06-12 18:02:23 -07:00
parent 6fe5bc8cca
commit 2464893018
3 changed files with 84 additions and 0 deletions

View File

@ -72,6 +72,8 @@ In addition to filters, there are some basic built-in functions:
- 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 @@ Some sample command line templates:
- 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"

View File

@ -477,6 +477,25 @@ def startswith(context, mapping, args):
return ''
def word(context, mapping, args):
"""return nth word from a string"""
if not (2 <= len(args) <= 3):
raise error.ParseError(_("word expects two or three arguments, got %d")
% len(args))
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 +523,7 @@ funcs = {
"startswith": startswith,
"strip": strip,
"sub": sub,
"word": word,
}
# template engine

View File

@ -1917,3 +1917,61 @@ Test bad template with better error message
$ hg log -Gv -R a --template '{desc|user()}'
hg: parse error: expected a symbol, got 'func'
[255]
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
Test word error messages for not enough and too many arguments
$ hg log -Gv -R a --template "{word('0')}"
hg: parse error: word expects two or three arguments, got 1
[255]
$ hg log -Gv -R a --template "{word('0', desc, 'o', 'h', 'b', 'o', 'y')}"
hg: parse error: word expects two or three arguments, got 7
[255]