Commit Graph

225 Commits

Author SHA1 Message Date
Yuya Nishihara
b81b754fe6 templater: catch regexp error at sub() function
This patch splits re.sub() into re.compile() and sub() so that it can
distinguish which argument causes re.error.
2015-09-07 21:58:17 +09:00
Yuya Nishihara
606d99d1eb templater: add optional timezone argument to localdate()
The keyword extension uses "utcdate" for a different function, so we can't
add new "utcdate" filter or function. Instead, this patch extends "localdate"
to a general timezone converter.
2015-08-18 22:15:46 +09:00
Yuya Nishihara
246636f6db templater: port localdate filter to a function
It will be extended to accept a timezone argument.
2015-09-01 19:15:16 +09:00
Danek Duvall
ccade6afcc tests: work around differing hunk headers between GNU and Solaris diff
The hunk headers specifying what lines the hunk apply to differ.  They're
irrelevant to the test, so just eliminate them from the output.
2015-07-20 15:39:15 -07:00
Danek Duvall
6c0991c070 tests: use egrep with regular expression branches for compatibility
GNU grep allows you to use "a\|b" in a regular expression to match either
"a" or "b", but at least Solaris grep does not; only egrep allows for that.
And egrep considers "a+" to be "a{1,}" instead of an "a" and a literal plus
sign, so escape that as well.
2015-07-20 15:33:20 -07:00
Yuya Nishihara
4377cc9e4b templatefilters: remove redundant 'date' and 'strip' filters
These filters are defined as 'date()' and 'strip()' functions. Help messages
are moved to the corresponding functions.
2015-07-04 16:07:42 +09:00
Yuya Nishihara
cb4039a392 templater: introduce unified filter syntax for unary functions
"filter(expr)" is allowed already. This patch adds the opposite, "expr|func".
2015-07-04 16:03:36 +09:00
Yuya Nishihara
4444465461 templater: introduce one-pass parsing of nested template strings
Instead of re-parsing quoted strings as templates, the tokenizer can delegate
the parsing of nested template strings to the parser. It has two benefits:

 1. syntax errors can be reported with absolute positions
 2. nested template can use quotes just like shell: "{"{rev}"}"

It doesn't sound nice that the tokenizer recurses into the parser. We could
instead make the tokenize itself recursive, but it would be much more
complicated because we would have to adjust binding strengths carefully and
put dummy infix operators to concatenate template fragments.

Now "string" token without r"" never appears. It will be removed by the next
patch.
2015-06-15 23:11:35 +09:00
Yuya Nishihara
c95926ebb3 templater: check existence of closing brace of template string 2015-06-15 23:03:30 +09:00
Yuya Nishihara
0cf602f409 changeset_printer: display wdirrev/wdirnode values for workingctx
Because we want to eliminate "if"s in the default template, it makes sense to
display wdirrev/wdirnode values for now. wdir() is still experimental, so the
output of "log -r'wdir()'" may change in future.
2015-07-04 17:19:49 +09:00
Yuya Nishihara
2f4ec7df91 templatekw: make {rev} return wdirrev instead of None
wdirrev/wdirnode identifiers are still experimental, but {node} is mapped to
wdirnode. So {rev} should do the same for consistency.

I'm not sure if templatekw can import scmutil. If not, we should move intrev()
to node module.
2015-07-02 22:18:21 +09:00
Yuya Nishihara
950db6aab2 templatekw: apply manifest template only if ctx.manifestnode() exists
This will prevent crash by "hg log -r 'wdir()' -Tdefault". We could use the
pseudo ff... hash introduced by 187c3ec3d83f, but it isn't proven idea yet.
For now, I want to make "hg log" just works in order to test 'wdir()' revset.

Note that unlike its name, "{manifest}" is not a list of files in that
revision, but a pair of (manifestrev, manifestnode).
2015-03-14 17:58:18 +09:00
Yuya Nishihara
2dde4312da templater: remove workaround for escaped quoted string in quoted template
This patch backs out 297d563e92af which should no longer be needed.

