scop / bash-completion

Programmable completion functions for bash
GNU General Public License v2.0
2.92k stars 380 forks source link

$HO<TAB> should become $HOME, no matter what position it is in in the command line #553

Open jidanni opened 3 years ago

jidanni commented 3 years ago

Can you please allow $BROWSER, etc. known variables to be expanded here: $ some_command <<< 3254 | sed $\!d | xargs $BROWSER

What good is not allowing $BROWSER to complete there?

akinomyoga commented 3 years ago

This is indeed an interesting idea, but there are several problems.

First, it conflicts with the completion of variable names. When a user hit TAB after $BROWSER, bash-completion doesn't know whether the user wants to complete the variable names starting from BROWSER or wants to expand the variable content.

Also, I don't think it is always useful to perform parameter expansions. For example, when some variable var has a very large size of data, a user doesn't want to expand such a large data in the command line. As TAB is frequently used for completions, users can unintendedly hit TAB after $var and find that the content is unexpectedly expanded in the command line, which is not user-friendly.

I think you should bind the feature to a distinct key other than TAB. For example, you may use M-C-e (bounded by the readline bindable function shell-expand-line) to perform shell expansions though it can cause problems because it changes the quoting. For example, in your case, $\!d will be replaced by $!d which has a different meaning. Instead of using shell-expand-line, you may define a custom bindable function and bind it to a keysequence using bind -x. I haven't tested it at all, but something like:

# bashrc
function _jidanni_expand_variable {
  local prefix=${READLINE_LINE::READLINE_POINT}
  local suffix=${READLINE_LINE:READLINE_POINT}
  local rex='\$([a-zA-Z_][a-zA-Z_0-9]*)$' LC_COLLATE=C.UTF-8
  [[ $prefix =~ $rex ]] || return 0
  prefix=${prefix::-${#BASH_REMATCH}}${!BASH_REMATCH[1]-}
  READLINE_LINE=$prefix$suffix
  READLINE_POINT=${#prefix}
}
bind -x '"\C-x\t": _jidanni_expand_variable'
jidanni commented 3 years ago

Sorry I didn't make myself clear. If

$ $BRO<TAB>

becomes

$ $BROWSER

at the beginning of lines, it should also do the same at other positions.

jidanni commented 3 years ago
$ : $BROWSER | xargs $BRO<TAB>
jidanni commented 3 years ago

I just don't want to have to type ... W S E R. I'm not wanting to see the value of the variable. I just want the name to be filled in for me.

akinomyoga commented 3 years ago

Well... it's honestly very weird though I wouldn't say it explicitly. Could you update the issue title which is hardly related to your new explanation? It is always welcome to update the goal on necessary with appropriate and honest comments. Anyway, it is indeed another good point that the command name completions and the completion by _minimal (the completer for :, echo, etc.) complete the variable names correctly, but _command (the completer for xargs) fails to do it.

jidanni commented 3 years ago

Actually all this has nothing to do with xargs, etc.

The tab expansion here doesn't need to even know anything about where it is in the entire command line.