diff options
author | amatanhead <amatanhead@yandex-team.ru> | 2022-02-10 16:50:04 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:50:04 +0300 |
commit | b6f3a80f7c2c8b7dbb0c01b056fdc1fd8cd820e9 (patch) | |
tree | 5d5cb817648f650d76cf1076100726fd9b8448e8 /library/cpp/getopt/small/completer.h | |
parent | 8879605a63ac17539be5b3bd41b529791f4d4b02 (diff) | |
download | ydb-b6f3a80f7c2c8b7dbb0c01b056fdc1fd8cd820e9.tar.gz |
Restoring authorship annotation for <amatanhead@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/getopt/small/completer.h')
-rw-r--r-- | library/cpp/getopt/small/completer.h | 612 |
1 files changed, 306 insertions, 306 deletions
diff --git a/library/cpp/getopt/small/completer.h b/library/cpp/getopt/small/completer.h index 6a2fdbbbf4..4136f13add 100644 --- a/library/cpp/getopt/small/completer.h +++ b/library/cpp/getopt/small/completer.h @@ -1,306 +1,306 @@ -#pragma once - -#include "formatted_output.h" - -#include <util/generic/strbuf.h> -#include <util/generic/hash.h> - -#include <utility> -#include <util/generic/fwd.h> - -namespace NLastGetopt::NComp { - class ICompleter; - - class TCompleterManager { - public: - TCompleterManager(TStringBuf command); - - /// Register new completer and get its function name. - TStringBuf GetCompleterID(const ICompleter* completer); - - /// Generate zsh code for all collected completers. - void GenerateZsh(TFormattedOutput& out); - - private: - TStringBuf Command_; - size_t Id_; - TVector<std::pair<TString, const ICompleter*>> Queue_; - }; - - class ICompleter { - public: - virtual ~ICompleter() = default; - - public: - /// Generate arbitrary bash code that modifies `COMPREPLY`. - virtual void GenerateBash(TFormattedOutput& out) const = 0; - - /// Generate action that will be used with `_arguments`. If this completer requires a separate function, - /// register it in the given manager and return function name assigned by manager. - /// Supported forms are '()', '(items...)', '((items...))', 'command ...' and ' command ...'. - /// Other forms, such as '{eval-string}', '->state', '=action' are not supported. - virtual TStringBuf GenerateZshAction(TCompleterManager& manager) const = 0; - - /// Generate body of a zsh function (if Action points to a custom function). - virtual void GenerateZsh(TFormattedOutput& out, TCompleterManager& manager) const = 0; - }; - - using ICompleterPtr = TSimpleSharedPtr<ICompleter>; - - /// Generate default completions. - /// Output of this completer depends on shell settings. - /// Usually ut generates file paths. - ICompleterPtr Default(); - - struct TAlternative { - /// Description for this group of completions. Leave empty to use completer's default description. - TString Description; - - /// Completer that generates values - ICompleterPtr Completer; - - TAlternative(ICompleterPtr completer) - : Description("") - , Completer(std::move(completer)) - { - } - - TAlternative(TString description, ICompleterPtr completer) - : Description(std::move(description)) - , Completer(std::move(completer)) - { - } - }; - - /// Run multiple completers and unite their output. - /// Each completer's output placed in a separate group with its own description. - ICompleterPtr Alternative(TVector<TAlternative> alternatives); - - struct TChoice { - /// Option value. - TString Choice; - - /// Description for a value. - TString Description = ""; - - TChoice(TString choice) - : Choice(std::move(choice)) - { - } - - TChoice(TString choice, TString description) - : Choice(std::move(choice)) - , Description(std::move(description)) - { - } - }; - - /// Complete items from a predefined list of choices. - ICompleterPtr Choice(TVector<TChoice> choices); - - /// Complete files and directories. May filter results by pattern, e.g. `*.txt`. - ICompleterPtr File(TString pattern= ""); - - /// Complete directories. - ICompleterPtr Directory(); - - /// Complete hosts. - ICompleterPtr Host(); - - /// Complete process IDs. - ICompleterPtr Pid(); - - /// Complete users that're found in the system. - ICompleterPtr User(); - - /// Complete user groups that're found in the system. - /// N: for some reason, - ICompleterPtr Group(); - - /// Complete URLs. - ICompleterPtr Url(); - - /// Complete TTY interfaces. - ICompleterPtr Tty(); - - /// Complete network interfaces. - ICompleterPtr NetInterface(); - - /// Complete timezone identifiers. - ICompleterPtr TimeZone(); - - /// Complete unix signal identifiers, e.g. `ABRT` or `KILL`. - ICompleterPtr Signal(); - - /// Complete domains. - ICompleterPtr Domain(); - - /// Custom completer. See `LaunchSelf` below. - class TCustomCompleter { - public: - static void FireCustomCompleter(int argc, const char** argv); - static void RegisterCustomCompleter(TCustomCompleter* completer) noexcept; - - struct TReg { - TReg(TCustomCompleter* completer) noexcept { - TCustomCompleter::RegisterCustomCompleter(completer); - } - }; - - public: - virtual ~TCustomCompleter() = default; - - public: - /// @param argc total number of command line arguments. - /// @param argv array of command line arguments. - /// @param curIdx index of the currently completed argument, may be equal to `argc` if cursor is at the end - /// of line. - /// @param cur currently completed argument. - /// @param prefix part of the currently completed argument before the cursor. - /// @param suffix part of the currently completed argument after the cursor. - virtual void GenerateCompletions(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix) = 0; - virtual TStringBuf GetUniqueName() const = 0; - - protected: - void AddCompletion(TStringBuf completion); - - private: - TCustomCompleter* Next_ = nullptr; - }; - - /// Custom completer for objects that consist of multiple parts split by a common separator, such as file paths. - class TMultipartCustomCompleter: public TCustomCompleter { - public: - TMultipartCustomCompleter(TStringBuf sep) - : Sep_(sep) - { - Y_VERIFY(!Sep_.empty()); - } - - public: - void GenerateCompletions(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix) final; - - public: - /// @param argc same as in `GenerateCompletions`. - /// @param argv same as in `GenerateCompletions`. - /// @param curIdx same as in `GenerateCompletions`. - /// @param cur same as in `GenerateCompletions`. - /// @param prefix same as in `GenerateCompletions`. - /// @param suffix same as in `GenerateCompletions`. - /// @param root part of the currently completed argument before the last separator. - virtual void GenerateCompletionParts(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix, TStringBuf root) = 0; - - protected: - TStringBuf Sep_; - }; - -#define Y_COMPLETER(N) \ -class T##N: public ::NLastGetopt::NComp::TCustomCompleter { \ - public: \ - void GenerateCompletions(int, const char**, int, TStringBuf, TStringBuf, TStringBuf) override; \ - TStringBuf GetUniqueName() const override { return #N; } \ - }; \ - T##N N = T##N(); \ - ::NLastGetopt::NComp::TCustomCompleter::TReg _Reg_##N = &N; \ - void T##N::GenerateCompletions( \ - Y_DECLARE_UNUSED int argc, \ - Y_DECLARE_UNUSED const char** argv, \ - Y_DECLARE_UNUSED int curIdx, \ - Y_DECLARE_UNUSED TStringBuf cur, \ - Y_DECLARE_UNUSED TStringBuf prefix, \ - Y_DECLARE_UNUSED TStringBuf suffix) - -#define Y_MULTIPART_COMPLETER(N, SEP) \ -class T##N: public ::NLastGetopt::NComp::TMultipartCustomCompleter { \ - public: \ - T##N() : ::NLastGetopt::NComp::TMultipartCustomCompleter(SEP) {} \ - void GenerateCompletionParts(int, const char**, int, TStringBuf, TStringBuf, TStringBuf, TStringBuf) override; \ - TStringBuf GetUniqueName() const override { return #N; } \ - }; \ - T##N N = T##N(); \ - ::NLastGetopt::NComp::TCustomCompleter::TReg _Reg_##N = &N; \ - void T##N::GenerateCompletionParts( \ - Y_DECLARE_UNUSED int argc, \ - Y_DECLARE_UNUSED const char** argv, \ - Y_DECLARE_UNUSED int curIdx, \ - Y_DECLARE_UNUSED TStringBuf cur, \ - Y_DECLARE_UNUSED TStringBuf prefix, \ - Y_DECLARE_UNUSED TStringBuf suffix, \ - Y_DECLARE_UNUSED TStringBuf root) - - /// Launches this binary with a specially formed flags and retrieves completions from stdout. - /// - /// Your application must be set up in a certain way for this to work. - /// - /// First, create a custom completer: - /// - /// ``` - /// Y_COMPLETER(SomeUniqueName) { - /// AddCompletion("foo"); - /// AddCompletion("bar"); - /// AddCompletion("baz"); - /// } - /// ``` - /// - /// Then, use it with this function. - /// - /// On completion attempt, completer will call your binary with some special arguments. - /// - /// In your main, before any other logic, call `TCustomCompleter::FireCustomCompleter`. This function will - /// check for said special arguments and invoke the right completer: - /// - /// ``` - /// int main(int argc, const char** argv) { - /// TCustomCompleter::FireCustomCompleter(argc, argv); - /// ... - /// } - /// ``` - ICompleterPtr LaunchSelf(TCustomCompleter& completer); - - /// Launches this binary with a specially formed flags and retrieves completions from stdout. - /// - /// Your application must be set up in a certain way for this to work. See `LaunchSelf` for more info. - /// - /// Multipart completion is designed for objects that consist of multiple parts split by a common separator. - /// It is ideal for completing remote file paths, for example. - /// - /// Multipart completers format stdout in the following way. - /// - /// On the first line, they print a common prefix that should be stripped from all completions. For example, - /// if you complete paths, this prefix would be a common directory. - /// - /// On the second line, they print a separator. If some completion ends with this separator, shell will not add - /// a whitespace after the item is completed. For example, if you complete paths, the separator would be a slash. - /// - /// On the following lines, they print completions, as formed by the `AddCompletion` function. - /// - /// For example, if a user invokes completion like this: - /// - /// ``` - /// $ program //home/logs/<tab><tab> - /// ``` - /// - /// The stdout might look like this: - /// - /// ``` - /// //home/logs/ - /// / - /// //home/logs/access-log - /// //home/logs/redir-log - /// //home/logs/blockstat-log - /// ``` - /// - /// Then autocompletion will look like this: - /// - /// ``` - /// $ program //home/logs/<tab><tab> - /// -- yt path -- - /// access-log redir-log blockstat-log - /// ``` - /// - /// Note: stdout lines with completion suggestions *must* be formatted by the `AddCompletion` function - /// because their format may change in the future. - /// - /// Note: we recommend using `Y_MULTIPART_COMPLETER` because it will handle all stdout printing for you. - ICompleterPtr LaunchSelfMultiPart(TCustomCompleter& completer); -} +#pragma once + +#include "formatted_output.h" + +#include <util/generic/strbuf.h> +#include <util/generic/hash.h> + +#include <utility> +#include <util/generic/fwd.h> + +namespace NLastGetopt::NComp { + class ICompleter; + + class TCompleterManager { + public: + TCompleterManager(TStringBuf command); + + /// Register new completer and get its function name. + TStringBuf GetCompleterID(const ICompleter* completer); + + /// Generate zsh code for all collected completers. + void GenerateZsh(TFormattedOutput& out); + + private: + TStringBuf Command_; + size_t Id_; + TVector<std::pair<TString, const ICompleter*>> Queue_; + }; + + class ICompleter { + public: + virtual ~ICompleter() = default; + + public: + /// Generate arbitrary bash code that modifies `COMPREPLY`. + virtual void GenerateBash(TFormattedOutput& out) const = 0; + + /// Generate action that will be used with `_arguments`. If this completer requires a separate function, + /// register it in the given manager and return function name assigned by manager. + /// Supported forms are '()', '(items...)', '((items...))', 'command ...' and ' command ...'. + /// Other forms, such as '{eval-string}', '->state', '=action' are not supported. + virtual TStringBuf GenerateZshAction(TCompleterManager& manager) const = 0; + + /// Generate body of a zsh function (if Action points to a custom function). + virtual void GenerateZsh(TFormattedOutput& out, TCompleterManager& manager) const = 0; + }; + + using ICompleterPtr = TSimpleSharedPtr<ICompleter>; + + /// Generate default completions. + /// Output of this completer depends on shell settings. + /// Usually ut generates file paths. + ICompleterPtr Default(); + + struct TAlternative { + /// Description for this group of completions. Leave empty to use completer's default description. + TString Description; + + /// Completer that generates values + ICompleterPtr Completer; + + TAlternative(ICompleterPtr completer) + : Description("") + , Completer(std::move(completer)) + { + } + + TAlternative(TString description, ICompleterPtr completer) + : Description(std::move(description)) + , Completer(std::move(completer)) + { + } + }; + + /// Run multiple completers and unite their output. + /// Each completer's output placed in a separate group with its own description. + ICompleterPtr Alternative(TVector<TAlternative> alternatives); + + struct TChoice { + /// Option value. + TString Choice; + + /// Description for a value. + TString Description = ""; + + TChoice(TString choice) + : Choice(std::move(choice)) + { + } + + TChoice(TString choice, TString description) + : Choice(std::move(choice)) + , Description(std::move(description)) + { + } + }; + + /// Complete items from a predefined list of choices. + ICompleterPtr Choice(TVector<TChoice> choices); + + /// Complete files and directories. May filter results by pattern, e.g. `*.txt`. + ICompleterPtr File(TString pattern= ""); + + /// Complete directories. + ICompleterPtr Directory(); + + /// Complete hosts. + ICompleterPtr Host(); + + /// Complete process IDs. + ICompleterPtr Pid(); + + /// Complete users that're found in the system. + ICompleterPtr User(); + + /// Complete user groups that're found in the system. + /// N: for some reason, + ICompleterPtr Group(); + + /// Complete URLs. + ICompleterPtr Url(); + + /// Complete TTY interfaces. + ICompleterPtr Tty(); + + /// Complete network interfaces. + ICompleterPtr NetInterface(); + + /// Complete timezone identifiers. + ICompleterPtr TimeZone(); + + /// Complete unix signal identifiers, e.g. `ABRT` or `KILL`. + ICompleterPtr Signal(); + + /// Complete domains. + ICompleterPtr Domain(); + + /// Custom completer. See `LaunchSelf` below. + class TCustomCompleter { + public: + static void FireCustomCompleter(int argc, const char** argv); + static void RegisterCustomCompleter(TCustomCompleter* completer) noexcept; + + struct TReg { + TReg(TCustomCompleter* completer) noexcept { + TCustomCompleter::RegisterCustomCompleter(completer); + } + }; + + public: + virtual ~TCustomCompleter() = default; + + public: + /// @param argc total number of command line arguments. + /// @param argv array of command line arguments. + /// @param curIdx index of the currently completed argument, may be equal to `argc` if cursor is at the end + /// of line. + /// @param cur currently completed argument. + /// @param prefix part of the currently completed argument before the cursor. + /// @param suffix part of the currently completed argument after the cursor. + virtual void GenerateCompletions(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix) = 0; + virtual TStringBuf GetUniqueName() const = 0; + + protected: + void AddCompletion(TStringBuf completion); + + private: + TCustomCompleter* Next_ = nullptr; + }; + + /// Custom completer for objects that consist of multiple parts split by a common separator, such as file paths. + class TMultipartCustomCompleter: public TCustomCompleter { + public: + TMultipartCustomCompleter(TStringBuf sep) + : Sep_(sep) + { + Y_VERIFY(!Sep_.empty()); + } + + public: + void GenerateCompletions(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix) final; + + public: + /// @param argc same as in `GenerateCompletions`. + /// @param argv same as in `GenerateCompletions`. + /// @param curIdx same as in `GenerateCompletions`. + /// @param cur same as in `GenerateCompletions`. + /// @param prefix same as in `GenerateCompletions`. + /// @param suffix same as in `GenerateCompletions`. + /// @param root part of the currently completed argument before the last separator. + virtual void GenerateCompletionParts(int argc, const char** argv, int curIdx, TStringBuf cur, TStringBuf prefix, TStringBuf suffix, TStringBuf root) = 0; + + protected: + TStringBuf Sep_; + }; + +#define Y_COMPLETER(N) \ +class T##N: public ::NLastGetopt::NComp::TCustomCompleter { \ + public: \ + void GenerateCompletions(int, const char**, int, TStringBuf, TStringBuf, TStringBuf) override; \ + TStringBuf GetUniqueName() const override { return #N; } \ + }; \ + T##N N = T##N(); \ + ::NLastGetopt::NComp::TCustomCompleter::TReg _Reg_##N = &N; \ + void T##N::GenerateCompletions( \ + Y_DECLARE_UNUSED int argc, \ + Y_DECLARE_UNUSED const char** argv, \ + Y_DECLARE_UNUSED int curIdx, \ + Y_DECLARE_UNUSED TStringBuf cur, \ + Y_DECLARE_UNUSED TStringBuf prefix, \ + Y_DECLARE_UNUSED TStringBuf suffix) + +#define Y_MULTIPART_COMPLETER(N, SEP) \ +class T##N: public ::NLastGetopt::NComp::TMultipartCustomCompleter { \ + public: \ + T##N() : ::NLastGetopt::NComp::TMultipartCustomCompleter(SEP) {} \ + void GenerateCompletionParts(int, const char**, int, TStringBuf, TStringBuf, TStringBuf, TStringBuf) override; \ + TStringBuf GetUniqueName() const override { return #N; } \ + }; \ + T##N N = T##N(); \ + ::NLastGetopt::NComp::TCustomCompleter::TReg _Reg_##N = &N; \ + void T##N::GenerateCompletionParts( \ + Y_DECLARE_UNUSED int argc, \ + Y_DECLARE_UNUSED const char** argv, \ + Y_DECLARE_UNUSED int curIdx, \ + Y_DECLARE_UNUSED TStringBuf cur, \ + Y_DECLARE_UNUSED TStringBuf prefix, \ + Y_DECLARE_UNUSED TStringBuf suffix, \ + Y_DECLARE_UNUSED TStringBuf root) + + /// Launches this binary with a specially formed flags and retrieves completions from stdout. + /// + /// Your application must be set up in a certain way for this to work. + /// + /// First, create a custom completer: + /// + /// ``` + /// Y_COMPLETER(SomeUniqueName) { + /// AddCompletion("foo"); + /// AddCompletion("bar"); + /// AddCompletion("baz"); + /// } + /// ``` + /// + /// Then, use it with this function. + /// + /// On completion attempt, completer will call your binary with some special arguments. + /// + /// In your main, before any other logic, call `TCustomCompleter::FireCustomCompleter`. This function will + /// check for said special arguments and invoke the right completer: + /// + /// ``` + /// int main(int argc, const char** argv) { + /// TCustomCompleter::FireCustomCompleter(argc, argv); + /// ... + /// } + /// ``` + ICompleterPtr LaunchSelf(TCustomCompleter& completer); + + /// Launches this binary with a specially formed flags and retrieves completions from stdout. + /// + /// Your application must be set up in a certain way for this to work. See `LaunchSelf` for more info. + /// + /// Multipart completion is designed for objects that consist of multiple parts split by a common separator. + /// It is ideal for completing remote file paths, for example. + /// + /// Multipart completers format stdout in the following way. + /// + /// On the first line, they print a common prefix that should be stripped from all completions. For example, + /// if you complete paths, this prefix would be a common directory. + /// + /// On the second line, they print a separator. If some completion ends with this separator, shell will not add + /// a whitespace after the item is completed. For example, if you complete paths, the separator would be a slash. + /// + /// On the following lines, they print completions, as formed by the `AddCompletion` function. + /// + /// For example, if a user invokes completion like this: + /// + /// ``` + /// $ program //home/logs/<tab><tab> + /// ``` + /// + /// The stdout might look like this: + /// + /// ``` + /// //home/logs/ + /// / + /// //home/logs/access-log + /// //home/logs/redir-log + /// //home/logs/blockstat-log + /// ``` + /// + /// Then autocompletion will look like this: + /// + /// ``` + /// $ program //home/logs/<tab><tab> + /// -- yt path -- + /// access-log redir-log blockstat-log + /// ``` + /// + /// Note: stdout lines with completion suggestions *must* be formatted by the `AddCompletion` function + /// because their format may change in the future. + /// + /// Note: we recommend using `Y_MULTIPART_COMPLETER` because it will handle all stdout printing for you. + ICompleterPtr LaunchSelfMultiPart(TCustomCompleter& completer); +} |