bash-completion icon indicating copy to clipboard operation
bash-completion copied to clipboard

"7z a" should (perhaps) allow filename completion

Open rwv37 opened this issue 9 months ago • 13 comments

Describe the feature/solution

I often create 7z files based on the filename(s) that I'm putting in there. For example, let's say I have these files: blah.data, blah.log, blah.whatever. From them, I want to create blah.7z.

Before I installed bash-completion, the way I would typically do that would be to type 7z a , hit tab, add 7z , hit tab again, and add .*, resulting in the command 7z a blah.7z blah.*. Unfortunately (at least for me), bash-completion does nothing when I hit tab the first time (i.e. after 7z a ). I think it would be nice if it allowed filename completion, so as to keep the standard behavior available instead of just removing it entirely.

Maintenance (please complete the following information)

  • [ ] This is a request for new completion
  • [ ] Link to upstream project query about shipping the completion:

rwv37 avatar Apr 14 '25 18:04 rwv37

These are kind of difficult corner cases to handle. If we supported arbitrary filename completions directly after a, we'd be knowingly generating completions that are certain to be incorrect, and I don't personally like that practice. I think we only have one exception to that "rule" in the tree -- I don't remember exactly what it was, but it was such a common case that we eventually did it.

This, on the other hand, my gut says is not such a common usage scenario, so I'm inclined not to do it. There are a couple of things you can do though instead of disabling the completion completely. I appreciate not any of them may be perfect for your use case, but I thought I'd mention them just in case:

scop avatar Apr 20 '25 09:04 scop

Thanks, I'll take a look at the workarounds. I am not sure that I'm understanding the objection, though: It seems to me that you'd be generating completions that are certain to be incorrect only if the user hit "tab" and didn't mean to.

EDIT: And even in that case, you wouldn't be "knowingly" generating completions are certain to be incorrect.

rwv37 avatar Apr 20 '25 19:04 rwv37

For example:

mkdir /tmp/foo
cd /tmp/foo
touch bar
7z a <TAB>

If we complete that to bar (and append a space which is what typically happens for filename completions), we have knowingly produced an invalid completion -- bar is not valid argument for a there, no matter if tab was hit intentionally or not.

scop avatar Apr 20 '25 20:04 scop

Why not?

[170206 bob@iron 1;~]$ mkdir tmp1 tmp2
[170211 bob@iron 1;~]$ echo "blah" > tmp1/tmpblah
[170222 bob@iron 1;~]$ cd tmp2
[170226 bob@iron 1;~/tmp2]$ touch bar
[170232 bob@iron 1;~/tmp2]$ 7z a bar ../tmp1/tmpblah
                                                           
7-Zip (z) 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29                                                 
64-bit locale=C.UTF-8 Threads:8 OPEN_MAX:1885104

Scanning the drive:
1 file, 5 bytes (1 KiB)

Creating archive: bar.7z

Add new data to archive: 1 file, 5 bytes (1 KiB)

Files read from disk: 1
Archive size: 131 bytes (1 KiB)
Everything is Ok
[170254 bob@iron 1;~/tmp2]$ ls -l
total 1
-rw-r--r--  1 bob bob   0 Apr 20 17:02 bar
-rw-r--r--  1 bob bob 131 Apr 20 17:02 bar.7z
[170258 bob@iron 1;~/tmp2]$ 7z x bar.7z

7-Zip (z) 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29                                                 
64-bit locale=C.UTF-8 Threads:8 OPEN_MAX:1885104

Scanning the drive for archives:
1 file, 131 bytes (1 KiB)

Extracting archive: bar.7z
--
Path = bar.7z
Type = 7z
Physical Size = 131
Headers Size = 122
Method = LZMA2:12
Solid = -
Blocks = 1

Everything is Ok

Size:       5
Compressed: 131
[170309 bob@iron 1;~/tmp2]$ ls
bar      bar.7z   tmpblah
[170310 bob@iron 1;~/tmp2]$ ls tmpblah
tmpblah
[170314 bob@iron 1;~/tmp2]$ cat tmpblah
blah
[170319 bob@iron 1;~/tmp2]$

rwv37 avatar Apr 20 '25 21:04 rwv37

Ouch, now that's weird/magical/unexpected behavior to me. --help or man page do not seem to offer any explanation for it. But given that, I'm willling to reconsider, given submitted PR along with a bunch of test cases that confirm it's the intended behavior.

scop avatar Apr 20 '25 22:04 scop

Yeah, honestly I didn't expect it to put ".7z" on automatically, but what I actually did expect was that it would just allow "bar" to be a 7z file (not "a file with a 7z extension"). And in that case, it would make sense too, since 7z allows you to extract such a file anyway:

[220620 bob@iron 1;~/tmp]$ echo "foo" > bar
[220627 bob@iron 1;~/tmp]$ 7z a bar.7z bar

7-Zip (z) 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29
 64-bit locale=C.UTF-8 Threads:8 OPEN_MAX:1885104

Scanning the drive:
1 file, 4 bytes (1 KiB)

Creating archive: bar.7z

Add new data to archive: 1 file, 4 bytes (1 KiB)


Files read from disk: 1
Archive size: 122 bytes (1 KiB)
Everything is Ok
[220639 bob@iron 1;~/tmp]$ mv bar.7z zipped
[220650 bob@iron 1;~/tmp]$ rm bar
[220718 bob@iron 1;~/tmp]$ 7z x zipped

7-Zip (z) 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29
 64-bit locale=C.UTF-8 Threads:8 OPEN_MAX:1885104

