ArkScript
A small, lisp-inspired, functional scripting language
PrettyPrinting.hpp
Go to the documentation of this file.
1/**
2 * @file PrettyPrinting.hpp
3 * @author Lex Plateau (lexplt.dev@gmail.com)
4 * @brief Pretty printing utilities for diagnostics
5 * @date 2025-08-16
6 *
7 * @copyright Copyright (c) 2025
8 *
9 */
10
11#ifndef ARK_ERROR_PRETTYPRINTING_HPP
12#define ARK_ERROR_PRETTYPRINTING_HPP
13
14#include <string>
15#include <vector>
16#include <ostream>
17#include <optional>
18
21
22namespace Ark::Diagnostics
23{
30
32 {
33 std::size_t start; ///< First line number to display
34 std::size_t target;
35 std::size_t target_end;
36 std::size_t end; ///< Last line of the context, not displayed
37
38 std::optional<std::size_t> skip_start_at = std::nullopt;
39 std::optional<std::size_t> resume_at = std::nullopt;
40
42 start(0), target(0), target_end(0), end(0)
43 {}
44
45 Window(const std::size_t target_line, const std::size_t target_line_end, const std::size_t line_count) :
46 target(target_line), target_end(target_line_end)
47 {
48 start = target_line >= 3 ? target_line - 3 : 0;
49 end = target_line_end + 3 <= line_count ? target_line_end + 3 : line_count;
50 }
51
52 [[nodiscard]] bool hasSkip() const
53 {
54 return skip_start_at.has_value() && resume_at.has_value();
55 }
56 };
57
58 /**
59 * @brief Source printer for diagnostics
60 */
62 {
63 public:
64 /**
65 * @brief Create a new Printer object
66 *
67 * @param filename path to the file that has an error
68 * @param target_line line of the error (0-indexed)
69 * @param end_target_line optional end line for the error (0-indexed)
70 * @param colorize if we should colorize the output or not
71 */
72 Printer(const std::string& filename, std::size_t target_line, std::optional<std::size_t> end_target_line, bool colorize);
73
74 /**
75 * @brief Slice the source code to get code between two cursors
76 *
77 * @param start
78 * @param end
79 * @return std::string
80 */
81 [[nodiscard]] std::string sliceCode(internal::FilePos start, const std::optional<internal::FilePos>& end) const;
82
83 /**
84 * @brief Extend the window of lines to show, to include a given line.
85 * Useful to display the origin of an error.
86 *
87 * @param line_to_include line to include (0-indexed)
88 */
89 void extendWindow(std::size_t line_to_include);
90
91 /**
92 * @brief Print the current line and advance by one
93 *
94 * @param os output stream
95 */
96 void printLine(std::ostream& os);
97
98 /**
99 * @brief Check if we printed the target line
100 *
101 * @return true if the last displayed line is the target line
102 * @return false otherwise
103 */
104 [[nodiscard]] bool isTargetLine() const;
105
106 /**
107 * @brief Check if there are lines to print
108 *
109 * @return true while the window isn't exhausted
110 * @return false when there is nothing more to print
111 */
112 [[nodiscard]] bool hasContent() const;
113
114 [[nodiscard]] bool coversLine(std::size_t line_number) const;
115
116 [[nodiscard]] inline const Window& window() const
117 {
118 return m_window;
119 }
120
121 // FIXME: we should not need this?
122 [[nodiscard]] inline std::size_t current() const
123 {
124 return m_current_line;
125 }
126
127 [[nodiscard]] inline const std::string& currentLine() const
128 {
129 return m_source[m_current_line];
130 }
131
132 const static inline std::string GhostLinePrefix = " |";
133
134 private:
136 std::vector<std::string> m_source;
138 std::size_t m_current_line;
140 };
141}
142
143#endif // ARK_ERROR_PRETTYPRINTING_HPP
#define ARK_API
Definition Module.hpp:22
ArkScript configuration macros.
Defines position utilities (for text in a file) for the parser, formatter, diagnostics.
Source printer for diagnostics.
const std::string & currentLine() const
std::vector< std::string > m_source
LineColorContextCounts m_color_ctx
const Window & window() const
std::size_t current() const
Window(const std::size_t target_line, const std::size_t target_line_end, const std::size_t line_count)
std::size_t end
Last line of the context, not displayed.
std::size_t start
First line number to display.