Skip to content

Commit

Permalink
templater: add special "self" variable to refer to top-level object
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yuja committed Feb 24, 2024
1 parent 50938e7 commit ab6363e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
template

Expand Down
21 changes: 21 additions & 0 deletions cli/src/template_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@ pub fn build_expression<'a, L: TemplateLanguage<'a>>(
if let Some(make) = build_ctx.local_variables.get(name) {
// Don't label a local variable with its name
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 {
build_keyword(language, build_ctx, name, node.span)
}
Expand Down Expand Up @@ -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]
fn test_boolean_cast() {
let mut env = TestTemplateEnv::default();
Expand Down
9 changes: 6 additions & 3 deletions docs/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ A couple of `jj` commands accept a template via `-T`/`--template` option.
## Keywords

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

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

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

Expand Down

0 comments on commit ab6363e

Please sign in to comment.