ArkScript
A small, lisp-inspired, functional scripting language
PrettyPrinting.hpp
Go to the documentation of this file.
1/**
2 * @file PrettyPrinting.hpp
3 * @author Lexy Plateau (lexplt.dev@gmail.com)
4 * @brief Pretty printing utilities for diagnostics
5 * @date 2025-08-16
6 *
7 * @copyright Copyright (c) 2025-2026
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 * @param maybe_content optional file content, if it was originally a string (via State.doString)
72 */
73 Printer(const std::string& filename, std::size_t target_line, std::optional<std::size_t> end_target_line, bool colorize, const std::optional<std::string>& maybe_content = std::nullopt);
74
75 /**
76 * @brief Slice the source code to get code between two cursors
77 *
78 * @param start
79 * @param end
80 * @return std::string
81 */
82 [[nodiscard]] std::string sliceCode(internal::FilePos start, const std::optional<internal::FilePos>& end) const;
83
84 /**
85 * @brief Extend the window of lines to show, to include a given line.
86 * Useful to display the origin of an error.
87 *
88 * @param line_to_include line to include (0-indexed)
89 */
90 void extendWindow(std::size_t line_to_include);
91
92 /**
93 * @brief Print the current line and advance by one
94 *
95 * @param os output stream
96 */
97 void printLine(std::ostream& os);
98
99 /**
100 * @brief Check if we printed the target line
101 *
102 * @return true if the last displayed line is the target line
103 * @return false otherwise
104 */
105 [[nodiscard]] bool isTargetLine() const;
106
107 [[nodiscard]] bool isNextLineTheFirstLineOfTarget() const;
108
109 [[nodiscard]] bool isLastLineOfTarget() const;
110
111 /**
112 * @brief Check if there are lines to print
113 *
114 * @return true while the window isn't exhausted
115 * @return false when there is nothing more to print
116 */
117 [[nodiscard]] bool hasContent() const;
118
119 [[nodiscard]] bool coversLine(std::size_t line_number) const;
120
121 [[nodiscard]] inline const Window& window() const
122 {
123 return m_window;
124 }
125
126 // FIXME: we should not need this?
127 [[nodiscard]] inline std::size_t current() const
128 {
129 return m_current_line;
130 }
131
132 [[nodiscard]] inline const std::string& currentLine() const
133 {
134 return m_source[m_current_line];
135 }
136
137 const static inline std::string GhostLinePrefix = " |";
138
139 private:
141 std::vector<std::string> m_source;
143 std::size_t m_current_line;
145 };
146}
147
148#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.