ok/jj
1
0
Fork 0
forked from mirrors/jj
jj/docs/templates.md
Anton Bulakh 82923afcc5 templater: add root keyword
Similar to other boolean flags, such as "working_copy" or "empty".
We could test something like
`"0000000000000000000000000000000000000000".contains(commit_id)`
like I did for myself, but first of all this is ugly, and secondly the root
commit id is not guaranteed to be 40 zeroes as custom backend implementations
could have some other root.
2023-08-15 18:54:59 +03:00

185 lines
4.8 KiB
Markdown

# Templates
Jujutsu supports a functional language to customize output of commands.
The language consists of literals, keywords, operators, functions, and
methods.
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.
### Commit keywords
The following keywords can be used in `jj log`/`jj obslog` templates.
* `description: String`
* `change_id: ChangeId`
* `commit_id: CommitId`
* `parents: List<Commit>`
* `author: Signature`
* `committer: Signature`
* `working_copies: String`: For multi-workspace repository, indicate
working-copy commit as `<workspace name>@`.
* `current_working_copy: Boolean`: True for the working-copy commit of the
current workspace.
* `branches: String`
* `tags: String`
* `git_refs: String`
* `git_head: String`
* `divergent: Boolean`: True if the commit's change id corresponds to multiple
visible commits.
* `hidden: Boolean`: True if the commit is not visible (a.k.a. abandoned).
* `conflict: Boolean`: True if the commit contains merge conflicts.
* `empty: Boolean`: True if the commit modifies no files.
* `root: Boolean`: True if the commit is the root commit.
### Operation keywords
The following keywords can be used in `jj op log` templates.
* `current_operation: Boolean`
* `description: String`
* `id: OperationId`
* `tags: String`
* `time: TimestampRange`
* `user: String`
## Operators
The following operators are supported.
* `x.f()`: Method call.
* `x ++ y`: Concatenate `x` and `y` templates.
## Global functions
The following functions are defined.
* `fill(width: Integer, content: Template) -> Template`: Fill lines at
the given `width`.
* `indent(prefix: Template, content: Template) -> Template`: Indent
non-empty lines by the given `prefix`.
* `label(label: Template, content: Template) -> Template`: Apply label to
the content. The `label` is evaluated as a space-separated string.
* `if(condition: Boolean, then: Template[, else: Template]) -> Template`:
Conditionally evaluate `then`/`else` template content.
* `concat(content: Template...) -> Template`:
Same as `content_1 ++ ... ++ content_n`.
* `separate(separator: Template, content: Template...) -> Template`:
Insert separator between **non-empty** contents.
## Types
### Boolean type
No methods are defined.
### Commit type
This type cannot be printed. All commit keywords are accessible as 0-argument
methods.
### CommitId / ChangeId type
The following methods are defined.
* `.short([len: Integer]) -> String`
* `.shortest([min_len: Integer]) -> ShortestIdPrefix`: Shortest unique prefix.
### Integer type
No methods are defined.
### List type
The following methods are defined.
* `.join(separator: Template) -> Template`: Concatenate elements with
the given `separator`.
* `.map(|item| expression) -> ListTemplate`: Apply template `expression`
to each element. Example: `parents.map(|c| c.commit_id().short())`
### ListTemplate type
The following methods are defined. See also the `List` type.
* `.join(separator: Template) -> Template`
### OperationId type
The following methods are defined.
* `.short([len: Integer]) -> String`
### ShortestIdPrefix type
The following methods are defined.
* `.prefix() -> String`
* `.rest() -> String`
* `.upper() -> ShortestIdPrefix`
* `.lower() -> ShortestIdPrefix`
### Signature type
The following methods are defined.
* `.name() -> String`
* `.email() -> String`
* `.username() -> String`
* `.timestamp() -> Timestamp`
### String type
A string can be implicitly converted to `Boolean`. The following methods are
defined.
* `.contains(needle: Template) -> Boolean`
* `.first_line() -> String`
* `.lines() -> List<String>`: Split into lines excluding newline characters.
* `.upper() -> String`
* `.lower() -> String`
### Template type
Most types can be implicitly converted to `Template`. No methods are defined.
### Timestamp type
The following methods are defined.
* `.ago() -> String`: Format as relative timestamp.
* `.format(format: String) -> String`: Format with [the specified strftime-like
format string](https://docs.rs/chrono/latest/chrono/format/strftime/).
### TimestampRange type
The following methods are defined.
* `.start() -> Timestamp`
* `.end() -> Timestamp`
* `.duration() -> String`
## Configuration
[The default templates and aliases](../src/config/templates.toml) are defined
in the `[templates]` and `[template-aliases]` sections respectively.
New keywords and functions can be defined as aliases, by using any
combination of the predefined keywords/functions and other aliases.
For example:
```toml
[template-aliases]
'commit_change_ids' = '''
concat(
format_field("Commit ID", commit_id),
format_field("Change ID", commit_id),
)
'''
'format_field(key, value)' = 'key ++ ": " ++ value ++ "\n"'
```