aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/index.rst1
-rw-r--r--doc/view.rst110
-rw-r--r--view.c12
-rw-r--r--view.h410
4 files changed, 413 insertions, 120 deletions
diff --git a/doc/index.rst b/doc/index.rst
index ef53ca8..e83bb53 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -6,6 +6,7 @@ Vis Editor API Documenation
vis
text
+ view
buffer
array
map
diff --git a/doc/view.rst b/doc/view.rst
new file mode 100644
index 0000000..c48d565
--- /dev/null
+++ b/doc/view.rst
@@ -0,0 +1,110 @@
+View
+====
+
+Provides a viewport of a text instance and mangages selections.
+
+Lifecycle
+---------
+
+.. doxygengroup:: view_life
+ :content-only:
+
+Viewport
+--------
+
+The cursor of the primary selection is always visible.
+
+.. doxygengroup:: view_viewport
+ :content-only:
+
+Dimension
+---------
+
+.. doxygengroup:: view_size
+ :content-only:
+
+Draw
+----
+
+.. doxygengroup:: view_draw
+ :content-only:
+
+Selections
+----------
+
+A selection is a non-empty, directed range with two endpoints called *cursor*
+and *anchor*. A selection can be anchored in which case the anchor remains
+fixed while only the position of the cursor is adjusted. For non-anchored
+selections both endpoints are updated. A singleton selection
+covers one character on which both cursor and anchor reside. There always
+exists a primary selection which remains visible (i.e. changes to its position
+will adjust the viewport).
+
+Creation and Destruction
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. doxygengroup:: view_selnew
+ :content-only:
+
+Navigation
+~~~~~~~~~~
+
+.. doxygengroup:: view_navigate
+ :content-only:
+
+Cover
+~~~~~
+
+.. doxygengroup:: view_cover
+ :content-only:
+
+Anchor
+~~~~~~
+
+.. doxygengroup:: view_anchor
+ :content-only:
+
+Cursor
+~~~~~~
+
+Selection endpoint to which cursor motions apply.
+
+Properties
+^^^^^^^^^^
+
+.. doxygengroup:: view_props
+ :content-only:
+
+Placement
+^^^^^^^^^
+
+.. doxygengroup:: view_place
+ :content-only:
+
+Motions
+^^^^^^^^
+
+These functions perform motions based on the current selection cursor position.
+
+.. doxygengroup:: view_motions
+ :content-only:
+
+Primary Selection
+~~~~~~~~~~~~~~~~~
+
+These are convenience function which operate on the primary selection.
+
+.. doxygengroup:: view_primary
+ :content-only:
+
+Save and Restore
+~~~~~~~~~~~~~~~~
+
+.. doxygengroup:: view_save
+ :content-only:
+
+Style
+-----
+
+.. doxygengroup:: view_style
+ :content-only:
diff --git a/view.c b/view.c
index 2106b0e..b891ef0 100644
--- a/view.c
+++ b/view.c
@@ -105,6 +105,14 @@ static const SyntaxSymbol symbols_default[] = {
static Cell cell_unused;
+
+/* move visible viewport n-lines up/down, redraws the view but does not change
+ * cursor position which becomes invalid and should be corrected by calling
+ * view_cursor_to. the return value indicates wether the visible area changed.
+ */
+static bool view_viewport_up(View *view, int n);
+static bool view_viewport_down(View *view, int n);
+
static void view_clear(View *view);
static bool view_addch(View *view, Cell *cell);
static void view_cursors_free(Cursor *c);
@@ -549,7 +557,7 @@ static size_t cursor_set(Cursor *cursor, Line *line, int col) {
return pos;
}
-bool view_viewport_down(View *view, int n) {
+static bool view_viewport_down(View *view, int n) {
Line *line;
if (view->end >= text_size(view->text))
return false;
@@ -563,7 +571,7 @@ bool view_viewport_down(View *view, int n) {
return true;
}
-bool view_viewport_up(View *view, int n) {
+static bool view_viewport_up(View *view, int n) {
/* scrolling up is somewhat tricky because we do not yet know where
* the lines start, therefore scan backwards but stop at a reasonable
* maximum in case we are dealing with a file without any newlines
diff --git a/view.h b/view.h
index 833252a..dc9d162 100644
--- a/view.h
+++ b/view.h
@@ -32,160 +32,334 @@ struct Line { /* a line on the screen, *not* in the file */
Cell cells[]; /* win->width cells storing information about the displayed characters */
};
+/**
+ * @defgroup view_life
+ * @{
+ */
View *view_new(Text*);
+void view_free(View*);
void view_ui(View*, UiWin*);
-/* change associated text displayed in this window */
+Text *view_text(View*);
void view_reload(View*, Text*);
-void view_free(View*);
-
-bool view_resize(View*, int width, int height);
-int view_height_get(View*);
-int view_width_get(View*);
-void view_invalidate(View*);
-void view_draw(View*);
-bool view_update(View*);
-/* changes how many spaces are used for one tab (must be >0), redraws the window */
-void view_tabwidth_set(View*, int tabwidth);
-
-/* cursor movements which also update selection if one is active.
- * they return new cursor postion */
-size_t view_line_down(Cursor*);
-size_t view_line_up(Cursor*);
-size_t view_screenline_down(Cursor*);
-size_t view_screenline_up(Cursor*);
-size_t view_screenline_begin(Cursor*);
-size_t view_screenline_middle(Cursor*);
-size_t view_screenline_end(Cursor*);
-
-/* move window content up/down, but keep cursor position unchanged unless it is
- * on a now invisible line in which case we try to preserve the column position */
+/**
+ * @}
+ * @defgroup view_viewport
+ * @{
+ */
+/** Get the currently displayed text range. */
+Filerange view_viewport_get(View*);
+/**
+ * Get window coordinate of text position.
+ * @param pos The position to query.
+ * @param line Will be updated with screen line on which `pos` resides.
+ * @param row Will be updaded with zero based window row on which `pos` resides.
+ * @param line Will be updated with zero based window column which `pos` resides.
+ * @return Whether `pos` is visible. If not, the pointer arguments are left unmodified.
+ */
+bool view_coord_get(View*, size_t pos, Line **line, int *row, int *col);
+/** Get position at the start ot the `n`-th window line, counting from 1. */
+size_t view_screenline_goto(View*, int n);
+/** Get first screen line. */
+Line *view_lines_first(View*);
+/** Get last non-empty screen line. */
+Line *view_lines_last(View*);
size_t view_slide_up(View*, int lines);
size_t view_slide_down(View*, int lines);
-/* scroll window contents up/down by lines, place the cursor on the newly
- * visible line, try to preserve the column position */
size_t view_scroll_up(View*, int lines);
size_t view_scroll_down(View*, int lines);
size_t view_scroll_page_up(View*);
size_t view_scroll_page_down(View*);
size_t view_scroll_halfpage_up(View*);
size_t view_scroll_halfpage_down(View*);
-/* place the cursor at the start ot the n-th window line, counting from 1 */
-size_t view_screenline_goto(View*, int n);
-
-Line *view_lines_first(View*);
-Line *view_lines_last(View*);
-Line *view_cursors_line_get(Cursor*);
-/* redraw current cursor line at top/center/bottom of window */
void view_redraw_top(View*);
void view_redraw_center(View*);
void view_redraw_bottom(View*);
-/* get the currently displayed area in bytes from the start of the file */
-Filerange view_viewport_get(View*);
-/* move visible viewport n-lines up/down, redraws the view but does not change
- * cursor position which becomes invalid and should be corrected by calling
- * view_cursor_to. the return value indicates wether the visible area changed.
+void view_scroll_to(View*, size_t pos);
+/**
+ * @}
+ * @defgroup view_size
+ * @{
*/
-bool view_viewport_up(View *view, int n);
-bool view_viewport_down(View *view, int n);
-
-void view_options_set(View*, enum UiOption options);
-enum UiOption view_options_get(View*);
-void view_colorcolumn_set(View*, int col);
-int view_colorcolumn_get(View*);
-
-bool view_coord_get(View*, size_t pos, Line **retline, int *retrow, int *retcol);
-/* A view can manage multiple cursors, one of which (the main cursor) is always
- * placed within the visible viewport. All functions named view_cursor_* operate
- * on this cursor. Additional cursor can be created and manipulated using the
- * functions named view_cursors_* */
+bool view_resize(View*, int width, int height);
+int view_height_get(View*);
+int view_width_get(View*);
+/**
+ * @}
+ * @defgroup view_draw
+ * @{
+ */
+void view_invalidate(View*);
+void view_draw(View*);
+bool view_update(View*);
-/* get main cursor position in bytes from start of the file */
-size_t view_cursor_get(View*);
-/* get selection associated with primary cursor */
-Filerange view_selection_get(View*);
-/* moves window viewport in direction until pos is visible. should only be
- * used for short distances between current cursor position and destination */
-void view_scroll_to(View*, size_t pos);
-/* move cursor to a given position. changes the viewport to make sure that
- * position is visible. if the position is in the middle of a line, try to
- * adjust the viewport in such a way that the whole line is displayed */
-void view_cursor_to(View*, size_t pos);
-/* create a new cursor at given position, fails if there already
- * exists a cursor at the same position */
+/**
+ * @}
+ * @defgroup view_selnew
+ * @{
+ */
+/**
+ * Create a new singleton selection at the given position.
+ * @rst
+ * .. note:: New selections are created non-anchored.
+ * .. warning:: Fails if position is already covered by a selection.
+ * @endrst
+ */
Cursor *view_cursors_new(View*, size_t pos);
-/* create a new cursor even if there already is one located at the
- * same position, this should only be used if the one of the two
- * cursors will later be disposed */
+/**
+ * Create a new selection even if position is already covered by an
+ * existing selection.
+ * @rst
+ * .. note:: This should only be used if the old selection is eventually
+ * disposed.
+ * @endrst
+ */
Cursor *view_cursors_new_force(View*, size_t pos);
-/* get number of active cursors */
-int view_cursors_count(View*);
-/* get index/relative order at time of creation of a cursor [0,count-1] */
-int view_cursors_number(Cursor*);
-/* exist there more than 1 cursor */
-bool view_cursors_multiple(View*);
-/* dispose an existing cursor with its associated selection (if any),
- * not applicaple for the last existing cursor */
+/**
+ * Dispose an existing selection.
+ * @rst
+ * .. warning:: Not applicaple for the last existing selection.
+ * @endrst
+ */
bool view_cursors_dispose(Cursor*);
-/* if called for the last existing cursor its selection is destroyed
- * and the cursor is marked for destruction and will be disposed as
- * soon as a new cursor is created. */
+/**
+ * Forcefully dispose an existing selection.
+ *
+ * If called for the last existing selection, it will be reduced and
+ * marked for destruction. As soon as a new selection is created this one
+ * will be disposed.
+ */
bool view_cursors_dispose_force(Cursor*);
-/* if the primary cursor was marked for destruction (by means of
- * view_cursors_dispose_force) return it and clear descruction flag */
+/**
+ * Query state of primary selection.
+ *
+ * If the primary selection was marked for destruction, return it and
+ * clear descruction flag.
+ */
Cursor *view_cursor_disposed(View*);
-/* only keep the main cursor, release all others together with their
- * selections (if any) */
+/** Dispose all but the primary selection. */
void view_cursors_clear(View*);
-/* get the first cursor */
+/**
+ * @}
+ * @defgroup view_navigate
+ * @{
+ */
+Cursor *view_cursors_primary_get(View*);
+void view_cursors_primary_set(Cursor*);
+/** Get first selection. */
Cursor *view_cursors(View*);
-/* get other cursors, no ordering is guaranteed */
+/** Get immediate predecessor of selection. */
Cursor *view_cursors_prev(Cursor*);
+/** Get immediate successor of selection. */
Cursor *view_cursors_next(Cursor*);
-/* get the primary cursor which is always in the visible viewport */
-Cursor *view_cursors_primary_get(View*);
-void view_cursors_primary_set(Cursor*);
-/* get current position of cursor in bytes from the start of the file */
+/**
+ * Get number of existing selections.
+ * @rst
+ * .. note:: Is always at least 1.
+ * @endrst
+ */
+int view_cursors_count(View*);
+/**
+ * Get selection index.
+ * @rst
+ * .. note:: Is always in range `[0, count-1]`.
+ * .. warning: The relative order is determined during creation and assumed
+ * to remain the same.
+ * @endrst
+ */
+int view_cursors_number(Cursor*);
+/** Get maximal number of selections on a single line. */
+int view_cursors_column_count(View*);
+/**
+ * Starting from the start of the text, get the `column`-th selection on a line.
+ * @param column The zero based column index.
+ */
+Cursor *view_cursors_column(View*, int column);
+/**
+ * Get the next `column`-th selection on a line.
+ * @param column The zero based column index.
+ */
+Cursor *view_cursors_column_next(Cursor*, int column);
+/**
+ * @}
+ * @defgroup view_cover
+ * @{
+ */
+/** Get an inclusive range of the selection cover. */
+Filerange view_cursors_selection_get(Cursor*);
+/** Set selection cover. Updates both cursor and anchor. */
+void view_cursors_selection_set(Cursor*, const Filerange*);
+/**
+ * Reduce selection to character currently covered by the cursor.
+ * @rst
+ * .. note:: Sets selection to non-anchored mode.
+ * @endrst
+ */
+void view_cursors_selection_clear(Cursor*);
+/** Reduce *all* currently active selections. */
+void view_selections_clear(View*);
+/**
+ * Flip selection orientation. Swap cursor and anchor.
+ * @rst
+ * .. note:: Has no effect on singleton selections.
+ * @endrst
+ */
+void view_cursors_selection_swap(Cursor*);
+/**
+ * @}
+ * @defgroup view_anchor
+ * @{
+ */
+/**
+ * Anchor selection.
+ * Further updates will only update the cursor, the anchor will remain fixed.
+ */
+void view_cursors_selection_start(Cursor*);
+/** Check whether selection is anchored. */
+bool view_selection_anchored(Cursor*);
+/** Get position of selection cursor. */
+/**
+ * @}
+ * @defgroup view_props
+ * @{
+ */
+/** TODO remove */
+bool view_cursors_multiple(View*);
+/** Get position of selection cursor. */
size_t view_cursors_pos(Cursor*);
-/* get 1-based line number of cursor location */
+/** Get 1-based line number of selection cursor. */
size_t view_cursors_line(Cursor*);
-/* get 1-based column (number of graphemes on line) cursor postion */
+/**
+ * Get 1-based column of selection cursor.
+ * @rst
+ * .. note:: Counts the number of graphemes on the logical line up to the cursor
+ * position.
+ * @endrst
+ */
size_t view_cursors_col(Cursor*);
-/* get/set zero based index of cell on which cursor currently resides,
- * -1 if cursor is currently not visible */
+/**
+ * Get screen line of selection cursor.
+ * @rst
+ * .. warning: Is `NULL` for non-visible selections.
+ * @endrst
+ */
+Line *view_cursors_line_get(Cursor*);
+/**
+ * Get zero based index of screen cell on which selection cursor currently resides.
+ * @rst
+ * .. warning:: Returns `-1` if the selection cursor is currently not visible.
+ * @endrst
+ */
int view_cursors_cell_get(Cursor*);
-int view_cursors_cell_set(Cursor*, int cell);
-/* place cursor at `pos' which should be in the interval [0, text-size] */
+/**
+ * @}
+ * @defgroup view_place
+ * @{
+ */
+/**
+ * Place cursor of selection at `pos`.
+ * @rst
+ * .. note:: If the selection is not anchored, both selection endpoints
+ * will be adjusted to form a singleton selection covering one
+ * character starting at `pos`. Otherwise only the selection
+ * cursor will be changed while the anchor remains fixed.
+ * @endrst
+ */
void view_cursors_to(Cursor*, size_t pos);
+/**
+ * Adjusts window viewport until the requested position becomes visible.
+ * @rst
+ * .. note:: For all but the primary selection this is equivalent to
+ * ``view_selection_to``.
+ * .. warning:: Repeatedly redraws the window content. Should only be used for
+ * short distances between current cursor position and destination.
+ * @endrst
+ */
void view_cursors_scroll_to(Cursor*, size_t pos);
-/* place cursor on given (line, column) pair, both values are 1-based */
+/**
+ * Place cursor on given (line, column) pair.
+ * @param line the 1-based line number
+ * @param col the 1 based column
+ * @rst
+ * .. note:: Except for the different addressing format this is equivalent to
+ * `view_selection_to`.
+ * @endrst
+ */
void view_cursors_place(Cursor*, size_t line, size_t col);
-/* start selected area at current cursor position. further cursor movements
- * will affect the selected region. */
-void view_cursors_selection_start(Cursor*);
-/* clear selection associated with this cursor (if any) */
-void view_cursors_selection_clear(Cursor*);
-/* move cursor position from one end of the selection to the other */
-void view_cursors_selection_swap(Cursor*);
-/* get/set the selected region associated with this cursor */
-Filerange view_cursors_selection_get(Cursor*);
-void view_cursors_selection_set(Cursor*, const Filerange*);
-
+/**
+ * Place selection cursor on zero based window cell index.
+ * @rst
+ * .. warning:: Fails if the selection cursor is currently not visible.
+ * @endrst
+ */
+int view_cursors_cell_set(Cursor*, int cell);
+/**
+ * @}
+ * @defgroup view_motions
+ * @{
+ */
+size_t view_line_down(Cursor*);
+size_t view_line_up(Cursor*);
+size_t view_screenline_down(Cursor*);
+size_t view_screenline_up(Cursor*);
+size_t view_screenline_begin(Cursor*);
+size_t view_screenline_middle(Cursor*);
+size_t view_screenline_end(Cursor*);
+/**
+ * @}
+ * @defgroup view_primary
+ * @{
+ */
+/**
+ * Move primary selection cursor to the given position.
+ * Makes sure that position is visisble.
+ * @rst
+ * .. note:: If position was not visible before, we attempt to show
+ * surrounding context. The viewport will be adjusted such
+ * that the line holding the cursor is shown in the middle
+ * of the window.
+ * @endrst
+ */
+void view_cursor_to(View*, size_t pos);
+/** Get cursor position of primary selection. */
+size_t view_cursor_get(View*);
+/**
+ * Get primary selection.
+ * @rst
+ * .. note:: Is always a non-empty range.
+ * @endrst
+ */
+Filerange view_selection_get(View*);
+/**
+ * @}
+ * @defgroup view_save
+ * @{
+ */
+/** Save selection which can later be restored. */
void view_cursors_selection_save(Selection*);
+/**
+ * Restore a previously active selection.
+ * @rst
+ * .. note:: Fails if selection boundaries no longer exist.
+ * @endrst
+ */
bool view_cursors_selection_restore(Selection*);
+/**
+ * @}
+ * @defgroup view_style
+ * @{
+ */
+void view_options_set(View*, enum UiOption options);
+enum UiOption view_options_get(View*);
+void view_colorcolumn_set(View*, int col);
+int view_colorcolumn_get(View*);
-bool view_selection_anchored(Cursor*);
-
-void view_selections_clear(View*);
-Text *view_text(View*);
-
-/* get number of columns, that is maximal number of cursors on a line */
-int view_cursors_column_count(View*);
-/* get first cursor in zero based column */
-Cursor *view_cursors_column(View*, int column);
-/* get next cursor (i.e. on another line) in zero based column */
-Cursor *view_cursors_column_next(Cursor*, int column);
-
+/** Set how many spaces are used to display a tab `\t` character. */
+void view_tabwidth_set(View*, int tabwidth);
+/** Define a display style. */
bool view_style_define(View*, enum UiStyle, const char *style);
+/** Apply a style to a text range. */
void view_style(View*, enum UiStyle, size_t start, size_t end);
+/** @} */
+
#endif