The test for '{\"invalid\"}' is removed because the parser is permissive for
\"...\" literal.
2015-06-27 15:28:46 +09:00
Matt Mackall
b050378961 merge with stable 2015-07-01 16:33:31 -05:00
Yuya Nishihara
274728564b templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)
As of Mercurial 3.4, there were several syntax rules to process nested
template strings. Unfortunately, they were inconsistent and conflicted
each other.

 a. buildmap() rule
    - template string is _parsed_ as string, and parsed as template
    - <\"> is not allowed in nested template:
      {xs % "{f(\"{x}\")}"} -> parse error
    - template escaping <\{> is handled consistently:
      {xs % "\{x}"} -> escaped
 b. _evalifliteral() rule
    - template string is _interpreted_ as string, and parsed as template
      in crafted environment to avoid double processing of escape sequences
    - <\"> is allowed in nested template:
      {if(x, "{f(\"{x}\")}")}
    - <\{> and escape sequences in string literal in nested template are not
      handled well
 c. pad() rule
    - template string is first interpreted as string, and parsed as template,
      which means escape sequences are processed twice
    - <\"> is allowed in nested template:
      {pad("{xs % \"{x}\"}', 10)}

Because of the issue of template escaping, issue4714, 56e0b66a4c27 (in stable)
unified the rule (b) to (a). Then, 41e044cfb1ef (in default) unified the rule
(c) to (b) = (a). But they disabled the following syntax that was somewhat
considered valid.

  {if(rev, "{if(rev, \"{rev}\")}")}
  {pad("{files % \"{file}\"}", 10)}

So, this patch introduces \"...\" literal to work around the escaped-quoted
nested template strings. Because this parsing rule exists only for the backward
compatibility, it is designed to copy the behavior of old _evalifliteral() as
possible.

Future patches will introduce a better parsing rule similar to a command
substitution of POSIX shells or a string interpolation of Ruby, where extra
escapes won't be necessary at all.

  {pad("{files % "{file}"}", 10)}
        ~~~~~~~~~~~~~~~~~~
        parsed as a template, not as a string

Because <\> character wasn't allowed in a template fragment, this patch won't
introduce more breakages. But the syntax of nested templates are interpreted
differently by people, there might be unknown issues. So if we want, we could
instead remove e926f2ef639a, 72be08a15d8d and 56e0b66a4c27 from the stable
branch as the bug fixed by these patches existed for longer periods.

554d6fcc3c8, "strip single backslash before quotation mark in quoted template",
should be superseded by this patch. I'll remove it later.
2015-06-25 22:07:38 +09:00
Matt Mackall
0508027d17 merge with stable 2015-06-24 13:41:27 -05:00
Yuya Nishihara
ec7ad76871 templater: fix handling of \-escapes in raw string literals
The backslash character should start escape sequences no matter if a string is
prefixed with 'r'. They are just not interpreted as escape sequences in raw
strings. revset.tokenize() handles them correctly, but templater didn't.

https://docs.python.org/2/reference/lexical_analysis.html#string-literals
2015-06-21 13:24:43 +09:00
Yuya Nishihara
930b78aeff templater: evaluate "query" argument passed to revset()
revset() had the same issue as f921aa09b251. It crashed by passing non-string
expression.
2015-06-20 23:13:34 +09:00
Yuya Nishihara
bd614aebda templater: evaluate arguments passed to diff() appropriately
Before this patch, diff() crashed by passing non-string expression because
it didn't evaluate arguments at all.
2015-06-13 20:14:22 +09:00
Yuya Nishihara
54bbfd7f6b templater: do not preprocess template string in "if" expression (issue4714)
The problem was spotted at cd1b50e99ed8, that says "this patch invokes it
with "strtoken='rawstring'" in "_evalifliteral()", because "t" is the result
of "arg" evaluation and it should be "string-escape"-ed if "arg" is "string"
expression." This workaround is no longer valid since 72be08a15d8d introduced
strict parsing of '\{'.

Instead, we should interpret bare token as "string" or "rawstring" template.
This is what buildmap() does at parsing phase.
2015-06-08 18:14:22 +09:00
Yuya Nishihara
60069c670b templater: strictly parse leading backslashes of '{' (issue4569) (BC)
Because double backslashes are processed as a string escape sequence, '\\{'
should start the template syntax. On the other hand, r'' disables any sort
of \-escapes, so r'\{' can go either way, never start the template syntax
or always start it. I simply chose the latter, which means r'\{' is the same
as '\\{'.
2015-05-04 10:17:34 +09:00
Yuya Nishihara
6b7d953b63 templater: do not process \-escapes at parsestring() (issue4290)
This patch brings back pre-2.8.1 behavior.

The result of parsestring() is stored in templater's cache, t.cache, and then
it is parsed as a template string by compiletemplate(). So t.cache should keep
an unparsed string no matter if it is sourced from config value. Otherwise
backslashes would be processed twice.

The test vector is borrowed from 83ff877959a6.
2015-05-04 09:54:01 +09:00
Yuya Nishihara
9420a5f503 templater: fix crash by passing invalid object to date() function
"date information" is somewhat obscure, but we call it that way in
templatekw.showdate().
2015-05-03 17:33:14 +09:00
Ryan McElroy
c2a7f23bdb templater: fail more gracefully for blank strings to word 2015-04-30 12:33:36 -07:00
Jordi Gutiérrez Hermoso
772b5e72a2 template-phases: do not show description or summary if empty
This is a copy of 942d64e0a1ee, but applied to the phases template,
which is itself almost a copy of the default template.

Perhaps we should rewrite these templates to use the %include syntax
afforded by config files. This change seems a bit too big for stable,
though.
2015-04-24 14:52:12 -04:00
Jordi Gutiérrez Hermoso
103a0c6840 test-command-template: add a short description of a temporary snippet
This snippet was introduced by 942d64e0a1ee. Its purpose seems a bit
obscure without historical context.
2015-04-24 14:17:14 -04:00
Yuya Nishihara
e9b10cef87 templates-default: do not show description or summary if empty
changeset_printer shows description only if ctx.description().strip() is not
empty. The default template should do the same way.
2015-03-27 22:12:53 +09:00
Yuya Nishihara
97a7438eb1 templatefilters: add "upper" and "lower" for case conversion
Typically it will be used in patchbomb's flag template, which will be
implemented by future patches.
2015-03-30 23:54:29 +09:00
Yuya Nishihara
7be294a6b8 templater: do not reevaluate rawstring as template (BC)
The previous patch made 'string' is always interpreted as a template. So
this patch removes the special handling of r'rawstring' instead. Now r''
disables template processing at all.
2015-06-10 21:44:43 +09:00
Yuya Nishihara
d95129ee92 templater: take any string literals as template, but not for rawstring (BC)
This patch series is intended to unify the interpretation of string literals.
It is breaking change that boldly assumes

 a. string literal "..." never contains template-like fragment or it is
    intended to be a template
 b. we tend to use raw string literal r"..." for regexp pattern in which "{"
    should have different meaning

Currently, we don't have a comprehensible rule how string literals are
evaluated in template functions. For example, fill() takes "initialindent"
and "hangindent" as templates, but not for "text", whereas "text" is a
template in pad() function.

  date(date, fmt)
  diff(includepattern, excludepattern)
  fill(text, width, initialident: T, hangindent: T)
  get(dict, key)
  if(expr, then: T, else: T)
  ifcontains(search, thing, then: T, else: T)
  ifeq(expr1, expr2, then: T, else: T)
  indent(text, indentchars, firstline)
  join(list, sep)
  label(label: T, expr: T)
  pad(text: T, width, fillchar, right)
  revset(query, formatargs...])
  rstdoc(text, style)
  shortest(node, minlength)
  startswith(pattern, text)
  strip(text, chars)
  sub(pattern, replacement, expression: T)
  word(number, text, separator)
  expr % template: T

  T: interpret "string" or r"rawstring" as template

This patch series adjusts the rule as follows:

 a. string literal, '' or "", starts template processing (BC)
 b. raw string literal, r'' or r"", disables both \-escape and template
    processing (BC, done by subsequent patches)
 c. fragment not surrounded by {} is non-templated string

  "ccc{'aaa'}{r'bbb'}"
   ------------------  *: template
   ---                 c: string
        ---            a: template
                ---    b: rawstring

Because this can eliminate the compilation of template arguments from the
evaluation phase, "hg log -Tdefault" gets faster.

  % cd mozilla-central
  % LANG=C HGRCPATH=/dev/null hg log -Tdefault -r0:10000 --time > /dev/null
  before: real 4.870 secs (user 4.860+0.000 sys 0.010+0.000)
  after:  real 3.480 secs (user 3.440+0.000 sys 0.030+0.000)

Also, this will allow us to parse nested templates at once for better error
indication.
2015-06-13 19:49:54 +09:00
Matt Mackall
a42ba8607a merge with stable 2015-06-15 13:31:22 -05:00
Matt Mackall
ac615a6f29 merge with stable 2015-03-16 13:41:45 -05:00
Yuya Nishihara
990aa241a1 templates: fix "log -q" output of default style
It was changed at ad92c202bbcd unintentionally due to name conflicts.
2015-03-14 22:34:27 +09:00
Yuya Nishihara
4c5195bbaa templatekw: fix {join(bookmarks, sep)} to always show associated bookmarks
The default joinfmt, "x.values()[0]", can't be used here because it picks
either 'bookmark' or 'current' randomly.

I got wrong result with PYTHONHASHSEED=1 on my amd64 machine.
2015-02-18 22:17:35 +09:00
Yuya Nishihara
d3b4291296 templater: allow piping generator-type function output to filters
Template functions use "yield"s assuming that the result will be combined
into a string, which means both "f -> str" and "f -> generator" should behave
in the same way.

Before this patch, piping generator function resulted in a cryptic error.
We had to insert "|stringify" in this case.

  $ hg log --template '{if(author, author)|user}\n'
  abort: template filter 'userfilter' is not compatible with keyword
  '[(<function runsymbol at 0x7f5af2e8d8c0>, 'author'),
    (<function runsymbol at 0x7f5af2e8d8c0>, 'author')]'
2015-02-24 00:04:55 +09:00
Yuya Nishihara
f407d33cc5 templatekw: forward _hybrid.get to raw values so that get(extras, key) works
fffa7616be9d implies that the primary goal is to allow "{get(extras, key)}",
but it didn't work.

I'm not sure if _hybrid should forward all unknown attributes to values, so
only "get" is forwarded for now.
2015-02-18 23:17:52 +09:00
Yuya Nishihara
3a37788d5b templater: implement _hybrid.__contains__ so that ifcontains can accept dict
7678263f920c is fine for "{revset()}", but "i.values()[0]" does not work if
each item has more than one values such as "{bookmarks}".

This fixes the problem by using list.__contains__ or dict.__contains__
appropriately.
2015-02-18 23:01:33 +09:00
Matt Mackall
80c883c82a merge with stable 2015-01-06 18:18:28 -06:00
Gregory Szorc
73fa937531 cmdutil.jsonchangeset: properly compute added and removed files
jsonchangeset._show() was computing the reverse status of the current
changeset. As a result, added files were showing up as removed and
removed files were showing up as adds.

There were existing tests for this code and they were flat out wrong.
2015-01-05 22:18:55 -08:00
Yuya Nishihara
652eea814d templater: make pad function evaluate both string and rawstring templates
"pad" function and "rawstring" type were introduced in parallel, 89145c35f76e
in default and cd1b50e99ed8 in stable respectively. Therefore, "pad" function
lacked handling of "rawstring" unintentionally.
2015-06-08 18:48:45 +09:00
Matt Mackall
7e65687d44 merge with stable 2015-06-09 13:21:20 -05:00
Ryan McElroy
dbe0173b5a templater: introduce indent function 2015-04-04 01:03:52 -07:00
Ryan McElroy
f73efddf9c commands: rename current to active in variables and comments
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
2015-05-28 20:06:19 -07:00
Ryan McElroy
7cd7aaf7a6 templatekw: introduce active subkeyword from bookmarks keyword
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
2015-05-28 20:03:42 -07:00
Ryan McElroy
1729fe1e93 templatekw: replace currentbookmark with activebookmark keyword
Today, the terms 'active' and 'current' are interchangeably used throughout the
codebase in reference to the active bookmark (the bookmark that will be updated
with the next commit). This leads to confusion among developers and users.
This patch is part of a series to standardize the usage to 'active' throughout
the mercurial codebase and user interface.
2015-04-15 08:19:36 -07:00
Jordi Gutiérrez Hermoso
27937c03a4 map-cmdline.bisect: rewrite to just %include the default template
This also adds labels to the output, as the tests now show.

I took the liberty to give two labels to the bisection status, just
like revisions get the log.changeset and changeset.phase statuses.
2015-05-10 13:48:10 -04:00
Jordi Gutiérrez Hermoso
da35c599bb log: add a status template
It appears that git users like having a --name-status option on `git
log`. There exist at least three questions on StackOverflow on how to
do this for hg. The desired output is not difficult to build with
templates, and since this is something that svn users might also want,
it seems desirable to have this as another standard template.

This mimics the output of `hg status` and adds it to the log output.
It also follows status's convention of displaying copies with a -C
option. Brief example:

    $ hg log -T status -C
    changeset:   24883:7d1b9b7ac9fd
    bookmark:    statustemplate
    tag:         tip
    parent:      24864:a08f05e3a9cf
    user:        Jordi Gutiérrez Hermoso <jordigh@octave.org>
    date:        Wed Apr 22 14:05:04 2015 -0400
    summary:     log: add a status template
    files:
    A added
    A copied
      original
    M modified
    R removed

Of course, everything is also coloured correctly, and there are tests
to prove it.
2015-05-10 14:04:43 -04:00
Matt Mackall
442532d14b tests: fix hidden repeatability problem with age filter test
This test was corrupting later cases in mysterious ways because the
hash of the changeset was changing every day at midnight. This made it
hard to figure out why tests were consistently breaking after they
were consistently working.
2015-05-12 12:33:42 -05:00
Yuya Nishihara
d32b63ddfe templater: update error message of invalid number passed to word() function
"word(3, desc)" is valid now.
2015-05-02 15:49:38 +09:00
Yuya Nishihara
c9018b3968 templater: tokenize decimal integer literal (issue4638) (BC)
Before this patch, we had to quote integer literals to pass to template
functions. It was error-prone, so we should allow "word(0, x)" syntax.
Currently only decimal integers are allowed. It's easy to support 0x, 0b and 0
prefixes, but I don't think they are useful.

This patch assumes that template keywords and names defined in map files do
not start with digits, except for positional variables seen in the schemes
extension.
2015-05-01 20:43:55 +09:00
Jordi Gutiérrez Hermoso
13181e1909 tests: add a new commit to test-commandline-template
This commit modifies, adds, renames, removes files all at once. It
will be mostly interesting for an upcoming test relating to the status
log template.
2015-05-05 14:45:09 -04:00
Yuya Nishihara
42c8c2abc2 templater: strip single backslash before quotation mark in quoted template
e926f2ef639a fixed the issue of double escapes, but it made the following
template fail with syntax error because of <\">. Strictly speaking, <\">
appears to be invalid in non-string part, but we are likely to escape <">
if surrounded by quotes, and we are used to write such templates by trial
and error.

  [templates]
  sl = "{tags % \"{ifeq(tag,'tip','',label('log.tag', ' {tag}'))}\"}"

So, for backward compatibility between 2.8.1 and 3.4, a single backslash
before quotation mark is stripped only in quoted template. We don't care
for <\"> in string literal in quoted template, which never worked as expected
before.

  template  result
  --------- ------------------------
  {\"\"}    parse error
  "{""}"    {""} -> <>
  "{\"\"}"  {""} -> <>
  {"\""}    {"\""} -> <">
  '{"\""}'  {"\""} -> <">
  "{"\""}"  parse error (don't care)
2015-05-08 18:11:26 +09:00
Matt Mackall
c2e038efe9 merge with stable 2015-05-07 13:47:45 -05:00
Jordi Gutiérrez Hermoso
cfeb0c0183 test-command-template: minor clarification in comment 2015-04-26 13:43:01 -04:00
Jordi Gutiérrez Hermoso
0e8593dcbc test-command-template: test the phase template more precisely
The current test that greps for "phase:" only checks that the word
"phase" is in the output, but does not test that nothing else gets
added by this template. This improves these tests by showing a unified
2015-04-28 15:29:15 -04:00
Siddharth Agarwal
bf23516938 jsonchangeset: don't honor whitespace and format-changing diffopts
JSON is meant to be parsed by computers, and format changes can break them.
2014-11-18 22:13:05 -08:00
Matt Mackall
7e6c7ddb4e merge with stable 2014-10-10 12:15:46 -05:00
Matt Mackall
8090c41031 templater: fix ifcontains when list is a string (issue4399) 2014-10-10 11:38:00 -05:00
Yuya Nishihara
525193c247 templater: fix precedence of --style and --template options
Since 266cfa7de44d, --template option is ignored if --style is specified,
which is wrong according to the doc of show_changeset():

    Display format will be the first non-empty hit of:
    1. option 'template'
    2. option 'style'
    ...
2014-09-30 23:15:56 +09:00
Jordi Gutiérrez Hermoso
49b364f72a log: rewrite default template to use labels (issue2866)
This is a complete rewrite of the default template to use labels. This
seems ultimately useless to me in most cases. The biggest benefit of
this patch to me seems to be a fairly complicated example of the
templating engine. It was a lot of hard work to figure out the precise
acceptable syntax, since it's almost undocumented. Hat tip to Steve
Losh's smartlog template, which helped me figure out a lot of the
syntax. Hopefully later I can use the present default log template
as an example for documenting the templating engine.

A test is attached. My goal was to match the --color=debug output,
which may differ slightly in newlines from the actual ANSI escape
codes output. I consider this an acceptable invisible deviation.

There seems to be a considerable slowdown with this rewrite.

Before:

    $ time hg log -T default -r .~100::. > /dev/null
    real  0m0.882s
    user  0m0.812s
    sys   0m0.064s
    $ time hg log -T default -r .~100::. > /dev/null
    real  0m0.872s
    user  0m0.796s
    sys   0m0.068s
    $ time hg log -T default -r .~100::. > /dev/null
    real  0m0.917s
    user  0m0.836s
    sys   0m0.076s

After:

    $ time hg log -T default -r .~100::. > /dev/null
    real  0m1.480s
    user  0m1.392s
    sys   0m0.072s
    $ time hg log -T default -r .~100::. > /dev/null
    real  0m1.500s
    user  0m1.400s
    sys   0m0.088s
    $ time hg log -T default -r .~100::. > /dev/null
    real  0m1.462s
    user  0m1.364s
    sys   0m0.092s

Following the maxim, "make it work, profile, make it faster, in that
order", I deem this slowdown acceptable for now.

I suspect but have not confirmed that a big slowdown comes from
calling keywords twice in the file templates, once to test the
existence of output and again to actually list the output. If so, a
simple speedup might be to improve the templating engine to cache
keywords when called more than once on the same revision.

TODO: I found a bug while working on this. The following stack traces:

    hg log -r . -T '{ifcontains(phase, "secret public", "lol", "omg")}\n'
2014-10-03 19:48:56 -04:00
Jordi Gutiérrez Hermoso
281cec5b64 templater: set the correct phase for parents
Akin to b5baef1e39f6 which did this for `hg log`, the following sets
the correct phase for the {phase} keyword when the context is a parent
of the current cset. This allows templates such as the following to be
defined,

    parent = '{label("log.parent changeset.{phase}",
                      "parent:      {rev}:{node|formatnode}")}\n'

