diff --git a/server-client.c b/server-client.c
index 596b12e7..32b51c50 100644
--- a/server-client.c
+++ b/server-client.c
@@ -302,6 +302,7 @@ server_client_lost(struct client *c)
 		free(msg);
 	}
 
+	free(c->prompt_saved);
 	free(c->prompt_string);
 	free(c->prompt_buffer);
 
diff --git a/status.c b/status.c
index a5f2a2c7..10f9f290 100644
--- a/status.c
+++ b/status.c
@@ -766,6 +766,9 @@ status_prompt_clear(struct client *c)
 	free(c->prompt_buffer);
 	c->prompt_buffer = NULL;
 
+	free(c->prompt_saved);
+	c->prompt_saved = NULL;
+
 	c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE);
 	c->flags |= CLIENT_ALLREDRAWFLAGS; /* was frozen and may have changed */
 
@@ -1217,6 +1220,12 @@ process_key:
 			}
 		}
 
+		free(c->prompt_saved);
+		c->prompt_saved = xcalloc(sizeof *c->prompt_buffer,
+		    (c->prompt_index - idx) + 1);
+		memcpy(c->prompt_saved, c->prompt_buffer + idx,
+		    (c->prompt_index - idx) * sizeof *c->prompt_buffer);
+
 		memmove(c->prompt_buffer + idx,
 		    c->prompt_buffer + c->prompt_index,
 		    (size + 1 - c->prompt_index) *
@@ -1290,22 +1299,28 @@ process_key:
 		c->prompt_index = utf8_strlen(c->prompt_buffer);
 		goto changed;
 	case '\031': /* C-y */
-		if ((pb = paste_get_top(NULL)) == NULL)
-			break;
-		bufdata = paste_buffer_data(pb, &bufsize);
-		for (n = 0; n < bufsize; n++) {
-			ch = (u_char)bufdata[n];
-			if (ch < 32 || ch >= 127)
+		if (c->prompt_saved != NULL) {
+			ud = c->prompt_saved;
+			n = utf8_strlen(c->prompt_saved);
+		} else {
+			if ((pb = paste_get_top(NULL)) == NULL)
 				break;
+			bufdata = paste_buffer_data(pb, &bufsize);
+			for (n = 0; n < bufsize; n++) {
+				ch = (u_char)bufdata[n];
+				if (ch < 32 || ch >= 127)
+					break;
+			}
+			ud = xreallocarray(NULL, n, sizeof *ud);
+			for (idx = 0; idx < n; idx++)
+				utf8_set(&ud[idx], bufdata[idx]);
 		}
 
 		c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
 		    sizeof *c->prompt_buffer);
 		if (c->prompt_index == size) {
-			for (idx = 0; idx < n; idx++) {
-				ud = &c->prompt_buffer[c->prompt_index + idx];
-				utf8_set(ud, bufdata[idx]);
-			}
+			memcpy(c->prompt_buffer + c->prompt_index, ud,
+			    n * sizeof *c->prompt_buffer);
 			c->prompt_index += n;
 			c->prompt_buffer[c->prompt_index].size = 0;
 		} else {
@@ -1313,12 +1328,13 @@ process_key:
 			    c->prompt_buffer + c->prompt_index,
 			    (size + 1 - c->prompt_index) *
 			    sizeof *c->prompt_buffer);
-			for (idx = 0; idx < n; idx++) {
-				ud = &c->prompt_buffer[c->prompt_index + idx];
-				utf8_set(ud, bufdata[idx]);
-			}
+			memcpy(c->prompt_buffer + c->prompt_index, ud,
+			    n * sizeof *c->prompt_buffer);
 			c->prompt_index += n;
 		}
+
+		if (ud != c->prompt_saved)
+			free(ud);
 		goto changed;
 	case '\024': /* C-t */
 		idx = c->prompt_index;
diff --git a/tmux.h b/tmux.h
index 7a1cc502..e95febf8 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1358,6 +1358,7 @@ struct client {
 	void		*prompt_data;
 	u_int		 prompt_hindex;
 	enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
+	struct utf8_data *prompt_saved;
 
 #define PROMPT_SINGLE 0x1
 #define PROMPT_NUMERIC 0x2