This allows use to remove the strcmp on "Close".
It requires python commands to be able to be marks closed_ok.
This is done with name "handle_close" or any name ending "_closed_ok".
Signed-off-by: NeilBrown <neil@brown.name>
return 1 + ret;
}
-DEF_CMD(doc_close_doc)
+DEF_CMD_CLOSED(doc_close_doc)
{
struct doc *d = ci->home->_data;
doc_free(d, ci->home);
return 1;
}
-DEF_CMD(doc_close)
+DEF_CMD_CLOSED(doc_close)
{
struct doc_data *dd = ci->home->data;
int i;
return Efallthrough;
}
-DEF_CMD(editor_close)
+DEF_CMD_CLOSED(editor_close)
{
struct ed_info *ei = ci->home->data;
stat_free();
if (!comm)
return;
+ if (strcmp(k, "Close") == 0 &&
+ !comm->closed_ok) {
+ LOG("WARNING: Command %s registered for \"Close\" but not marked closed_ok",
+ comm->name);
+ }
pos = key_find(map, k);
/* cases:
return 1;
}
-DEF_CMD(log_close)
+DEF_CMD_CLOSED(log_close)
{
struct log *l = ci->home->doc_data;
if (home)
ci.home = home;
if ((home->damaged & DAMAGED_CLOSED) &&
- !home->handle->closed_ok &&
- ci.key[0] != 'C' && /* Compile will often optimise
- * the strncmp away
- */
- strcmp(ci.key, "Close") != 0)
+ !home->handle->closed_ok)
/* This pane cannot accept anything but
- * "Close"
+ * close_ok commands.
*/
return Efallthrough;
ci.comm = home->handle;
return 1;
}
-DEF_CMD(nc_close)
+DEF_CMD_CLOSED(nc_close)
{
struct pane *p = ci->home;
struct display_data *dd = p->data;
return 1;
}
-DEF_CMD(xcb_close_display)
+DEF_CMD_CLOSED(xcb_close_display)
{
/* If this is only display, then refuse to close this one */
struct call_return cr;
static void kbd_free(struct xcb_data *xd safe);
-DEF_CMD(xcb_close)
+DEF_CMD_CLOSED(xcb_close)
{
struct xcb_data *xd = ci->home->data;
return Efalse;
}
-DEF_CMD(dir_destroy)
+DEF_CMD_CLOSED(dir_destroy)
{
struct directory *dr = ci->home->doc_data;
return Efalse;
}
-DEF_CMD(docs_close)
+DEF_CMD_CLOSED(docs_close)
{
struct docs *docs = ci->home->doc_data;
return Efail;
}
-DEF_CMD(email_view_close)
+DEF_CMD_CLOSED(email_view_close)
{
struct email_view *evi = ci->home->data;
return comm_call(ci->comm2, "callback:doc", p);
}
-DEF_CMD(list_close)
+DEF_CMD_CLOSED(list_close)
{
struct list *l = ci->home->doc_data;
struct elmnt *e;
}
}
-DEF_CMD(mp_close)
+DEF_CMD_CLOSED(mp_close)
{
struct mp_info *mpi = ci->home->doc_data;
int i;
}
}
-DEF_CMD(text_destroy)
+DEF_CMD_CLOSED(text_destroy)
{
struct text *t = ci->home->doc_data;
}
-DEF_CMD(search_close)
+DEF_CMD_CLOSED(search_close)
{
struct es_info *esi = ci->home->data;
return Efallthrough;
}
-DEF_CMD(emacs_highlight_close)
+DEF_CMD_CLOSED(emacs_highlight_close)
{
/* ci->focus is being closed */
struct highlight_info *hi = ci->home->data2;
DEF_CMD(python_doc_call);
static void python_free_command(struct command *c safe);
-static struct python_command *export_callable(PyObject *callable safe)
+static struct python_command *export_callable(PyObject *callable safe,
+ PyObject *nm)
{
struct python_command *c;
+ const char *name = NULL;
+ int len;
+
+ if (nm && PyUnicode_Check(nm))
+ name = PyUnicode_AsUTF8(nm);
+ if (!name)
+ name = "";
+ len = strlen(name);
list_for_each_entry(c, &exported_commands, lst)
if (c->callable == callable) {
c->c = python_call;
c->c.free = python_free_command;
c->c.refcnt = 0;
- c->c.closed_ok = 0;
+ if (strcmp(name, "handle_close") == 0 ||
+ (len > 10 &&
+ strcmp(name+len-10, "_closed_ok") == 0))
+ c->c.closed_ok = 1;
+ else
+ c->c.closed_ok = 0;
command_get(&c->c);
Py_INCREF(callable);
c->callable = callable;
if (doc && doc != Py_None) {
PyObject *tofree = NULL;
char *docs = python_as_string(doc, &tofree);
+
if (docs &&
strstarts(docs, "handle-range") &&
docs[12]) {
char *b = strndup(s1+1, s2-(s1+1));
struct python_command *comm =
- export_callable(m);
+ export_callable(m, e);
key_add_range(self->map, a, b,
&comm->c);
free(a); free(b);
char *b = strconcat(self->pane,
a, "\xFF\xFF\xFF\xFF");
struct python_command *comm =
- export_callable(m);
+ export_callable(m, e);
key_add_range(self->map, a, b,
&comm->c);
command_put(&comm->c);
if (m && PyMethod_Check(m)) {
PyObject *doc = PyObject_GetAttrString(m, "__doc__");
- if (doc && doc != Py_None) {
- PyObject *tofree = NULL;
- char *docs = python_as_string(doc, &tofree);
- if (docs &&
- strstarts(docs, "handle:")) {
+ char *docs;
+ PyObject *tofree = NULL;
+ if (doc && doc != Py_None &&
+ (docs = python_as_string(doc, &tofree)) != NULL) {
+
+ if (strstarts(docs, "handle:")) {
struct python_command *comm =
- export_callable(m);
+ export_callable(m, e);
key_add(self->map, docs+7, &comm->c);
command_put(&comm->c);
}
- if (docs &&
- strstarts(docs, "handle-list") &&
+ if (strstarts(docs, "handle-list") &&
docs[11]) {
char sep = docs[11];
char *s1 = docs + 12;
while (s1 && *s1 && *s1 != sep) {
struct python_command *comm =
- export_callable(m);
+ export_callable(m, e);
char *a;
char *s2 = strchr(s1, sep);
if (s2) {
command_put(&comm->c);
}
}
- Py_XDECREF(tofree);
}
+ Py_XDECREF(tofree);
Py_XDECREF(doc);
}
Py_XDECREF(m);
return False;
}
} else if (PyCallable_Check(a)) {
- struct python_command *pc = export_callable(a);
+ struct python_command *pc = export_callable(a, NULL);
if (ci->comm2 == NULL)
ci->comm2 = &pc->c;
return False;
}
} else if (PyCallable_Check(a)) {
- struct python_command *pc = export_callable(a);
+ struct python_command *pc = export_callable(a, NULL);
ci->comm2 = &pc->c;
} else {
return Efail;
}
-DEF_CMD(askpass_close)
+DEF_CMD_CLOSED(askpass_close)
{
struct apinfo *ai = ci->home->data;
return 1;
}
-DEF_CMD(aspell_close)
+DEF_CMD_CLOSED(aspell_close)
{
struct aspell_data *as = ci->home->data;
free(t);
}
-DEF_CMD(copy_close)
+DEF_CMD_CLOSED(copy_close)
{
struct copy_info *cyi = ci->home->data;
return True;
}
-DEF_CMD(crop_close)
+DEF_CMD_CLOSED(crop_close)
{
struct crop_data *cd = ci->home->data;
}
}
-DEF_CMD(history_close)
+DEF_CMD_CLOSED(history_close)
{
struct history_info *hi = ci->home->data;
return 1;
}
-DEF_CMD(input_close)
+DEF_CMD_CLOSED(input_close)
{
struct input_mode *im = ci->home->data;
int i;
static struct pane *safe do_keymap_attach(struct pane *p safe);
-DEF_CMD(keymap_handle)
+DEF_CMD_CLOSED(keymap_handle)
{
struct key_data *kd = ci->home->data;
command_put(kd->globalcmd);
return 1;
}
+ if (ci->home->damaged & DAMAGED_CLOSED)
+ return Efallthrough;
+
if (strcmp(ci->key, "Clone") == 0) {
struct pane *p = do_keymap_attach(ci->focus);
struct key_data *kd_old = ci->home->data;
pane_resize(p, x, y, w, h);
}
-DEF_CMD(popup_close)
+DEF_CMD_CLOSED(popup_close)
{
struct popup_info *ppi = ci->home->data;
return 1;
}
-DEF_CMD(renderline_close)
+DEF_CMD_CLOSED(renderline_close)
{
struct rline_data *rd = ci->home->data;
struct render_item *ri = rd->content;
return t->z == 0 && t->handle == &tile_handle.c;
}
-DEF_CMD(tile_close)
+DEF_CMD_CLOSED(tile_close)
{
struct tileinfo *ti = ci->home->data;
return 1;
}
-DEF_CMD(view_close)
+DEF_CMD_CLOSED(view_close)
{
struct view_data *vd = ci->home->data;
return Efallthrough;
}
-DEF_CMD(ws_close)
+DEF_CMD_CLOSED(ws_close)
{
struct ws_info *ws = ci->home->data;
return 1;
}
-DEF_CMD(wiggle_close)
+DEF_CMD_CLOSED(wiggle_close)
{
struct wiggle_data *wd = ci->home->data;
int i;
return Efallthrough;
}
-DEF_CMD(xs_close)
+DEF_CMD_CLOSED(xs_close)
{
struct xs_info *xsi = ci->home->data;
return 1;
}
-DEF_CMD(xcbc_close)
+DEF_CMD_CLOSED(xcbc_close)
{
struct xcbc_info *xci = ci->home->data2;
char *cn = strconcat(ci->home, "xcb-selection-", xci->display);
return ret;
}
-DEF_CMD(complete_close)
+DEF_CMD_CLOSED(complete_close)
{
struct complete_data *cd = ci->home->data;
struct stk *stk = cd->stk;
return 1;
}
-DEF_CMD(format_close)
+DEF_CMD_CLOSED(format_close)
{
struct rf_data *rf = ci->home->data;
DEF_LOOKUP_CMD(render_hex_handle, he_map);
-DEF_CMD(render_hex_close)
+DEF_CMD_CLOSED(render_hex_close)
{
struct pane *p = ci->home;
struct he_data *he = p->data;
return 1;
}
-DEF_CMD(render_lines_close)
+DEF_CMD_CLOSED(render_lines_close)
{
struct rl_data *rl = ci->home->data;