which when called on a parent (e.g. with the `parents` template
keyword), will produce the correct phase.
2014-10-03 22:03:31 -04:00
Anton Shestakov
ca791cb0ef templater: add count template filter, plus tests
Previously there was no way of telling how much children or bookmarks or tags a
certain changeset has in a template. It was possible to tell if a changeset has
either 0 or not 0 bookmarks, but not to tell if it has 1 or 2 of them, for
example.

This filter, simply named count, makes it possible to count the number of items
in a list or the length of a string (or, anything that python's len can count).
E.g.: {children|count}, {bookmarks|count}, {file_adds|count}.

Testing the filter on node hash and shortened node hash is chosen because they
both have defined length.

As for lists of strings - children, tags and file_adds are used, because they
provide some variety and also prove that what's counted is the number of string
items in the list, and not the list stringified (they are lists of non-empty,
multi-character strings).

Additionally, revset template function is used for testing the filter, since
the combination is very flexible and will possibly be used together a lot.

(The previous version of this patch had an incorrect email subject and was
apparently lost - patchwork says the patch has been accepted, but it's not so.
The changes between that and this patch are minimal: now the filter does not
disturb the alphabetical order of function definitions and dict keys.)
2014-09-09 22:14:13 +09:00
Matt Mackall
0602ddc218 merge with stable 2014-09-30 18:22:58 -05:00
FUJIWARA Katsunori
330bc07caa templater: add "diff" template function
"diff" allows to embed changes in the target revision into template
output, even if the command itself doesn't take "--patch" option

Combination of "[committemplate]" configuration and "diff" template
function can achieve the feature like issue231 ("option to have diff
displayed in commit editor buffer")

    http://bz.selenic.com/show_bug.cgi?id=231

For example, templating below can be used to add each "diff" output
lines "HG: " prefix::

      {splitlines(diff) % 'HG: {line}\n'}

This patch implements "diff" not as "a template keyword" but as "a
template function" to take include/exclude patterns at runtime.

It allows to specify target files of command (by -I/-X command line
options) and "diff" separately.
2014-08-28 22:45:36 +09:00
Matt Mackall
7cc7319641 cmdutil: add json style to log-like commands
Sadly, this can't be done with the normal templater like we do with
XML due to JSON's inter-record comma rules.
2014-09-15 13:11:13 -05:00
FUJIWARA Katsunori
baa869750d templater: enable alias predicates to be used in "revset()" function
Before this patch, predicates defined in "[revsetalias]" can't be used
in the query specified to template function "revset()", because:

  - "revset()" uses "localrepository.revs()" to get query result, but
  - "localrepository.revs()" passes "None" as "ui" to "revset.match()", then
  - "revset.match()" can't recognize any alias predicates

To enable alias predicates to be used in "revset()" function, this
patch invokes "revset.match()" directly with "repo.ui".

This patch doesn't make "localrepository.revs()" pass "self.ui" to
"revset.match()", because this may be intentional implementation to
prevent alias predicates from shadowing built-in ones and breaking
functions internally using "localrepository.revs()".

Even if it isn't intentional one, the check for shadowing should be
implemented (maybe on default branch) before fixing it for safety.
2014-08-23 21:23:02 +09:00
Matt Mackall
f648f507dd templates: re-add template listing support
We used to have --style nosuch to list templates, but --style is now
merged with --template/-T where random strings are acceptable
templates. So we reserve 'list' to allow listing templates.
2014-07-25 15:35:09 -05:00
FUJIWARA Katsunori
843d08c987 templatekw: add 'currentbookmark' keyword to show current bookmark easily
Before this patch, complicated template expression below is required
to show current active bookmark if it is associated with the
changeset.

    "{bookmarks % '{ifeq(bookmark, current, \"{bookmark}\")}'}"

This patch add 'currentbookmark' keyword to show current bookmark
easily.
2014-07-15 23:34:13 +09:00
Ryan McElroy
2464893018 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.
2014-06-12 18:02:23 -07:00
Ryan McElroy
e3b09c4564 templater: add symbol to error
This patch makes it easier to debug writing templater functions by
telling the user exactly what was sent to the templater.
2014-06-12 18:07:21 -07:00
Ryan McElroy
f735b30979 templater: introduce startswith function
This function returns a string only if it starts with a given string.
It is particularly useful when combined with splitlines and/or used with
conditionals that fail when empty strings are passed in to take action
based on the contents of a line.
2014-06-12 17:53:37 -07:00
Ryan McElroy
9f5399cbcd templatefilter: add splitlines function
This is useful for applying changes to each line, and it's especially powerful
when used in conjunction with conditionals to modify lines based on content.
2014-06-12 17:45:41 -07:00
Durham Goode
63d5c92a11 templates: fix ifcontains against sets with length > 1 (issue4259)
Previously the ifcontains revset was checking against the set using a pure
__contains__ check.  It turns out the set was actually a list of
formatted strings meant for ui output, which meant the contains check failed if
the formatted string wasn't significantly different from the raw value.

This change makes it check against the raw data, prior to it being formatted.
2014-05-23 16:25:55 -07:00
Mads Kiilerich
0e8795ccd6 spelling: fixes from spell checker 2014-04-13 19:01:00 +02:00
Kevin Bullock
c63d1fcf68 merge with stable
This should correct an earlier couple of bad merges (5433856b2558 and
596960a4ad0d, now pruned) that accidentally brought in a change that had
been marked obsolete (244ac996a821).
2014-03-31 10:12:07 -05:00
Sean Farley
029b060498 templater: raise error for unknown func
Previously, if a template '{foo()}' was given, the buildfunc would not be able
to match it and hit a code path that would not return so it would error out
later in the templater stating that NoneType was not iterable. This patch makes
sure that a proper error is raised so that the user can be informed.

Tests have been updated.
2014-03-27 17:21:27 -05:00
FUJIWARA Katsunori
d28789bf48 templater: make strings in template expressions be "string-escape"-ed correctly
Changeset 83ff877959a6 (released with 2.8.1) fixed "recursively
evaluate string literals as templates" problem (issue4102) by moving
the location of "string-escape"-ing from "tokenizer()" to
"compiletemplate()".

But some parts in template expressions below are not processed by
"compiletemplate()", and it may cause unexpected result.

  - 'expr' of 'if(expr, then, else)'
  - 'expr's of 'ifeq(expr, expr, then, else)'
  - 'sep' of 'join(list, sep)'
  - 'text' and 'style' of 'rstdoc(text, style)'
  - 'text' and 'chars' of 'strip(text, chars)'
  - 'pat' and 'repl' of 'sub(pat, repl, expr)'

For example, '\n' of "{join(extras, '\n')}" is not "string-escape"-ed
and treated as a literal '\n'. This breaks "Display the contents of
the 'extra' field, one per line" example in "hg help templates".

Just "string-escape"-ing on each parts above may not work correctly,
because inside expression of nested ones already applies
"string-escape" on string literals. For example:

  - "{join(files, '\n')}" doesn't return "string-escape"-ed string, but
  - "{join(files, if(branch, '\n', '\n'))}" does

To fix this problem, this patch does:

  - introduce "rawstring" token and "runrawstring" method to handle
    strings not to be "string-escape"-ed correctly, and

  - make "runstring" method return "string-escape"-ed string, and
    delay "string-escape"-ing until evaluation

This patch invokes "compiletemplate()" with "strtoken=exp[0]" in
"gettemplate()", because "exp[1]" is not yet evaluated. This code path
is tested via mapping ("expr % '{template}'").

In the other hand, this patch invokes it with "strtoken='rawstring'"
in "_evalifliteral()", because "t" is the result of "arg" evaluation
and it should be "string-escape"-ed if "arg" is "string" expression.

This patch doesn't test "string-escape"-ing on 'expr' of 'if(expr,
then, else)', because it doesn't affect the result.
2014-03-10 01:01:43 +09:00
FUJIWARA Katsunori
f3e5f1e6c1 templater: apply "stringify()" on sub expression to get string correctly
Templating syntax allows nested expression to be specified as parts
below, but they are evaluated as a generator and don't work correctly.

  - 'sep' of 'join(list, sep)'
  - 'text' and 'chars' of 'strip(text, chars)'

In the former case, 'sep' returns expected string only for the first
separation, and empty one for the second or later, because the
generator has only one element.

In the latter case, templating is aborted by exception, because the
generator doesn't have 'strip()' method (as 'text') and can't be
passed as the argument to 'str.strip()' (as 'chars').

This patch applies "stringify()" on these sub expression to get string
correctly.
2014-03-10 01:01:43 +09:00
FUJIWARA Katsunori
7a7d1bc22c templater: avoid recursive evaluation of string literals completely
Changeset c84f81c3e120 (released with 2.8.1) fixed "recursively
evaluate string literals as templates" problem (issue4103) by
introducing "_evalifliteral()".

But some parts in template expressions below are still processed by
the combination of "compiletemplate()" and "runtemplate()", and may
cause same problem unexpectedly.

  - 'init' and 'hang' of 'fill(text, width, init, hang)'
  - 'expr' of 'sub(pat, repl, expr)'
  - 'label' of 'label(label, expr)'

This patch processes them by "_evalifliteral()" instead of the
combination of "compiletemplate()" and "runtemplate()" to avoid
recursive evaluation of string literals completely.
2014-03-10 01:01:42 +09:00
Matt Mackall
3672c23fd5 merge with stable 2014-03-11 16:19:08 -05:00
Matt Mackall
94e268974b templating: make -T much more flexible
It can now accept styles and paths and references to settings in
[templates].
2014-03-08 17:38:50 -06:00
Matt Mackall
a759f7ceae commands: add -T alternative to --template 2014-03-08 15:27:25 -06:00
Durham Goode
2d869e6a8e template: add 'current' to scope during {bookmarks % ...}
This adds the keyword 'current' to the template scope when processing a
bookmark list. The 'current' keyword resolves to the name of the currently
active bookmark in the repo. This allows us to apply special labels to the
current bookmark to distinguish it (especially in the case where there are
multiple bookmarks on the same commit).

Example: "{bookmarks % '{bookmark}{ifeq(bookmark, current, \"*\")} '}"

Results in a space separated list of bookmarks where the current bookmark has
an asterix.
2014-02-11 21:40:33 -08:00
Durham Goode
f8aca20bcb template: add revset() template function
Adds a template function that executes a revset and returns the list of
revisions as the result. It has the signature 'revset(query [, args...])'. The
args are optional and are applied to the query string using the standard
python string.format(args) pattern. This allows things like:
'{revset("parents({0})", rev)}' to produce the parents of each individual
commit in the log output.  If no args are specified, the revset result is
cached for the duration of the templater; so it's better to not use args if
performance is a concern.

By itself, revset() can be used to print commit parents, print the common
ancestor of a commit with the main branch, etc.

It can be used with the ifcontains() function to do things like
'{ifcontains(rev, revset('.'), label(...), ...)}' to color the working copy
parent, to color certain branches, to color draft commits, etc.
2014-02-11 21:04:12 -08:00
Durham Goode
cb61deed09 template: add ifcontains template function
Adds a template function with the signature 'ifcontains(item, set, then[,
else])'.  It can be used to do things like '{ifcontains('.hgignore',
file_mods, label(...), ...)}' to color commits that edit the .hgignore file.
A future patch will add the revset() function which will combine with
ifcontains to allow us to color commits if they are in the revset.
2014-02-11 21:10:00 -08:00
Durham Goode
fe9653ca83 template: add pad function for padding output
Adds a pad template function with the following signature:

