diff --git a/src/g_editor.c b/src/g_editor.c
index 3d0bb10bacf9d0b7a9301918fd7af72cd7ffb3b0..7b348087b0ba619f92dc7bd2c7a2550ddee992b0 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -3246,12 +3246,12 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av)
 			|| !strcmp(gotkeysym->s_name, "End")))
         {
                 /* send the key to the box's editor */
-            if (!x->gl_editor->e_textdirty)
+            /*if (!x->gl_editor->e_textdirty)
             {
                 //canvas_setundo(x, canvas_undo_cut,
                 //    canvas_undo_set_cut(x, UCUT_TEXT), "typing");
 				canvas_undo_add(x, 3, "typing", canvas_undo_set_cut(x, UCUT_TEXT));
-            }
+            }*/
             rtext_key(x->gl_editor->e_textedfor,
                 (int)keynum, gotkeysym);
 			canvas_fixlinesfor(x, (t_text *)(x->gl_editor->e_selection->sel_what));
diff --git a/src/g_text.c b/src/g_text.c
index 13aa139c1ff988d454b4e1eac0dffe6b1149677e..d1658c3b622aea4bdd3dfe347a3d6efdc902535f 100644
--- a/src/g_text.c
+++ b/src/g_text.c
@@ -1782,8 +1782,13 @@ void text_eraseborder(t_text *x, t_glist *glist, char *tag)
     /* change text; if T_OBJECT, remake it.  LATER we'll have an undo buffer
     which should be filled in here before making the change. */
 
+EXTERN int check_for_redundant_typed_undo(t_canvas *x, void *data);
+
 void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
 {
+	char *c1, *c2;
+	int i1, i2;
+
     if (x->te_type == T_OBJECT)
     {
         t_binbuf *b = binbuf_new();
@@ -1800,24 +1805,35 @@ void text_setto(t_text *x, t_glist *glist, char *buf, int bufsize)
              vec2[0].a_type == A_SYMBOL
             && !strcmp(vec2[0].a_w.w_symbol->s_name, "pd"))
         {
-			//TODO: add rename undo
-            typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
-            binbuf_free(x->te_binbuf);
-            x->te_binbuf = b;
+			//first check if the contents have changed to see if there is any point of recreating the object
+			binbuf_gettext(x->te_binbuf, &c1, &i1);
+			binbuf_gettext(b, &c2, &i2);
+			if (strcmp(c1, c2)) {
+				canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
+					(void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g));
+		        typedmess(&x->te_pd, gensym("rename"), natom2-1, vec2+1);
+		        binbuf_free(x->te_binbuf);
+		        x->te_binbuf = b;
+			}
         }
         else  /* normally, just destroy the old one and make a new one. */
         {
-			//fprintf(stderr,"text_setto calls canvas_undo_add\n");
-			canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
-				(void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g));
-            int xwas = x->te_xpix, ywas = x->te_ypix;
-			canvas_eraselinesfor(glist, x);
-            glist_delete(glist, &x->te_g);
-            canvas_objtext(glist, xwas, ywas, 0, b);
-                /* if it's an abstraction loadbang it here */
-            if (newest && pd_class(newest) == canvas_class)
-                canvas_loadbang((t_canvas *)newest);
-            canvas_restoreconnections(glist_getcanvas(glist));
+			//first check if the contents have changed to see if there is any point of recreating the object
+			binbuf_gettext(x->te_binbuf, &c1, &i1);
+			binbuf_gettext(b, &c2, &i2);
+			if (strcmp(c1, c2)) {
+				fprintf(stderr,"text_setto calls canvas_undo_add\n");
+				canvas_undo_add(glist_getcanvas(glist), 10, "recreate",
+					(void *)canvas_undo_set_recreate(glist_getcanvas(glist), &x->te_g));
+		        int xwas = x->te_xpix, ywas = x->te_ypix;
+				canvas_eraselinesfor(glist, x);
+		        glist_delete(glist, &x->te_g);
+		        canvas_objtext(glist, xwas, ywas, 0, b);
+		            /* if it's an abstraction loadbang it here */
+		        if (newest && pd_class(newest) == canvas_class)
+		            canvas_loadbang((t_canvas *)newest);
+		        canvas_restoreconnections(glist_getcanvas(glist));
+			}
         }
             /* if we made a new "pd" or changed a window name,
                 update window list */
diff --git a/src/g_undo.c b/src/g_undo.c
index a1929ad66d017b6398ebf7c2ebb6e9722038472b..6b7373bbde4a230d3762116af694238a62f6da28 100644
--- a/src/g_undo.c
+++ b/src/g_undo.c
@@ -83,7 +83,7 @@ void canvas_undo_redo(t_canvas *x)
 	if (x->u_queue && x->u_last->next) {
 		we_are_undoing = 1;
 		x->u_last = x->u_last->next;
-		fprintf(stderr,"canvas_undo_undo %d\n", x->u_last->type);
+		fprintf(stderr,"canvas_undo_redo %d\n", x->u_last->type);
 		glist_noselect(x);
         switch(x->u_last->type)
         {
@@ -153,6 +153,7 @@ void canvas_undo_free(t_canvas *x)
 		    {
 				case 1:	canvas_undo_connect(x, a->data, UNDO_FREE); break; 		//connect
 				case 2:	canvas_undo_disconnect(x, a->data, UNDO_FREE); break; 	//disconnect
+				case 3:	canvas_undo_cut(x, a->data, UNDO_FREE); break; 			//cut
 				case 4:	canvas_undo_move(x, a->data, UNDO_FREE); break;			//move
 				case 5:	canvas_undo_paste(x, a->data, UNDO_FREE); break;		//paste
 				case 9:	canvas_undo_create(x, a->data, UNDO_FREE); break;		//create
diff --git a/src/g_undo.h b/src/g_undo.h
index 13a135275cc13fd09e2fce742891854346df5338..8dd13f6eaa61aa710e719da247798c89eabab0ba 100644
--- a/src/g_undo.h
+++ b/src/g_undo.h
@@ -37,7 +37,6 @@ Types of undo data:
 8  - canvas apply
 9  - create
 10 - recreate
-11 - rename (TODO)
 */
 
 struct _undo_action
@@ -104,3 +103,4 @@ EXTERN void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y);
 /* ------------------------------- */
 
 #endif /* __g_undo_h_ */
+