summaryrefslogtreecommitdiff
path: root/src/dged
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-05-01 23:35:16 +0200
committerAlbert Cervin <albert@acervin.com>2023-05-01 23:35:16 +0200
commit8d73eace6806bd67852189b1a16de5895c565688 (patch)
treed3071f31f535189adeb768cf742ec68f017ae9d9 /src/dged
parenta123725a12e948d78badb2cb686d38548f1c633b (diff)
downloaddged-8d73eace6806bd67852189b1a16de5895c565688.tar.gz
dged-8d73eace6806bd67852189b1a16de5895c565688.tar.xz
dged-8d73eace6806bd67852189b1a16de5895c565688.zip
Implement buffer reload
Currently only implemented on the buffer itself, and will discard any pending changes to the buffer. Idea is to use a command to detect that state and warn the user.
Diffstat (limited to 'src/dged')
-rw-r--r--src/dged/buffer.c70
-rw-r--r--src/dged/buffer.h4
2 files changed, 57 insertions, 17 deletions
diff --git a/src/dged/buffer.c b/src/dged/buffer.c
index 25a8a4a..958d1bb 100644
--- a/src/dged/buffer.c
+++ b/src/dged/buffer.c
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include <wchar.h>
@@ -126,6 +127,7 @@ struct buffer buffer_create(char *name) {
.modified = false,
.readonly = false,
.lang = lang_from_id("fnd"),
+ .last_write = {0},
};
undo_init(&b.undo, 100);
@@ -467,15 +469,14 @@ void buffer_end_of_line(struct buffer_view *view) {
void buffer_beginning_of_line(struct buffer_view *view) { view->dot.col = 0; }
-struct buffer buffer_from_file(char *filename) {
- struct buffer b = buffer_create(basename((char *)filename));
- b.filename = strdup(filename);
- if (access(b.filename, F_OK) == 0) {
- FILE *file = fopen(filename, "r");
+void buffer_read_from_file(struct buffer *b) {
+ struct stat sb;
+ if (stat(b->filename, &sb) == 0) {
+ FILE *file = fopen(b->filename, "r");
if (file == NULL) {
- minibuffer_echo("Error opening %s: %s", filename, strerror(errno));
- return b;
+ minibuffer_echo("Error opening %s: %s", b->filename, strerror(errno));
+ return;
}
while (true) {
@@ -483,24 +484,35 @@ struct buffer buffer_from_file(char *filename) {
int bytes = fread(buff, 1, 4096, file);
if (bytes > 0) {
uint32_t ignore;
- text_append(b.text, buff, bytes, &ignore, &ignore);
+ text_append(b->text, buff, bytes, &ignore, &ignore);
} else if (bytes == 0) {
break; // EOF
} else {
- minibuffer_echo("error reading from %s: %s", filename, strerror(errno));
+ minibuffer_echo("error reading from %s: %s", b->filename,
+ strerror(errno));
fclose(file);
- return b;
+ return;
}
}
fclose(file);
+ b->last_write = sb.st_mtim;
+ } else {
+ minibuffer_echo("Error opening %s: %s", b->filename, strerror(errno));
+ return;
}
- const char *ext = strrchr(b.filename, '.');
+ const char *ext = strrchr(b->filename, '.');
if (ext != NULL) {
- b.lang = lang_from_extension(ext + 1);
+ b->lang = lang_from_extension(ext + 1);
}
- undo_push_boundary(&b.undo, (struct undo_boundary){.save_point = true});
+ undo_push_boundary(&b->undo, (struct undo_boundary){.save_point = true});
+}
+
+struct buffer buffer_from_file(char *filename) {
+ struct buffer b = buffer_create(basename((char *)filename));
+ b.filename = strdup(filename);
+ buffer_read_from_file(&b);
return b;
}
@@ -540,6 +552,7 @@ void buffer_to_file(struct buffer *buffer) {
buffer->filename);
fclose(file);
+ clock_gettime(CLOCK_REALTIME, &buffer->last_write);
buffer->modified = false;
undo_push_boundary(&buffer->undo, (struct undo_boundary){.save_point = true});
}
@@ -549,6 +562,26 @@ void buffer_write_to(struct buffer *buffer, const char *filename) {
buffer_to_file(buffer);
}
+void buffer_reload(struct buffer *buffer) {
+ if (buffer->filename == NULL) {
+ return;
+ }
+
+ // check if we actually need to reload
+ struct stat sb;
+ if (stat(buffer->filename, &sb) < 0) {
+ minibuffer_echo_timeout(4, "failed to run stat on %s", buffer->filename);
+ return;
+ }
+
+ if (sb.st_mtim.tv_sec != buffer->last_write.tv_sec) {
+ text_clear(buffer->text);
+ buffer_read_from_file(buffer);
+ } else {
+ minibuffer_echo_timeout(2, "buffer %s not changed", buffer->filename);
+ }
+}
+
struct search_data {
VEC(struct match) matches;
const char *pattern;
@@ -774,15 +807,18 @@ void render_line(struct text_chunk *line, void *userdata) {
bytei < text_nbytes_scroll && linewidth < cmdbuf->width; ++bytei) {
uint8_t *txt = &text[bytei];
if (*txt == '\t') {
- linewidth += 3;
+ linewidth += 4;
} else if (utf8_byte_is_unicode_start(*txt)) {
wchar_t wc;
- if (mbrtowc(&wc, (char *)txt, 6, NULL) >= 0) {
- linewidth += wcwidth(wc) - 1;
+ size_t nbytes;
+ if ((nbytes = mbrtowc(&wc, (char *)txt, 6, NULL)) > 0) {
+ text_nbytes += nbytes - 1;
+ linewidth += wcwidth(wc);
}
+ } else if (utf8_byte_is_ascii(*txt)) {
+ ++linewidth;
}
- ++linewidth;
++text_nbytes;
}
diff --git a/src/dged/buffer.h b/src/dged/buffer.h
index 539c427..b9edf4a 100644
--- a/src/dged/buffer.h
+++ b/src/dged/buffer.h
@@ -1,6 +1,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
+#include <time.h>
#include "bits/stdint-uintn.h"
#include "command.h"
@@ -138,6 +139,8 @@ struct buffer {
/** Associated filename, this is where the buffer will be saved to */
char *filename;
+ struct timespec last_write;
+
/** Text data structure */
struct text *text;
@@ -213,6 +216,7 @@ uint32_t buffer_add_create_hook(create_hook_cb hook, void *userdata);
struct buffer buffer_from_file(char *filename);
void buffer_to_file(struct buffer *buffer);
void buffer_write_to(struct buffer *buffer, const char *filename);
+void buffer_reload(struct buffer *buffer);
void buffer_update(struct buffer_view *view, uint32_t width, uint32_t height,
struct command_list *commands, uint64_t frame_time,