akinomyoga / ble.sh

Bash Line Editor―a line editor written in pure Bash with syntax highlighting, auto suggestions, vim modes, etc. for Bash interactive sessions.
BSD 3-Clause "New" or "Revised" License
2.52k stars 81 forks source link

Completion of commands prefixed with `sudo` #480

Open pallaswept opened 4 weeks ago

pallaswept commented 4 weeks ago

ble version: 0.4.0-nightly+a9b962d Bash version: 5.2.26(1)-release (x86_64-suse-linux)

This is a very minor thing, but I keep bumping into it, so I thought I should mention it.

I have noticed that sometimes, if I am typing a command (let's call it my_command) which needs to be run as root, I start typing sudo my_command <tab> and the completions do not seem right for my_command, instead, I get the completions for sudo.

This is often not "wrong" or a "bug" because the sudo options could be used, but I thought that perhaps, the syntax-aware part of ble.sh might consider something like, it will show completion for 'sudo', only if another command has not been entered afterward?

Thanks!

akinomyoga commented 3 weeks ago

The handling of the command part my_command ... of sudo my_command ... is not processed at the shell-syntax level, but just the sudo command executes the specified command with the specified arguments. For this reason, the completion setting for the sudo command should handle it. In particular, the completion setting for the sudo command can call another completion setting corresponding to the specified command if necessary. In fact, the completion setting for sudo provided by bash-completion calls the corresponding completion setting, and it correctly generates the candidates for the specified command in my environment. Maybe the setup is different in your environment.

$ ble/widget/display-shell-version
$ complete -p sudo
$ complete -p my_command
pallaswept commented 3 weeks ago

Sorry I took some time on this. I saw some behaviour I wanted to isolate from my settings, by spinning up a VM....

> ble/widget/display-shell-version
GNU bash, version 5.2.26(1)-release (x86_64-suse-linux) [openSUSE Tumbleweed]
ble.sh, version 0.4.0-nightly+a9b962d (noarch) [git 2.45.2, GNU Make 4.3, GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)]
bash-completion, version 2.12.0 (hash:480ffcc6a751e55621ec526eb5dea7a0d86d9e72, 17877 bytes) (noarch)
starship, version 1.20.1 (rustc 1.79.0 (129f3b996 2024-06-10) (built from a source tarball), 2024-07-29 03:04:26 +00:00)
zoxide, version 0.9.4 (/usr/bin/zoxide) (integration: on)
locale: LANG=en_DK.UTF-8 LC_ADDRESS=en_AU.UTF-8 LC_MEASUREMENT=C LC_MONETARY=en_AU.UTF-8 LC_NAME=en_AU.UTF-8 LC_NUMERIC=en_AU.UTF-8 LC_PAPER=en_AU.UTF-8 LC_TELEPHONE=en_AU.UTF-8 LC_TIME=C
terminal: TERM=xterm-256color wcwidth=15.0-west/15.1-2+ri, konsole:220380 (1;115;0)

With fzf

> complete -p sudo
bash: complete: sudo: no completion specification

> complete -p cp
complete -o filenames -F _fzf_path_completion cp

Without fzf

> complete -p sudo
bash: complete: sudo: no completion specification

> complete -p cp
complete -o filenames -F _comp_complete_longopt cp

I completely removed my .bashrc and got

> complete -p sudo
bash: complete: sudo: no completion specification

> complete -p cp
complete -o filenames -F _comp_complete_longopt cp

So I guessed this is a problem with my distro... To be sure, I tested with a clean install, in a VM with no blesh, and I saw the same. But then, if I do: cp -<tab> I see completions for cp If I do: sudo -<tab> I see completions for sudo

And if I do: sudo cp -<tab> then I see completions for cp But if I do: cp - and then use navigation keys to move to the start of the line, and edit it to sudo cp - and then navigate to the end of the line and hit <tab> , now I see completions for sudo, even though the line is exactly as above, and the cursor is in a place where I could only be entering options for cp. With stock bash, this procedure shows completions for cp in both cases.

Another interesting behaviour I noticed - completions for sudo change after I try it. eg:

