diff --git a/src/winio.c b/src/winio.c
index a66a4a31302f5a081432864f8d81d4f72338a021..650f93b55dcd11a6d263fc55448b9c4e4877ced5 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -2982,8 +2982,8 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
     while (*text != '\0' && column < leftedge)
 	text += parse_mbchar(text, NULL, &column);
 
-    /* Use a full screen row for text. */
-    goal_column = column + editwincols;
+    /* The intention is to use the entire available width. */
+    goal_column = leftedge + editwincols;
 
     while (*text != '\0' && column <= goal_column) {
 	/* When breaking at blanks, do it *before* the target column. */
@@ -3011,9 +3011,18 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
     if (found_blank) {
 	text = text - index + lastblank_index;
 	parse_mbchar(text, NULL, &lastblank_column);
+
+	/* If we've now overshot the screen's edge, then break there. */
+	if (lastblank_column > goal_column)
+	    return goal_column;
+
 	return lastblank_column;
     }
 
+    /* If a tab is split over two chunks, break at the screen's edge. */
+    if (*(text - char_len) == '\t')
+	prev_column = goal_column;
+
     /* Otherwise, return the column of the last character that doesn't
      * overshoot the target, since we can't break the text anywhere else. */
     return (editwincols > 1) ? prev_column : column - 1;