forked from mirrors/jj
templater: add special "self" variable to refer to top-level object
This allows us to call alias function with the top-level object. For convenience, all self.<method>()s are available as keywords. I don't think we'll want to deprecate them. It would be tedious if we had to specify -T'self.commit_id()' instead of -Tcommit_id.
This commit is contained in:
parent
ff37b07d90
commit
7525fac12a
3 changed files with 30 additions and 3 deletions
|
@ -37,6 +37,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
* Templates now support logical operators: `||`, `&&`, `!`
|
* Templates now support logical operators: `||`, `&&`, `!`
|
||||||
|
|
||||||
|
* Templates now support the `self` keyword, which is the current commit in `jj
|
||||||
|
log`/`obslog` templates.
|
||||||
|
|
||||||
* `jj show` now accepts `-T`/`--template` option to render its output using
|
* `jj show` now accepts `-T`/`--template` option to render its output using
|
||||||
template
|
template
|
||||||
|
|
||||||
|
|
|
@ -866,6 +866,9 @@ pub fn build_expression<'a, L: TemplateLanguage<'a>>(
|
||||||
if let Some(make) = build_ctx.local_variables.get(name) {
|
if let Some(make) = build_ctx.local_variables.get(name) {
|
||||||
// Don't label a local variable with its name
|
// Don't label a local variable with its name
|
||||||
Ok(Expression::unlabeled(make()))
|
Ok(Expression::unlabeled(make()))
|
||||||
|
} else if *name == "self" {
|
||||||
|
// "self" is a special variable, so don't label it
|
||||||
|
Ok(Expression::unlabeled(language.build_self()))
|
||||||
} else {
|
} else {
|
||||||
build_keyword(language, build_ctx, name, node.span)
|
build_keyword(language, build_ctx, name, node.span)
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1318,24 @@ mod tests {
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_self_keyword() {
|
||||||
|
let mut env = TestTemplateEnv::default();
|
||||||
|
env.add_keyword("say_hello", |language| {
|
||||||
|
language.wrap_string(Literal("Hello".to_owned()))
|
||||||
|
});
|
||||||
|
|
||||||
|
insta::assert_snapshot!(env.render_ok(r#"self.say_hello()"#), @"Hello");
|
||||||
|
insta::assert_snapshot!(env.parse_err(r#"self"#), @r###"
|
||||||
|
--> 1:1
|
||||||
|
|
|
||||||
|
1 | self
|
||||||
|
| ^--^
|
||||||
|
|
|
||||||
|
= Expected expression of type "Template"
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_boolean_cast() {
|
fn test_boolean_cast() {
|
||||||
let mut env = TestTemplateEnv::default();
|
let mut env = TestTemplateEnv::default();
|
||||||
|
|
|
@ -9,17 +9,20 @@ A couple of `jj` commands accept a template via `-T`/`--template` option.
|
||||||
## Keywords
|
## Keywords
|
||||||
|
|
||||||
Keywords represent objects of different types; the types are described in
|
Keywords represent objects of different types; the types are described in
|
||||||
a follow-up section.
|
a follow-up section. In addition to context-specific keywords, the top-level
|
||||||
|
object can be referenced as `self`.
|
||||||
|
|
||||||
### Commit keywords
|
### Commit keywords
|
||||||
|
|
||||||
In `jj log`/`jj obslog` templates, all 0-argument methods of [the `Commit`
|
In `jj log`/`jj obslog` templates, all 0-argument methods of [the `Commit`
|
||||||
type](#commit-type) are available as keywords.
|
type](#commit-type) are available as keywords. For example, `commit_id` is
|
||||||
|
equivalent to `self.commit_id()`.
|
||||||
|
|
||||||
### Operation keywords
|
### Operation keywords
|
||||||
|
|
||||||
In `jj op log` templates, all 0-argument methods of [the `Operation`
|
In `jj op log` templates, all 0-argument methods of [the `Operation`
|
||||||
type](#operation-type) are available as keywords.
|
type](#operation-type) are available as keywords. For example,
|
||||||
|
`current_operation` is equivalent to `self.current_operation()`.
|
||||||
|
|
||||||
## Operators
|
## Operators
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue