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
20namespace 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.
24struct 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;
35 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.
91class Highlighter {
92public:
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.
127class DefaultHighlighter : public Highlighter {
128public:
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.
137class HighlighterManager {
138 DefaultHighlighter m_default;
139
140public:
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;
152 const Highlighter &getDefaultHighlighter() const { return m_default; }
153};
154
155} // namespace lldb_private
156
157#endif // LLDB_CORE_HIGHLIGHTER_H
158

source code of lldb/include/lldb/Core/Highlighter.h