Skip to content

Support external subcommands: rg, diff, git-show (etc.)#1769

Merged
dandavison merged 2 commits into
dandavison:mainfrom
th1000s:subcmds
Nov 29, 2024
Merged

Support external subcommands: rg, diff, git-show (etc.)#1769
dandavison merged 2 commits into
dandavison:mainfrom
th1000s:subcmds

Conversation

@th1000s

@th1000s th1000s commented Jul 22, 2024

Copy link
Copy Markdown
Collaborator
  • Support external subcommands: rg, diff, git-show (etc.)

The possible command line now is:

delta <delta-args> [SUBCMD <subcmd-args>]

If the entire command line fails to parse because SUBCMD is unknown,
then try (until the next arg fails) parsing only,
and then parse and call SUBCMD.., output is piped into delta.
Other subcommands also take precedence over the diff/git-diff mode
(delta a b, where e.g. a=show and b=HEAD), and any diff call gets
converted into an external subcommand first.

Available are:
delta rg .. => rg --json .. | delta
delta a b .. => git diff a b .. | delta
delta show .. => git <color-on> show .. | delta

And various other git-CMDS: add, blame, checkout, diff, grep, log, reflog and stash.

The piping is not done by the shell, but delta, so the subcommands
are now child processes of delta.


  • Set calling process directly because delta started it

This info then takes precedence over whatever
start_determining_calling_process_in_thread() finds or rather
doesn't find.
(The simple yet generous SeqCst is used on purpose for the atomic operations.)


Looking at the Call { Delta, .. } enum from the --help PR, and how the diff sub-command works (both how -@ is needed to add extra args, and how its ouput is fed back into delta when running as a child process) I had the idea of generalizing that.

Deltas rg integration is great, but rg --json .. | delta is a bit clunky, now it is just delta rg ... This also allows using delta without touching any git configs ("try before you edit anything"), as a proof of concept delta show is implemented here.

This is a bit ... creative with the clap command line parser, but it is all quite contained.

@dandavison

Copy link
Copy Markdown
Owner

Nice, very interesting!

  • I'm sure you considered this but is supporting delta git $subcommand a possibility also?
  • Are there any parse ambiguity challenges, e.g. if someone tries to diff a file named rg etc?

