* FileManipulator The file manipulator service is a service that is mainly used to investigate and to examine a file. ** Classes *** Text The `Text` class provides a line-based UTF-8 aware text container supporting insertions, deletions, streaming, regex search/replace, and efficient window extraction. It uses a `std::vector` to store lines and caches UTF-8 line lengths for performance. **** Interface Summary - `Text();` Default constructor. - `static int utf8_length(const std::string &line);` Counts the number of Unicode codepoints in a UTF-8 string. - `static std::vector split_lines(const std::string &text);` Splits a normalized string into lines at `\n`. - `static std::string normalize_newlines(const std::string &input);` Converts CRLF/CR into LF. - `void insert_chars(const std::string &s, int column, int line);` Inserts UTF-8 text at the specified codepoint position. - `void delete_chars(int nofcharacters, int column, int line);` Deletes a number of codepoints, possibly across lines. - `Text window(int x, int y, int width, int height) const;` Extracts a rectangular region of codepoints and lines. - `std::vector line_lengths(int y, int height) const;` Returns UTF-8 codepoint lengths for a range of lines. - `std::vector regex_search(const std::regex &pattern, bool return_lines) const;` Returns lines or matches based on regex. - `void regex_replace(const std::regex &pattern, const std::string &replacement);` Replaces matches in all lines with a replacement string. - `friend std::ostream& operator<<(std::ostream &os, const Text &text);` Streams out the text using `\n` between lines. - `friend std::istream& operator>>(std::istream &is, Text &text);` Reads text from stream and normalizes newlines. --- **** `Text::Text()` Default constructor initializes an empty text buffer. **** `utf8_length` Counts Unicode codepoints in a UTF-8 string. It scans byte-by-byte and classifies leading bytes of UTF-8 sequences using masks. Used for cursor positioning and line length caching. **** `split_lines` Splits a string on `\n` using `std::getline`. Returns a vector of strings. Used after normalization or to rebuild the buffer. **** `normalize_newlines` Converts CRLF and CR into LF (`\n`). Ensures the internal representation uses consistent newlines. This is called on input streams and insertions. **** `insert_chars` Inserts UTF-8 text at a specified logical position (codepoint index) in a line. If the string contains newlines, lines are split and inserted. Line length cache is updated and lines below are shifted accordingly. Steps: - Convert codepoint to byte index. - Split line into before/after segments. - Split inserted string into lines. - Insert and adjust `_lines` and `_line_length_cache`. **** `delete_chars` Deletes a number of codepoints starting from the given location. Deletion may span multiple lines. Internally flattens the text, erases codepoints, then re-splits. Steps: - Flatten from `line` to end. - Compute byte range from codepoints. - Erase and resplit using `split_lines`. - Invalidate all length caches. **** `window` Returns a `Text` object containing a visual window (slice) of the text. It: - Extracts lines in the range `[y, y + height)`. - Extracts visible codepoints from each line in `[x, x + width)` range. - Returns a new `Text` object with the clipped lines. Useful for viewport drawing. **** `line_lengths` Returns a vector of codepoint lengths for `height` lines starting at `y`. Uses a cache to avoid recomputing lengths unless content changes. **** `regex_search` Searches each line using a regular expression: - If `return_lines` is `true`, returns full lines that match. - If `false`, returns individual matches (`smatch::str()`). Does not support multi-line regex. **** `regex_replace` Performs regex replacement on each line individually. Replaces all matches with the replacement string. Clears the line length cache after changes. **** `operator<<` Streams the entire text buffer to an `ostream`, separating lines with `\n`. This preserves a normalized view of the buffer. **** `operator>>` Reads a full input stream into the `Text` object: - Buffers full input. - Normalizes newlines. - Splits into lines. - Clears length cache. *** ViewWindow The `ViewWindow` class models a rectangular viewport into a `Text` object, anchored at a position relative to the window. The anchor is always inside the window bounds and moves with the window when the window is moved. The class delegates events related to insertions, deletions, moves, and resizes to an `AlterationInterface`, which is used to notify external systems (e.g., collaborative editors or UI clients). Window and anchor semantics: - The window is defined by its top-left position `(x, y)` in the `Text`, and its size `(width, height)`. - The anchor point `(anchor_x, anchor_y)` is always relative to the window, clamped to `[0, width) × [0, height)`. - The window does not own the `Text`; it receives a reference during operations. - All operations are reflected only within the current visible window and through annotations. - The anchor line is assumed to be process-locked at a higher abstraction layer. - The `ViewWindow` class does not implement its own synchronization. **** Interface Overview - `ViewWindow(int x, int y, int width, int height, int anchor_x, int anchor_y)` - `Text content(const Text& txt) const` - `void annotate_insert(std::string s, int x, int y, const Text& txt, AlterationInterface& ai)` - `void annotate_delete(int nof_chars, int x, int y, const Text& txt, AlterationInterface& ai)` - `void annotate_move(int win_x, int win_y, const Text& txt, AlterationInterface& ai)` - `void annotate_resize(int new_width, int new_height, const Text& txt, AlterationInterface& ai)` - `std::vector lengths(const Text& txt) const` - `void set_anchor(int ax, int ay)` - `void move(int deltax, int deltay)` - `void position(int new_x, int new_y)` - `void resize(int new_width, int new_height)` --- **** ViewWindow Constructor Initializes the window's top-left position and dimensions, and sets the relative anchor point within the window. - Input: - `x`, `y`: top-left position of the window in the text - `width`, `height`: dimensions of the window - `anchor_x`, `anchor_y`: relative anchor coordinates - Behavior: - The anchor is clamped within the bounds `[0, width) × [0, height)`. --- **** content(const Text& txt) Returns a `Text` object representing the visible window into the given `txt`. - Uses `Text::window(x, y, width, height)`. - This is a shallow view with no metadata retention. --- **** annotate_insert(std::string s, int x, int y, const Text& txt, AlterationInterface& ai) Annotates an insertion event. - Parameters: - `s`: the inserted UTF-8 string - `x`, `y`: position in the original text (absolute) - `txt`: the current `Text` - `ai`: the `AlterationInterface` to receive notifications - Behavior: - Notifies about line length changes within the window - If content affects the current view, notifies via `insert(...)` on the interface - The window and anchor do not move unless affected --- **** annotate_delete(int nof_chars, int x, int y, const Text& txt, AlterationInterface& ai) Annotates a deletion event. - Parameters: - `nof_chars`: number of characters deleted - `x`, `y`: position in the original text (absolute) - `txt`: the current `Text` - `ai`: the `AlterationInterface` to receive notifications - Behavior: - Notifies about line length changes within the window - Emits `remove(...)` for affected text - Anchor and window remain stationary unless deletion affects their content --- **** annotate_move(int win_x, int win_y, const Text& txt, AlterationInterface& ai) Moves the window to a new position and reports the change. - Parameters: - `win_x`, `win_y`: new top-left position of the window - `txt`: the current `Text` - `ai`: the `AlterationInterface` to notify - Behavior: - Moves the window - Anchor remains relative (it moves along) - Emits `move_window()` and `set_anchor()` based on new positions --- **** annotate_resize(int new_width, int new_height, const Text& txt, AlterationInterface& ai) Resizes the window and notifies changes. - Parameters: - `new_width`, `new_height`: new window dimensions - `txt`: the current `Text` - `ai`: the `AlterationInterface` - Behavior: - Adjusts window dimensions - Anchor is clamped - Emits `full_content(txt.window(...))` as a wholesale update --- **** lengths(const Text& txt) const Returns cached or computed line lengths for the window. - Uses `Text::line_lengths(...)` - Returns a vector of lengths for the lines within the current window --- **** set_anchor(int ax, int ay) Sets a new anchor location within the window. - Input: - `ax`, `ay`: new anchor position (relative) - Behavior: - Anchor is clamped to window size - No position updates are triggered --- **** move(int deltax, int deltay) Moves the window by the given delta. - Input: - `deltax`, `deltay`: offsets to apply to current window position - Behavior: - Anchor remains at the same location relative to window - Emits no automatic annotations --- **** position(int new_x, int new_y) Moves the window to a new absolute position. - Input: - `new_x`, `new_y`: absolute top-left coordinates of window - Behavior: - Anchor remains fixed relative to the window - No alteration events are triggered by default --- **** resize(int new_width, int new_height) Sets a new window size. - Input: - `new_width`, `new_height`: updated dimensions - Behavior: - Anchor clamped to new dimensions - If `annotate_resize` is not explicitly called, no events are emitted ---