diff options
Diffstat (limited to 'src/base/string_attr_type.hh')
-rw-r--r-- | src/base/string_attr_type.hh | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/src/base/string_attr_type.hh b/src/base/string_attr_type.hh new file mode 100644 index 0000000..fe1b987 --- /dev/null +++ b/src/base/string_attr_type.hh @@ -0,0 +1,670 @@ +/** + * Copyright (c) 2020, Timothy Stack + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of Timothy Stack nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef lnav_string_attr_type_hh +#define lnav_string_attr_type_hh + +#include <string> +#include <utility> + +#include <stdint.h> + +#include "base/intern_string.hh" +#include "mapbox/variant.hpp" + +class logfile; +struct bookmark_metadata; + +/** Roles that can be mapped to curses attributes using attrs_for_role() */ +enum class role_t : int32_t { + VCR_NONE = -1, + + VCR_TEXT, /*< Raw text. */ + VCR_IDENTIFIER, + VCR_SEARCH, /*< A search hit. */ + VCR_OK, + VCR_INFO, + VCR_ERROR, /*< An error message. */ + VCR_WARNING, /*< A warning message. */ + VCR_ALT_ROW, /*< Highlight for alternating rows in a list */ + VCR_HIDDEN, + VCR_ADJUSTED_TIME, + VCR_SKEWED_TIME, + VCR_OFFSET_TIME, + VCR_INVALID_MSG, + VCR_STATUS, /*< Normal status line text. */ + VCR_WARN_STATUS, + VCR_ALERT_STATUS, /*< Alert status line text. */ + VCR_ACTIVE_STATUS, /*< */ + VCR_ACTIVE_STATUS2, /*< */ + VCR_STATUS_TITLE, + VCR_STATUS_SUBTITLE, + VCR_STATUS_INFO, + VCR_STATUS_STITCH_TITLE_TO_SUB, + VCR_STATUS_STITCH_SUB_TO_TITLE, + VCR_STATUS_STITCH_SUB_TO_NORMAL, + VCR_STATUS_STITCH_NORMAL_TO_SUB, + VCR_STATUS_STITCH_TITLE_TO_NORMAL, + VCR_STATUS_STITCH_NORMAL_TO_TITLE, + VCR_STATUS_TITLE_HOTKEY, + VCR_STATUS_DISABLED_TITLE, + VCR_STATUS_HOTKEY, + VCR_INACTIVE_STATUS, + VCR_INACTIVE_ALERT_STATUS, + VCR_SCROLLBAR, + VCR_SCROLLBAR_ERROR, + VCR_SCROLLBAR_WARNING, + VCR_FOCUSED, + VCR_DISABLED_FOCUSED, + VCR_POPUP, + VCR_COLOR_HINT, + + VCR_QUOTED_CODE, + VCR_CODE_BORDER, + VCR_KEYWORD, + VCR_STRING, + VCR_COMMENT, + VCR_DOC_DIRECTIVE, + VCR_VARIABLE, + VCR_SYMBOL, + VCR_NUMBER, + VCR_RE_SPECIAL, + VCR_RE_REPEAT, + VCR_FILE, + + VCR_DIFF_DELETE, /*< Deleted line in a diff. */ + VCR_DIFF_ADD, /*< Added line in a diff. */ + VCR_DIFF_SECTION, /*< Section marker in a diff. */ + + VCR_LOW_THRESHOLD, + VCR_MED_THRESHOLD, + VCR_HIGH_THRESHOLD, + + VCR_H1, + VCR_H2, + VCR_H3, + VCR_H4, + VCR_H5, + VCR_H6, + + VCR_HR, + VCR_HYPERLINK, + VCR_LIST_GLYPH, + VCR_BREADCRUMB, + VCR_TABLE_BORDER, + VCR_TABLE_HEADER, + VCR_QUOTE_BORDER, + VCR_QUOTED_TEXT, + VCR_FOOTNOTE_BORDER, + VCR_FOOTNOTE_TEXT, + VCR_SNIPPET_BORDER, + + VCR__MAX +}; + +struct text_attrs { + bool empty() const + { + return this->ta_attrs == 0 && !this->ta_fg_color && !this->ta_bg_color; + } + + text_attrs operator|(const text_attrs& other) const + { + return text_attrs{ + this->ta_attrs | other.ta_attrs, + this->ta_fg_color ? this->ta_fg_color : other.ta_fg_color, + this->ta_bg_color ? this->ta_bg_color : other.ta_bg_color, + }; + } + + bool operator==(const text_attrs& other) const + { + return this->ta_attrs == other.ta_attrs && + this->ta_fg_color == other.ta_fg_color && + this->ta_bg_color == other.ta_bg_color; + } + + int32_t ta_attrs{0}; + nonstd::optional<short> ta_fg_color; + nonstd::optional<short> ta_bg_color; +}; + +using string_attr_value = mapbox::util::variant<int64_t, + role_t, + text_attrs, + const intern_string_t, + std::string, + std::shared_ptr<logfile>, + bookmark_metadata*, + timespec, + string_fragment>; + +class string_attr_type_base { +public: + explicit string_attr_type_base(const char* name) noexcept : sat_name(name) + { + } + + const char* const sat_name; +}; + +using string_attr_pair + = std::pair<const string_attr_type_base*, string_attr_value>; + +template<typename T> +class string_attr_type : public string_attr_type_base { +public: + using value_type = T; + + explicit string_attr_type(const char* name) noexcept + : string_attr_type_base(name) + { + } + + template<typename U = T> + std::enable_if_t<!std::is_void<U>::value, string_attr_pair> value( + const U& val) const + { + return std::make_pair(this, val); + } + + template<typename U = T> + std::enable_if_t<std::is_void<U>::value, string_attr_pair> value() const + { + return std::make_pair(this, string_attr_value{}); + } +}; + +extern string_attr_type<void> SA_ORIGINAL_LINE; +extern string_attr_type<void> SA_BODY; +extern string_attr_type<void> SA_HIDDEN; +extern string_attr_type<const intern_string_t> SA_FORMAT; +extern string_attr_type<void> SA_REMOVED; +extern string_attr_type<void> SA_PREFORMATTED; +extern string_attr_type<std::string> SA_INVALID; +extern string_attr_type<std::string> SA_ERROR; +extern string_attr_type<int64_t> SA_LEVEL; +extern string_attr_type<string_fragment> SA_ORIGIN; +extern string_attr_type<int64_t> SA_ORIGIN_OFFSET; + +extern string_attr_type<role_t> VC_ROLE; +extern string_attr_type<role_t> VC_ROLE_FG; +extern string_attr_type<text_attrs> VC_STYLE; +extern string_attr_type<int64_t> VC_GRAPHIC; +extern string_attr_type<int64_t> VC_FOREGROUND; +extern string_attr_type<int64_t> VC_BACKGROUND; + +namespace lnav { + +namespace string { +namespace attrs { + +template<typename S> +inline std::pair<S, string_attr_pair> +preformatted(S str) +{ + return std::make_pair(std::move(str), SA_PREFORMATTED.template value()); +} + +} // namespace attrs +} // namespace string + +namespace roles { + +template<typename S> +inline std::pair<S, string_attr_pair> +error(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_ERROR)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +warning(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_WARNING)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +status(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_STATUS)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +inactive_status(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_INACTIVE_STATUS)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +status_title(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_STATUS_TITLE)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +ok(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_OK)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +file(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_FILE)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +symbol(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_SYMBOL)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +keyword(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_KEYWORD)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +variable(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_VARIABLE)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +number(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_NUMBER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +comment(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_COMMENT)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +identifier(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_IDENTIFIER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +hr(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_HR)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +hyperlink(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_HYPERLINK)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +list_glyph(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_LIST_GLYPH)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +breadcrumb(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_BREADCRUMB)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +quoted_code(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_QUOTED_CODE)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +code_border(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_CODE_BORDER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +table_border(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_TABLE_BORDER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +table_header(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_TABLE_HEADER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +quote_border(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_QUOTE_BORDER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +quoted_text(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_QUOTED_TEXT)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +footnote_border(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_FOOTNOTE_BORDER)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +footnote_text(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_FOOTNOTE_TEXT)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h1(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H1)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h2(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H2)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h3(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H3)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h4(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H4)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h5(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H5)); +} + +template<typename S> +inline std::pair<S, string_attr_pair> +h6(S str) +{ + return std::make_pair(std::move(str), + VC_ROLE.template value(role_t::VCR_H6)); +} + +namespace literals { + +inline std::pair<std::string, string_attr_pair> operator"" _ok(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_OK)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _error( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_ERROR)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _info( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_INFO)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _symbol( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_SYMBOL)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _keyword( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_KEYWORD)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _variable( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_VARIABLE)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _comment( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_COMMENT)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _hotkey( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_STATUS_HOTKEY)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _h1(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_H1)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _h2(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_H2)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _h3(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_H3)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _h4(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_H4)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _h5(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_H5)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _hr(const char* str, + std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_HR)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _hyperlink( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_HYPERLINK)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _list_glyph( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_LIST_GLYPH)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _breadcrumb( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_BREADCRUMB)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _quoted_code( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_QUOTED_CODE)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _code_border( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_CODE_BORDER)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _table_border( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_TABLE_BORDER)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _quote_border( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_QUOTE_BORDER)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _quoted_text( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_QUOTED_TEXT)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _footnote_border( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_FOOTNOTE_BORDER)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _footnote_text( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_FOOTNOTE_BORDER)); +} + +inline std::pair<std::string, string_attr_pair> operator"" _snippet_border( + const char* str, std::size_t len) +{ + return std::make_pair(std::string(str, len), + VC_ROLE.template value(role_t::VCR_SNIPPET_BORDER)); +} + +} // namespace literals + +} // namespace roles +} // namespace lnav + +#endif |