Some miscellaneous comments about subcommands; not sure how relevant to this PR:

  • there are various existing options that perhaps should be subcommands themselves, such as --show-colors, --show-config, --show-syntax-themes, --show-themes, --parse-ansi. Ought we to consider making those subcommands before 1.0?
  • Would be nice to have auto-generated shell completion for all this (I believe the trend nowadays is for that to be another subcommand, i.e. eval $(delta completion bash) Use https://crates.io/crates/clap_complete?).
  • Also maybe eval $(delta toggle side-by-side) and eval $(delta toggle line-numbers) mutating $DELTA_FEATURES?

@th1000s

th1000s commented Sep 30, 2024

Copy link
Copy Markdown
Collaborator Author

I'm sure you considered this but is supporting delta git $subcommand a possibility also?

I used --color=always, which is not accepted by all subcommands - but by calling git -c color.ui=always .. any subcommand should become callable. Just check if git-$subcommand is in $PATH.

Are there any parse ambiguity challenges, e.g. if someone tries to diff a file named rg etc?

Yes, and in that case I would give priority to the subcommand. By using ./rg this can ways be overwritten.

Some miscellaneous comments about subcommands; not sure how relevant to this PR:

there are various existing options that perhaps should be subcommands themselves, such as --show-colors, --show-config, --show-syntax-themes, --show-themes, --parse-ansi. Ought we to consider making those subcommands before 1.0?

I think these are not used that often, I would leave them as flags (these being located in src/subcommands/ notwithstanding).

Would be nice to have auto-generated shell completion for all this (I believe the trend nowadays is for that to be another subcommand, i.e. eval $(delta completion bash) Use https://crates.io/crates/clap_complete?).

Already present, see --generate-completion :) But that could also become a subcommand like that.

Also maybe eval $(delta toggle side-by-side) and eval $(delta toggle line-numbers) mutating $DELTA_FEATURES?

Sure, should be possible as well.

@th1000s th1000s changed the title Generalize delta subcommands: rg, diff (implicit), show Generalize subcommands: rg, git-show (etc.), diff Nov 5, 2024
@th1000s

th1000s commented Nov 5, 2024

Copy link
Copy Markdown
Collaborator Author

I'm sure you considered this but is supporting delta git $subcommand a possibility also?

Now also possible!

However enabling all git-X commands directly would mean checking if "git $X" is a valid git subcommand first (while parsing the command line, repeatedly), so I use a specific list:

pub const SUBCOMMANDS: &[&str] = &[RG, "show", "log", "diff", "grep", "blame", GIT];

Are there any other useful commands? Also, can you check why the rg test fails on macOS?

@th1000s th1000s requested a review from dandavison November 5, 2024 10:29
@dandavison

Copy link
Copy Markdown
Owner

"show", "log", "diff", "grep", "blame"
Are there any other useful commands?

The ones that are coming to mind are add for git add -p, and reflog and stash for git reflog -p and git stash list -p.

@dandavison

Copy link
Copy Markdown
Owner

Also, can you check why the rg test fails on macOS?

It fails because of

if grep_cli::resolve_binary("rg").is_err() {

https://docs.rs/grep-cli/latest/grep_cli/fn.resolve_binary.html

On non-Windows, this is a no-op.

This API has always seemed very surprising to me. I've opened BurntSushi/ripgrep#2928 to ask about it and maybe make the docstring clearer.

@dandavison

Copy link
Copy Markdown
Owner

I use zsh and have eval "$(delta --generate-completion zsh 2>/dev/null)" in my shell config. It looks like there might be a shell completion challenge relating to this PR: normally, a command line like rg pattern xxx<TAB> completes xxx as a file path. But delta rg pattern xxx<TAB> is not doing that.

@th1000s th1000s marked this pull request as ready for review November 11, 2024 23:14
Comment thread src/subcommands/mod.rs Outdated
// start subprocesses:
// diff (fileA, fileB), and generic subcommands
pub mod diff;
mod generic_subcmd;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That name is a bit ... generic I think. Ideas?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

external!

@th1000s

th1000s commented Nov 11, 2024

Copy link
Copy Markdown
Collaborator Author

The ones that are coming to mind are add for git add -p, and reflog and stash for git reflog -p and git stash list -p.

Done.

[The rg test fails on macOS fail] because of
https://docs.rs/grep-cli/latest/grep_cli/fn.resolve_binary.html

Oh, thanks! Never would have suspected that, re-implemented some of try_resolve_binary() (which is not public!) in an almost-one-liner for the test.

shell completion

Indeed, I have also asked myself that for simpler stuff like writing my own git-foo command, the completion has to embed itself into the existing git completion.

@dandavison

Copy link
Copy Markdown
Owner

The ones that are coming to mind are add for git add -p, and reflog and stash for git reflog -p and git stash list -p.

And one more: I recently learned of the existence of checkout -p (from #1908)

@dandavison

Copy link
Copy Markdown
Owner

there are various existing options that perhaps should be subcommands themselves, such as --show-colors, --show-config, --show-syntax-themes, --show-themes, --parse-ansi. Ought we to consider making those subcommands before 1.0?

I think these are not used that often, I would leave them as flags (these being located in src/subcommands/ notwithstanding).

Also maybe eval $(delta toggle side-by-side) and eval $(delta toggle line-numbers) mutating $DELTA_FEATURES?

Sure, should be possible as well.

Just to mention one more -- I'm attracted to adding a "doctor" command that users can run to obtain a standard suite of diagnostics describing their environment, something like the direction started in #1193. Would something like that fit with the work in this branch as a delta doctor subcommand with doctor-specific arguments?

@th1000s th1000s changed the title Generalize subcommands: rg, git-show (etc.), diff Support external subcommands: rg, diff, git-show (etc.) Nov 16, 2024
@th1000s

th1000s commented Nov 16, 2024

Copy link
Copy Markdown
Collaborator Author

checkout -p

Added.

The doctor or other subcommands can be added via clap directly, or --show-color can be become a show-color subcommand if you prefer that. These here are external (renamed it to that!) subcommands which have to side-step clap and pipe their output back into the parent process.

@dandavison dandavison left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've gone through the code changes now; all looks very nice. Please excuse/ignore the code golf suggestions -- that was just helping me get into the code.

Before we proceed let's revisit the overall argument here. For rg this is clearly an improvement: otherwise to make delta-rg integration ergonomic you have to write a shell wrapper.

Another possibility along the lines of the rg integration might be visualizing difftastic JSON output.

But what's your thinking about the utility of this for git xxx commands? delta integrates with git transparently via git's external pager mechanism, and many shell completion projects exist giving intricate completion over git commands. Is there a clear advantage to being able to invoke git commands prefixed by delta, especially given that it wouldn't have shell completion? Also, if we were to do it, are we sure that we want to inject 9 (currently) git command names into delta's top-level subcommand namespace? Or should it only support delta git xxx? delta diff in particular seems to have potentially confusing semantics given the presence of the delta a b diff. Sorry I've been slow to bring up these hesitations.

Comment thread src/cli.rs
Comment on lines +1284 to +1283
if let Some(subcmd) = &minus_file {
if let Some(arg) = subcmd.to_str() {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically just code golf, done while trying to get into the substance of the PR. Feel free to ignore.

Suggested change
if let Some(subcmd) = &minus_file {
if let Some(arg) = subcmd.to_str() {
if let Some(arg) = minus_file.as_ref().and_then(|p| p.to_str()) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait for if-let chains :)

Comment thread src/cli.rs
}
Ok(matches) => {
// subcommands take precedence over diffs
let minus_file = matches.get_one::<PathBuf>("minus_file").map(PathBuf::from);

@dandavison dandavison Nov 20, 2024

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is our support for delta file_a file_b going to cause trouble when introducing standard clap subcommands?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything clap parses takes precedence, in fact, here intervention is required to "steal" this argument from the command line parser.

Comment thread src/subcommands/external.rs Outdated
Comment on lines +59 to +64
for (i, arg) in args.iter().enumerate() {
let arg = if let Some(arg) = arg.to_str() {
arg
} else {
continue;
};

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, more code golf suggestions:

Suggested change
for (i, arg) in args.iter().enumerate() {
let arg = if let Some(arg) = arg.to_str() {
arg
} else {
continue;
};
for (i, arg) in args.iter().filter_map(|a| a.to_str()).enumerate() {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent, Done.

Comment thread src/subcommands/external.rs Outdated
SubCmdKind::Rg
} else {
SubCmdKind::Git(
args[i..]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constructs Git("git") in the case of delta git show. Is that intentional / does it matter?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the single .pop() is not enough, fixed.

Comment thread src/subcommands/external.rs Outdated
.to_string(),
)
};
subcmd.extend(args[i + 1..].iter().map(|arg| arg.into()));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More ignorable code golf:

There might be an attractive alternative way to write the above using .split_first()? The best I've come up with is

                    let invalid_placeholder = OsString::from("?");
                    let (subsubcmd, rest) = args[i..]
                        .split_first()
                        .unwrap_or((&invalid_placeholder, &[]));
                    let kind = if arg == RG {
                        SubCmdKind::Rg
                    } else {
                        SubCmdKind::Git(subsubcmd.to_string_lossy().to_string())
                    };
                    subcmd.extend(rest.iter().cloned());

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, merged with the above.

}
}

pub fn extract(args: &[OsString], orig_error: Error) -> (ArgMatches, SubCommand) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A docstring could be good. My attempt:

Suggested change
pub fn extract(args: &[OsString], orig_error: Error) -> (ArgMatches, SubCommand) {
/// Find the first arg that is a registered external subcommand and return a
/// tuple containing:
/// 0. The args prior to that point
/// 1. A SubCommand representing the external subcommand and its subsequent args
pub fn extract(args: &[OsString], orig_error: Error) -> (ArgMatches, SubCommand) {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread src/cli.rs
Err(e) => {
e.exit();
// Calls `e.exit()` if error persists.
let (matches, subcmd) = subcommands::extract(args, e);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clever...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that... praise? It must be, so elegant!

Comment thread src/main.rs Outdated
}
let mut cmd = cmd.unwrap();

let cmd_stdout = cmd.stdout.as_mut().expect("Failed to open stdout");

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a so-far-upheld tradition of using unwrap_or_else(|| panic(...)) because of my personal belief that expect() is confusing as reader and author, but I'd certainly understand if you wished to discontinue that tradition.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@dandavison

dandavison commented Nov 21, 2024

Copy link
Copy Markdown
Owner

This is slightly off-topic because I think this would be an internal rather than an external subcommand, but I just found myself doing delta /dev/null path/to/myfile in order to "cat" a file but with delta's hyperlinked line numbers (which I have set up to open in my IDE). So perhaps that suggests delta cat might be another entry in our subcommand namespace, with the green background color disabled, and the minus line number column removed.

@th1000s

th1000s commented Nov 26, 2024

Copy link
Copy Markdown
Collaborator Author

Apart from delta rg, the other commands mostly make trying out delta easier. But yes, they could just as well sit behind git for that. And I am not even against the redundant diff command, because well, a diff is a diff, and a delta is something not-quite-a-diff. But whatever you prefer.

I sometimes try to use delta 0123.patch, which doesn't work, until I remember delta < 0123.patch also does the job. Maybe default to something like that for a single argument?

@dandavison

Copy link
Copy Markdown
Owner

Apart from delta rg, the other commands mostly make trying out delta easier. But yes, they could just as well sit behind git for that.

Let's make them sit behind git for now. We can then watch how our subcommand namespace evolves, and of course it would always be possible to revisit the decision in the future.

@th1000s

th1000s commented Nov 27, 2024

Copy link
Copy Markdown
Collaborator Author

Done.

This is untested on Windows, but the process logic is from subcommands/diff.rs so I don't expect surprises so feel free to merge.

@dandavison

dandavison commented Nov 28, 2024

Copy link
Copy Markdown
Owner

Apologies if the problem is at my end but I think that something might have gone wrong in the last change? When I do delta git show xxx it looks like the show is being popped out of the command, yielding git -c color.ui=always xxx. I'm guessing related to that double "git" thing we were discussing above?

@th1000s th1000s force-pushed the subcmds branch 2 times, most recently from 482affb to 53ae80c Compare November 28, 2024 22:56
@th1000s

th1000s commented Nov 28, 2024

Copy link
Copy Markdown
Collaborator Author

No, you are perfectly right! Fixed, and not just testing rg but also git now. That was some hasty last-minute refactoring. Refactored that part again, the logic is much cleaner now.

Ah, the test doesn't work because the CI runners do a shallow --depth=1 clone, fix. And a new clippy with Rust v1.83, with a false positive zombie warning...

The possible command line now is:

  delta <delta-args> [SUBCMD <subcmd-args>]

If the entire command line fails to parse because SUBCMD is unknown,
then try (until the next arg fails) parsing <delta-args> only,
and then parse and call SUBCMD with args, its output is piped into
delta.  Other subcommands also take precedence over the diff/git-diff
mode (`delta a b`, where e.g. a=git and b=show), and any diff call gets
converted into an external subcommand first.

Available are:
  delta rg ..       => rg --json .. | delta
  delta a b ..      => git diff --no-index a b .. | delta
  delta git show .. => git <color-on> show .. | delta

and all other git-CMDS, of which
add -p, blame, checkout -p, diff, grep, log -p, reflog -p, and stash show -p
produce a diff.

Because --json is automatically added for `delta rg ..`, it avoids the
parsing ambiguities of and is easier to type than `rg .. | delta`.

The piping is not done by the shell but delta, so the subcommands are
child processes of delta.
This info then takes precedence over whatever
start_determining_calling_process_in_thread() finds or rather
doesn't find.
(The simple yet generous SeqCst is used on purpose for the atomic operations.)
@dandavison dandavison merged commit 31296e7 into dandavison:main Nov 29, 2024
@dandavison

Copy link
Copy Markdown
Owner

Excellent, merged!

@dandavison

Copy link
Copy Markdown
Owner

Both git and ripgrep have special behavior when their output is redirected, aimed at creating predictable and parseable output when it's being consumed by a machine. Should we consider not invoking delta at all in that case, instead execing the external command?

@th1000s

th1000s commented Dec 2, 2024

Copy link
Copy Markdown
Collaborator Author

Excellent, merged!

Booo, squash merged again :)

You envision someone doing alias rg='delta rg', which would break on rg foo | rg bar? But then delta also needs the equivalent of --color=always|auto|none, but for terminal detection, so someone still can do delta rg > pretty-result.ansi.txt.

@dandavison

Copy link
Copy Markdown
Owner

Booo, squash merged again :)

Oh I'm sorry, that is annoying. The button is usually defaulted to squash since we use it for other delta contributors so it is a bit of an easy mistake for me to make, especially because we only ever squash at work, so my brain sees "Squash and merge" as "This is the green merge button"... But perhaps now I will not forget again.

But then delta also needs the equivalent of --color=always|auto|none, but for terminal detection, so someone still can do delta rg > pretty-result.ansi.txt.

Perhaps, but I think that I might have a good counterargument to that: today, if a user wants to save delta output with ANSI escapes, they have to do git foo | delta > pretty-result.ansi.txt because git itself has tty detection that doesn't even invoke $GIT_PAGER when redirected. And since saving pretty colored output to disk is unusual, I don't think it has to be particularly ergonomic. So I think in fact it might make sense for us to keep a consistent rule that always, with delta, if you want to save pretty output to disk, then pipe explicitly to delta.

For rg, a user would have to supply --json explicitly: rg --json | delta > pretty-result.ansi.txt, or delta rg --json | delta > pretty-result.ansi.txt. So there'd be a bit of abstraction leakage since it kind of requires them to know that delta's rg integration is based on rg --json. But, at the end of the day, I do think "delta output is for humans" is a reasonable project design principle and that people that are saving ANSI escape codes in text files (or parsing them) probably can be trusted to figure out the details?

@th1000s

th1000s commented Dec 9, 2024

Copy link
Copy Markdown
Collaborator Author

Our git workflow uses Gerrit and is heavily based on "stacked PRs" (as it is now called) - so exactly the opposite, and clearly superior ;)
No worries, I'll just leave multi-commit PRs as a draft/WIP and do the final merge myself.

Agreed, the direct exec subcommand PR is #1925, without an opt-out. Let's see if someone runs into that and comes up with another argument for --color=always.

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Mar 26, 2026
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [dandavison/delta](https://github.com/dandavison/delta) | minor | `0.18.2` → `0.19.1` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>dandavison/delta (dandavison/delta)</summary>

### [`v0.19.1`](https://github.com/dandavison/delta/releases/tag/0.19.1)

[Compare Source](dandavison/delta@0.19.0...0.19.1)

This patch release fixes a release automation [bug](dandavison/delta#2127): release [0.19.0](https://github.com/dandavison/delta/releases/tag/0.19.0) did not include all release binaries.

#### What's Changed

- Fix CD: replace defunct ubuntu-20.04 runners by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;2129](dandavison/delta#2129)

**Full Changelog**: <dandavison/delta@0.19.0...0.19.1>

### [`v0.19.0`](https://github.com/dandavison/delta/releases/tag/0.19.0)

[Compare Source](dandavison/delta@0.18.2...0.19.0)

Tons of improvements; thanks very much to all delta contributors.

**This release is missing several binaries due to a [bug in the GitHub Actions release workflow](dandavison/delta#2127). Please use <https://github.com/dandavison/delta/releases/tag/0.19.1> instead.**

#### What's Changed

- Do not double panic in FakeParentArgs::drop by [@&#8203;dvermd](https://github.com/dvermd) in [#&#8203;1856](dandavison/delta#1856)
- Improve blame file type detection ([#&#8203;1803](dandavison/delta#1803)) by [@&#8203;dvermd](https://github.com/dvermd) in [#&#8203;1829](dandavison/delta#1829)
- Use same example config in manual as README by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1879](dandavison/delta#1879)
- Clarify grep highlighter-related code by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1877](dandavison/delta#1877)
- Don't set colorMoved in introductory instructions by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1884](dandavison/delta#1884)
- Recommend zdiff3 merge.conflictStyle by [@&#8203;adamchainz](https://github.com/adamchainz) in [#&#8203;1260](dandavison/delta#1260)
- Add themes `weeping-willow`, `mirthful-willow` by [@&#8203;lvdh](https://github.com/lvdh) in [#&#8203;1864](dandavison/delta#1864)
- CI: switch to macos-13, as 12 will be unsupported soon by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1890](dandavison/delta#1890)
- Add optional capture-output writer to run\_app() by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1889](dandavison/delta#1889)
- Center-align README content by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1893](dandavison/delta#1893)
- Redundant Option Checks, Unwrap Safety by [@&#8203;sharma-shray](https://github.com/sharma-shray) in [#&#8203;1892](dandavison/delta#1892)
- Add console commands for git configuration by [@&#8203;harmtemolder](https://github.com/harmtemolder) in [#&#8203;1896](dandavison/delta#1896)
- Honor pager path when checking less version by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1903](dandavison/delta#1903)
- Rename some variables by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1904](dandavison/delta#1904)
- Delete now-unused pricate homebrew formula step from Makefile (III) by [@&#8203;dvermd](https://github.com/dvermd) in [#&#8203;1830](dandavison/delta#1830)
- Support {host} in hyperlinks by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;1901](dandavison/delta#1901)
- Allow multiple hyperlinks per line by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1909](dandavison/delta#1909)
- Clippy 1.83 by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1918](dandavison/delta#1918)
- Support external subcommands: rg, diff, git-show (etc.) by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1769](dandavison/delta#1769)
- Don't keep subcommand stdout around by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1920](dandavison/delta#1920)
- hyperlink commit hashes of length 7 as well by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1924](dandavison/delta#1924)
- clippy 1.84 fix by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1938](dandavison/delta#1938)
- chore(deps): update git2 to use libgit2 1.9 by [@&#8203;chenrui333](https://github.com/chenrui333) in [#&#8203;1930](dandavison/delta#1930)
- Suggest minimum bat version in manual by [@&#8203;ernstki](https://github.com/ernstki) in [#&#8203;1941](dandavison/delta#1941)
- Upgrade unicode-width to v0.1.14 (but still < 0.2.0) by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1937](dandavison/delta#1937)
- Update terminal-colorsaurus version to 0.4.8 by [@&#8203;rashil2000](https://github.com/rashil2000) in [#&#8203;1936](dandavison/delta#1936)
- Fix index out of bounds crash for '@&#8203;@&#8203;  @&#8203;@&#8203;' hunk header by [@&#8203;adamchainz](https://github.com/adamchainz) in [#&#8203;1995](dandavison/delta#1995)
- Tune themes weeping-willow, mirthful-willow by [@&#8203;lvdh](https://github.com/lvdh) in [#&#8203;2011](dandavison/delta#2011)
- clippy 1.88 fixes by [@&#8203;injust](https://github.com/injust) in [#&#8203;2016](dandavison/delta#2016)
- Fix diff output when a diff ends with a mode change by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;2023](dandavison/delta#2023)
- fix: `cargo install git-delta --locked` fails on systems with GCC 15 by [@&#8203;tquin](https://github.com/tquin) in [#&#8203;2007](dandavison/delta#2007)
- Normalize `merge.conflictStyle` casing by [@&#8203;injust](https://github.com/injust) in [#&#8203;2015](dandavison/delta#2015)
- Styled zero lines fix by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;1916](dandavison/delta#1916)
- config: add setup instructions for Jujutsu (jj) vcs by [@&#8203;arjunmahishi](https://github.com/arjunmahishi) in [#&#8203;2048](dandavison/delta#2048)
- all: fix clippy complaints by [@&#8203;charlievieth](https://github.com/charlievieth) in [#&#8203;2038](dandavison/delta#2038)
- Cache the Git remote URL to speed up rendering hyperlinks by [@&#8203;charlievieth](https://github.com/charlievieth) in [#&#8203;1940](dandavison/delta#1940)
- deps: update cc by [@&#8203;ognevny](https://github.com/ognevny) in [#&#8203;2053](dandavison/delta#2053)
- rg json handling: fix line comment highlighting by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;2057](dandavison/delta#2057)
- Update dirs dependency to version 6 by [@&#8203;musicinmybrain](https://github.com/musicinmybrain) in [#&#8203;2063](dandavison/delta#2063)
- default line number to 1 for hyperlinks by [@&#8203;schpet](https://github.com/schpet) in [#&#8203;2061](dandavison/delta#2061)
- Fix line numbers showing filename when hyperlinks enabled by [@&#8203;tsvikas](https://github.com/tsvikas) in [#&#8203;2058](dandavison/delta#2058)
- less hist file: look at xdg paths by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;2065](dandavison/delta#2065)
- CI: remove x86 apple/macOS by [@&#8203;th1000s](https://github.com/th1000s) in [#&#8203;2074](dandavison/delta#2074)
- Update bat dependency from 0.24 to 0.26 by [@&#8203;dandavison](https://github.com/dandavison) in [#&#8203;2115](dandavison/delta#2115)

#### New Contributors

- [@&#8203;dvermd](https://github.com/dvermd) made their first contribution in [#&#8203;1856](dandavison/delta#1856)
- [@&#8203;lvdh](https://github.com/lvdh) made their first contribution in [#&#8203;1864](dandavison/delta#1864)
- [@&#8203;sharma-shray](https://github.com/sharma-shray) made their first contribution in [#&#8203;1892](dandavison/delta#1892)
- [@&#8203;harmtemolder](https://github.com/harmtemolder) made their first contribution in [#&#8203;1896](dandavison/delta#1896)
- [@&#8203;ernstki](https://github.com/ernstki) made their first contribution in [#&#8203;1941](dandavison/delta#1941)
- [@&#8203;tquin](https://github.com/tquin) made their first contribution in [#&#8203;2007](dandavison/delta#2007)
- [@&#8203;arjunmahishi](https://github.com/arjunmahishi) made their first contribution in [#&#8203;2048](dandavison/delta#2048)
- [@&#8203;charlievieth](https://github.com/charlievieth) made their first contribution in [#&#8203;2038](dandavison/delta#2038)
- [@&#8203;ognevny](https://github.com/ognevny) made their first contribution in [#&#8203;2053](dandavison/delta#2053)
- [@&#8203;musicinmybrain](https://github.com/musicinmybrain) made their first contribution in [#&#8203;2063](dandavison/delta#2063)
- [@&#8203;schpet](https://github.com/schpet) made their first contribution in [#&#8203;2061](dandavison/delta#2061)
- [@&#8203;tsvikas](https://github.com/tsvikas) made their first contribution in [#&#8203;2058](dandavison/delta#2058)

**Full Changelog**: <dandavison/delta@0.18.2...0.19.0>

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My44OS42IiwidXBkYXRlZEluVmVyIjoiNDMuODkuNiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90IiwiYXV0b21hdGlvbjpib3QtYXV0aG9yZWQiLCJkZXBlbmRlbmN5LXR5cGU6Om1pbm9yIl19-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants