tFix crash on closing view - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow) | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit b4b11228f9a7851bd47ceb8e9e31d8a3a857af79 | |
parent d3e5c88151dca9a99f6c62bd0526391eecfc15cd | |
Author: lumidify <[email protected]> | |
Date: Sun, 26 Dec 2021 19:10:08 +0100 | |
Fix crash on closing view | |
Diffstat: | |
M buffer.c | 2 +- | |
M keys_command.c | 12 ++++++++---- | |
M ledit.1 | 4 ++++ | |
M ledit.c | 23 +++++++++++++++++++++++ | |
M view.c | 1 + | |
M view.h | 1 + | |
6 files changed, 38 insertions(+), 5 deletions(-) | |
--- | |
diff --git a/buffer.c b/buffer.c | |
t@@ -311,7 +311,7 @@ buffer_remove_view(ledit_buffer *buffer, ledit_view *view)… | |
buffer->views + i + 1, | |
(buffer->views_num - i - 1) * sizeof(ledit_view *) | |
); | |
- ledit_reallocarray(buffer->views, --buffer->views_num, sizeof(… | |
+ buffer->views = ledit_reallocarray(buffer->views, --buffer->vi… | |
} | |
} | |
diff --git a/keys_command.c b/keys_command.c | |
t@@ -199,11 +199,15 @@ close_view(ledit_view *view, char *cmd, size_t l1, size_… | |
(void)l2; | |
/* FIXME: This will lead to problems if I add something that | |
requires access to the view after the command is handled. */ | |
+ cmd++; | |
+ int force = 0; | |
+ if (*cmd == '!') | |
+ force = 1; | |
ledit_buffer *buffer = view->buffer; | |
- buffer_remove_view(buffer, view); | |
- if (buffer->views_num == 0) { | |
- ledit_cleanup(); | |
- exit(0); | |
+ if (buffer->views_num == 1 && buffer->modified && !force) { | |
+ window_show_message(view->window, "File modified; write or use… | |
+ } else { | |
+ view->destroy = 1; | |
} | |
return 0; | |
} | |
diff --git a/ledit.1 b/ledit.1 | |
t@@ -801,6 +801,10 @@ Confirm each substitution before performing it. | |
Open a new view. | |
Each view is a window that shows the text in the current buffer, | |
which is synced between the views. | |
+.It Cm :c | |
+Close a view. | |
+.It Cm :c\&! | |
+Close a view, even if it is the last one and there are unsaved changes. | |
.El | |
.Sh MOUSE ACTIONS | |
There currently are not many mouse actions. | |
diff --git a/ledit.c b/ledit.c | |
t@@ -84,6 +84,29 @@ mainloop(void) { | |
clock_gettime(CLOCK_MONOTONIC, &last); | |
sleep_time.tv_sec = 0; | |
while (running) { | |
+ /* This "lazy destroying" is not entirely ideal yet, but it's | |
+ necessary to avoid a crash when closing a view (I'm not | |
+ entirely sure what exactly causes the crash) | |
+ -> Update: The cause of the crash was something different, | |
+ but I'm still leaving it as is for now because there | |
+ may be other reasons for doing it lazily. */ | |
+ for (size_t i = 0; i < buffer->views_num; i++) { | |
+ if (buffer->views[i]->destroy) { | |
+ buffer_remove_view(buffer, buffer->views[i]); | |
+ if (buffer->views_num == 0) { | |
+ ledit_cleanup(); | |
+ exit(0); | |
+ } | |
+ /* only delete one - otherwise, | |
+ the loop would need to be | |
+ modified | |
+ I guess it's unrealistic to | |
+ assume that the deletion cmd | |
+ will be called multiple times | |
+ in such a short time anyways */ | |
+ break; | |
+ } | |
+ } | |
while (XPending(common.dpy)) { | |
XNextEvent(common.dpy, &event); | |
if (event.type == xkb_event_type) { | |
diff --git a/view.c b/view.c | |
t@@ -131,6 +131,7 @@ view_create(ledit_buffer *buffer, ledit_theme *theme, ledi… | |
view->display_offset = 0; | |
view->sel.line1 = view->sel.byte1 = 0; | |
view->sel.line2 = view->sel.byte2 = 0; | |
+ view->destroy = 0; | |
view->button2_pressed = 0; | |
view->selecting = 0; | |
view->sel_valid = 0; | |
diff --git a/view.h b/view.h | |
t@@ -77,6 +77,7 @@ struct ledit_view { | |
long display_offset; /* current pixel offset of viewport */ | |
ledit_range sel; /* current selection */ | |
ledit_mode mode; /* current mode of this view */ | |
+ char destroy; /* whether the view should be destroyed at t… | |
char selecting; /* whether user is currently selecting text … | |
char button2_pressed; /* whether button 2 (middle button) is press… | |
char sel_valid; /* whether there is currently a valid select… |