pad(text, width, fillchar=' ', right=False)

This uses the standard python ljust and rjust functions to produce a string
that is at least a certain width. This is useful for aligning variable length
strings in log output (like user names or shortest(node) output).
2014-01-17 00:16:48 -08:00
Durham Goode
156d6da226 template: add shortest(node) template function
Adds a '{shortest(node)}' template function that results in the shortest hex node
that uniquely identifies the changeset at that time. The minimum length can be
specified as an optional second argument and defaults to 4.

This is useful for producing prettier log output, like so:

@  durham  shortestnode
|  77cf    template: add pad function for padding output
|
o  durham
|  b183    template: add shortestnode keyword
|
o  pierre-yves @
|  6545    backout: add a message after backout that need manual commit
|
| o  durham   manifestcache
|/   93f0    manifest cache
|
| o  durham   catperf
| |  c765    cat: increase perf when catting single files
| |
| o  durham
|/   9c53    changectx: increase perf of walk function
|
2014-01-17 00:10:37 -08:00
Matt Mackall
df890e8b8a merge with stable 2013-11-21 15:08:30 -06:00
Siddharth Agarwal
5b9c86b786 test-command-template.t: fix failure due to trailing whitespace 2013-11-21 12:47:03 -08:00
Matt Mackall
fb22d26dbd templater: makes branches work correctly with stringify (issue4108) 2013-11-21 11:30:52 -06:00
Matt Mackall
52dafe7a2a templater: only recursively evaluate string literals as templates (issue4103) 2013-11-18 15:37:09 -05:00
Matt Mackall
c9a233d77e templater: fix escaping in nested string literals (issue4102)
Before the templater got extended for nested expressions, it made
sense to decode string escapes across the whole string. Now we do it
on a piece by piece basis.
2013-11-18 14:02:26 -05:00
Matt Mackall
74cf3d4bf4 merge with stable 2013-11-19 11:29:56 -05:00
Matt Mackall
280eec0087 tests: skip tests that require not having root (issue4089)
This adds a new root hghave to test against. Almost all of these are a
subset of unix-permissions, but that is also used for checking exec
bit handling.
2013-11-14 18:07:43 -06:00
Matt Mackall
6e88e21cca date: allow %z in format (issue4040) 2013-11-07 15:24:23 -06:00
Alexander Plavin
38dc1f0139 templater: support using templates with non-standard names from map file
Allow to add arbitrarily-named entries to a template map file and then
reference them, to make it possible to deduplicate and simplify
templates code.
2013-09-22 13:52:18 +04:00
Alexander Plavin
10b1e709b7 templater: add strip function with chars as an extra argument
This allows specifying characters to strip, like the Python strip function.
2013-06-25 21:02:22 +04:00
Augie Fackler
40d8d30902 templater: fix output instability from gsoc patches 2013-05-02 20:41:22 -05:00
Sean Farley
766233e4bb template: call runtemplate on the src argument to sub
This allows using a template keyword on calls to the sub function and brings
the function inline with most other semantics of the other template functions.
2013-04-10 19:27:49 -05:00
Matt Mackall
7f909e9c22 templatekw: add default styles for hybrid types (issue3887)
This allows elements like file_copies to be printed as 'name (source)'
when used with join.
2013-04-16 09:44:29 -05:00
Brendan Cully
6bf5800d14 templater: back out 0da42d2ff029, it breaks schemes ({1}) 2013-04-09 21:38:08 -07:00
Brendan Cully
1c111a8da8 template: allow unquoted int function arguments 2013-04-07 23:25:50 -07:00
Matt Mackall
b88b659df4 templater: properly handle file_copies with % 2013-02-22 13:45:46 -06:00
Benoit Boissinot
487f5cb58d test-command-template.t: make "age" filter test work on Feb 29th
reported by Julien Cristau.
2013-01-02 13:59:07 +01:00
Augie Fackler
f909cd2da7 test-command-template.t: fix test so it all year
This test started failing for me after midnight UTC on December
31st. Fixed it by specifying a date 7 years in the future more
precisely (rather than just adding 8 to the year and specifying
January 1st), which allows the test to pass both now and on 2012-12-01
at the same time.
2012-12-31 21:50:35 -06:00
Matt Mackall
0dd30183db templating: make new-style templating features work with command line lists 2012-09-21 18:54:00 -05:00
Matt Mackall
3fda097fb9 tests: fix template test output 2012-08-24 14:52:45 -05:00
Bryan O'Sullivan
3234b8f8c6 Merge 2012-08-21 13:12:56 -07:00
Neil Kodner
68912667a4 templater: abort when a template filter raises an exception (issue2987) 2012-08-17 15:12:01 -07:00
Mads Kiilerich
9cddfd19ab check-code: fix check for trailing whitespace on sh command lines
The $ has been without necessary escaping since introduced in c4ecbbd282fe.
2012-08-08 18:10:16 +02:00
Ross Lagerwall
48a670fcaf templater: handle a missing value correctly
Before, using a broken style such as:
changeset =
would result in a traceback.

