Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@ add_project_arguments(
language: 'c',
)

tree_sitter_dep = dependency('tree-sitter')
cc = meson.get_compiler('c')
dl_dep = cc.find_library('dl', required: false)

subdir('src')
subdir('tests')
98 changes: 60 additions & 38 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ static void buffer_append_line(buffer_t *buf, const char *data, size_t len)
buffer_ensure_line_cap(buf, buf->num_lines + 1);
line_t *line = &buf->lines[buf->num_lines];
line->chars = NULL;
line->cap = 0;
line->len = 0;
if (len > 0) {
line_ensure_cap(line, len);
Expand All @@ -58,6 +57,7 @@ void buffer_init(buffer_t *buf)
buf->cap_lines = 0;
buf->filename = NULL;
buf->dirty = 0;
buf->version = 0;
buf->encoding = ENCODING_UTF8;
buf->use_crlf = 0;
buf->trailing_newline = 1;
Expand Down Expand Up @@ -117,6 +117,7 @@ int buffer_load(buffer_t *buf, const char *filename)
buf->use_crlf = 0;
buf->trailing_newline = 1;
buf->dirty = 0;
buf->version = 0;

size_t line_start = offset;
int first_line = 1;
Expand All @@ -139,15 +140,15 @@ int buffer_load(buffer_t *buf, const char *filename)
line_start = i + 1;
}

if (line_start < total) {
buffer_append_line(buf, (const char *)data + line_start, total - line_start);
if (line_start < total || buf->num_lines == 0) {
size_t line_end = total;
if (line_end > line_start && data[line_end - 1] == '\r') {
line_end--;
}
buffer_append_line(buf, (const char *)data + line_start, line_end - line_start);
buf->trailing_newline = 0;
}

if (buf->num_lines == 0) {
buffer_append_line(buf, "", 0);
}

free(data);
return 0;
}
Expand Down Expand Up @@ -204,6 +205,7 @@ void buffer_insert_bytes(buffer_t *buf, size_t row, size_t col, const char *byte
memcpy(line->chars + col, bytes, n);
line->len += n;
buf->dirty = 1;
buf->version++;
}

void buffer_delete_range(buffer_t *buf, size_t r1, size_t c1, size_t r2, size_t c2)
Expand All @@ -214,6 +216,7 @@ void buffer_delete_range(buffer_t *buf, size_t r1, size_t c1, size_t r2, size_t
memmove(line->chars + c1, line->chars + c1 + n, line->len - c1 - n);
line->len -= n;
buf->dirty = 1;
buf->version++;
return;
}

Expand All @@ -235,6 +238,7 @@ void buffer_delete_range(buffer_t *buf, size_t r1, size_t c1, size_t r2, size_t
(buf->num_lines - r2 - 1) * sizeof(line_t));
buf->num_lines -= remove_count;
buf->dirty = 1;
buf->version++;
}

void buffer_split_line(buffer_t *buf, size_t row, size_t col)
Expand All @@ -260,6 +264,7 @@ void buffer_split_line(buffer_t *buf, size_t row, size_t col)

buf->num_lines += 1;
buf->dirty = 1;
buf->version++;
}

void buffer_join_lines(buffer_t *buf, size_t row)
Expand All @@ -276,61 +281,78 @@ void buffer_join_lines(buffer_t *buf, size_t row)
(buf->num_lines - row - 2) * sizeof(line_t));
buf->num_lines -= 1;
buf->dirty = 1;
buf->version++;
}

