Skip to content

Commit 272955f

Browse files
committed
templater: add .escape_json method to string
1 parent e83b328 commit 272955f

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
3636
`ellipsis` parameter; passing this prepends or appends the ellipsis to the
3737
content if it is truncated to fit the maximum width.
3838

39+
* Templates now support additional string method `.escape_json(x)` which serializes
40+
the string in JSON format. It is useful for making machine-readable templates
41+
by escaping problematic characters like `\n`.
42+
3943
### Fixed bugs
4044

4145
* `jj status` now shows untracked files under untracked directories.

cli/src/template_builder.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,14 @@ fn builtin_string_methods<'a, L: TemplateLanguage<'a> + ?Sized>(
895895
Ok(L::wrap_string(out_property))
896896
},
897897
);
898+
map.insert(
899+
"escape_json",
900+
|_language, _diagnostics, _build_ctx, self_property, function| {
901+
function.expect_no_arguments()?;
902+
let out_property = self_property.map(|s| serde_json::to_string(&s).unwrap());
903+
Ok(L::wrap_string(out_property))
904+
},
905+
);
898906
map
899907
}
900908

@@ -2659,6 +2667,9 @@ mod tests {
26592667
// ranges with end > start are empty
26602668
insta::assert_snapshot!(env.render_ok(r#""abcdef".substr(4, 2)"#), @"");
26612669
insta::assert_snapshot!(env.render_ok(r#""abcdef".substr(-2, -4)"#), @"");
2670+
2671+
insta::assert_snapshot!(env.render_ok(r#""hello".escape_json()"#), @r#""hello""#);
2672+
insta::assert_snapshot!(env.render_ok(r#""he \n ll \n \" o".escape_json()"#), @r#""he \n ll \n \" o""#);
26622673
}
26632674

26642675
#[test]

docs/templates.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ defined.
318318
* `.substr(start: Integer, end: Integer) -> String`: Extract substring. The
319319
`start`/`end` indices should be specified in UTF-8 bytes. Negative values
320320
count from the end of the string.
321+
* `.escape_json() -> String`: Serializes the string in JSON format. This
322+
function is useful for making machine-readable templates. For example, you
323+
can use it in a template like `"{ \"foo\": " ++ self.foo().escape_json() ++ "}"` to
324+
return a JSON/JSONL.
325+
321326

322327
#### String literals
323328

0 commit comments

Comments
 (0)