Scanning the drive for archives:
1 file, 122 bytes (1 KiB)

Extracting archive: zipped
--
Path = zipped
Type = 7z
Physical Size = 122
Headers Size = 114
Method = LZMA2:12
Solid = -
Blocks = 1

Everything is Ok

Size:       4
Compressed: 122
[220724 bob@iron 1;~/tmp]$ cat bar
foo
[220736 bob@iron 1;~/tmp]$

Lots of programs are like this, especially in the *nix world. They don't really care about extensions. Maybe there's a common, suggested, or even default extension, but it's not required.

rwv37 avatar Apr 21 '25 02:04 rwv37

Sure, extensions aren't often that interesting. But what I find very surprising, non-unixy, and directly against the tool's own usage message and man page is the behavior of 7z a foo when a file foo is present: it creates a foo.7z and puts foo in it (or adds foo in the archive if it was already present). But the usage message says

Usage: 7z <command> [<switches>...] <archive_name> [<file_names>...] [@listfile]

...and the man page says

       7z command [switches...] archive_name [file_names] [@listfile]

...i.e. archive_name is a mandatory argument, and my foo should have been treated as that. Instead, the tool did not treat it as archive_name but a file_name and came up with an archive_name on its own. I understand it tries to "DWIM", but it would be better if the documentation matched reality.

scop avatar Apr 21 '25 06:04 scop

[170226 bob@iron 1;~/tmp2]$ touch bar
[170232 bob@iron 1;~/tmp2]$ 7z a bar ../tmp1/tmpblah
...
[170309 bob@iron 1;~/tmp2]$ ls
bar      bar.7z   tmpblah

[...]

Sure, extensions aren't often that interesting. But what I find very surprising, non-unixy, and directly against the tool's own usage message and man page is the behavior of 7z a foo when a file foo is present:

I think the above code example was a bit confusing. The 7z a bar creates bar.7z regardless of the existence of the file bar. In my environment (Fedora 41),

$ ls
$ 7za a non-existent

7-Zip (a) [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,8 CPUs Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (906E9),ASM,AES-NI)

Scanning the drive:
0 files, 0 bytes

Creating archive: non-existent.7z

Items to compress: 0


Files read from disk: 0
Archive size: 32 bytes (1 KiB)
Everything is Ok
$ ls
non-existent.7z

So this behavior couldn't be a reason to specifically generate the filenames because the argument can be an arbitrary string.

The expectation behind the suggested fallback filename completion would be simply that we may want to name a new file similar to existing ones. Making it a habit to press M-/ in this kind of situation seems a good idea to me.

akinomyoga avatar Apr 21 '25 08:04 akinomyoga

Lots of programs are like this, especially in the *nix world.

I agree that filenames can have an arbitrary name (and the filename extension doesn't matter) with Unix programs. However, automatically suffixing .7z feels non-Unixy. It comes from MS-DOS/Windows. 7-Zip is originally a Windows application. I'm not aware of many Unix programs that automatically add the filename extension; I know the TeX toolset does it somehow, but I feel it tries to form its own ecosystem (which is slightly different from the Unix world).

akinomyoga avatar Apr 21 '25 08:04 akinomyoga

However, automatically suffixing .7z feels non-Unixy

I agree; like I said, I was surprised by it. But it's not really important to my immediate point, which is that this "invalid argument" argument doesn't seem to apply. It's not an invalid argument, and even if it didn't do this weird "append an extension" thing, it still wouldn't be an invalid argument.

But more importantly, to me, at least, my main point is summed up by what you said in your earlier comment:

The expectation behind the suggested fallback filename completion would be simply that we may want to name a new file similar to existing ones.

This is exactly the behavior I requested in this issue. It's default bash functionality that I used very often before I installed bash-completion, and I can't imagine I'm the only one.

Making it a habit to press M-/ in this kind of situation seems a good idea to me.

Thanks, I'll try it out. I was unaware of it.

rwv37 avatar Apr 21 '25 15:04 rwv37

Here, by the way, is an example of an actual invalid argument which bash-completion has no issue with:

[112233 bob@iron 1;~]$ mkdir tmp1
[112239 bob@iron 1;~]$ cd tmp1/
[112241 bob@iron 1;~/tmp1]$ touch blah
[112243 bob@iron 1;~/tmp1]$ echo "cp<space><tab><tab>"
cp<space><tab><tab>
[112247 bob@iron 1;~/tmp1]$ cp blah blah
cp: blah and blah are identical (not copied).
[112249 bob@iron 1;~/tmp1]$

Of course, that's fairly silly as it is, but it's actually useful (with slight modification) in the same way as with my 7z suggestion:

[112726 bob@iron 1;~/tmp1]$ echo "cp<space><tab><tab><backspace>.bak"
cp<space><tab><tab><backspace>.bak
[112755 bob@iron 1;~/tmp1]$ cp blah blah.bak
[112801 bob@iron 1;~/tmp1]$

I do this sort of thing a lot - i.e. not just with 7z, but in many situations with many commands.

rwv37 avatar Apr 21 '25 15:04 rwv37

actual invalid argument which bash-completion has no issue with

bash-completion might not at the moment, but I do -- I've had the intent to address this class of issues for a long time (there's a lot of it across the tree) but haven't got around to it yet. It doesn't mean we should knowingly continue the practice when we can sanely avoid it.

scop avatar Apr 26 '25 08:04 scop

There was a duplicate request at #1384, which was about the fallback filename completion for the general command.

akinomyoga avatar May 26 '25 03:05 akinomyoga