Skip to content
Tim Vergenz edited this page Mar 14, 2025 · 18 revisions

Configuring Starship to call jj

https://starship.rs/ is a cross-shell prompt.

For some info about the jj change you are currently at you can use:

[custom.jj]
command = '''
jj log -r@ -n1 --ignore-working-copy --no-graph --color always  -T '
  separate(" ",
    bookmarks.map(|x| if(
        x.name().substr(0, 10).starts_with(x.name()),
        x.name().substr(0, 10),
        x.name().substr(0, 9) ++ "…")
      ).join(" "),
    tags.map(|x| if(
        x.name().substr(0, 10).starts_with(x.name()),
        x.name().substr(0, 10),
        x.name().substr(0, 9) ++ "…")
      ).join(" "),
    surround("\"","\"",
      if(
         description.first_line().substr(0, 24).starts_with(description.first_line()),
         description.first_line().substr(0, 24),
         description.first_line().substr(0, 23) ++ "…"
      )
    ),
    if(conflict, "conflict"),
    if(divergent, "divergent"),
    if(hidden, "hidden"),
  )
'
'''
when = "jj root"
symbol = "jj"

[custom.jjstate]
when = "jj root"
command = '''
jj log -r@ -n1 --no-graph -T "" --stat | tail -n1 | sd "(\d+) files? changed, (\d+) insertions?\(\+\), (\d+) deletions?\(-\)" ' ${1}m ${2}+ ${3}-' | sd " 0." ""
'''

Tip

You can add the --ignore-working-copy flag to the jj root call, which tells jj not to update its snapshot of the working copy, to improve performance of the when check.

This is partially inspired by the Fish Shell prompt example. This is a quick solution, feel free to improve on it and share your improvements.

Example screenshot:

image

Here's an alternate configuration. Importantly, by setting when to true and combining jj root && jj log ... directly into command, we can move from two (very expensive!) shell invocations down to one.

# custom module for jj status
[custom.jj]
ignore_timeout = true
description = "current jj status"
symbol = ""
when = true
command = '''
jj root > /dev/null && jj log --revisions @ --no-graph --ignore-working-copy --color always --limit 1 --template '
  separate(" ",
    "🥋",
    change_id.shortest(4),
    bookmarks,
    "|",
    concat(
      if(conflict, "💥"),
      if(divergent, "🚧"),
      if(hidden, "👻"),
      if(immutable, "🔒"),
    ),
    raw_escape_sequence("\x1b[1;32m") ++ if(empty, "(empty)"),
    raw_escape_sequence("\x1b[1;32m") ++ if(description.first_line().len() == 0,
      "(no description set)",
      if(description.first_line().substr(0, 29) == description.first_line(),
        description.first_line(),
        description.first_line().substr(0, 29) ++ "…",
      )
    ) ++ raw_escape_sequence("\x1b[0m"),
  )
'
'''

# disable git modules
[git_state]
disabled = true

[git_commit]
disabled = true

[git_metrics]
disabled = true

[git_branch]
disabled = true

# re-enable git_branch as long as we're not in a jj repo
[custom.git_branch]
when = true
command = "jj root >/dev/null 2>&1 || starship module git_branch"
description = "Only show git_branch if we're not in a jj repo"

Example screenshot:

image

Using starship-jj in Starship

starship-jj uses the jj-cli crate to have better performance than having multiple jj invocations in your starship.toml

https://gitlab.com/Lanastara/starship-jj

install via

  cargo install starship-jj --locked

and add it to your starship.toml

format="""
...
${custom.jj}\
...
"""

#...

[custom.jj]
command='''starship-jj --ignore-working-copy starship prompt'''
format = "[$symbol](blue bold) $output "
symbol = "󱗆 "
when = "jj root --ignore-working-copy"
Clone this wiki locally