- [ ] lib-diff slowness with large diff
- [ ] linecount :when used in 'view' mode, stack the counting pane with all the
others so it can easily catch view-changed.
-- [ ] C config module that reads an ini-style file to set attributes
+- [X] C config module that reads an ini-style file to set attributes
based on path
- [ ] review all doc:char implementations for simplification.
- [ ] make it easy for a make-search command to search backwards
Core features
-------------
+- [ ] Do I really need global-multicall- or can I just use
+ notifications.
+ It would mean more modules would need a private pane, but might
+ I want that to support module unload anyway?
- [ ] if a view creation fails - like render_master_view_attach
hitting a python error - there will be no active view so the
screen will be meaningless. I need to properly abort and
### config
-- [ ] C config module that reads an ini-style file to set attributes
+- [X] C config module that reads an ini-style file to set attributes
based on path
- [ ] configure "initial_panes"
- [ ] discard old auto-load??
fclose(f);
}
+static bool __glob_match(const char *patn safe, const char *path safe)
+{
+ while(1) {
+ switch (*patn) {
+ case '\0':
+ return *path == '\0';
+ case '?':
+ if (!*path || *path == '/')
+ return False;
+ patn += 1;
+ path += 1;
+ break;
+ case '*':
+ if (patn[1] == '*') {
+ if (__glob_match(patn+2, path))
+ return True;
+ } else {
+ if (__glob_match(patn+1, path))
+ return True;
+ if (*path == '/')
+ return False;
+ }
+ if (!*path)
+ return False;
+ path += 1;
+ break;
+ default:
+ if (*patn != *path)
+ return False;
+ patn += 1;
+ path += 1;
+ break;
+ }
+ }
+}
+
+static bool glob_match(const char *patn safe, const char *path safe)
+{
+ int ret;
+ if (patn[0] != '/' && !strstarts(patn, "**")) {
+ /* must match basename */
+ const char *sl = strrchr(path, '/');
+ if (sl)
+ path = sl + 1;
+ }
+ ret = __glob_match(patn, path);
+ return ret;
+}
+
struct config_data {
struct command c;
+ struct command appeared;
struct pane *root safe;
+ struct trigger {
+ char *path safe;
+ struct attrset *attrs;
+ struct trigger *next;
+ } *triggers;
};
+static void add_trigger(struct config_data *cd safe, char *path safe,
+ char *name safe, char *val safe, int append)
+{
+ struct trigger *t = cd->triggers;
+
+ if (strstarts(name, "TESTING ")) {
+ if (getenv("EDLIB_TESTING") == NULL)
+ return;
+ name += 8;
+ }
+ if (strstarts(name, "NOTESTING ")) {
+ if (getenv("EDLIB_TESTING") != NULL)
+ return;
+ name += 10;
+ }
+ if (!t || strcmp(t->path, path) != 0) {
+ alloc(t, pane);
+ t->next = cd->triggers;
+ cd->triggers = t;
+ t->path = strdup(path);
+ }
+ if (append) {
+ const char *old = attr_find(t->attrs, name);
+ if (old) {
+ val = strconcat(NULL, old, val);
+ attr_set_str(&t->attrs, name, val);
+ free(val);
+ } else
+ attr_set_str(&t->attrs, name, val);
+ } else
+ attr_set_str(&t->attrs, name, val);
+}
+
+static void config_file(char *path safe, struct pane *doc safe,
+ struct config_data *cd safe)
+{
+ struct trigger *t;
+
+ for (t = cd->triggers; t; t = t->next)
+ if (glob_match(t->path, path)) {
+ const char *val;
+ const char *k = "";
+ while ((k = attr_get_next_key(t->attrs, k, -1, &val)) != NULL) {
+ if (strstarts(k, "APPEND "))
+ call("doc:append:", doc, 0, NULL, val,
+ 0, NULL, k + 7);
+ else
+ call("doc:set:", doc, 0, NULL, val,
+ 0, NULL, k);
+ }
+ }
+}
+
struct mod_cmd {
char *module;
int tried;
}
if (strstarts(section, "file:")) {
- char *k = strconcat(NULL, "global-file-attr:", section+5);
- call(k, cd->root, append, NULL, name, 0, NULL, value);
+ add_trigger(cd, section+5, name, value, append);
return;
}
}
free(cd);
}
+DEF_CMD(config_appeared)
+{
+ struct config_data *cd = container_of(ci->comm, struct config_data, appeared);
+ char *path = pane_attr_get(ci->focus, "filename");
+ if (!path)
+ return Efallthrough;
+ config_file(path, ci->focus, cd);
+ return Efallthrough;
+}
+
DEF_CMD(config_load)
{
struct config_data *cd;
alloc(cd, pane);
cd->c = config_load;
cd->c.free = config_free;
+ cd->appeared = config_appeared;
cd->root = ci->home;
call_comm("global-set-command", ci->home, &cd->c, 0, NULL, "config-load");
+ call_comm("global-set-command", ci->home, &cd->appeared,
+ 0, NULL, "doc:appeared-config");
} else {
cd = container_of(ci->comm, struct config_data, c);
}
+++ /dev/null
-# -*- coding: utf-8 -*-
-# Copyright Neil Brown ©2020-2023 <neil@brown.name>
-# May be distributed under terms of GPLv2 - see file:COPYING
-
-# This is a "config" script. It just for experimenting
-# with simple configuration. I plan to write a proper
-# config module with a more abstract language one day.
-# But I want some simple configuration NOW
-
-from edlib import editor
-import os
-
-def config_appeared(key, focus, **a):
-
- p = focus['filename']
-
- if p and ("COMMIT_EDITMSG" in p or "/.stgit" in p):
- focus.call("doc:append:view-default", ",textfill,whitespace,autospell")
- focus.call("doc:set:fill-width", "72")
- if "/git/lustre-release/" in p:
- # looks like a lustre commit, need to limit line width
- focus.call("doc:set:fill-width", "70")
- focus.call("doc:set:whitespace-width", "60")
-
- if p and p[-3:] == ".md":
- # Until I have a real markdown module, I need this at least.
- if os.getenv("EDLIB_TESTING"):
- focus.call("doc:append:view-default", ",textfill,whitespace")
- else:
- focus.call("doc:append:view-default", ",textfill,whitespace,autospell")
- focus["fill-width"] = "72"
- focus["word-wrap"] = "1"
- focus["fill:start-re"] = ("^("
- "[^a-zA-Z0-9\\n]*$|" # empty/puctuation line
- " *-|" # list item
- " *- *\\[[ X]]|" # todo list item
- " *#+|" # section head
- " *[0-9]*\\.)") # Numbered list
-
-editor.call("global-set-command", "doc:appeared-config", config_appeared)