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

Edit multiple files / load multiple files into buffer list for :Git <command>'s #2352

Open
fab4100 opened this issue Nov 3, 2024 · 3 comments · May be fixed by #2359
Open

Edit multiple files / load multiple files into buffer list for :Git <command>'s #2352

fab4100 opened this issue Nov 3, 2024 · 3 comments · May be fixed by #2359

Comments

@fab4100
Copy link

fab4100 commented Nov 3, 2024

Assume the command in question is :Git send-email --annotate HEAD~2. This will prepare patches for the last two commits pointed to by HEAD and prepare one email message for each which will be sent to the editor for further editing because of the --annotate flag. The default for the option sendemail.multiEdit is true which will start one editor instance with two buffers loaded (one for each email message) when above command is executed from the command line. The user can then jump back and forth between these buffers and further edit the messages. When the editor instance is closed git will send the emails. When sendemail.multiEdit is false the process is sequential, starting a new editor instance for every file that needs editing.

When the above command is executed from within vim (with sendemail.multiEdit = true) only the first file to edit is loaded into the buffer list. When that buffer is removed, the command immediately proceeds to sending the email(s), assuming the remaining email messages do not need editing (these buffers are somehow lost in the process). When sendemail.multiEdit = false, the user gets the chance to edit each message but the process is sequential.

Is it possible for a Git <command> that expects to edit multiple files, to load all these files into the buffer list at once? The command must only proceed when all these buffers are removed using something like :bd /tmp/tmp_folder/*.patch or some other means.

Thanks,
fabs

@tpope
Copy link
Owner

tpope commented Nov 4, 2024

The one file limitation is a consequence of this shell script only acting on $1:

\ '[ -f "$FUGITIVE.exit" ] && cat "$FUGITIVE.exit" >&2 && exit 1',
\ 'echo "$1" > "$FUGITIVE.edit"',
\ 'printf "\033]51;fugitive:edit\007" >&2',
\ 'while [ -f "$FUGITIVE.edit" -a ! -f "$FUGITIVE.exit" ]; do sleep 0.05 2>/dev/null || sleep 1; done',

Wrapping a for file in "$@"; do loop around it could potentially allow it to process multiple files, albeit serially. Parallel processing would be possible with a larger change.

Is it possible for a Git <command> that expects to edit multiple files, to load all these files into the buffer list at once? The command must only proceed when all these buffers are removed using something like :bd /tmp/tmp_folder/*.patch or some other means.

Not a fan of any interface that would put the files somewhere they aren't readily visible to the user. Would be amenable to splits.

@fab4100
Copy link
Author

fab4100 commented Nov 4, 2024

Thanks for your input.

The wrapping with a for file in "$@"; do would emulate what
sendemail.multiEdit = false is already doing (not sure but I believe git send-email might be the only git command that could potentially require to
edit more than just one file). Sequential editing of the emails for a patch
series is not ideal since for a complex patch set you may need to go back and
forth between the messages during the editing process before sending out the
patches.

Parallel processing would be possible with a larger change.

This is the proper solution. From the top of your head, what would roughly be
the required tasks to realize this? I may look into this.

Not a fan of any interface that would put the files somewhere they aren't
readily visible to the user. Would be amenable to splits.

I think I might have not expressed myself clearly. The /tmp/tmpFolder/*.patch
files I mentioned are created by git send-email and are passed via the $1
argument in shell script to the calling vim session. For a single file edit
(e.g. with sendemail.multiEdit = false) listing buffers with :ls during the
editing session will show the file in the buffer list. I envision a parallel
processing solution above that would just list n files if there are n
patches (and possibly a cover letter) which can then be edited by just switching
buffers. This already happens when sendemail.multiEdit = true and git send-email ... is called from the shell directly. Being able to do this from
within a vim session by calling :G send-email ... is what I aim at.

@tpope
Copy link
Owner

tpope commented Nov 4, 2024

Thanks for your input.

The wrapping with a for file in "$@"; do would emulate what sendemail.multiEdit = false is already doing

Yes, that seems better than the current behavior of ignoring all but the first file.

Parallel processing would be possible with a larger change.

This is the proper solution. From the top of your head, what would roughly be the required tasks to realize this? I may look into this.

Big picture, you could write the full list of filenames to $FUGITIVE.edit rather than just the first one:

for arg in "$@"; do echo "$arg" >> "$FUGITIVE.edit"; done

Then change the code Fugitive side to handle that list. Exact steps there will depend on the interface.

Not a fan of any interface that would put the files somewhere they aren't
readily visible to the user. Would be amenable to splits.

I think I might have not expressed myself clearly. The /tmp/tmpFolder/*.patch files I mentioned are created by git send-email and are passed via the $1 argument in shell script to the calling vim session. For a single file edit (e.g. with sendemail.multiEdit = false) listing buffers with :ls during the editing session will show the file in the buffer list. I envision a parallel processing solution above that would just list n files if there are n patches (and possibly a cover letter) which can then be edited by just switching buffers. This already happens when sendemail.multiEdit = true and git send-email ... is called from the shell directly. Being able to do this from within a vim session by calling :G send-email ... is what I aim at.

The way it works when it's called from the shell is that Vim is invoked with multiple arguments, which Vim loads into the "argument list". See :help argument-list. The first file is loaded automatically, and you can cycle between the files using commands like :next and :previous. When you're done, you can exit with :q, as usual. But if you haven't made it to the last file, that's an error. You need :q! to exit prematurely.

Adapting this workflow to a long-running Vim instance complicates things. Most notably, we need an alternative to exiting Vim. If the best you can do is "something like :bd /tmp/tmp_folder/*.patch", then it's a no-go.

fab4100 pushed a commit to fab4100/vim-fugitive that referenced this issue Dec 2, 2024
Git send-email by default uses multi-file edit mode
(sendemail.multiEdit) when more than one patch file requires editing an
associated email message and/or cover-letters.  Multi edit mode spawns
one editor instance with multiple files in argument list.  This behavior
is supported by creating multiple splits for a running vim instance when
`:G send-email` is called.  When the user sets sendemail.multiEdit to
false in the local or global config, if multiple files need editing then
they are processed sequentially in a single split at a time.

Closes tpope#2352
@fab4100 fab4100 linked a pull request Dec 2, 2024 that will close this issue
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 a pull request may close this issue.

2 participants