Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesigning config for diff and merge editors #1285

Open
ilyagr opened this issue Feb 19, 2023 · 6 comments
Open

Redesigning config for diff and merge editors #1285

ilyagr opened this issue Feb 19, 2023 · 6 comments

Comments

@ilyagr
Copy link
Contributor

ilyagr commented Feb 19, 2023

Continuing a discussion with @martinvonz and @yuja from ... (couldn't find where), it might be good to redesign the configuration for merge and diff editors along the following lines:

  1. ui.merge-editor can be either a single word like "TOOL", or a value that would be valid for merge-tools.TOOL.
  2. ui.diff-editor can be either a single word like "TOOL", or a value that would be valid for diff-tools.TOOL. We might also allow it to be a command that can be executed as command $left $right.
  3. The namespaces for merge editors and diff editors are separate. In particular, it is allowed for the diff tool vim to execute a script vimdirdiff (or sh -c SOMETHING) while the merge tool vim executes vimdiff.
  4. The actual set of values that ui.merge-editor or ui.diff-editor can take is a TOML table, an array ["command", "arg1", "arg2"], maybe a space-separated string.
  5. I'm not sure whether the tool should continue to default to a binary that's named the same as the tool. One option would be to have an args key that works like merge-args and diff-args work now, as well as a command key that always includes the command. It would then be illegal to specify both.

Part of the motivation is that I expect the config for diff and merge tools to become more complex with time. For example, we might want to support diff tools that cannot compare dirs but only compare two files. There may be multiple way to call such tools (some might support opening many tabs with separate diffs, some might not) This seems to make the overlap between a merge tool and a diff tool configs confusing as well as the difference between what can be specified where.

WDYT?

@yuja
Copy link
Contributor

yuja commented Feb 19, 2023

My feeling for merge-tools.<tool>.<op>-args = { command = ..., env = ... } is it's too structured. Implementation-wise, it's correct, but I prefer a flattened structure for human interface.

Somewhat related:
If we add a feature like GIT_EXTERNAL_DIFF, we might want to specify a tool with jj diff/log --tool <name> (as in --git/--summary). We can also add a readonly GUI/CUI diff command/option which will take -t/--tool <name> option.

Should these tools be defined in the single merge-tools namespace?

@martinvonz
Copy link
Member

I think that all makes sense.

Regarding item 5: Since the arguments usually have to be specified anyway, it doesn't seem like much more work to specify the name of the binary, even if it's often the same as the tool name, like diff-tools.meld.command = ["meld", "$left", "$right"] or diff-tools.meld.command = "meld $left $right".

My feeling for merge-tools.<tool>.<op>-args = { command = ..., env = ... } is it's too structured. Implementation-wise, it's correct, but I prefer a flattened structure for human interface.

I agree. I think that's what item 4 says, right? I.e. that we can allow more complex form but we can also allow a form that's easier to read and write for when that's good enough (which is most of the time).

If we add a feature like GIT_EXTERNAL_DIFF, we might want to specify a tool with jj diff/log --tool <name> (as in --git/--summary). We can also add a readonly GUI/CUI diff command/option which will take -t/--tool <name> option.

I think we can reuse the [diff-tools] for that. Do you mean that there might be a need to treat "diff viewers" and "diff editors" differently?

@ilyagr
Copy link
Contributor Author

ilyagr commented Feb 19, 2023

My feeling for merge-tools..-args = { command = ..., env = ... } is it's too structured. Implementation-wise, it's correct, but I prefer a flattened structure for human interface.

Yeah, this is one of the problems I wanted to solve. Instead I want configs to look as follows:

ui.diff-editor = ["cmd", "tool"]
ui.merge-editor = { command = "...", env = "..."}
# ui.diff-editor = "TOOL" is also valid

[tools.merge.TOOL]
command = "..."
args = ["..."]  # This might look different if we implement my point number 5.
env = ["..."]

[tools.diff.TOOL]
command = "..."
args = ["..."]
env = ["..."]

# The following could also be valid, maybe
[tools.diff]
ANOTHER_TOOL = ["sh", "-c", "script", "$left", "$right"]

This could potentially support different kinds of tools as well.

@yuja
Copy link
Contributor

yuja commented Feb 20, 2023

Oh, I though diff-tools.TOOL in the item 2 were typo of merge-tools.TOOL.

Mercurial started with separate diff-tools/merge-tools sections, and they've got merged later.
I don't know the exact reason, but that might be related to tool lookup on Windows. Mercurial supports registry key to resolve full executable path, and such configuration can be shared within merge/diff tools.

Regarding item 5: Since the arguments usually have to be specified anyway, it doesn't seem like much more work to specify the name of the binary,

I think it's not uncommon on Windows to override only the executable path.

@ilyagr
Copy link
Contributor Author

ilyagr commented Feb 20, 2023

I think it's not uncommon on Windows to override only the executable path.

Good point, that's good to remember.

Registry paths are also an interesting point, though to me it doesn't seem prohibitive to simply repeat them. I doubt end users often use them, so it's just a matter of the default config.

@yuja
Copy link
Contributor

yuja commented Feb 20, 2023

Registry paths are also an interesting point, though to me it doesn't seem prohibitive to simply repeat them. I doubt end users often use them, so it's just a matter of the default config.

True. It's not meant for user to configure.

I think we can reuse the [diff-tools] for that. Do you mean that there might be a need to treat "diff viewers" and "diff editors" differently?

A diff tool of GIT_EXTERNAL_DIFF type can be streamed (so log -p -t <tool> should work), but vimdiff for example can't. I'm not sure if they should be defined separately, or flagged like .type = stream|gui|cui.

Regarding "diff viewer" vs "diff editor", command arguments can be different. I wouldn't pass kdiff3 --merge for viewing.

yuja added a commit to yuja/jj that referenced this issue Aug 2, 2023
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in jj-vcs#1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes jj-vcs#1886
yuja added a commit to yuja/jj that referenced this issue Aug 3, 2023
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in jj-vcs#1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes jj-vcs#1886
yuja added a commit to yuja/jj that referenced this issue Aug 3, 2023
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in jj-vcs#1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes jj-vcs#1886
yuja added a commit to yuja/jj that referenced this issue Aug 3, 2023
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in jj-vcs#1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes jj-vcs#1886
yuja added a commit that referenced this issue Aug 3, 2023
This is basic implementation. There's no config knob to enable the external
diff command by default. It reuses the merge-tools table because that's how
external diff/merge commands are currently configured. We might want to
reorganize them in #1285.

If you run "jj diff --tool meld", GUI diff will open and jj will wait for
meld to quit. This also applies to "jj log -p". The "diff --tool gui" behavior
is somewhat useful, but "log -p --tool gui" wouldn't. We might want some flag
to mark the tool output can't be streamed.

Another thing to consider is tools that can't generate directory diffs. Git
executes ext-diff tool per file, but we don't. Difftastic can compare
directories, and doing that should be more efficient since diffs can be
computed in parallel (at the expense of unsorted output.)

Closes #1886
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

No branches or pull requests

3 participants