xref: /aosp_15_r20/external/gflags/src/gflags_completions.sh (revision 08ab5237c114d5c0eac1090c56f941d3f639d7d3)
1*08ab5237SOystein Eftevaag#!/bin/bash
2*08ab5237SOystein Eftevaag
3*08ab5237SOystein Eftevaag# Copyright (c) 2008, Google Inc.
4*08ab5237SOystein Eftevaag# All rights reserved.
5*08ab5237SOystein Eftevaag#
6*08ab5237SOystein Eftevaag# Redistribution and use in source and binary forms, with or without
7*08ab5237SOystein Eftevaag# modification, are permitted provided that the following conditions are
8*08ab5237SOystein Eftevaag# met:
9*08ab5237SOystein Eftevaag#
10*08ab5237SOystein Eftevaag#     * Redistributions of source code must retain the above copyright
11*08ab5237SOystein Eftevaag# notice, this list of conditions and the following disclaimer.
12*08ab5237SOystein Eftevaag#     * Redistributions in binary form must reproduce the above
13*08ab5237SOystein Eftevaag# copyright notice, this list of conditions and the following disclaimer
14*08ab5237SOystein Eftevaag# in the documentation and/or other materials provided with the
15*08ab5237SOystein Eftevaag# distribution.
16*08ab5237SOystein Eftevaag#     * Neither the name of Google Inc. nor the names of its
17*08ab5237SOystein Eftevaag# contributors may be used to endorse or promote products derived from
18*08ab5237SOystein Eftevaag# this software without specific prior written permission.
19*08ab5237SOystein Eftevaag#
20*08ab5237SOystein Eftevaag# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21*08ab5237SOystein Eftevaag# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*08ab5237SOystein Eftevaag# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23*08ab5237SOystein Eftevaag# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24*08ab5237SOystein Eftevaag# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25*08ab5237SOystein Eftevaag# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26*08ab5237SOystein Eftevaag# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*08ab5237SOystein Eftevaag# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*08ab5237SOystein Eftevaag# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*08ab5237SOystein Eftevaag# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30*08ab5237SOystein Eftevaag# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*08ab5237SOystein Eftevaag#
32*08ab5237SOystein Eftevaag# ---
33*08ab5237SOystein Eftevaag# Author: Dave Nicponski
34*08ab5237SOystein Eftevaag#
35*08ab5237SOystein Eftevaag# This script is invoked by bash in response to a matching compspec.  When
36*08ab5237SOystein Eftevaag# this happens, bash calls this script using the command shown in the -C
37*08ab5237SOystein Eftevaag# block of the complete entry, but also appends 3 arguments.  They are:
38*08ab5237SOystein Eftevaag#   - The command being used for completion
39*08ab5237SOystein Eftevaag#   - The word being completed
40*08ab5237SOystein Eftevaag#   - The word preceding the completion word.
41*08ab5237SOystein Eftevaag#
42*08ab5237SOystein Eftevaag# Here's an example of how you might use this script:
43*08ab5237SOystein Eftevaag# $ complete -o bashdefault -o default -o nospace -C                         \
44*08ab5237SOystein Eftevaag#   '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
45*08ab5237SOystein Eftevaag#   time  env  binary_name  another_binary  [...]
46*08ab5237SOystein Eftevaag
47*08ab5237SOystein Eftevaag# completion_word_index gets the index of the (N-1)th argument for
48*08ab5237SOystein Eftevaag# this command line.  completion_word gets the actual argument from
49*08ab5237SOystein Eftevaag# this command line at the (N-1)th position
50*08ab5237SOystein Eftevaagcompletion_word_index="$(($# - 1))"
51*08ab5237SOystein Eftevaagcompletion_word="${!completion_word_index}"
52*08ab5237SOystein Eftevaag
53*08ab5237SOystein Eftevaag# TODO(user): Replace this once gflags_completions.cc has
54*08ab5237SOystein Eftevaag# a bool parameter indicating unambiguously to hijack the process for
55*08ab5237SOystein Eftevaag# completion purposes.
56*08ab5237SOystein Eftevaagif [ -z "$completion_word" ]; then
57*08ab5237SOystein Eftevaag  # Until an empty value for the completion word stops being misunderstood
58*08ab5237SOystein Eftevaag  # by binaries, don't actually execute the binary or the process
59*08ab5237SOystein Eftevaag  # won't be hijacked!
60*08ab5237SOystein Eftevaag  exit 0
61*08ab5237SOystein Eftevaagfi
62*08ab5237SOystein Eftevaag
63*08ab5237SOystein Eftevaag# binary_index gets the index of the command being completed (which bash
64*08ab5237SOystein Eftevaag# places in the (N-2)nd position.  binary gets the actual command from
65*08ab5237SOystein Eftevaag# this command line at that (N-2)nd position
66*08ab5237SOystein Eftevaagbinary_index="$(($# - 2))"
67*08ab5237SOystein Eftevaagbinary="${!binary_index}"
68*08ab5237SOystein Eftevaag
69*08ab5237SOystein Eftevaag# For completions to be universal, we may have setup the compspec to
70*08ab5237SOystein Eftevaag# trigger on 'harmless pass-through' commands, like 'time' or 'env'.
71*08ab5237SOystein Eftevaag# If the command being completed is one of those two, we'll need to
72*08ab5237SOystein Eftevaag# identify the actual command being executed.  To do this, we need
73*08ab5237SOystein Eftevaag# the actual command line that the <TAB> was pressed on.  Bash helpfully
74*08ab5237SOystein Eftevaag# places this in the $COMP_LINE variable.
75*08ab5237SOystein Eftevaagif [ "$binary" == "time" ] || [ "$binary" == "env" ]; then
76*08ab5237SOystein Eftevaag  # we'll assume that the first 'argument' is actually the
77*08ab5237SOystein Eftevaag  # binary
78*08ab5237SOystein Eftevaag
79*08ab5237SOystein Eftevaag
80*08ab5237SOystein Eftevaag  # TODO(user): This is not perfect - the 'env' command, for instance,
81*08ab5237SOystein Eftevaag  #   is allowed to have options between the 'env' and 'the command to
82*08ab5237SOystein Eftevaag  #   be executed'.  For example, consider:
83*08ab5237SOystein Eftevaag  # $ env FOO="bar"  bin/do_something  --help<TAB>
84*08ab5237SOystein Eftevaag  # In this case, we'll mistake the FOO="bar" portion as the binary.
85*08ab5237SOystein Eftevaag  #   Perhaps we should continuing consuming leading words until we
86*08ab5237SOystein Eftevaag  #   either run out of words, or find a word that is a valid file
87*08ab5237SOystein Eftevaag  #   marked as executable.  I can't think of any reason this wouldn't
88*08ab5237SOystein Eftevaag  #   work.
89*08ab5237SOystein Eftevaag
90*08ab5237SOystein Eftevaag  # Break up the 'original command line' (not this script's command line,
91*08ab5237SOystein Eftevaag  # rather the one the <TAB> was pressed on) and find the second word.
92*08ab5237SOystein Eftevaag  parts=( ${COMP_LINE} )
93*08ab5237SOystein Eftevaag  binary=${parts[1]}
94*08ab5237SOystein Eftevaagfi
95*08ab5237SOystein Eftevaag
96*08ab5237SOystein Eftevaag# Build the command line to use for completion.  Basically it involves
97*08ab5237SOystein Eftevaag# passing through all the arguments given to this script (except the 3
98*08ab5237SOystein Eftevaag# that bash added), and appending a '--tab_completion_word "WORD"' to
99*08ab5237SOystein Eftevaag# the arguments.
100*08ab5237SOystein Eftevaagparams=""
101*08ab5237SOystein Eftevaagfor ((i=1; i<=$(($# - 3)); ++i)); do
102*08ab5237SOystein Eftevaag  params="$params \"${!i}\"";
103*08ab5237SOystein Eftevaagdone
104*08ab5237SOystein Eftevaagparams="$params --tab_completion_word \"$completion_word\""
105*08ab5237SOystein Eftevaag
106*08ab5237SOystein Eftevaag# TODO(user): Perhaps stash the output in a temporary file somewhere
107*08ab5237SOystein Eftevaag# in /tmp, and only cat it to stdout if the command returned a success
108*08ab5237SOystein Eftevaag# code, to prevent false positives
109*08ab5237SOystein Eftevaag
110*08ab5237SOystein Eftevaag# If we think we have a reasonable command to execute, then execute it
111*08ab5237SOystein Eftevaag# and hope for the best.
112*08ab5237SOystein Eftevaagcandidate=$(type -p "$binary")
113*08ab5237SOystein Eftevaagif [ ! -z "$candidate" ]; then
114*08ab5237SOystein Eftevaag  eval "$candidate 2>/dev/null $params"
115*08ab5237SOystein Eftevaagelif [ -f "$binary" ] && [ -x "$binary" ]; then
116*08ab5237SOystein Eftevaag  eval "$binary 2>/dev/null $params"
117*08ab5237SOystein Eftevaagfi
118