git.y1.nz

lwl

Less with links.
download: http://git.y1.nz/archives/lwl.tar.gz
README | Files | Log | Refs

draw.c

      1 #include <stdio.h>
      2 
      3 #include "config.h"
      4 #include "text.h"
      5 #include "state.h"
      6 
      7 void
      8 draw_status_line(State *state)
      9 {
     10 	if (state->message != NULL) {
     11 		printf(
     12 			"\033[30;47m" "%s",
     13 			state->message
     14 		);
     15 	} else if (state->mode != MODE_GROUND) {
     16 		printf(
     17 			"\033[1m" "%c%s" "\033[0m",
     18 			state->mode,
     19 			state->input
     20 		);
     21 	} else {
     22 		printf("\033[1m" "%c" "\033[0m", state->mode);
     23 	}
     24 
     25 	/* reset graphical rendition */
     26 	printf("\033[0m");
     27 }
     28 
     29 int color = -1;
     30 int active = 0;
     31 
     32 void
     33 set_color(Markup *markup)
     34 {
     35 	int new_color = markup == NULL ? COLOR_BLACK : markup->color;
     36 	int new_active = markup == NULL ? 0 : markup->active;
     37 
     38 	if (new_color == color && new_active == active)
     39 		return;
     40 
     41 	color = new_color;
     42 	active = new_active;
     43 
     44 	switch (color) {
     45 	case COLOR_BLACK:
     46 		if (active) fputs("\033[0;47;30m", stdout);
     47 		else fputs("\033[0m", stdout);
     48 		break;
     49 	case COLOR_RED:
     50 		if (active) fputs("\033[0;41;37m", stdout);
     51 		else fputs("\033[1;40;31m", stdout);
     52 		break;
     53 	case COLOR_BLUE:
     54 		if (active) fputs("\033[1;44;37m", stdout);
     55 		else fputs("\033[1;40;34m", stdout);
     56 		break;
     57 	case COLOR_GREEN:
     58 		if (active) fputs("\033[0;42;37m", stdout);
     59 		else fputs("\033[1;40;32m", stdout);
     60 		break;
     61 	case COLOR_YELLOW:
     62 		if (active) fputs("\033[0;43;30m", stdout);
     63 		else fputs("\033[1;40;33m", stdout);
     64 		break;
     65 	case COLOR_CYAN:
     66 		if (active) fputs("\033[0;46;30m", stdout);
     67 		else fputs("\033[40;36m", stdout);
     68 		break;
     69 	case COLOR_MAGENTA:
     70 		if (active) fputs("\033[0;45;30m", stdout);
     71 		else fputs("\033[1;40;35m", stdout);
     72 		break;
     73 	case COLOR_WHITE:
     74 		if (active) fputs("\033[0;47;30m", stdout);
     75 		else fputs("\033[1;47;30m", stdout);
     76 		break;
     77 	}
     78 }
     79 
     80 Markup *
     81 get_markup_at(Markup **markups, int count, Markup *inner0, int index)
     82 {
     83 	Markup *markup;
     84 	Markup *inner = inner0;
     85 
     86 	// TODO iterate over all lists before printing the ""verdict""
     87 	for (int k = 0; k < count; k++) {
     88 		markup = markups[k];
     89 		if (inner != NULL && inner->active && !markup->active) continue;
     90 		if (
     91 			index >= markup->start &&
     92 			index < markup->start + markup->width &&
     93 			(
     94 				inner == NULL ||
     95 				markup->start > inner->start ||
     96 				markup->active
     97 			)
     98 		) inner = markup;
     99 	}
    100 	
    101 	return inner;
    102 }
    103 
    104 /* draws (wrapped) line index y in the cursor's current row. */
    105 /*** must pop all formatting before returning ***/
    106 void
    107 draw_line(FileContents *contents, Wrap *wrap, State *state, int y)
    108 {
    109 	char ch;
    110 	int index;
    111 	Markup *markup;
    112 	int line_length = wrap->lines[y+1] - wrap->lines[y];
    113 
    114 	printf("\033[2K"); /* clear current line */
    115 
    116 	if (y < 0) {
    117 		printf("!!!");
    118 		return;
    119 	}
    120 
    121 	if (y >= wrap->line_count) {
    122 		printf("~");
    123 		return;
    124 	}
    125 
    126 	Markup *inner;
    127 	int j;
    128 	int print_length = line_length;
    129 	if (print_length > wrap->width) print_length = wrap->width;
    130 	for (j = 0; j < print_length; j++) {
    131 		index = wrap->lines[y] + j;
    132 		ch = contents->buffer[index];
    133 		if (ch == '\n') break;
    134 
    135 		inner = NULL;
    136 		inner = get_markup_at(
    137 			contents->highlights,
    138 			contents->highlight_count,
    139 			inner,
    140 			index
    141 		);
    142 		inner = get_markup_at(
    143 			contents->links,
    144 			contents->link_count,
    145 			inner,
    146 			index);
    147 		inner = get_markup_at(
    148 			state->results,
    149 			state->result_count,
    150 			inner,
    151 			index
    152 		);
    153 		set_color(inner);
    154 		putchar(ch);
    155 	}
    156 	if (ch != '\n' && ch != '\0') {
    157 		printf("\033[1;47;30m" "-");
    158 	}
    159 
    160 	printf("\033[0m"); /* reset graphic rendition */
    161 	color = COLOR_BLACK;
    162 	active = 0;
    163 }
    164 
    165 void
    166 redraw(FileContents *contents, Wrap *wrap, State *state)
    167 {
    168 	int y;
    169 
    170 	printf("\033[1;1H"); /* cursor to top-left corner */
    171 	for (int i = 0; i < wrap->height; i++) {
    172 		y = state->line_offset+i;
    173 		draw_line(contents, wrap, state, y);
    174 		printf("\r\n");
    175 	}
    176 
    177 	printf("\033[2K"); /* clear status line */
    178 	draw_status_line(state);
    179 
    180 	fflush(stdout);
    181 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.