This fixes a regression introduced in 47618355ffc8.
2012-08-04 14:37:17 +02:00
epriestley
0e72c6b3d0 templatekw: add p1rev, p1node, p2rev, p2node keywords
The {parents} template is cumbersome for some uses, as it does not show
anything if there's only one "natural" parent and you can't use it to get the
full 40 digit node hashes for parents unless you rely on the behavior of
the --debug flag.

Introduce four new template keywords: {p1rev}, {p2rev}, {p1node} and
{p2node}. The "node" flavors of these always show full 40 digit hashes,
but users can get the short version with a filter construction like
'{p1node|short}'.
2012-07-10 08:43:32 -07:00
Adrian Buehlmann
d65f3078fe test-command-template: enable for Windows 2012-06-11 19:18:36 +02:00
Martin Geisler
1b6b741fb5 templater: handle SyntaxError when parsing ui.logtemplate
Before, Mercurial would crash with a traceback ending with

  SyntaxError: unmatched quotes

if you configured

  [ui]
  logtemplate = {rev}\n

The SyntaxError is now catched and the string is re-parsed without
requiring quotes.
2012-05-12 22:12:54 +02:00
Steven Brown
a6c2ab15fb tests: make {date|age} template output independent of the current date 2012-01-11 22:18:20 +08:00
Matt Mackall
c19e8e450d merge with stable 2012-01-03 17:13:03 -06:00
Matt Mackall
a5d2446886 tests: patch up silly new year's bug 2012-01-03 17:09:26 -06:00
Mads Kiilerich
72ebeacea3 tests: use 'hghave unix-permissions' for tests that really use chmod
chmod of helper scripts is not included.

