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 }