diff options
| author | Stefan Boberg <[email protected]> | 2026-04-23 18:16:57 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2026-04-23 18:16:57 +0200 |
| commit | 0232b991cd7d8e3a2114ea30e4591dd3e7b65c36 (patch) | |
| tree | 94730e7594fd09ae1fa820391ce311f6daf13905 /src/zen/zen.h | |
| parent | Fix forward declaration order for s_GotSigWinch and SigWinchHandler (diff) | |
| parent | trace: declare Region event name fields as AnsiString (#1012) (diff) | |
| download | archived-zen-sb/zen-help.tar.xz archived-zen-sb/zen-help.zip | |
Merge branch 'main' into sb/zen-helpsb/zen-help
- Combine HelpCommand (this branch) with HistoryCommand (main) in zen CLI dispatcher
- Keep filter-aware TuiPickOne rewrite; adopt main's ASCII arrow glyphs in doc comment
Diffstat (limited to 'src/zen/zen.h')
| -rw-r--r-- | src/zen/zen.h | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/src/zen/zen.h b/src/zen/zen.h index 80178910a..5cf3b99ed 100644 --- a/src/zen/zen.h +++ b/src/zen/zen.h @@ -9,12 +9,15 @@ #include <zenutil/config/commandlineoptions.h> #include <zenutil/config/loggingconfig.h> +#include <csignal> + namespace zen { struct ZenCliOptions { - bool IsDebug = false; - bool IsVerbose = false; + bool IsDebug = false; + bool IsVerbose = false; + bool EnableExecutionHistory = true; ZenLoggingConfig LoggingConfig; @@ -37,6 +40,33 @@ extern ZenCmdCategory g_ProjectStoreCategory; extern ZenCmdCategory g_CacheStoreCategory; extern ZenCmdCategory g_StorageCategory; +// RAII wrapper around `signal(2)` that restores the previous handler on scope +// exit. Use in command Run() methods so an exception during option parsing or +// execution doesn't leave a handler installed whose flag is scoped to a +// now-dead lifetime. +class ScopedSignalHandler +{ +public: + using Handler = void (*)(int); + + ScopedSignalHandler(int SigNum, Handler NewHandler) : m_SigNum(SigNum), m_PrevHandler(std::signal(SigNum, NewHandler)) {} + + ~ScopedSignalHandler() + { + if (m_PrevHandler != SIG_ERR) + { + std::signal(m_SigNum, m_PrevHandler); + } + } + + ScopedSignalHandler(const ScopedSignalHandler&) = delete; + ScopedSignalHandler& operator=(const ScopedSignalHandler&) = delete; + +private: + int m_SigNum; + Handler m_PrevHandler; +}; + class ErrorWithReturnCode : public std::runtime_error { public: @@ -58,6 +88,11 @@ public: virtual cxxopts::Options& Options() = 0; virtual ZenCmdCategory& CommandCategory() const; + // Hidden commands are dispatched normally but omitted from the top-level + // `zen --help` listing. Used for deprecated aliases that remain functional + // but should not be advertised. + virtual bool IsHidden() const { return false; } + bool ParseOptions(int argc, char** argv); static bool ParseOptions(cxxopts::Options& Options, int argc, char** argv); static bool ParseOptionsPermissive(cxxopts::Options& Options, int argc, char** argv, std::vector<std::string>& OutUnmatched); @@ -103,15 +138,19 @@ class ZenSubCmdBase public: ZenSubCmdBase(std::string_view Name, std::string_view Description); virtual ~ZenSubCmdBase() = default; - cxxopts::Options& SubOptions() { return m_SubOptions; } - std::string_view Description() const { return m_Description; } - virtual void Run(const ZenCliOptions& GlobalOptions) = 0; + cxxopts::Options& SubOptions() { return m_SubOptions; } + std::string_view Description() const { return m_Description; } + const std::vector<std::string>& Aliases() const { return m_Aliases; } + virtual void Run(const ZenCliOptions& GlobalOptions) = 0; protected: + void AddAlias(std::string Alias) { m_Aliases.push_back(std::move(Alias)); } + cxxopts::Options m_SubOptions; private: - std::string m_Description; + std::string m_Description; + std::vector<std::string> m_Aliases; }; // Base for commands that host subcommands - handles all dispatch boilerplate |