summaryrefslogtreecommitdiff
path: root/src/dged/buffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/dged/buffer.h')
-rw-r--r--src/dged/buffer.h550
1 files changed, 372 insertions, 178 deletions
diff --git a/src/dged/buffer.h b/src/dged/buffer.h
index 28d9797..e29e3e1 100644
--- a/src/dged/buffer.h
+++ b/src/dged/buffer.h
@@ -1,3 +1,6 @@
+#ifndef _BUFFER_H
+#define _BUFFER_H
+
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -5,81 +8,22 @@
#include "command.h"
#include "lang.h"
+#include "location.h"
#include "text.h"
#include "undo.h"
#include "window.h"
-struct keymap;
struct command_list;
-enum text_property_type {
- TextProperty_Colors,
-};
-
-struct text_property_colors {
- bool set_fg;
- uint32_t fg;
- bool set_bg;
- uint32_t bg;
-};
-
-struct text_property {
- enum text_property_type type;
- union {
- struct text_property_colors colors;
- };
-};
-
-/**
- * Margins where buffer text should not be
- */
-struct margin {
- uint32_t left;
- uint32_t right;
- uint32_t top;
- uint32_t bottom;
-};
-
-/** Callback for line rendering hooks */
-typedef void (*line_render_cb)(struct text_chunk *line_data, uint32_t line,
- struct command_list *commands, void *userdata);
-
-typedef void (*line_render_empty_cb)(uint32_t line,
- struct command_list *commands,
- void *userdata);
-
-/**
- * A line render hook
- *
- * A callback paired with userdata
- */
-struct line_render_hook {
- line_render_cb callback;
- line_render_empty_cb empty_callback;
- void *userdata;
-};
-
-/**
- * Result of updating a buffer hook
- */
-struct update_hook_result {
- /** Desired margins for this hook */
- struct margin margins;
-
- /** Hook to be added to rendering of buffer lines */
- struct line_render_hook line_render_hook;
-};
-
/** Buffer update hook callback function */
-typedef struct update_hook_result (*update_hook_cb)(
- struct buffer_view *view, struct command_list *commands, uint32_t width,
- uint32_t height, uint64_t frame_time, void *userdata);
+typedef void (*update_hook_cb)(struct buffer *buffer, uint32_t width,
+ uint32_t height, void *userdata);
/**
* A buffer update hook.
*
* Can be used to implement custom behavior on top of a buffer. Used for
- * minibuffer, line numbers, modeline etc.
+ * minibuffer.
*/
struct update_hook {
/** Callback function */
@@ -89,67 +33,9 @@ struct update_hook {
void *userdata;
};
-typedef void (*create_hook_cb)(struct buffer *buffer, void *userdata);
-
-/**
- * A set of update hooks
- */
-struct update_hooks {
- /** The update hooks */
- struct update_hook hooks[32];
-
- /** The number of update hooks */
- uint32_t nhooks;
-};
-
-struct buffer_location {
- uint32_t line;
- uint32_t col;
-};
-
-bool buffer_location_is_between(struct buffer_location location,
- struct buffer_location start,
- struct buffer_location end);
-
-struct match {
- struct buffer_location begin;
- struct buffer_location end;
-};
-
-struct buffer_view {
- /** Location of dot (cursor) */
- struct buffer_location dot;
-
- /** Location of mark (where a selection starts) */
- struct buffer_location mark;
-
- /** Current buffer scroll position */
- struct buffer_location scroll;
-
- /** True if the start of a selection has been set */
- bool mark_set;
-
- /** Modeline buffer (may be NULL) */
- struct modeline *modeline;
-
- bool line_numbers;
-
- struct buffer *buffer;
-};
-
-struct buffer_view buffer_view_create(struct buffer *buffer, bool modeline,
- bool line_numbers);
-struct buffer_view buffer_view_clone(struct buffer_view *view);
-
-void buffer_view_scroll_down(struct buffer_view *view, uint32_t height);
-void buffer_view_scroll_up(struct buffer_view *view, uint32_t height);
-
-void buffer_view_destroy(struct buffer_view *view);
-
-struct text_property_entry {
- struct buffer_location start;
- struct buffer_location end;
- struct text_property property;
+struct update_hook_entry {
+ uint32_t id;
+ struct update_hook hook;
};
/**
@@ -166,103 +52,411 @@ struct buffer {
/** Associated filename, this is where the buffer will be saved to */
char *filename;
+ /** Time when buffer was last written to disk */
struct timespec last_write;
/** Text data structure */
struct text *text;
/** Buffer update hooks */
- struct update_hooks update_hooks;
+ VEC(struct update_hook_entry) update_hooks;
/** Buffer undo stack */
struct undo_stack undo;
+ /** Buffer programming language */
+ struct language lang;
+
/** Has this buffer been modified from when it was last saved */
bool modified;
/** Can this buffer be changed */
bool readonly;
+};
- /** Buffer programming language */
- struct language lang;
+void buffer_static_init();
+void buffer_static_teardown();
- VEC(struct text_property_entry) text_properties;
-};
+/**
+ * Create a new buffer.
+ *
+ * @param [in] name The buffer name.
+ * @returns A new buffer
+ */
+struct buffer buffer_create(const char *name);
+
+/**
+ * Create a new buffer from a file path.
+ *
+ * @param [in] path Path to the file to load into the new buffer.
+ * @returns A new buffer with @ref path loaded.
+ */
+struct buffer buffer_from_file(const char *path);
+
+/**
+ * Save buffer to the backing file.
+ *
+ * @param [in] buffer Buffer to save.
+ */
+void buffer_to_file(struct buffer *buffer);
-struct buffer buffer_create(char *name);
+/**
+ * Set path to backing file for buffer.
+ *
+ * The backing file is used when writing the buffer to a file.
+ * @param [in] buffer The buffer to set filename for.
+ * @param [in] filename The filename to use. It is required that this is a full
+ * path.
+ */
+void buffer_set_filename(struct buffer *buffer, const char *filename);
+
+/**
+ * Reload the buffer from disk.
+ *
+ * Reload the buffer from the backing file.
+ * @param [in] buffer The buffer to reload.
+ */
+void buffer_reload(struct buffer *buffer);
+
+/**
+ * Destroy the buffer.
+ *
+ * Destroy the buffer, releasing all associated resources.
+ * @param [in] buffer The buffer to destroy.
+ */
void buffer_destroy(struct buffer *buffer);
-void buffer_static_init();
-void buffer_static_teardown();
+/**
+ * Add text to the buffer at the specified location.
+ *
+ * @param [in] buffer The buffer to add text to.
+ * @param [in] at The location to add text at.
+ * @param [in] text Pointer to the text bytes, not NULL-terminated.
+ * @param [in] nbytes Number of bytes in @ref text.
+ *
+ * @returns The location at the end of the inserted text.
+ */
+struct location buffer_add(struct buffer *buffer, struct location at,
+ uint8_t *text, uint32_t nbytes);
+
+/**
+ * Set the entire text contents of the buffer.
+ *
+ * @param [in] buffer The buffer to set text for.
+ * @param [in] text Pointer to the text bytes, not NULL-terminated.
+ * @param [in] nbytes Number of bytes in @ref text.
+ *
+ * @returns The location at the end of the inserted text
+ */
+struct location buffer_set_text(struct buffer *buffer, uint8_t *text,
+ uint32_t nbytes);
+
+/**
+ * Clear all text in the buffer
+ *
+ * @param [in] buffer The buffer to clear.
+ */
+void buffer_clear(struct buffer *buffer);
-int buffer_add_text(struct buffer_view *view, uint8_t *text, uint32_t nbytes);
-void buffer_set_text(struct buffer *buffer, uint8_t *text, uint32_t nbytes);
-void buffer_clear(struct buffer_view *view);
+/**
+ * Does buffer contain any text?
+ *
+ * @param [in] buffer The buffer to check.
+ * @returns True if the buffer is empty (has no text in it), false otherwise.
+ */
bool buffer_is_empty(struct buffer *buffer);
+
+/**
+ * Has the buffer been modified since it was last retrieved from/saved to disk?
+ *
+ * @param [in] buffer The buffer to examine.
+ * @returns True if the buffer has been modified, false otherwise.
+ */
bool buffer_is_modified(struct buffer *buffer);
+
+/**
+ * Is this buffer read-only?
+ *
+ * @param [in] buffer The buffer to examine.
+ * @returns True if the buffer is read-only (cannot be modified), false
+ * otherwise.
+ */
bool buffer_is_readonly(struct buffer *buffer);
+
+/**
+ * Set the read-only status for the buffer.
+ *
+ * @param [in] buffer The buffer to set read-only for.
+ * @param [in] readonly If true, the buffer is set to read-only, otherwise it is
+ * set to writable.
+ */
void buffer_set_readonly(struct buffer *buffer, bool readonly);
+
+/**
+ * Is the buffer backed by a file on disk?
+ *
+ * @param [in] buffer The buffer to examine.
+ * @returns True if the buffer has a path to a file on disk to use as backing
+ * file, false otherwise. Note that this function returns true even if the
+ * buffer has never been written to the backing file.
+ */
bool buffer_is_backed(struct buffer *buffer);
-void buffer_kill_line(struct buffer_view *view);
-void buffer_forward_delete_char(struct buffer_view *view);
-void buffer_forward_delete_word(struct buffer_view *view);
-void buffer_backward_delete_char(struct buffer_view *view);
-void buffer_backward_delete_word(struct buffer_view *view);
-void buffer_backward_char(struct buffer_view *view);
-void buffer_backward_word(struct buffer_view *view);
-void buffer_forward_char(struct buffer_view *view);
-void buffer_forward_word(struct buffer_view *view);
-void buffer_backward_line(struct buffer_view *view);
-void buffer_forward_line(struct buffer_view *view);
-void buffer_end_of_line(struct buffer_view *view);
-void buffer_beginning_of_line(struct buffer_view *view);
-void buffer_newline(struct buffer_view *view);
-void buffer_indent(struct buffer_view *view);
-
-void buffer_undo(struct buffer_view *view);
-
-void buffer_goto_beginning(struct buffer_view *view);
-void buffer_goto_end(struct buffer_view *view);
-void buffer_goto(struct buffer_view *view, uint32_t line, uint32_t col);
+/**
+ * Get location of previous character in buffer.
+ *
+ * @param [in] buffer The buffer to use.
+ * @param [in] dot The location to start from.
+ * @returns The location in front of the previous char given @ref dot.
+ */
+struct location buffer_previous_char(struct buffer *buffer,
+ struct location dot);
+
+/**
+ * Get location of previous word in buffer.
+ *
+ * @param [in] buffer The buffer to look in.
+ * @param [in] dot The location to start from.
+ * @returns The location at the start of the previous word, given @ref dot.
+ */
+struct location buffer_previous_word(struct buffer *buffer,
+ struct location dot);
+
+/**
+ * Get location of previous line.
+ *
+ * @param [in] buffer The buffer to look in.
+ * @param [in] dot The location to start from.
+ * @returns The location at the start of the line above the current one (the one
+ * @ref dot is on). If @ref dot is on the first line, the location (0, 0) is
+ * returned.
+ */
+struct location buffer_previous_line(struct buffer *buffer,
+ struct location dot);
+
+/**
+ * Get location of next character in buffer.
+ *
+ * @param [in] buffer The buffer to use.
+ * @param [in] dot The location to start from.
+ * @returns The location in front of the next char given @ref dot.
+ */
+struct location buffer_next_char(struct buffer *buffer, struct location dot);
+
+/**
+ * Get location of next word in buffer.
+ *
+ * @param [in] buffer The buffer to look in.
+ * @param [in] dot The location to start from.
+ * @returns The location at the start of the next word, given @ref dot.
+ */
+struct location buffer_next_word(struct buffer *buffer, struct location dot);
+
+/**
+ * Get location of next line.
+ *
+ * @param [in] buffer The buffer to look in.
+ * @param [in] dot The location to start from.
+ * @returns The location at the start of the line above the current one (the one
+ * @ref dot is on). If @ref dot is on the last line, the last location in the
+ * buffer is returned.
+ */
+struct location buffer_next_line(struct buffer *buffer, struct location dot);
+
+/**
+ * Clamp a buffer position to the boundaries of the buffer.
+ *
+ * Note that both @ref line and @ref col can be negative or bigger than the
+ * buffer.
+ *
+ * @param [in] buffer The buffer to use for clamping.
+ * @param [in] line The line position to clamp.
+ * @param [in] col The column position to clamp.
+ * @returns The closest position inside the buffer matching (line, col).
+ */
+struct location buffer_clamp(struct buffer *buffer, int64_t line, int64_t col);
+
+/**
+ * Get location of buffer end.
+ *
+ * @param [in] buffer The buffer to use.
+ * @returns the position after the last character in @ref buffer.
+ */
+struct location buffer_end(struct buffer *buffer);
+
+/**
+ * Get the number of lines in the buffer
+ *
+ * @param [in] buffer The buffer to use.
+ * @returns The number of lines in @ref buffer.
+ */
+uint32_t buffer_num_lines(struct buffer *buffer);
+
+/**
+ * Get the number of chars in a given line in buffer.
+ *
+ * @param [in] buffer The buffer to use.
+ * @param [in] line The line to get number of chars for.
+ * @returns The number of chars in @ref line.
+ */
+uint32_t buffer_num_chars(struct buffer *buffer, uint32_t line);
+
+/**
+ * Insert a newline in the buffer.
+ *
+ * @param [in] buffer The buffer to insert in.
+ * @param [in] at The point to insert at.
+ * @returns The location at the start of the new line.
+ */
+struct location buffer_newline(struct buffer *buffer, struct location at);
+
+/**
+ * Insert indentation in the buffer.
+ *
+ * @param [in] buffer The buffer to indent in.
+ * @param [in] at The location to insert indentation at.
+ * @returns The position after indenting.
+ */
+struct location buffer_indent(struct buffer *buffer, struct location at);
+
+/**
+ * Undo the last operation in the buffer.
+ *
+ * @param [in] buffer The buffer to undo in.
+ * @param [in] dot The point to undo at.
+ * @returns The position in the buffer after undo.
+ */
+struct location buffer_undo(struct buffer *buffer, struct location dot);
+/**
+ * Search for a substring in the buffer.
+ *
+ * @param [in] buffer The buffer to search in.
+ * @param [in] pattern The substring to search for.
+ * @param [out] matches The pointer passed in is modified to point at the
+ * resulting matches. This pointer should be freed using @ref free.
+ * @param [nmatches] nmatches The pointer passed in is modified to point at the
+ * number of resulting matches.
+ */
void buffer_find(struct buffer *buffer, const char *pattern,
- struct match **matches, uint32_t *nmatches);
+ struct region **matches, uint32_t *nmatches);
-void buffer_set_mark(struct buffer_view *view);
-void buffer_clear_mark(struct buffer_view *view);
-void buffer_set_mark_at(struct buffer_view *view, uint32_t line, uint32_t col);
+/**
+ * Copy a region in the buffer into the kill ring.
+ *
+ * @param [in] buffer The buffer to copy from.
+ * @param [in] region The region to copy.
+ * @returns The position in the buffer after the copy.
+ */
+struct location buffer_copy(struct buffer *buffer, struct region region);
-void buffer_copy(struct buffer_view *view);
-void buffer_paste(struct buffer_view *view);
-void buffer_paste_older(struct buffer_view *view);
-void buffer_cut(struct buffer_view *view);
+/**
+ * Cut a region in the buffer into the kill ring.
+ *
+ * @param [in] buffer The buffer to cut from.
+ * @param [in] region The region to cut.
+ * @returns The position in the buffer after the cut.
+ */
+struct location buffer_cut(struct buffer *buffer, struct region region);
-void buffer_clear_text_properties(struct buffer *buffer);
+/**
+ * Delete a region in the buffer without putting it into the kill ring.
+ *
+ * @param [in] buffer The buffer to delete from.
+ * @param [in] region The region to delete.
+ * @returns The position in the buffer after the delete.
+ */
+struct location buffer_delete(struct buffer *buffer, struct region region);
+
+/**
+ * Paste from the kill ring into the buffer.
+ *
+ * @param [in] buffer Buffer to paste in.
+ * @param [in] at Location to paste at.
+ * @returns The location in the buffer after the paste.
+ */
+struct location buffer_paste(struct buffer *buffer, struct location at);
+
+/**
+ * Paste the next older entry from the kill ring into the buffer.
+ *
+ * @param [in] buffer Buffer to paste in.
+ * @param [in] at Location to paste at.
+ * @returns The location in the buffer after the paste.
+ */
+struct location buffer_paste_older(struct buffer *buffer, struct location at);
-void buffer_add_text_property(struct buffer *buffer,
- struct buffer_location start,
- struct buffer_location end,
+/**
+ * Get one line from the buffer.
+ *
+ * @param buffer The buffer to get the line from.
+ * @param line Line number in the buffer.
+ * @returns A text chunk describing the line. Note that if the line number is
+ * greater than the number of lines, the @ref text_chunk will be empty.
+ */
+struct text_chunk buffer_line(struct buffer *buffer, uint32_t line);
+
+void buffer_add_text_property(struct buffer *buffer, struct location start,
+ struct location end,
struct text_property property);
-void buffer_get_text_properties(struct buffer *buffer,
- struct buffer_location location,
+void buffer_get_text_properties(struct buffer *buffer, struct location location,
struct text_property **properties,
uint32_t max_nproperties,
uint32_t *nproperties);
-struct text_chunk buffer_get_line(struct buffer *buffer, uint32_t line);
+void buffer_clear_text_properties(struct buffer *buffer);
+/**
+ * Add a buffer update hook.
+ *
+ * @param [in] buffer The buffer to add the hook to.
+ * @param [in] hook The update hook callback.
+ * @param [in] userdata Data that is passed unmodified to the update hook.
+ * @returns The hook id.
+ */
uint32_t buffer_add_update_hook(struct buffer *buffer, update_hook_cb hook,
void *userdata);
+/** Buffer create hook callback function */
+typedef void (*create_hook_cb)(struct buffer *buffer, void *userdata);
+
+/**
+ * Add a buffer create hook.
+ *
+ * @param [in] hook Create hook callback.
+ * @param [in] userdata Pointer to data that is passed unmodified to the update
+ * hook.
+ * @returns The hook id.
+ */
uint32_t buffer_add_create_hook(create_hook_cb hook, void *userdata);
-struct buffer buffer_from_file(char *filename);
-void buffer_to_file(struct buffer *buffer);
-void buffer_write_to(struct buffer *buffer, const char *filename);
-void buffer_reload(struct buffer *buffer);
+/**
+ * Parameters for updating a buffer.
+ */
+struct buffer_update_params {
+
+ /** Command list to add rendering commands for the buffer */
+ struct command_list *commands;
+
+ /** Where is the upper left corner of the buffer */
+ struct location origin;
+
+ /** Window width for this buffer, -1 if it is not in a window */
+ uint32_t width;
+
+ /** Window height for this buffer, -1 if it is not in a window */
+ uint32_t height;
+};
+
+/**
+ * Update a buffer.
+ *
+ * @param [in] buffer The buffer to update.
+ * @param [inout] params The parameters for the update. The @ref commands field
+ * in @ref params will be modified with the rendering commands needed for this
+ * buffer.
+ */
+void buffer_update(struct buffer *buffer, struct buffer_update_params *params);
-void buffer_update(struct buffer_view *view, uint32_t window_id, uint32_t width,
- uint32_t height, struct command_list *commands,
- uint64_t frame_time, uint32_t *relline, uint32_t *relcol);
+#endif