tests that exercise the x bit in the file system uses 'hghave execbit'.
2011-11-07 03:14:55 +01:00
Peter Arrenbrecht
5fbc4a50f1 localrepo: reuse parent manifest in commitctx if no files have changed
This speeds up the in-memory version of debugbuilddag that I'm
working on considerably for the case where we want to build just
a 00changelog.i (for discovery tests, for instance).

There are a couple of test changes because node ids in tests
have changed.

The changes to the patch names in test-mq-qdelete.t were required
because they could collide with nodeid abbreviations and newly
actually do (patch "c" collides with id "cafe..." for patch "b").
2011-05-02 19:20:29 +02:00
timeless
56241a1f0c templates: provide granularity for future values for age filter 2011-03-16 03:28:56 +01:00
Matt Mackall
39437f5a68 templater: give slightly nicer error for unknown map entries 2010-12-20 12:09:00 -06:00
Eric Eisner
8113ebb989 template: add showbranch template for {branch}
Like showbranches, but always yields exactly one branch. Replaces the less
correct {branches|nonempty}.
2010-12-13 10:30:15 -05:00
Martin Geisler
3d112b3042 tests: added a short description to issue numbers
Many tests already had a short line to describe what IssueXXX is
about. I find that quite useful when reading a test.
2010-09-24 10:13:49 +02:00
Matt Mackall
08439e0f2d tests: add exit codes to unified tests 2010-09-16 17:51:32 -05:00
Adrian Buehlmann
f7441a3667 tests: unify test-command-template 2010-09-14 19:31:00 +02:00