Highlighter.h revision 360784
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 liblldb_Highlighter_h_
10#define liblldb_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  DISALLOW_COPY_AND_ASSIGN(Highlighter);
95
96  /// Returns a human readable name for the selected highlighter.
97  virtual llvm::StringRef GetName() const = 0;
98
99  /// Highlights the given line
100  /// \param options
101  ///     The highlight options.
102  /// \param line
103  ///     The user supplied line that needs to be highlighted.
104  /// \param cursor_pos
105  ///     The cursor position of the user in this line, starting at 0 (which
106  ///     means the cursor is on the first character in 'line').
107  /// \param previous_lines
108  ///     Any previous lines the user has written which we should only use
109  ///     for getting the context of the Highlighting right.
110  /// \param s
111  ///     The stream to which the highlighted version of the user string should
112  ///     be written.
113  virtual void Highlight(const HighlightStyle &options, llvm::StringRef line,
114                         llvm::Optional<size_t> cursor_pos,
115                         llvm::StringRef previous_lines, Stream &s) const = 0;
116
117  /// Utility method for calling Highlight without a stream.
118  std::string Highlight(const HighlightStyle &options, llvm::StringRef line,
119                        llvm::Optional<size_t> cursor_pos,
120                        llvm::StringRef previous_lines = "") const;
121};
122
123/// A default highlighter that only highlights the user cursor, but doesn't
124/// do any other highlighting.
125class DefaultHighlighter : public Highlighter {
126public:
127  llvm::StringRef GetName() const override { return "none"; }
128
129  void Highlight(const HighlightStyle &options, llvm::StringRef line,
130                 llvm::Optional<size_t> cursor_pos,
131                 llvm::StringRef previous_lines, Stream &s) const override;
132};
133
134/// Manages the available highlighters.
135class HighlighterManager {
136  DefaultHighlighter m_default;
137
138public:
139  /// Queries all known highlighter for one that can highlight some source code.
140  /// \param language_type
141  ///     The language type that the caller thinks the source code was given in.
142  /// \param path
143  ///     The path to the file the source code is from. Used as a fallback when
144  ///     the user can't provide a language.
145  /// \return
146  ///     The highlighter that wants to highlight the source code. Could be an
147  ///     empty highlighter that does nothing.
148  const Highlighter &getHighlighterFor(lldb::LanguageType language_type,
149                                       llvm::StringRef path) const;
150  const Highlighter &getDefaultHighlighter() const { return m_default; }
151};
152
153} // namespace lldb_private
154
155#endif // liblldb_Highlighter_h_
156