1895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Copyright (c) 2008, Google Inc. 2895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// All rights reserved. 3895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 4895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Redistribution and use in source and binary forms, with or without 5895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// modification, are permitted provided that the following conditions are 6895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// met: 7895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 8895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// * Redistributions of source code must retain the above copyright 9895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// notice, this list of conditions and the following disclaimer. 10895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// * Redistributions in binary form must reproduce the above 11895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// copyright notice, this list of conditions and the following disclaimer 12895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// in the documentation and/or other materials provided with the 13895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// distribution. 14895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// * Neither the name of Google Inc. nor the names of its 15895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// contributors may be used to endorse or promote products derived from 16895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// this software without specific prior written permission. 17895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 18895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 30895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// --- 31895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Author: Dave Nicponski 32895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 33895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Implement helpful bash-style command line flag completions 34895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 35895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// ** Functional API: 36895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// HandleCommandLineCompletions() should be called early during 37895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// program startup, but after command line flag code has been 38895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// initialized, such as the beginning of HandleCommandLineHelpFlags(). 39895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// It checks the value of the flag --tab_completion_word. If this 40895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// flag is empty, nothing happens here. If it contains a string, 41895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// however, then HandleCommandLineCompletions() will hijack the 42895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// process, attempting to identify the intention behind this 43895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// completion. Regardless of the outcome of this deduction, the 44895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// process will be terminated, similar to --helpshort flag 45895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// handling. 46895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 47895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// ** Overview of Bash completions: 48895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Bash can be told to programatically determine completions for the 49895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// current 'cursor word'. It does this by (in this case) invoking a 50895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// command with some additional arguments identifying the command 51895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// being executed, the word being completed, and the previous word 52895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// (if any). Bash then expects a sequence of output lines to be 53895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// printed to stdout. If these lines all contain a common prefix 54895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// longer than the cursor word, bash will replace the cursor word 55895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// with that common prefix, and display nothing. If there isn't such 56895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// a common prefix, bash will display the lines in pages using 'more'. 57895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 58895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// ** Strategy taken for command line completions: 59895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// If we can deduce either the exact flag intended, or a common flag 60895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// prefix, we'll output exactly that. Otherwise, if information 61895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// must be displayed to the user, we'll take the opportunity to add 62895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// some helpful information beyond just the flag name (specifically, 63895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// we'll include the default flag value and as much of the flag's 64895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// description as can fit on a single terminal line width, as specified 65895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// by the flag --tab_completion_columns). Furthermore, we'll try to 66895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// make bash order the output such that the most useful or relevent 67895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// flags are the most likely to be shown at the top. 68895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 69895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// ** Additional features: 70895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// To assist in finding that one really useful flag, substring matching 71895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// was implemented. Before pressing a <TAB> to get completion for the 72895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// current word, you can append one or more '?' to the flag to do 73895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// substring matching. Here's the semantics: 74895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// --foo<TAB> Show me all flags with names prefixed by 'foo' 75895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// --foo?<TAB> Show me all flags with 'foo' somewhere in the name 76895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// --foo??<TAB> Same as prior case, but also search in module 77895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// definition path for 'foo' 78895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// --foo???<TAB> Same as prior case, but also search in flag 79895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// descriptions for 'foo' 80895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Finally, we'll trim the output to a relatively small number of 81895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// flags to keep bash quiet about the verbosity of output. If one 82895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// really wanted to see all possible matches, appending a '+' to the 83895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// search word will force the exhaustive list of matches to be printed. 84895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 85895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// ** How to have bash accept completions from a binary: 86895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Bash requires that it be informed about each command that programmatic 87895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// completion should be enabled for. Example addition to a .bashrc 88895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// file would be (your path to gflags_completions.sh file may differ): 89895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 90895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid/* 91895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid$ complete -o bashdefault -o default -o nospace -C \ 92895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ 93895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid time env binary_name another_binary [...] 94895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid*/ 95895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 96895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// This would allow the following to work: 97895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// $ /path/to/binary_name --vmodule<TAB> 98895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Or: 99895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// $ ./bin/path/another_binary --gfs_u<TAB> 100895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// (etc) 101895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// 102895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Sadly, it appears that bash gives no easy way to force this behavior for 103895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// all commands. That's where the "time" in the above example comes in. 104895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// If you haven't specifically added a command to the list of completion 105895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// supported commands, you can still get completions by prefixing the 106895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// entire command with "env". 107895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// $ env /some/brand/new/binary --vmod<TAB> 108895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// Assuming that "binary" is a newly compiled binary, this should still 109895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid// produce the expected completion output. 110895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 111895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 112895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ 113895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid#define GOOGLE_GFLAGS_COMPLETIONS_H_ 114895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 115895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsidnamespace google { 116895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 117895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsidvoid HandleCommandLineCompletions(void); 118895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 119895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid} 120895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid 121895d3d17ee873ea12b64db0df2d2e2e390c9d5e8nealsid#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ 122