vip

VI Plus
git clone https://codeberg.org/night0721/vip
Log | Files | Refs | README | LICENSE

row.c (3123B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 #include "vip.h"
      6 #include "row.h"
      7 #include "syntax.h"
      8 
      9 extern editor vip;
     10 
     11 int row_cx_to_rx(row *row, int cx)
     12 {
     13 	int rx = 0;
     14 	for (int j = 0; j < cx; j++) {
     15 		if (row->chars[j] == '\t') {
     16 			rx += (TAB_SIZE - 1) - (rx % TAB_SIZE);
     17 		}
     18 		rx++;
     19 	}
     20 	return rx;
     21 }
     22 
     23 int row_rx_to_cx(row *row, int rx)
     24 {
     25   int cur_rx = 0;
     26   int cx;
     27   for (cx = 0; cx < row->size; cx++) {
     28 	  if (row->chars[cx] == '\t') {
     29 		  cur_rx += (TAB_SIZE - 1) - (cur_rx % TAB_SIZE);
     30 	  }
     31     cur_rx++;
     32     if (cur_rx > rx)
     33 		return cx;
     34   }
     35   return cx;
     36 }
     37 
     38 void update_row(row *row)
     39 {
     40 	int tabs = 0;
     41 	for (int j = 0; j < row->size; j++)
     42 		if (row->chars[j] == '\t') tabs++;
     43 	free(row->render);
     44 	row->render = malloc(row->size + tabs * (TAB_SIZE - 1) + 1);
     45 	int idx = 0;
     46 	for (int j = 0; j < row->size; j++) {
     47 		if (row->chars[j] == '\t') {
     48 			row->render[idx++] = ' ';
     49 			while (idx % TAB_SIZE != 0) {
     50 				row->render[idx++] = ' ';
     51 			}
     52 		}
     53 		else {
     54 			row->render[idx++] = row->chars[j];
     55 		}
     56 	}
     57 	row->render[idx] = '\0';
     58 	row->render_size = idx;
     59 	update_highlight(row);
     60 }
     61 
     62 void insert_row(int at, char *s, size_t len)
     63 {
     64 	if (at < 0 || at > vip.rows) return;
     65 
     66 	vip.row = realloc(vip.row, sizeof(row) * (vip.rows + 1));
     67 	memmove(&vip.row[at + 1], &vip.row[at], sizeof(row) * (vip.rows - at));
     68 	for (int j = at + 1; j <= vip.rows; j++) {
     69 		vip.row[j].idx++;
     70 	}
     71 
     72 	vip.row[at].idx = at;
     73 
     74 	vip.row[at].size = len;
     75 	vip.row[at].chars = malloc(len + 1);
     76 	memcpy(vip.row[at].chars, s, len);
     77 	vip.row[at].chars[len] = '\0';
     78 
     79 	vip.row[at].render_size = 0;
     80 	vip.row[at].render = NULL;
     81 	vip.row[at].hl = NULL;
     82 	vip.row[at].opened_comment = 0;
     83 	update_row(&vip.row[at]);
     84 
     85 	vip.rows++;
     86 	vip.dirty++;
     87 }
     88 
     89 void free_row(row *row)
     90 {
     91 	free(row->render);
     92 	free(row->chars);
     93 	free(row->hl);
     94 }
     95 
     96 void del_row(int at)
     97 {
     98 	if (at < 0 || at >= vip.rows) return;
     99 	free_row(&vip.row[at]);
    100 	memmove(&vip.row[at], &vip.row[at + 1], sizeof(row) * (vip.rows - at - 1));
    101 	for (int j = at; j < vip.rows - 1; j++) {
    102 		vip.row[j].idx--;
    103 	}
    104 	vip.rows--;
    105 	vip.dirty++;
    106 }
    107 
    108 void row_insert_char(row *row, int at, int c)
    109 {
    110 	if (at < 0 || at > row->size) {
    111 		at = row->size;
    112 	}
    113 	row->chars = realloc(row->chars, row->size + 2);
    114 	memmove(&row->chars[at + 1], &row->chars[at], row->size - at + 1);
    115 	row->size++;
    116 	row->chars[at] = c;
    117 	update_row(row);
    118 	vip.dirty++;
    119 }
    120 
    121 void row_append_str(row *row, char *s, size_t len)
    122 {
    123 	row->chars = realloc(row->chars, row->size + len + 1);
    124 	memcpy(&row->chars[row->size], s, len);
    125 	row->size += len;
    126 	row->chars[row->size] = '\0';
    127 	update_row(row);
    128 	vip.dirty++;
    129 }
    130 
    131 void row_del_char(row *row, int at)
    132 {
    133 	if (at < 0 || at >= row->size) return;
    134 	memmove(&row->chars[at], &row->chars[at + 1], row->size - at);
    135 	row->size--;
    136 	update_row(row);
    137 	vip.dirty++;
    138 }
    139 
    140 char *rows_to_str(int *buflen)
    141 {
    142 	int total_len = 0;
    143 	for (int j = 0; j < vip.rows; j++) {
    144 		total_len += vip.row[j].size + 1;
    145 	}
    146 	*buflen = total_len;
    147 	char *buf = malloc(total_len);
    148 	char *p = buf;
    149 	for (int j = 0; j < vip.rows; j++) {
    150 		memcpy(p, vip.row[j].chars, vip.row[j].size);
    151 		p += vip.row[j].size;
    152 		*p = '\n';
    153 		p++;
    154 	}
    155 	return buf;
    156 }