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
19namespace 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.
23struct 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;
34 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.
90class Highlighter {
91public:
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.
126class DefaultHighlighter : public Highlighter {
127public:
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.
136class HighlighterManager {
137 DefaultHighlighter m_default;
138
139public:
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;
151 const Highlighter &getDefaultHighlighter() const { return m_default; }
152};
153
154} // namespace lldb_private
155
156#endif // LLDB_CORE_HIGHLIGHTER_H
157