Skip to content

Add !@B! modifier to collect marked files from both panels into a sin…#3297

Open
YuryChaikou-ServiceNow wants to merge 2 commits intoelfmz:masterfrom
YuryChaikou-ServiceNow:scratch/yc5
Open

Add !@B! modifier to collect marked files from both panels into a sin…#3297
YuryChaikou-ServiceNow wants to merge 2 commits intoelfmz:masterfrom
YuryChaikou-ServiceNow:scratch/yc5

Conversation

@YuryChaikou-ServiceNow
Copy link
Copy Markdown
Contributor

@YuryChaikou-ServiceNow YuryChaikou-ServiceNow commented Mar 10, 2026

…gle list file

The B modifier for !@...! and !$...! substitutions creates a temp file containing marked (selected) files from both the active and passive panels. When B is present, the command is executed once for all selected files rather than once per file.

Can be combined with existing modifiers: F (full paths), Q (quote spaces), U (UTF-8 BOM), W (UTF-16LE), A (ANSI).

Example usage in user menu (F2):
Compare two marked files with Beyond Compare:
open -a 'Beyond Compare' "$(sed -n '1p' "!@BF!")" "$(sed -n '2p' "!@BF!")"
or with diff:
diff "$(sed -n '1p' "!@BF!")" "$(sed -n '2p' "!@BF!")"

Mark one file on the left panel and one on the right panel (with Insert), then run the command to compare them.

…gle list file

The B modifier for !@...! and !$...! substitutions creates a temp file
containing marked (selected) files from both the active and passive panels.
When B is present, the command is executed once for all selected files
rather than once per file.

Can be combined with existing modifiers: F (full paths), Q (quote spaces),
U (UTF-8 BOM), W (UTF-16LE), A (ANSI).

Example usage in user menu (F2):
  Compare two marked files with Beyond Compare:
    open -a 'Beyond Compare' "$(sed -n '1p' "!@bf!")" "$(sed -n '2p' "!@bf!")"
  or with diff:
    diff "$(sed -n '1p' "!@bf!")" "$(sed -n '2p' "!@bf!")"

Mark one file on the left panel and one on the right panel (with Insert),
then run the command to compare them.
@yulian5
Copy link
Copy Markdown
Contributor

yulian5 commented Mar 11, 2026

@YuryChaikou-ServiceNow Your example is not very useful: there is existing functionality to refer to selected file on passive panel (even the selection is not visible) using "!#" symbols. I'm using that to compare files in Far3 and far2l. I suspect it maybe overwritten in some cases with your changes. Here is working code from Far3 I have right now:
WinMergeU.exe "!\!.!" "!#!\!.!"
I have the similar code for Kompare on Ubuntu.
However new modifier maybe useful with multiple selections. And then: do we need the temp file for that? It's probably not like tens of thousands files should be selected (and even so).

@YuryChaikou-ServiceNow
Copy link
Copy Markdown
Contributor Author

Thank you for the feedback! You're right that !\!.! and !#!\!.! can reference files on both panels. However, there are limitations with that approach that motivated this change:

  1. No visible cursor on passive panel: the active file bar only shows on the active panel, so it's easy to lose track of which file !#!\!.! refers to on the passive side.
  2. Same-panel comparison: !\!.! / !#!\!.! can't compare two files within the same panel since you need explicit selection.
  3. Multiple selections: this is where !@B! really shines - select N files across both panels and operate on all of them in a single command invocation.

Regarding the temp file, I agree it's somewhat heavy for the common two-file case. An alternative could be to expand selected filenames inline (space-separated), but that would break with filenames containing spaces and would diverge from how !@! already works (it produces a list file). Keeping the same list-file approach as !@! maintains consistency and handles edge cases (spaces, special chars, large selections) cleanly. The temp file is deleted immediately after command execution.

The existing !@! / !$! / !\!.! / !#! behavior is fully preserved, the B modifier is only activated when explicitly specified in the pattern. No existing functionality is overwritten.

That said, if you have a different approach in mind (e.g. inline expansion for small selections, or a different modifier syntax), I'm happy to review and implement it.

@yulian5
Copy link
Copy Markdown
Contributor

yulian5 commented Mar 11, 2026

No visible cursor on passive panel

That's right and should be fixed one day.

Same-panel comparison: !!.! / !#!!.! can't compare two files within the same panel since you need explicit selection.

I use
WinMergeU.exe !&
It works, just need to select 2 files on the panel.

Otherwise quite useful feature, I think. As for temp file then it should be a separate task, too many changes are already. Let me test this.

@YuryChaikou-ServiceNow
Copy link
Copy Markdown
Contributor Author

!& works when both selected files are in the same panel. I would like to have a single command for both same and different panels.

@YuryChaikou-ServiceNow
Copy link
Copy Markdown
Contributor Author

FYI for this and other PRs: I work on a MacBook running macOS 26.3, so additional testing on Linux may be needed.

@yulian5
Copy link
Copy Markdown
Contributor

yulian5 commented Mar 12, 2026

!& is more like workaround. I agree that consistent approach is much better.

BTW I don't see that you updated help files for this change.

Then it may be a lot of corner cases with !@b! modifier. Some operations maybe possible (like get the sizes). But, for example, there is multiple files selection on both panels and I started command to copy those files with !@b! modifier. What happens in this case?

@YuryChaikou-ServiceNow
Copy link
Copy Markdown
Contributor Author

YuryChaikou-ServiceNow commented Mar 12, 2026

Copy all files to one folder
cp $(cat !@BF!) ~/foo/

Zip all files, preserve folder structure
zip files.zip -@ < !@BF!

!@B! (without F) will generate a list of filenames without paths, some commands will ignore missing files in the current panel's working folder, some may return a warning/error.

Example (zip files.zip -@ < !@B!):

~/.config/far2l$ zip files.zip -@ < /var/folders/9k/3llv3c611qlflq4rwx96mj800000gp/T/far2l_1f6_0/FTMP622e0010.tmp
        zip warning: name not matched: farcolors.ini  <--- Files in passive panel
        zip warning: name not matched: key_macros.ini
        zip warning: name not matched: maskgroups.ini
  adding: ps.warned (stored 0%)  <--- Files in active panel
  adding: winstate (stored 0%)

Add B modifier documentation to the MetaSymbols section in English,
Russian, Hungarian, and Ukrainian help files. Also adds missing U and W
modifiers to the Hungarian help file.
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