1 //===-- Highlighter.h -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_CORE_HIGHLIGHTER_H 10 #define LLDB_CORE_HIGHLIGHTER_H 11 12 #include <optional> 13 #include <utility> 14 #include <vector> 15 16 #include "lldb/Utility/Stream.h" 17 #include "lldb/lldb-enumerations.h" 18 #include "llvm/ADT/StringRef.h" 19 20 namespace lldb_private { 21 22 /// Represents style that the highlighter should apply to the given source code. 23 /// Stores information about how every kind of token should be annotated. 24 struct HighlightStyle { 25 26 /// A pair of strings that should be placed around a certain token. Usually 27 /// stores color codes in these strings (the suffix string is often used for 28 /// resetting the terminal attributes back to normal). 29 class ColorStyle { 30 std::string m_prefix; 31 std::string m_suffix; 32 33 public: 34 ColorStyle() = default; ColorStyleHighlightStyle35 ColorStyle(llvm::StringRef prefix, llvm::StringRef suffix) { 36 Set(prefix, suffix); 37 } 38 39 /// Applies this style to the given value. 40 /// \param s 41 /// The stream to which the result should be appended. 42 /// \param value 43 /// The value that we should place our strings around. 44 void Apply(Stream &s, llvm::StringRef value) const; 45 46 /// Sets the prefix and suffix strings. 47 void Set(llvm::StringRef prefix, llvm::StringRef suffix); 48 }; 49 50 /// The style for the token which is below the cursor of the user. Note that 51 /// this style is overwritten by the SourceManager with the values of 52 /// stop-show-column-ansi-prefix/stop-show-column-ansi-suffix. 53 ColorStyle selected; 54 55 /// Matches identifiers to variable or functions. 56 ColorStyle identifier; 57 /// Matches any string or character literals in the language: "foo" or 'f' 58 ColorStyle string_literal; 59 /// Matches scalar value literals like '42' or '0.1'. 60 ColorStyle scalar_literal; 61 /// Matches all reserved keywords in the language. 62 ColorStyle keyword; 63 /// Matches any comments in the language. 64 ColorStyle comment; 65 /// Matches commas: ',' 66 ColorStyle comma; 67 /// Matches one colon: ':' 68 ColorStyle colon; 69 /// Matches any semicolon: ';' 70 ColorStyle semicolons; 71 /// Matches operators like '+', '-', '%', '&', '=' 72 ColorStyle operators; 73 74 /// Matches '{' or '}' 75 ColorStyle braces; 76 /// Matches '[' or ']' 77 ColorStyle square_brackets; 78 /// Matches '(' or ')' 79 ColorStyle parentheses; 80 81 // C language specific options 82 83 /// Matches directives to a preprocessor (if the language has any). 84 ColorStyle pp_directive; 85 86 /// Returns a HighlightStyle that is based on vim's default highlight style. 87 static HighlightStyle MakeVimStyle(); 88 }; 89 90 /// Annotates source code with color attributes. 91 class Highlighter { 92 public: 93 Highlighter() = default; 94 virtual ~Highlighter() = default; 95 Highlighter(const Highlighter &) = delete; 96 const Highlighter &operator=(const Highlighter &) = delete; 97 98 /// Returns a human readable name for the selected highlighter. 99 virtual llvm::StringRef GetName() const = 0; 100 101 /// Highlights the given line 102 /// \param options 103 /// The highlight options. 104 /// \param line 105 /// The user supplied line that needs to be highlighted. 106 /// \param cursor_pos 107 /// The cursor position of the user in this line, starting at 0 (which 108 /// means the cursor is on the first character in 'line'). 109 /// \param previous_lines 110 /// Any previous lines the user has written which we should only use 111 /// for getting the context of the Highlighting right. 112 /// \param s 113 /// The stream to which the highlighted version of the user string should 114 /// be written. 115 virtual void Highlight(const HighlightStyle &options, llvm::StringRef line, 116 std::optional<size_t> cursor_pos, 117 llvm::StringRef previous_lines, Stream &s) const = 0; 118 119 /// Utility method for calling Highlight without a stream. 120 std::string Highlight(const HighlightStyle &options, llvm::StringRef line, 121 std::optional<size_t> cursor_pos, 122 llvm::StringRef previous_lines = "") const; 123 }; 124 125 /// A default highlighter that only highlights the user cursor, but doesn't 126 /// do any other highlighting. 127 class DefaultHighlighter : public Highlighter { 128 public: GetName()129 llvm::StringRef GetName() const override { return "none"; } 130 131 void Highlight(const HighlightStyle &options, llvm::StringRef line, 132 std::optional<size_t> cursor_pos, 133 llvm::StringRef previous_lines, Stream &s) const override; 134 }; 135 136 /// Manages the available highlighters. 137 class HighlighterManager { 138 DefaultHighlighter m_default; 139 140 public: 141 /// Queries all known highlighter for one that can highlight some source code. 142 /// \param language_type 143 /// The language type that the caller thinks the source code was given in. 144 /// \param path 145 /// The path to the file the source code is from. Used as a fallback when 146 /// the user can't provide a language. 147 /// \return 148 /// The highlighter that wants to highlight the source code. Could be an 149 /// empty highlighter that does nothing. 150 const Highlighter &getHighlighterFor(lldb::LanguageType language_type, 151 llvm::StringRef path) const; getDefaultHighlighter()152 const Highlighter &getDefaultHighlighter() const { return m_default; } 153 }; 154 155 } // namespace lldb_private 156 157 #endif // LLDB_CORE_HIGHLIGHTER_H 158