1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
|
#ifndef VIEW_H
#define VIEW_H
#include <stddef.h>
#include <stdbool.h>
typedef struct View View;
typedef struct Selection Selection;
#include "text.h"
#include "ui.h"
#include "array.h"
typedef struct {
Mark anchor;
Mark cursor;
} SelectionRegion;
typedef struct {
char data[16]; /* utf8 encoded character displayed in this cell (might be more than
one Unicode codepoint. might also not be the same as in the
underlying text, for example tabs get expanded */
size_t len; /* number of bytes the character displayed in this cell uses, for
characters which use more than 1 column to display, their length
is stored in the leftmost cell whereas all following cells
occupied by the same character have a length of 0. */
int width; /* display width i.e. number of columns occupied by this character */
CellStyle style; /* colors and attributes used to display this cell */
} Cell;
typedef struct Line Line;
struct Line { /* a line on the screen, *not* in the file */
Line *prev, *next; /* pointer to neighbouring screen lines */
size_t len; /* line length in terms of bytes */
size_t lineno; /* line number from start of file */
int width; /* zero based position of last used column cell */
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*);
Text *view_text(View*);
void view_reload(View*, Text*);
/**
* @}
* @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 col Will be updated with zero based window column on 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 of 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);
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*);
void view_redraw_top(View*);
void view_redraw_center(View*);
void view_redraw_bottom(View*);
void view_scroll_to(View*, size_t pos);
/**
* @}
* @defgroup view_size
* @{
*/
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*);
/**
* @}
* @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
*/
Selection *view_selections_new(View*, size_t pos);
/**
* 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
*/
Selection *view_selections_new_force(View*, size_t pos);
/**
* Dispose an existing selection.
* @rst
* .. warning:: Not applicable for the last existing selection.
* @endrst
*/
bool view_selections_dispose(Selection*);
/**
* 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_selections_dispose_force(Selection*);
/**
* Query state of primary selection.
*
* If the primary selection was marked for destruction, return it and
* clear destruction flag.
*/
Selection *view_selection_disposed(View*);
/** Dispose all but the primary selection. */
void view_selections_dispose_all(View*);
/** Dispose all invalid and merge all overlapping selections. */
void view_selections_normalize(View*);
/**
* Replace currently active selections.
* @param array The array of ``Filerange`` objects.
* @param anchored Whether *all* selection should be anchored.
*/
void view_selections_set_all(View*, Array*, bool anchored);
/** Get array containing a ``Fileranges`` for each selection. */
Array view_selections_get_all(View*);
/**
* @}
* @defgroup view_navigate
* @{
*/
Selection *view_selections_primary_get(View*);
void view_selections_primary_set(Selection*);
/** Get first selection. */
Selection *view_selections(View*);
/** Get immediate predecessor of selection. */
Selection *view_selections_prev(Selection*);
/** Get immediate successor of selection. */
Selection *view_selections_next(Selection*);
/**
* Get number of existing selections.
* @rst
* .. note:: Is always at least 1.
* @endrst
*/
int view_selections_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_selections_number(Selection*);
/** Get maximal number of selections on a single line. */
int view_selections_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.
*/
Selection *view_selections_column(View*, int column);
/**
* Get the next `column`-th selection on a line.
* @param column The zero based column index.
*/
Selection *view_selections_column_next(Selection*, int column);
/**
* @}
* @defgroup view_cover
* @{
*/
/** Get an inclusive range of the selection cover. */
Filerange view_selections_get(Selection*);
/** Set selection cover. Updates both cursor and anchor. */
bool view_selections_set(Selection*, const Filerange*);
/**
* Reduce selection to character currently covered by the cursor.
* @rst
* .. note:: Sets selection to non-anchored mode.
* @endrst
*/
void view_selection_clear(Selection*);
/** Reduce *all* currently active selections. */
void view_selections_clear_all(View*);
/**
* Flip selection orientation. Swap cursor and anchor.
* @rst
* .. note:: Has no effect on singleton selections.
* @endrst
*/
void view_selections_flip(Selection*);
/**
* @}
* @defgroup view_anchor
* @{
*/
/**
* Anchor selection.
* Further updates will only update the cursor, the anchor will remain fixed.
*/
void view_selections_anchor(Selection*, bool anchored);
/** Check whether selection is anchored. */
bool view_selections_anchored(Selection*);
/** Get position of selection cursor. */
/**
* @}
* @defgroup view_props
* @{
*/
/** Get position of selection cursor. */
size_t view_cursors_pos(Selection*);
/** Get 1-based line number of selection cursor. */
size_t view_cursors_line(Selection*);
/**
* 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(Selection*);
/**
* Get screen line of selection cursor.
* @rst
* .. warning: Is `NULL` for non-visible selections.
* @endrst
*/
Line *view_cursors_line_get(Selection*);
/**
* 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(Selection*);
/**
* @}
* @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(Selection*, 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(Selection*, size_t pos);
/**
* 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(Selection*, size_t line, size_t col);
/**
* 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(Selection*, int cell);
/**
* @}
* @defgroup view_motions
* @{
*/
size_t view_line_down(Selection*);
size_t view_line_up(Selection*);
size_t view_screenline_down(Selection*);
size_t view_screenline_up(Selection*);
size_t view_screenline_begin(Selection*);
size_t view_screenline_middle(Selection*);
size_t view_screenline_end(Selection*);
/**
* @}
* @defgroup view_primary
* @{
*/
/**
* Move primary selection cursor to the given position.
* Makes sure that position is visible.
* @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
* @{
*/
Filerange view_regions_restore(View*, SelectionRegion*);
bool view_regions_save(View*, Filerange*, SelectionRegion*);
/**
* @}
* @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*);
/** 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);
char *view_symbol_eof_get(View*);
/** @} */
#endif
|