reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
//===-- Highlighter.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Highlighter_h_
#define liblldb_Highlighter_h_

#include <utility>
#include <vector>

#include "lldb/Utility/Stream.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/StringRef.h"

namespace lldb_private {

/// Represents style that the highlighter should apply to the given source code.
/// Stores information about how every kind of token should be annotated.
struct HighlightStyle {

  /// A pair of strings that should be placed around a certain token. Usually
  /// stores color codes in these strings (the suffix string is often used for
  /// resetting the terminal attributes back to normal).
  class ColorStyle {
    std::string m_prefix;
    std::string m_suffix;

  public:
    ColorStyle() = default;
    ColorStyle(llvm::StringRef prefix, llvm::StringRef suffix) {
      Set(prefix, suffix);
    }

    /// Applies this style to the given value.
    /// \param s
    ///     The stream to which the result should be appended.
    /// \param value
    ///     The value that we should place our strings around.
    void Apply(Stream &s, llvm::StringRef value) const;

    /// Sets the prefix and suffix strings.
    /// \param prefix
    /// \param suffix
    void Set(llvm::StringRef prefix, llvm::StringRef suffix);
  };

  /// The style for the token which is below the cursor of the user. Note that
  /// this style is overwritten by the SourceManager with the values of
  /// stop-show-column-ansi-prefix/stop-show-column-ansi-suffix.
  ColorStyle selected;

  /// Matches identifiers to variable or functions.
  ColorStyle identifier;
  /// Matches any string or character literals in the language: "foo" or 'f'
  ColorStyle string_literal;
  /// Matches scalar value literals like '42' or '0.1'.
  ColorStyle scalar_literal;
  /// Matches all reserved keywords in the language.
  ColorStyle keyword;
  /// Matches any comments in the language.
  ColorStyle comment;
  /// Matches commas: ','
  ColorStyle comma;
  /// Matches one colon: ':'
  ColorStyle colon;
  /// Matches any semicolon: ';'
  ColorStyle semicolons;
  /// Matches operators like '+', '-', '%', '&', '='
  ColorStyle operators;

  /// Matches '{' or '}'
  ColorStyle braces;
  /// Matches '[' or ']'
  ColorStyle square_brackets;
  /// Matches '(' or ')'
  ColorStyle parentheses;

  // C language specific options

  /// Matches directives to a preprocessor (if the language has any).
  ColorStyle pp_directive;

  /// Returns a HighlightStyle that is based on vim's default highlight style.
  static HighlightStyle MakeVimStyle();
};

/// Annotates source code with color attributes.
class Highlighter {
public:
  Highlighter() = default;
  virtual ~Highlighter() = default;
  DISALLOW_COPY_AND_ASSIGN(Highlighter);

  /// Returns a human readable name for the selected highlighter.
  virtual llvm::StringRef GetName() const = 0;

  /// Highlights the given line
  /// \param options
  /// \param line
  ///     The user supplied line that needs to be highlighted.
  /// \param cursor_pos
  ///     The cursor position of the user in this line, starting at 0 (which
  ///     means the cursor is on the first character in 'line').
  /// \param previous_lines
  ///     Any previous lines the user has written which we should only use
  ///     for getting the context of the Highlighting right.
  /// \param s
  ///     The stream to which the highlighted version of the user string should
  ///     be written.
  virtual void Highlight(const HighlightStyle &options, llvm::StringRef line,
                         llvm::Optional<size_t> cursor_pos,
                         llvm::StringRef previous_lines, Stream &s) const = 0;

  /// Utility method for calling Highlight without a stream.
  std::string Highlight(const HighlightStyle &options, llvm::StringRef line,
                        llvm::Optional<size_t> cursor_pos,
                        llvm::StringRef previous_lines = "") const;
};

/// A default highlighter that only highlights the user cursor, but doesn't
/// do any other highlighting.
class DefaultHighlighter : public Highlighter {
public:
  llvm::StringRef GetName() const override { return "none"; }

  void Highlight(const HighlightStyle &options, llvm::StringRef line,
                 llvm::Optional<size_t> cursor_pos,
                 llvm::StringRef previous_lines, Stream &s) const override;
};

/// Manages the available highlighters.
class HighlighterManager {
  DefaultHighlighter m_default;

public:
  /// Queries all known highlighter for one that can highlight some source code.
  /// \param language_type
  ///     The language type that the caller thinks the source code was given in.
  /// \param path
  ///     The path to the file the source code is from. Used as a fallback when
  ///     the user can't provide a language.
  /// \return
  ///     The highlighter that wants to highlight the source code. Could be an
  ///     empty highlighter that does nothing.
  const Highlighter &getHighlighterFor(lldb::LanguageType language_type,
                                       llvm::StringRef path) const;
  const Highlighter &getDefaultHighlighter() const { return m_default; }
};

} // namespace lldb_private

#endif // liblldb_Highlighter_h_