From d256ceb2b7261ec2ae8f0d7d3d24bd6d6e0152ea Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 2 Dec 2015 14:19:07 +1100 Subject: [PATCH] Add lib-messageline. This places a line on the bottom on the display and displayed messages there. Signed-off-by: NeilBrown --- Makefile | 2 +- core-keymap.c | 6 +++- doc-text.c | 21 +++++++++-- edlib.c | 3 +- lib-messageline.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 lib-messageline.c diff --git a/Makefile b/Makefile index 73fb8e0e..75afe8b5 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ SHOBJ = O/doc-text.o O/doc-dir.o \ O/render-hex.o O/render-lines.o \ O/render-format.o O/render-complete.o \ O/lib-view.o O/lib-tile.o O/lib-popup.o O/lib-line-count.o O/lib-keymap.o \ - O/lib-search.o \ + O/lib-search.o O/lib-messageline.o \ O/lang-python.o \ O/mode-emacs.o \ O/display-ncurses.o diff --git a/core-keymap.c b/core-keymap.c index 060325ef..64f77a42 100644 --- a/core-keymap.c +++ b/core-keymap.c @@ -343,9 +343,13 @@ int key_handle_focus(struct cmd_info *ci) { return __key_handle_focus(ci, 0); } + int key_handle_focus_point(struct cmd_info *ci) { - return __key_handle_focus(ci, 1); + int ret = __key_handle_focus(ci, 1); + if (ret < 0) + call5("Message", ci->focus, 0, NULL, "** Command Failed **", 1); + return ret; } static int __key_handle_xy(struct cmd_info *ci, int savepoint) diff --git a/doc-text.c b/doc-text.c index 930b22d4..2bd45e4b 100644 --- a/doc-text.c +++ b/doc-text.c @@ -52,6 +52,7 @@ */ +#define _GNU_SOURCE /* for asprintf */ #include #include #include @@ -298,10 +299,24 @@ DEF_CMD(text_save_file) { struct doc_data *dd = ci->home->data; struct text *t = container_of(dd->doc, struct text, doc); + int ret; + char *msg; - if (!t->fname) - return -1; - return do_text_write_file(t, t->fname); + if (!t->fname) { + asprintf(&msg, "** No file name known for %s ***", dd->doc->name); + ret = -1; + } else { + ret = do_text_write_file(t, t->fname); + if (ret == 0) + asprintf(&msg, "Successfully wrote %s", t->fname); + else + asprintf(&msg, "*** Faild to write %s ***", t->fname); + } + call5("Message", ci->home, 0, NULL, msg, 0); + free(msg); + if (ret == 0) + return 1; + return -1; } DEF_CMD(text_same_file) diff --git a/edlib.c b/edlib.c index 6a872d03..e94621f3 100644 --- a/edlib.c +++ b/edlib.c @@ -67,7 +67,8 @@ int main(int argc, char *argv[]) if (!key_lookup(ed->commands, &ci)) exit(1); root = ci.focus; - global = pane_attach(root, "global-keymap", NULL, NULL); + global = pane_attach(root, "messageline", NULL, NULL); + global = pane_attach(global, "global-keymap", NULL, NULL); editor_load_module(ed, "mode-emacs"); call5("global-set-keymap", global, 0, NULL, "mode-emacs", 0); diff --git a/lib-messageline.c b/lib-messageline.c new file mode 100644 index 00000000..4adf46c3 --- /dev/null +++ b/lib-messageline.c @@ -0,0 +1,91 @@ +/* + * Copyright Neil Brown 2015 + * May be distributed under terms of GPLv2 - see file:COPYING + * + * trim a line off the bottom of a pane and capture messages + * to go there. They disappear on the next keystroke. + * + * Later it might be good to allow boarderless popups to appear here. + */ + +#include +#include +#include + +#include "core.h" + +struct mlinfo { + char *message; + struct pane *line; +}; + +static void pane_str(struct pane *p, char *s, char *attr, int x, int y) +{ + mbstate_t ps = {0}; + int err; + wchar_t ch; + + while ((err = mbrtowc(&ch, s, 5, &ps)) > 0) { + pane_text(p, ch, attr, x, y); + s += err; + x += 1; + } +} + +DEF_CMD(messageline_handle) +{ + struct mlinfo *mli = ci->home->data; + + if (strcmp(ci->key, "Message") == 0) { + if (ci->extra == 0 || mli->message == NULL) { + free(mli->message); + mli->message = strdup(ci->str); + pane_damaged(mli->line, DAMAGED_CONTENT); + } + return 0; /* allow other handlers */ + } + if (strcmp(ci->key, "Abort") == 0) { + free(mli->message); + mli->message = strdup("ABORTED"); + pane_damaged(mli->line, DAMAGED_CONTENT); + return 0; + } + if (strcmp(ci->key, "Refresh") == 0) { + if (ci->home == mli->line) { + pane_resize(ci->home, 0, ci->home->parent->h - 1, + ci->home->parent->w, 1); + pane_clear(mli->line, ""); + if (mli->message) + pane_str(mli->line, mli->message, "bold", 0, 0); + } else { + pane_resize(ci->home, 0, 0, ci->home->parent->w, + ci->home->parent->h - 1); + } + return 1; + } + /* Anything else clears the message */ + if (strncmp(ci->key, "pane", 4) != 0 && mli->message) { + free(mli->message); + mli->message = NULL; + pane_clear(mli->line, ""); + } + return 0; +} + +DEF_CMD(messageline_attach) +{ + struct mlinfo *mli = malloc(sizeof(*mli)); + struct pane *p = ci->focus; + + mli->message = NULL; + ci->focus = pane_register(p, 0, &messageline_handle, mli, NULL); + mli->line = pane_register(p, 1, &messageline_handle, mli, NULL); + pane_focus(ci->focus); + return 1; +} + + +void edlib_init(struct editor *ed) +{ + key_add(ed->commands, "attach-messageline", &messageline_attach); +} -- 2.39.5