> complete -p sudo
bash: complete: sudo: no completion specification
> sudo cp - ## I pressed tab here
--archive                 --copy-contents           --help                    --no-clobber              --one-file-system         --recursive               --sparse=                 --symbolic-link           --version                 
--attributes-only         --debug                   --interactive             --no-dereference          --parents                 --reflink                 --strip-trailing-slashes  --target-directory=       
--backup                  --dereference             --keep-directory-symlink  --no-preserve=            --preserve                --reflink=                --suffix                  --update                  
--context                 --force                   --link                    --no-target-directory     --preserve=               --remove-destination      --suffix=                 --verbose                 
> complete -p sudo
complete -F _comp_cmd_sudo sudo

It does this in stock bash with no blesh as well as with blesh. I'm unsure if this is relevant or normal?

Hope this is helpful.

akinomyoga commented 3 weeks ago

And if I do: sudo cp -<tab> then I see completions for cp But if I do: cp - and then use navigation keys to move to the start of the line, and edit it to sudo cp - and then navigate to the end of the line and hit <tab> , now I see completions for sudo, even though the line is exactly as above, and the cursor is in a place where I could only be entering options for cp. With stock bash, this procedure shows completions for cp in both cases.

This is an interesting behavior. I'm confused about whether this behavior is observed with or without blesh (since you mention that something is the same even without blesh). Does this happen both with and without blesh?

Another interesting behaviour I noticed - completions for sudo change after I try it. eg:

Ah, yes. This is an intended behavior. Your result of complete -p cp tells that the bash-completion framework is loaded in your environment. With the bash-completion framework, the completion for the sudo command is loaded dynamically, i.e., the setting will be loaded in the first attempt of the completion for the sudo command. So, I should have asked the results of complete -p sudo after attempting the completion involving the sudo command` at least once.


I'm not sure if it is the same as the reported one, but I noticed that the ble.sh's mandb module (i.e., the module to find the description for the generated completions based on the man page) picks the descriptions from the man page of sudo even if the generated completions for sudo cp -[TAB] are the ones for the cp command.

This is a somewhat expected behavior because the generation of the option descriptions is independent of the generation of the options. Since the plain Bash doesn't offer a way to show the descriptions, the bash-completion framework (which aims at providing completions for the plain Bash) doesn't generate the descriptions. For this reason, to show descriptions, ble.sh tries to complement the descriptions by extracting them from the man page of the current command based on the syntax (e.g., sudo in the case of sudo cp -[TAB]). Since ble.sh doesn't try to implement the completions for respective commands but instead tries to let other settings (such as bash-completion or the specific completion scripts provided by the respective tools) implement the detailed completions, ble.sh wouldn't want to implement the detailed handling for the commands like sudo.

However, this may contaminate the mandb cache for the sudo command with the descriptions for the other commands, (though this problem seems opposite to the reported behavior). For this issue, maybe ble.sh can hook into the _comp_command_offset in the bash-completion framework. I'll consider it later.

pallaswept commented 3 weeks ago

Does this happen both with and without blesh?

Sorry, I knew that my wording was bad! English is not a good language for describing a state machine... And maybe I'm just not good at English :rofl:

Without blesh, I see completions for cp with both examples. With blesh, I see completions for sudo, if I edit the line to add 'sudo' at the beginning.

So: cp -<home>sudo <end><tab> shows sudo completions sudo cp -<tab> shows cp completions

I think this might be a more precise definition of the original issue I was reporting. I mentioned that it happens "sometimes", but I could not quite make a pattern of it, but I do this a lot, this "type in the command - oh wait, I need sudo for this - edit the line to add sudo to the beginning", and I suspect that this behaviour of mine is the "sometimes".

Ah, yes. This is an intended behavior.

OK that's cool, it seemed intentional, but I thought it might be relevant. I don't have any problem with this.

akinomyoga commented 3 weeks ago

I'm not sure if it is the same as the reported one, but I noticed that the ble.sh's mandb module [...] picks the descriptions from the man page of sudo even if the generated completions for sudo cp -[TAB] are the ones for the cp command.

@pallaswept In commit cbcce62527f6a379a635d4515d4b1a220e70db34, I fixed the above issue. Although this problem seems different from the problem that you reported, I think it might be correlated. Could you check the behavior with the latest master branch and see if anything changes with your problem?