1 //===-- Highlighter.cpp ---------------------------------------------------===// 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 #include "lldb/Core/Highlighter.h" 10 11 #include "lldb/Target/Language.h" 12 #include "lldb/Utility/AnsiTerminal.h" 13 #include "lldb/Utility/StreamString.h" 14 #include <optional> 15 16 using namespace lldb_private; 17 using namespace lldb_private::ansi; 18 19 void HighlightStyle::ColorStyle::Apply(Stream &s, llvm::StringRef value) const { 20 s << m_prefix << value << m_suffix; 21 } 22 23 void HighlightStyle::ColorStyle::Set(llvm::StringRef prefix, 24 llvm::StringRef suffix) { 25 m_prefix = FormatAnsiTerminalCodes(prefix); 26 m_suffix = FormatAnsiTerminalCodes(suffix); 27 } 28 29 void DefaultHighlighter::Highlight(const HighlightStyle &options, 30 llvm::StringRef line, 31 std::optional<size_t> cursor_pos, 32 llvm::StringRef previous_lines, 33 Stream &s) const { 34 // If we don't have a valid cursor, then we just print the line as-is. 35 if (!cursor_pos || *cursor_pos >= line.size()) { 36 s << line; 37 return; 38 } 39 40 // If we have a valid cursor, we have to apply the 'selected' style around 41 // the character below the cursor. 42 43 // Split the line around the character which is below the cursor. 44 size_t column = *cursor_pos; 45 // Print the characters before the cursor. 46 s << line.substr(0, column); 47 // Print the selected character with the defined color codes. 48 options.selected.Apply(s, line.substr(column, 1)); 49 // Print the rest of the line. 50 s << line.substr(column + 1U); 51 } 52 53 static HighlightStyle::ColorStyle GetColor(const char *c) { 54 return HighlightStyle::ColorStyle(c, "${ansi.normal}"); 55 } 56 57 HighlightStyle HighlightStyle::MakeVimStyle() { 58 HighlightStyle result; 59 result.comment = GetColor("${ansi.fg.purple}"); 60 result.scalar_literal = GetColor("${ansi.fg.red}"); 61 result.keyword = GetColor("${ansi.fg.green}"); 62 return result; 63 } 64 65 const Highlighter & 66 HighlighterManager::getHighlighterFor(lldb::LanguageType language_type, 67 llvm::StringRef path) const { 68 Language *language = lldb_private::Language::FindPlugin(language_type, path); 69 if (language && language->GetHighlighter()) 70 return *language->GetHighlighter(); 71 return m_default; 72 } 73 74 std::string Highlighter::Highlight(const HighlightStyle &options, 75 llvm::StringRef line, 76 std::optional<size_t> cursor_pos, 77 llvm::StringRef previous_lines) const { 78 StreamString s; 79 Highlight(options, line, cursor_pos, previous_lines, s); 80 s.Flush(); 81 return s.GetString().str(); 82 } 83