Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Matching anywhere in the filename is rather complicated, and I'm not sure it's really all that useful. Matching at the start of filenames makes more sense and is much easier to implement, even recursively.</p> <p>Now, you mentioned find as a requirement, but bash (since version 4.0) can also find files recursively, and it should be more efficient to let bash do that part. To match recursively in bash, you enable the globstar shell option by running <code>shopt -s globstar</code>, then two consecutive asterisks, <code>**</code>, will match recursively. </p> <p>Next up, given that you want to match files recursively inside a git repository, we best have a way to detect that we're actually in a git repository, otherwise, if you accidentally trigger it in <code>/</code> for instance, your prompt will hang while waiting for bash to search through your entire filesystem. The following function should be fairly efficient at determining if we're inside a git repository. Given the current working directory, e.g. <code>/foo/bar/baz</code>, it'll look for <code>/foo/bar/baz/.git</code>, <code>/foo/bar/.git</code>, <code>/foo/.git</code>, <code>/.git</code> and return true if it finds one, false otherwise.</p> <pre><code>isgit() { local p=$PWD while [[ $p ]]; do [[ -d $p/.git ]] &amp;&amp; return p=${p%/*} done return 1 } </code></pre> <p>For simplicity, we'll create a <code>gadd</code> command to add the completions for. A completion function can only be applied to the first word of the command. E.g. we can add completion for <code>git</code>, but not <code>git add</code>, thus we'll make a new command that turns <code>git add</code> into one word.</p> <pre><code>gadd() { git add "$@" } </code></pre> <p>Now for the actual completion function. When triggered by hitting TAB, the function will be invoked with three arguments. <code>$1</code> is the command being completed, <code>$2</code> is the current word of the command line being completed, and <code>$3</code> is the previous word on the line. So the files we want to search will be matched by the glob <code>**/"$2"*</code>; all files starting with <code>"$2"</code>. We iterate these filenames, and append them to the COMPREPLY array. If the COMPREPLY array only contains one value when the function is done, the word will be replaced by that value. If it contains more than one value, hit tab another time to get a list of all the matches.</p> <pre><code>shopt -s globstar _git_add_complete() { local file isgit || return for file in **/"$2"*; do # If the glob doesn't match, we'll get the glob itself, so make sure # we have an existing file [[ -e $file ]] || continue # If it's a directory, add a trailing / [[ -d $file ]] &amp;&amp; file+=/ COMPREPLY+=( "$file" ) done } complete -F _git_add_complete gadd </code></pre> <p>Add the above three code blocks to your <code>~/.bashrc</code>, then open a new terminal, enter a git repository and try <code>gadd something&lt;tab&gt;</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload