From: NeilBrown Date: Fri, 25 Aug 2023 01:10:37 +0000 (+1000) Subject: Allow command name to be used to choose some data files. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=3a5d6e76aa8bd4810b3ae311e589f80d5ce3c9da;p=edlib.git Allow command name to be used to choose some data files. The icon file, Welcome text, and initial config file are now chosen based on the base name of the command being run. So if "edlib" is copied to "elma", then "elma.ini" is used for config, and "elma-icon.png" for an icon. If the expected file isn't found, a file named for "edlib" is tried instead. This should make it easy to have have various commands providing different interfaces. elma - EMACS mode elvi - VI mode elnm - notmuch email reader elpnt - presentation mode eled - editor with A binding. maybe. Signed-off-by: NeilBrown --- diff --git a/DOC/TODO.md b/DOC/TODO.md index a7f360ec..77edd718 100644 --- a/DOC/TODO.md +++ b/DOC/TODO.md @@ -98,7 +98,7 @@ Requirements for a v1.0 release - [ ] vi mode - [ ] CUA mode - [ ] nano mode(?) -- [ ] multiple front ends: elvi, elma, elnm, eled? +- [ ] multiple front ends: elvi, elma, elnm, eled, elpnt? - [ ] introspection - [ ] markdown editor (with PDF output) - [ ] non-line-based render, such as a tabular render for spreadsheet, diff --git a/Makefile b/Makefile index 0f1205b2..537b013b 100644 --- a/Makefile +++ b/Makefile @@ -94,9 +94,10 @@ SHOBJ = O/doc-text.o O/doc-dir.o O/doc-docs.o \ XOBJ = O/rexel.o WOBJ = O/libwiggle.a -BIN = edlib elc el-askpass +BIN = edlib elma elc el-askpass bin/edlib : edlib +bin/elma : edlib bin/elc : python/lib-server.py bin/el-askpass : python/lib-server.py diff --git a/core-editor.c b/core-editor.c index da680677..988208ce 100644 --- a/core-editor.c +++ b/core-editor.c @@ -630,7 +630,9 @@ static char *set_bin_path(struct pane *p safe) DEF_CMD(global_find_file) { /* - * ->str is a file basename. + * ->str is a file basename. If it contains {COMM}, that will + * be replaced with the "command-name" attr from root, or + * "edlib" if nothing can be found. * ->str2 is one of "data", "config", "bin" * We find a file with basename in a known location following * the XDG Base Directory Specificaton. @@ -649,8 +651,11 @@ DEF_CMD(global_find_file) * For bin we look in $HERE/../bin and $PATH */ char *path = NULL; + const char *base[2] = {ci->str, NULL}; + int i; + char *cn; - if (ci->str == NULL || ci->str2 == NULL) + if (base[0] == NULL || ci->str2 == NULL) return -Enoarg; if (strcmp(ci->str2, "data") == 0) path = set_data_path(ci->home); @@ -661,25 +666,38 @@ DEF_CMD(global_find_file) if (!path) return Einval; - for (; path && *path; path += strlen(path)+1) { - char *p = strconcat(NULL, path, ci->str); - int fd; - if (!p) - continue; - fd = open(p, O_RDONLY); - if (fd < 0) { + cn = strstr(base[0], "{COMM}"); + if (cn) { + char *p = strndup(base[0], cn - base[0]); + char *comm = attr_find(ci->home->attrs, "command-name"); + if (!comm) + comm = "edlib"; + base[0] = strconcat(ci->home, p, comm, cn+6); + if (strcmp(comm, "edlib") != 0) + base[1] = strconcat(ci->home, p, "edlib", cn+6); + } + for (i = 0; i < 2 && base[i] ; i++) { + char *pth; + for (pth = path; pth && *pth; pth += strlen(pth)+1) { + char *p = strconcat(NULL, pth, base[i]); + int fd; + if (!p) + continue; + fd = open(p, O_RDONLY); + if (fd < 0) { + free(p); + continue; + } + close(fd); + comm_call(ci->comm2, "cb", ci->focus, 0, NULL, p); free(p); - continue; + return 1; } - close(fd); - comm_call(ci->comm2, "cb", ci->focus, 0, NULL, p); - free(p); - return 1; } return Efalse; } -struct pane *editor_new(void) +struct pane *editor_new(const char *comm_name) { struct pane *ed; struct ed_info *ei; @@ -708,6 +726,7 @@ struct pane *editor_new(void) return NULL; ei = &ed->data; ei->magic = ED_MAGIC; + attr_set_str(&ed->attrs, "command-name", comm_name ?: "edlib"); ei->testing = (getenv("EDLIB_TESTING") != NULL); ei->map = key_alloc(); key_add_chain(ei->map, ed_map); diff --git a/core.h b/core.h index b6cae64b..68bc7888 100644 --- a/core.h +++ b/core.h @@ -111,7 +111,7 @@ int do_pane_notify(struct pane *home, const char *notification safe, struct command *comm2); void pane_drop_notifiers(struct pane *p safe, char *notification); -struct pane *editor_new(void); +struct pane *editor_new(const char *comm_name); void * safe memsave(struct pane *p safe, const char *buf, int len); char *strsave(struct pane *p safe, const char *buf); char *strnsave(struct pane *p safe, const char *buf, int len); diff --git a/display-x11-xcb.c b/display-x11-xcb.c index f27c8700..b5bd7aa8 100644 --- a/display-x11-xcb.c +++ b/display-x11-xcb.c @@ -1953,7 +1953,7 @@ static struct pane *xcb_display_init(const char *d safe, XCB_MOD_MASK_LOCK | XCB_MOD_MASK_CONTROL); - xcb_load_icon(focus, xd, "edlib-icon.png"); + xcb_load_icon(focus, xd, "{COMM}-icon.png"); xcb_map_window(conn, xd->win); xcb_flush(conn); pane_resize(p, 0, 0, xd->charwidth*80, xd->lineheight*26); diff --git a/edlib.c b/edlib.c index 9955a8e8..c4e8d47c 100644 --- a/edlib.c +++ b/edlib.c @@ -21,11 +21,21 @@ static const char shortopt[] = "gtx"; int main(int argc, char *argv[]) { - struct pane *ed = editor_new(); + struct pane *ed; struct pane *first_window = NULL; struct pane *p, *doc = NULL; bool gtk = False, term = False, x11 = False; int opt; + char *base = NULL; + + if (argv[0]) { + base = strrchr(argv[0], '/'); + if (base) + base += 1; + else + base = argv[0]; + } + ed = editor_new(base); if (!ed) exit(1); @@ -50,7 +60,7 @@ int main(int argc, char *argv[]) setlocale(LC_CTYPE, "enUS.UTF-8"); call("global-load-module", ed, 0, NULL, "lib-config"); - call("config-load", ed, 0, NULL, "edlib.ini"); + call("config-load", ed, 0, NULL, "{COMM}.ini"); call("attach-doc-docs", ed); @@ -68,7 +78,7 @@ int main(int argc, char *argv[]) if (!doc) { char *welcome_file = call_ret(str, "xdg-find-edlib-file", ed, - 0, NULL, "Welcome-edlib.txt", + 0, NULL, "Welcome-{COMM}.txt", 0, NULL, "data"); char *WelcomeText = NULL; if (welcome_file) {