6

Is there a way how to control completion for first command being typed on bash4 command prompt?

I can control completions for "empty line" with complete -E, but as soon as some characters are typed, bash (or possibly readline) gives me all filenames from PATH, builtin commands (if, then, else...) and functions on completion attempt (TAB).

I was able to avoid PATH entries by unsetting PATH in PROMPT_COMMAND and restoring it by binding function to trap DEBUG, but no luck with getting rid of bash bultin commands completions.

Any ideas?

tshepang
  • 12,111
  • 21
  • 91
  • 136
  • Sorry, not a programming question, voting to move to http://superuser.com/ R you can 'flag' it and ask for a moderator to move i. (I didn't downvote your question). Good luck. – shellter May 04 '12 at 14:37
  • 2
    In what way this is not programming question? It is absolutely programming related, maybe I should describe my problem more clearly. It is closely related to http://stackoverflow.com/questions/4726695/bash-and-readline-tab-completion-in-a-user-input-loop. I'm developing CLI for integration framework in bash4 and need to control bash4 completions to filter unwanted suggestions. – Stanislav Pavlíček May 04 '12 at 19:52
  • In my opinion, this is about using an editor, which puts in squarely in superuser.com. You may very well get a response here on S.O. anyway, so good luck! – shellter May 04 '12 at 21:01
  • Bump;) Any bash4 programmable completion hackers around to help me with this issue? I think is pretty weird I can control completions for blank line, but as soon as I start typing characters those "blank line" completions are lost... – Stanislav Pavlíček May 11 '12 at 08:55

3 Answers3

3

This is a veritable weak point in the design of bash's programmable completion facilities. Even the “default” command completion -D takes effect for commands on a blank line only (provided that no complete -E is specified). Something like complete -I (for incompletely typed-in commands) is missing.

Armali
  • 18,255
  • 14
  • 57
  • 171
0

As of Bash 5.0, the bash built-in complete supports the -I option:

The -I option indicates that other supplied options and actions should apply to completion on the initial non-assignment word on the line, or after a command delimiter such as ‘;’ or ‘|’, which is usually command name completion.

I was able to download and install bash 5.1 on an ubuntu docker image with no problem and used this to emulate a tool environment shell. Bash 5 should mostly be a drop-in replacement.

zanerock
  • 3,042
  • 3
  • 26
  • 35
-3

bash completions are stored in /etc/bash_completion.d/ If you have root access, then you could edit/delete files there.

If you want to control things at the user level, then you could create and edit ~/.inputrc. Have a look at /etc/inputrc and it will give you an idea of where to start.

~/.inputrc overrides anything in /etc/inputrc, so you could change the places where bash_completion looks for completion files. You could make a local completion directory and have only the items you want completed in there. I believe you can also eliminate bash built-ins also.

There are also a couple of very good tutorials on bash completion online. Here Here

xizdaqrian
  • 716
  • 6
  • 10
  • He is specifically asking about controlling the completion of the *first* word on a command line. – chepner Jun 22 '12 at 00:19
  • and that is specifically what I am talking about. He wants to setup a controlled environment with limited access to tab expansion. I answered the question. Here is the quote "and need to control bash4 completions to filter unwanted suggestions" – xizdaqrian Jun 22 '12 at 01:17
  • The problem is that there appears to be no mechanism for controlling expansion of the *first* word. You can set completions for a completely empty line using 'complete -E'; otherwise, completions are based on a *completed* first word. – chepner Jun 22 '12 at 12:51
  • Sorry to drag this out but that's only partly true. If I have an empty command line and I type b - the first thing that completes is 'bluetooth-agent' which is in '/usr/bin' which is in my path. Now, let's say the OP restricts the path for the user to a directory containing only links or files he wants the user to run. Then, the FIRST word will be completed as he has requested. Unless I misunderstand the question. Please correct me if I do. I think bash -r, or a chroot jail should accomplish either of these. – xizdaqrian Jun 22 '12 at 22:27
  • If you read his question, he already clears his PATH to avoid completing such commands. One specific thing he is looking for is how to avoid completing `bash` built-ins as well. – chepner Jun 22 '12 at 22:57
  • Thanks a lot for discussing my question! Chepner is right, I'm not able to filter out bash internal commands from suggestions for first word. Still no luck so far:/ Even tweaking bash/readline source code is not option for me, because GUI (or TUI) I'm developing must be built on top of bash from official distribution. – Stanislav Pavlíček Jun 25 '12 at 10:43
  • Well, I did find a way to filter ALL empty commands from being completed. In bashrc, add 'shopt -s no_empty_cmd_completion'. That will keep ANYTHING from being completed, including builtins. I tried it myself in a test shell. Here is a link: http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html – xizdaqrian Jun 25 '12 at 17:22
  • ... btw I also added 'shopt -s restricted_shell' and 'shopt -u expand_aliases'. I also edited .inputrc to a single line, which is: 'disable_completion on'. That's probably more than you want, but it certainly did the trick. So much that even some of the keys on my keyboard no longer work under this set of configs. – xizdaqrian Jun 25 '12 at 17:25