vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

view.h

(12423B)


      1 #ifndef VIEW_H
      2 #define VIEW_H
      3 
      4 #include <stddef.h>
      5 #include <stdbool.h>
      6 
      7 #include "ui.h"
      8 #include "text.h"
      9 #include "array.h"
     10 
     11 enum {
     12 	SYNTAX_SYMBOL_SPACE,
     13 	SYNTAX_SYMBOL_TAB,
     14 	SYNTAX_SYMBOL_TAB_FILL,
     15 	SYNTAX_SYMBOL_EOL,
     16 	SYNTAX_SYMBOL_EOF,
     17 	SYNTAX_SYMBOL_LAST,
     18 };
     19 
     20 typedef struct {
     21 	Mark anchor;
     22 	Mark cursor;
     23 } SelectionRegion;
     24 
     25 typedef struct Line Line;
     26 struct Line {               /* a line on the screen, *not* in the file */
     27 	Line *prev, *next;  /* pointer to neighbouring screen lines */
     28 	size_t len;         /* line length in terms of bytes */
     29 	size_t lineno;      /* line number from start of file */
     30 	int width;          /* zero based position of last used column cell */
     31 	Cell cells[];       /* win->width cells storing information about the displayed characters */
     32 };
     33 
     34 struct View;
     35 typedef struct Selection {
     36 	Mark cursor;            /* other selection endpoint where it changes */
     37 	Mark anchor;            /* position where the selection was created */
     38 	bool anchored;          /* whether anchor remains fixed */
     39 	size_t pos;             /* in bytes from the start of the file */
     40 	int row, col;           /* in terms of zero based screen coordinates */
     41 	int lastcol;            /* remembered column used when moving across lines */
     42 	Line *line;             /* screen line on which cursor currently resides */
     43 	int generation;         /* used to filter out newly created cursors during iteration */
     44 	int number;             /* how many cursors are located before this one */
     45 	struct View *view;      /* associated view to which this cursor belongs */
     46 	struct Selection *prev, *next; /* previous/next cursors ordered by location at creation time */
     47 } Selection;
     48 
     49 typedef struct View {
     50 	Text *text;         /* underlying text management */
     51 	char *textbuf;      /* scratch buffer used for drawing */
     52 	int width, height;  /* size of display area */
     53 	size_t start, end;  /* currently displayed area [start, end] in bytes from the start of the file */
     54 	size_t start_last;  /* previously used start of visible area, used to update the mark */
     55 	Mark start_mark;    /* mark to keep track of the start of the visible area */
     56 	size_t lines_size;  /* number of allocated bytes for lines (grows only) */
     57 	Line *lines;        /* view->height number of lines representing view content */
     58 	Line *topline;      /* top of the view, first line currently shown */
     59 	Line *lastline;     /* last currently used line, always <= bottomline */
     60 	Line *bottomline;   /* bottom of view, might be unused if lastline < bottomline */
     61 	Selection *selection;    /* primary selection, always placed within the visible viewport */
     62 	Selection *selection_latest; /* most recently created cursor */
     63 	Selection *selection_dead;   /* primary cursor which was disposed, will be removed when another cursor is created */
     64 	int selection_count;   /* how many cursors do currently exist */
     65 	Line *line;         /* used while drawing view content, line where next char will be drawn */
     66 	int col;            /* used while drawing view content, column where next char will be drawn */
     67 	const char *symbols[SYNTAX_SYMBOL_LAST]; /* symbols to use for white spaces etc */
     68 	int tabwidth;       /* how many spaces should be used to display a tab character */
     69 	Selection *selections;    /* all cursors currently active */
     70 	int selection_generation; /* used to filter out newly created cursors during iteration */
     71 	bool need_update;   /* whether view has been redrawn */
     72 	bool large_file;    /* optimize for displaying large files */
     73 	int colorcolumn;
     74 	char *breakat;  /* characters which might cause a word wrap */
     75 	int wrapcolumn; /* wrap lines at minimum of window width and wrapcolumn (if != 0) */
     76 	int wrapcol;    /* used while drawing view content, column where word wrap might happen */
     77 	bool prevch_breakat; /* used while drawing view content, previous char is part of breakat */
     78 } View;
     79 
     80 /**
     81  * @defgroup view_life View Lifecycle
     82  * @{
     83  */
     84 bool view_init(struct Win*, Text*);
     85 void view_free(View*);
     86 void view_reload(View*, Text*);
     87 /**
     88  * @}
     89  * @defgroup view_viewport View Viewport
     90  * @{
     91  */
     92 /** Get the currently displayed text range. */
     93 #define VIEW_VIEWPORT_GET(v) (Filerange){ .start = v.start, .end = v.end }
     94 /**
     95  * Get window coordinate of text position.
     96  * @param view The view to manipulate.
     97  * @param pos The position to query.
     98  * @param line Will be updated with screen line on which ``pos`` resides.
     99  * @param row Will be updated with zero based window row on which ``pos`` resides.
    100  * @param col Will be updated with zero based window column on which ``pos`` resides.
    101  * @return Whether ``pos`` is visible. If not, the pointer arguments are left unmodified.
    102  */
    103 bool view_coord_get(View *view, size_t pos, Line **line, int *row, int *col);
    104 /** Get position at the start of the ``n``-th window line, counting from 1. */
    105 size_t view_screenline_goto(View*, int n);
    106 size_t view_slide_up(View*, int lines);
    107 size_t view_slide_down(View*, int lines);
    108 size_t view_scroll_up(View*, int lines);
    109 size_t view_scroll_down(View*, int lines);
    110 size_t view_scroll_page_up(View*);
    111 size_t view_scroll_page_down(View*);
    112 size_t view_scroll_halfpage_up(View*);
    113 size_t view_scroll_halfpage_down(View*);
    114 void view_redraw_top(View*);
    115 void view_redraw_center(View*);
    116 void view_redraw_bottom(View*);
    117 void view_scroll_to(View*, size_t pos);
    118 /**
    119  * @}
    120  * @defgroup view_size View Sizing
    121  * @{
    122  */
    123 bool view_resize(View*, int width, int height);
    124 /**
    125  * @}
    126  * @defgroup view_draw View Drawing
    127  * @{
    128  */
    129 void view_draw(View*);
    130 bool view_update(View*);
    131 
    132 /**
    133  * @}
    134  * @defgroup view_selnew View Selections
    135  * @{
    136  */
    137 /**
    138  * Create a new singleton selection at the given position.
    139  * @rst
    140  * .. note:: New selections are created non-anchored.
    141  * .. warning:: Fails if position is already covered by a selection.
    142  * @endrst
    143  */
    144 Selection *view_selections_new(View*, size_t pos);
    145 /**
    146  * Create a new selection even if position is already covered by an
    147  * existing selection.
    148  * @rst
    149  * .. note:: This should only be used if the old selection is eventually
    150  *           disposed.
    151  * @endrst
    152  */
    153 Selection *view_selections_new_force(View*, size_t pos);
    154 /**
    155  * Dispose an existing selection.
    156  * @rst
    157  * .. warning:: Not applicable for the last existing selection.
    158  * @endrst
    159  */
    160 bool view_selections_dispose(Selection*);
    161 /**
    162  * Forcefully dispose an existing selection.
    163  *
    164  * If called for the last existing selection, it will be reduced and
    165  * marked for destruction. As soon as a new selection is created this one
    166  * will be disposed.
    167  */
    168 bool view_selections_dispose_force(Selection*);
    169 /**
    170  * Query state of primary selection.
    171  *
    172  * If the primary selection was marked for destruction, return it and
    173  * clear destruction flag.
    174  */
    175 Selection *view_selection_disposed(View*);
    176 /** Dispose all but the primary selection. */
    177 void view_selections_dispose_all(View*);
    178 /** Dispose all invalid and merge all overlapping selections. */
    179 void view_selections_normalize(View*);
    180 /**
    181  * Replace currently active selections.
    182  * @param view The view to manipulate.
    183  * @param array The array of ``Filerange`` objects.
    184  * @param anchored Whether *all* selection should be anchored.
    185  */
    186 void view_selections_set_all(View *view, Array *array, bool anchored);
    187 /** Get array containing a ``Fileranges`` for each selection. */
    188 Array view_selections_get_all(View*);
    189 /**
    190  * @}
    191  * @defgroup view_navigate Selection Navigation
    192  * @{
    193  */
    194 Selection *view_selections_primary_get(View*);
    195 void view_selections_primary_set(Selection*);
    196 /** Get first selection. */
    197 Selection *view_selections(View*);
    198 /** Get immediate predecessor of selection. */
    199 Selection *view_selections_prev(Selection*);
    200 /** Get immediate successor of selection. */
    201 Selection *view_selections_next(Selection*);
    202 /**
    203  * Get selection index.
    204  * @rst
    205  * .. note:: Is always in range ``[0, count-1]``.
    206  * .. warning: The relative order is determined during creation and assumed
    207  *             to remain the same.
    208  * @endrst
    209  */
    210 int view_selections_number(Selection*);
    211 /** Get maximal number of selections on a single line. */
    212 int view_selections_column_count(View*);
    213 /**
    214  * Starting from the start of the text, get the `column`-th selection on a line.
    215  * @param view The view to manipulate.
    216  * @param column The zero based column index.
    217  */
    218 Selection *view_selections_column(View *view, int column);
    219 /**
    220  * Get the next `column`-th selection on a line.
    221  * @param sel The selection to manipulate.
    222  * @param column The zero based column index.
    223  */
    224 Selection *view_selections_column_next(Selection *sel, int column);
    225 /**
    226  * @}
    227  * @defgroup view_cover Selection Coverage
    228  * @{
    229  */
    230 /** Get an inclusive range of the selection cover. */
    231 Filerange view_selections_get(Selection*);
    232 /** Set selection cover. Updates both cursor and anchor. */
    233 bool view_selections_set(Selection*, const Filerange*);
    234 /**
    235  * Reduce selection to character currently covered by the cursor.
    236  * @rst
    237  * .. note:: Sets selection to non-anchored mode.
    238  * @endrst
    239  */
    240 void view_selection_clear(Selection*);
    241 /** Reduce *all* currently active selections. */
    242 void view_selections_clear_all(View*);
    243 /**
    244  * Flip selection orientation. Swap cursor and anchor.
    245  * @rst
    246  * .. note:: Has no effect on singleton selections.
    247  * @endrst
    248  */
    249 void view_selections_flip(Selection*);
    250 /**
    251  * @}
    252  * @defgroup view_props Selection Properties
    253  * @{
    254  */
    255 /** Get position of selection cursor. */
    256 size_t view_cursors_pos(Selection*);
    257 /** Get 1-based line number of selection cursor. */
    258 size_t view_cursors_line(Selection*);
    259 /**
    260  * Get 1-based column of selection cursor.
    261  * @rst
    262  * .. note:: Counts the number of graphemes on the logical line up to the cursor
    263  *           position.
    264  * @endrst
    265  */
    266 size_t view_cursors_col(Selection*);
    267 /**
    268  * @}
    269  * @defgroup view_place Cursor Placement
    270  * @{
    271  */
    272 /**
    273  * Place cursor of selection at `pos`.
    274  * @rst
    275  * .. note:: If the selection is not anchored, both selection endpoints
    276  *           will be adjusted to form a singleton selection covering one
    277  *           character starting at `pos`. Otherwise only the selection
    278  *           cursor will be changed while the anchor remains fixed.
    279  *
    280  *           If primary position was not visible before, we attempt to show
    281  *           the surrounding context. The viewport will be adjusted such
    282  *           that the line holding the primary cursor is shown in the middle
    283  *           of the window.
    284  * @endrst
    285  */
    286 void view_cursors_to(Selection*, size_t pos);
    287 /**
    288  * Adjusts window viewport until the requested position becomes visible.
    289  * @rst
    290  * .. note:: For all but the primary selection this is equivalent to
    291  *           ``view_selection_to``.
    292  * .. warning:: Repeatedly redraws the window content. Should only be used for
    293  *              short distances between current cursor position and destination.
    294  * @endrst
    295  */
    296 void view_cursors_scroll_to(Selection*, size_t pos);
    297 /**
    298  * Place cursor on given (line, column) pair.
    299  * @param s the selection to manipulate
    300  * @param line the 1-based line number
    301  * @param col the 1 based column
    302  * @rst
    303  * .. note:: Except for the different addressing format this is equivalent to
    304  *           `view_selection_to`.
    305  * @endrst
    306  */
    307 void view_cursors_place(Selection *s, size_t line, size_t col);
    308 /**
    309  * Place selection cursor on zero based window cell index.
    310  * @rst
    311  * .. warning:: Fails if the selection cursor is currently not visible.
    312  * @endrst
    313  */
    314 int view_cursors_cell_set(Selection*, int cell);
    315 /**
    316  * @}
    317  * @defgroup view_motions View Motions
    318  * @{
    319  */
    320 size_t view_line_down(Selection*);
    321 size_t view_line_up(Selection*);
    322 size_t view_screenline_down(Selection*);
    323 size_t view_screenline_up(Selection*);
    324 size_t view_screenline_begin(Selection*);
    325 size_t view_screenline_middle(Selection*);
    326 size_t view_screenline_end(Selection*);
    327 /**
    328  * @}
    329  * @defgroup view_primary Primary Selection
    330  * @{
    331  */
    332 /** Get cursor position of primary selection. */
    333 size_t view_cursor_get(View*);
    334 /**
    335  * @}
    336  * @defgroup view_save Selection State
    337  * @{
    338  */
    339 Filerange view_regions_restore(View*, SelectionRegion*);
    340 bool view_regions_save(View*, Filerange*, SelectionRegion*);
    341 /**
    342  * @}
    343  * @defgroup view_style View Styling
    344  * @{
    345  */
    346 void win_options_set(struct Win *, enum UiOption);
    347 bool view_breakat_set(View*, const char *breakat);
    348 
    349 /** Set how many spaces are used to display a tab `\t` character. */
    350 void view_tabwidth_set(View*, int tabwidth);
    351 /** Apply a style to a text range. */
    352 void win_style(struct Win*, enum UiStyle, size_t start, size_t end, bool keep_non_default);
    353 
    354 /** @} */
    355 
    356 #endif