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