Index: editwin.c
===================================================================
--- editwin.c	(revision f449096479541df1434d1d796890d0bd2939f072)
+++ editwin.c	(revision 1b1cd2cda4440db58f76fdfc5a6f5ab697a2bdf5)
@@ -37,4 +37,5 @@
   char *command;
   void (*callback)(struct _owl_editwin*);
+  void (*destroy_cbdata)(void *);
   void *cbdata;
 };
@@ -58,4 +59,5 @@
 static int oe_copy_region(owl_editwin *e);
 static char *oe_chunk(owl_editwin *e, int start, int end);
+static void oe_destroy_cbdata(owl_editwin *e);
 
 #define INCR 4096
@@ -145,11 +147,4 @@
   e->echochar='\0';
 
-  /* We get initialized multiple times, but we need to hold on to
-     the callbacks, so we can't NULL them here. */
-  /*
-    e->command = NULL;
-    e->callback = NULL;
-    e->cbdata = NULL;
-  */
   if (win) werase(win);
 }
@@ -210,7 +205,16 @@
 }
 
-void owl_editwin_set_cbdata(owl_editwin *e, void *data)
-{
+static void oe_destroy_cbdata(owl_editwin *e) {
+  if (e->destroy_cbdata)
+    e->destroy_cbdata(e->cbdata);
+  e->cbdata = NULL;
+  e->destroy_cbdata = NULL;
+}
+
+void owl_editwin_set_cbdata(owl_editwin *e, void *data, void (*destroy)(void *))
+{
+  oe_destroy_cbdata(e);
   e->cbdata = data;
+  e->destroy_cbdata = destroy;
 }
 
@@ -282,4 +286,6 @@
   owl_free(e->buff);
   owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
+  e->callback = NULL;
+  oe_destroy_cbdata(e);
 }
 
Index: functions.c
===================================================================
--- functions.c	(revision 6b78afbdfa6160a7138d7bc7c87bc5e9055b6e64)
+++ functions.c	(revision 1b1cd2cda4440db58f76fdfc5a6f5ab697a2bdf5)
@@ -277,5 +277,5 @@
 }
 
-void owl_function_start_edit_win(const char *line, void (*callback)(owl_editwin *), void *data)
+void owl_function_start_edit_win(const char *line, void (*callback)(owl_editwin *), void *data, void (*cleanup)(void *))
 {
   owl_editwin *e;
@@ -295,5 +295,5 @@
   owl_global_set_typwin_active(&g);
 
-  owl_editwin_set_cbdata(owl_global_get_typwin(&g), data);
+  owl_editwin_set_cbdata(owl_global_get_typwin(&g), data, cleanup);
   owl_global_set_buffercallback(&g, callback);
   owl_global_push_context(&g, OWL_CTX_EDITMULTI, e, "editmulti");
@@ -312,5 +312,5 @@
 			 noun);
 
-  owl_function_start_edit_win(line, callback, NULL);
+  owl_function_start_edit_win(line, callback, NULL, NULL);
   owl_global_set_buffercommand(&g, line);
 }
Index: perlconfig.c
===================================================================
--- perlconfig.c	(revision 8f2d9bf19fa0ce948c8f50406b95759c78a06046)
+++ perlconfig.c	(revision 1b1cd2cda4440db58f76fdfc5a6f5ab697a2bdf5)
@@ -574,7 +574,10 @@
   FREETMPS;
   LEAVE;
-
-  SvREFCNT_dec(cb);
-  owl_editwin_set_cbdata(e, NULL);
+}
+
+void owl_perlconfig_dec_refcnt(void *data)
+{
+  SV *v = data;
+  SvREFCNT_dec(v);
 }
 
Index: perlglue.xs
===================================================================
--- perlglue.xs	(revision 8c591789302e72f4d45fab6b792bfd08bfed194a)
+++ perlglue.xs	(revision 1b1cd2cda4440db58f76fdfc5a6f5ab697a2bdf5)
@@ -179,5 +179,7 @@
 		owl_function_start_question(line);
 
-		owl_editwin_set_cbdata(owl_global_get_typwin(&g), newSVsv(callback));
+		owl_editwin_set_cbdata(owl_global_get_typwin(&g),
+				       newSVsv(callback),
+				       owl_perlconfig_dec_refcnt);
 		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
 	}
@@ -195,5 +197,7 @@
 		owl_function_start_password(line);
 
-		owl_editwin_set_cbdata(owl_global_get_typwin(&g), newSVsv(callback));
+		owl_editwin_set_cbdata(owl_global_get_typwin(&g),
+				       newSVsv(callback),
+				       owl_perlconfig_dec_refcnt);
 		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
 	}
@@ -208,5 +212,8 @@
 			croak("Callback must be a subref");
 
-		owl_function_start_edit_win(line, owl_perlconfig_edit_callback, newSVsv(callback));
+		owl_function_start_edit_win(line,
+					    owl_perlconfig_edit_callback,
+					    newSVsv(callback),
+					    owl_perlconfig_dec_refcnt);
 	}
 