char *buffer_extract_text(const buffer_t *buf, size_t r1, size_t c1, size_t r2, size_t c2,
size_t *out_len)
size_t *out_len)
{
if (r1 == r2) {
const line_t *line = &buf->lines[r1];
size_t len = c2 - c1;
char *text = xmalloc(len > 0 ? len : 1);
char *text = xmalloc(len + 1);
memcpy(text, line->chars + c1, len);
*out_len = len;
text[len] = '\0';
if (out_len != NULL) {
*out_len = len;
}
return text;
}

size_t total = (buf->lines[r1].len - c1) + 1;
for (size_t row = r1 + 1; row < r2; row++) {
total += buf->lines[row].len + 1;
size_t total = 0;
total += buf->lines[r1].len - c1 + 1;
for (size_t r = r1 + 1; r < r2; r++) {
total += buf->lines[r].len + 1;
}
total += c2;

char *text = xmalloc(total > 0 ? total : 1);
size_t pos = 0;
char *text = xmalloc(total + 1);
size_t offset = 0;

memcpy(text + pos, buf->lines[r1].chars + c1, buf->lines[r1].len - c1);
pos += buf->lines[r1].len - c1;
text[pos++] = '\n';
size_t first_len = buf->lines[r1].len - c1;
memcpy(text + offset, buf->lines[r1].chars + c1, first_len);
offset += first_len;
text[offset++] = '\n';

for (size_t row = r1 + 1; row < r2; row++) {
memcpy(text + pos, buf->lines[row].chars, buf->lines[row].len);
pos += buf->lines[row].len;
text[pos++] = '\n';
for (size_t r = r1 + 1; r < r2; r++) {
size_t len = buf->lines[r].len;
memcpy(text + offset, buf->lines[r].chars, len);
offset += len;
text[offset++] = '\n';
}

memcpy(text + pos, buf->lines[r2].chars, c2);
pos += c2;
memcpy(text + offset, buf->lines[r2].chars, c2);
offset += c2;
text[offset] = '\0';

*out_len = pos;
if (out_len != NULL) {
*out_len = offset;
}
return text;
}

void buffer_insert_text(buffer_t *buf, size_t row, size_t col, const char *text, size_t len)
{
size_t start = 0;
for (size_t i = 0; i < len; i++) {
if (text[i] != '\n') {
continue;
size_t cur_row = row;
size_t cur_col = col;
size_t seg_start = 0;

for (size_t i = 0; i <= len; i++) {
if (i == len || text[i] == '\n') {
size_t seg_len = i - seg_start;
if (seg_len > 0 && text[i - 1] == '\r') {
seg_len--;
}
if (seg_len > 0) {
buffer_insert_bytes(buf, cur_row, cur_col, text + seg_start, seg_len);
cur_col += seg_len;
}
if (i < len && text[i] == '\n') {
buffer_split_line(buf, cur_row, cur_col);
cur_row++;
cur_col = 0;
}
seg_start = i + 1;
}
buffer_insert_bytes(buf, row, col, text + start, i - start);
col += i - start;
buffer_split_line(buf, row, col);
row += 1;
col = 0;
start = i + 1;
}
if (start < len) {
buffer_insert_bytes(buf, row, col, text + start, len - start);
}
}
3 changes: 2 additions & 1 deletion src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ typedef struct {
size_t cap_lines;
char *filename;
int dirty;
size_t version;
encoding_t encoding;
int use_crlf;
int trailing_newline;
Expand All @@ -41,7 +42,7 @@ void buffer_split_line(buffer_t *buf, size_t row, size_t col);
void buffer_join_lines(buffer_t *buf, size_t row);

char *buffer_extract_text(const buffer_t *buf, size_t r1, size_t c1, size_t r2, size_t c2,
size_t *out_len);
size_t *out_len);

void buffer_insert_text(buffer_t *buf, size_t row, size_t col, const char *text, size_t len);

Expand Down
15 changes: 15 additions & 0 deletions src/editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,23 @@ void editor_free(editor_t *ed)
free(ed->redo_stack);
free(ed->clipboard);
free(ed->search_matches);
syntax_destroy(ed->syntax);
ed->syntax = NULL;
buffer_free(&ed->buf);
}

void editor_setup_syntax(editor_t *ed)
{
if (ed->syntax != NULL) {
syntax_destroy(ed->syntax);
ed->syntax = NULL;
}
ed->syntax = syntax_create(ed->filetype);
if (ed->syntax != NULL) {
syntax_update(ed->syntax, &ed->buf);
}
}

void editor_open(editor_t *ed, const char *filename)
{
if (buffer_load(&ed->buf, filename) == 0) {
Expand All @@ -237,6 +251,7 @@ void editor_open(editor_t *ed, const char *filename)
editor_set_status(ed, "New file \"%s\"", filename);
}
ed->filetype = filetype_detect(filename);
editor_setup_syntax(ed);
ed->cy = 0;
ed->cx = 0;
ed->rowoff = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "buffer.h"
#include "search.h"
#include "syntax.h"
#include "theme.h"

typedef enum {
Expand Down Expand Up @@ -63,6 +64,7 @@ typedef struct {
char status_msg[256];
const char *filetype;
const theme_t *theme;
syntax_highlighter_t *syntax;

edit_record_t *undo_stack;
size_t undo_count;
Expand All @@ -81,6 +83,7 @@ typedef struct {
void editor_init(editor_t *ed, int screen_rows, int screen_cols);
void editor_free(editor_t *ed);
void editor_open(editor_t *ed, const char *filename);
void editor_setup_syntax(editor_t *ed);
void editor_update_screen_size(editor_t *ed, int screen_rows, int screen_cols);

void editor_set_status(editor_t *ed, const char *fmt, ...);
Expand Down
1 change: 1 addition & 0 deletions src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ static void confirm_prompt(editor_t *ed)
if (ed->prompt_len > 0) {
if (buffer_save_as(&ed->buf, ed->prompt_input) == 0) {
ed->filetype = filetype_detect(ed->buf.filename);
editor_setup_syntax(ed);
editor_set_status(ed, "Saved \"%s\"", ed->buf.filename);
} else {
editor_set_status(ed, "Error: could not save \"%s\"", ed->prompt_input);
Expand Down
3 changes: 3 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ daf_lib_sources = files(
'render.c',
'input.c',
'editor.c',
'syntax.c',
)

daf_inc = include_directories('.')
Expand All @@ -18,12 +19,14 @@ daf_lib = static_library(
'daf_lib',
daf_lib_sources,
include_directories: daf_inc,
dependencies: [tree_sitter_dep, dl_dep],
)

executable(
'daf',
'main.c',
include_directories: daf_inc,
link_with: daf_lib,
dependencies: [tree_sitter_dep, dl_dep],
install: true,
)
Loading
Loading