diff --git a/src/display/selection.js b/src/display/selection.js
index d9b69d4921932f62fcecf3aaa1a4933cf18ca73e..32c9a611fe2228ecbdd847ffaaba023b380610d7 100644
--- a/src/display/selection.js
+++ b/src/display/selection.js
@@ -46,6 +46,8 @@ export function drawSelectionCursor(cm, head, output) {
   }
 }
 
+function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
+
 // Draws the given range as a highlighted selection
 function drawSelectionRange(cm, range, output) {
   let display = cm.display, doc = cm.doc
@@ -71,29 +73,37 @@ function drawSelectionRange(cm, range, output) {
     }
 
     iterateBidiSections(getOrder(lineObj, doc.direction), fromArg || 0, toArg == null ? lineLen : toArg, (from, to, dir) => {
-      let leftPos = coords(from, "left"), rightPos, left, right
-      if (from == to) {
-        rightPos = leftPos
-        left = right = leftPos.left
-      } else {
-        rightPos = coords(to - 1, "right")
-        if (dir == "rtl") { let tmp = leftPos; leftPos = rightPos; rightPos = tmp }
-        left = leftPos.left
-        right = rightPos.right
+      let fromPos, toPos
+      if (dir == "ltr") {
+        fromPos = coords(from, "left")
+        toPos = coords(to - 1, "right")
+        let fromLeft = fromArg == null && from == 0 ? leftSide : fromPos.left
+        let toRight = toArg == null && to == lineLen ? rightSide : toPos.right
+        if (toPos.top - fromPos.top <= 3) { // Single line
+          add(fromLeft, toPos.top, toRight - fromLeft, toPos.bottom)
+        } else { // Multiple lines
+          add(fromLeft, fromPos.top, null, fromPos.bottom)
+          if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top)
+          add(leftSide, toPos.top, toPos.right, toPos.bottom)
+        }
+      } else { // RTL
+        fromPos = coords(from, "right")
+        toPos = coords(to - 1, "left")
+        let fromRight = fromArg == null && from == 0 ? rightSide : fromPos.right
+        let toLeft = toArg == null && to == lineLen ? leftSide : toPos.left
+        if (toPos.top - fromPos.top <= 3) { // Single line
+          add(toLeft, toPos.top, fromRight - toLeft, toPos.bottom)
+        } else { // Multiple lines
+          add(leftSide, fromPos.top, fromRight - leftSide, fromPos.bottom)
+          if (fromPos.bottom < toPos.top) add(leftSide, fromPos.bottom, null, toPos.top)
+          add(toLeft, toPos.top, null, toPos.bottom)
+        }
       }
-      if (fromArg == null && from == 0) left = leftSide
-      if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
-        add(left, leftPos.top, null, leftPos.bottom)
-        left = leftSide
-        if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top)
-      }
-      if (toArg == null && to == lineLen) right = rightSide
-      if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
-        start = leftPos
-      if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
-        end = rightPos
-      if (left < leftSide + 1) left = leftSide
-      add(left, rightPos.top, right - left, rightPos.bottom)
+
+      if (!start || cmpCoords(fromPos, start) < 0) start = fromPos
+      if (cmpCoords(toPos, start) < 0) start = toPos
+      if (!end || cmpCoords(fromPos, end) < 0) end = fromPos
+      if (cmpCoords(toPos, end) < 0) end = toPos
     })
     return {start: start, end: end}
   }
diff --git a/test/test.js b/test/test.js
index 59b760d5ae0eaaa604f84167a7d7c66dfc183b10..0f1d8f830f7bb3f3c4939cd652a09f3d9ce6222e 100644
--- a/test/test.js
+++ b/test/test.js
@@ -2468,6 +2468,12 @@ for (var i = 0; i < 5; ++i) {
 }
 */
 
+testCM("bidi_wrapped_selection", function(cm) {
+  cm.setSelection(Pos(0, 10), Pos(0, 190))
+  is(byClassName(cm.getWrapperElement(), "CodeMirror-selected").length >= 3)
+  is(false)
+}, {value: new Array(10).join(" فتي تم تضمينها فتي تم"), lineWrapping: true})
+
 testCM("delete_wrapped", function(cm) {
   makeItWrapAfter(cm, Pos(0, 2));
   cm.doc.setCursor(Pos(0, 3, "after"));