mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-24 13:12:31 +00:00
templater: add fill(width, content) function
The parameter order follows indent()/label() functions, but this might be a bad idea because fill() is more likely to have optional parameters. We can instead add template.fill(width) method as well as .indent(prefix). If we take this approach, we'll probably need to add string.fill()/indent() methods, and/or implicit cast at method resolution. The good thing about the method syntax is that we can add string.refill(), etc. for free, without inventing generic labeled template functions. For #1043, I think it's better to add a config like ui.log-word-wrap = true. We could add term_width/graph_width keywords to the templater, but the implementation would be more complicated, and is difficult to use for the basic use case. Unlike Mercurial, our templater doesn't have a context map to override the graph_width stub.
This commit is contained in:
parent
ec554f6df2
commit
c52efd9df3
3 changed files with 51 additions and 0 deletions
|
@ -56,6 +56,8 @@ The following operators are supported.
|
|||
|
||||
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
|
||||
|
|
|
@ -1071,6 +1071,16 @@ fn build_global_function<'a, L: TemplateLanguage<'a>>(
|
|||
function: &FunctionCallNode,
|
||||
) -> TemplateParseResult<Expression<L::Property>> {
|
||||
let property = match function.name {
|
||||
"fill" => {
|
||||
let [width_node, content_node] = expect_exact_arguments(function)?;
|
||||
let width = expect_integer_expression(language, width_node)?;
|
||||
let content = build_expression(language, content_node)?.into_template();
|
||||
let template = ReformatTemplate::new(content, move |context, formatter, recorded| {
|
||||
let width = width.extract(context).try_into().unwrap_or(0);
|
||||
text_util::write_wrapped(formatter, recorded, width)
|
||||
});
|
||||
language.wrap_template(template)
|
||||
}
|
||||
"indent" => {
|
||||
let [prefix_node, content_node] = expect_exact_arguments(function)?;
|
||||
let prefix = build_expression(language, prefix_node)?.into_template();
|
||||
|
|
|
@ -332,6 +332,45 @@ fn test_templater_signature() {
|
|||
insta::assert_snapshot!(render(r#"author.username()"#), @"x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_templater_fill_function() {
|
||||
let test_env = TestEnvironment::default();
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
let render = |template| get_colored_template_output(&test_env, &repo_path, "@-", template);
|
||||
|
||||
insta::assert_snapshot!(
|
||||
render(r#"fill(20, "The quick fox jumps over the " ++
|
||||
label("error", "lazy") ++ " dog\n")"#),
|
||||
@r###"
|
||||
The quick fox jumps
|
||||
over the [38;5;1mlazy[39m dog
|
||||
"###);
|
||||
|
||||
// Word-wrap, then indent
|
||||
insta::assert_snapshot!(
|
||||
render(r#""START marker to help insta\n" ++
|
||||
indent(" ", fill(20, "The quick fox jumps over the " ++
|
||||
label("error", "lazy") ++ " dog\n"))"#),
|
||||
@r###"
|
||||
START marker to help insta
|
||||
The quick fox jumps
|
||||
over the [38;5;1mlazy[39m dog
|
||||
"###);
|
||||
|
||||
// Word-wrap indented (no special handling for leading spaces)
|
||||
insta::assert_snapshot!(
|
||||
render(r#""START marker to help insta\n" ++
|
||||
fill(20, indent(" ", "The quick fox jumps over the " ++
|
||||
label("error", "lazy") ++ " dog\n"))"#),
|
||||
@r###"
|
||||
START marker to help insta
|
||||
The quick fox
|
||||
jumps over the [38;5;1mlazy[39m
|
||||
dog
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_templater_indent_function() {
|
||||
let test_env = TestEnvironment::default();
|
||||
|
|
Loading…
Reference in a new issue