dbghelp: Return the size of each directory instead of passing a pointer to it.
[wine] / dlls / riched20 / caret.c
index 057e5d8..2337107 100644 (file)
 
 WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 
-
 static BOOL
 ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs);
 
-
 void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
 {
   *from = ME_GetCursorOfs(editor, 0);
@@ -48,19 +46,19 @@ int ME_GetTextLength(ME_TextEditor *editor)
 }
 
 
-int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how)
+int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
 {
   int length;
-  
+
   if (how->flags & GTL_PRECISE && how->flags & GTL_CLOSE)
     return E_INVALIDARG;
   if (how->flags & GTL_NUMCHARS && how->flags & GTL_NUMBYTES)
     return E_INVALIDARG;
   
   length = ME_GetTextLength(editor);
-  
-  if (how->flags & GTL_USECRLF)
-    length += editor->nParagraphs;
+
+  if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE) && (how->flags & GTL_USECRLF))
+    length += editor->nParagraphs - 1;
   
   if (how->flags & GTL_NUMBYTES)
   {
@@ -79,33 +77,81 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how)
 }
 
 
-void ME_SetSelection(ME_TextEditor *editor, int from, int to)
+int ME_SetSelection(ME_TextEditor *editor, int from, int to)
 {
+  int selectionEnd = 0;
+  const int len = ME_GetTextLength(editor);
+
+  /* all negative values are effectively the same */
+  if (from < 0)
+    from = -1;
+  if (to < 0)
+    to = -1;
+
+  /* select all */
   if (from == 0 && to == -1)
   {
-    editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); 
+    editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun);
     editor->pCursors[1].nOffset = 0; 
     editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); 
-    editor->pCursors[0].nOffset = 0; 
-    ME_Repaint(editor);
+    editor->pCursors[0].nOffset = 0;
+    ME_InvalidateSelection(editor);
     ME_ClearTempStyle(editor);
-    return;
+    return len + 1;
   }
-  if (from == -1)
+
+  /* if both values are equal and also out of bound, that means to */
+  /* put the selection at the end of the text */
+  if ((from == to) && (to < 0 || to > len))
   {
-    editor->pCursors[1] = editor->pCursors[0]; 
-    ME_Repaint(editor);
-    ME_ClearTempStyle(editor);
-    return;
+    selectionEnd = 1;
+  }
+  else
+  {
+    /* if from is negative and to is positive then selection is */
+    /* deselected and caret moved to end of the current selection */
+    if (from < 0)
+    {
+      int start, end;
+      ME_GetSelection(editor, &start, &end);
+      editor->pCursors[1] = editor->pCursors[0];
+      ME_Repaint(editor);
+      ME_ClearTempStyle(editor);
+      return end;
+    }
+
+    /* adjust to if it's a negative value */
+    if (to < 0)
+      to = len + 1;
+
+    /* flip from and to if they are reversed */
+    if (from>to)
+    {
+      int tmp = from;
+      from = to;
+      to = tmp;
+    }
+
+    /* after fiddling with the values, we find from > len && to > len */
+    if (from > len)
+      selectionEnd = 1;
+    /* special case with to too big */
+    else if (to > len)
+      to = len + 1;
   }
-  if (from>to)
+
+  if (selectionEnd)
   {
-    int tmp = from;
-    from = to;
-    to = tmp;
+    editor->pCursors[1].pRun = editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
+    editor->pCursors[1].nOffset = editor->pCursors[0].nOffset = 0;
+    ME_InvalidateSelection(editor);
+    ME_ClearTempStyle(editor);
+    return len;
   }
+
   ME_RunOfsFromCharOfs(editor, from, &editor->pCursors[1].pRun, &editor->pCursors[1].nOffset);
-  ME_RunOfsFromCharOfs(editor, to, &editor->pCursors[0].pRun, &editor->pCursors[0].nOffset);  
+  ME_RunOfsFromCharOfs(editor, to, &editor->pCursors[0].pRun, &editor->pCursors[0].nOffset);
+  return to;
 }
 
 
@@ -118,6 +164,9 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
 
   assert(!pCursor->nOffset || !editor->bCaretAtEnd);
   assert(height && x && y);
+  assert(!(ME_GetParagraph(pCursorRun)->member.para.nFlags & MEPF_REWRAP));
+  assert(pCursor->pRun);
+  assert(pCursor->pRun->type == diRun);
   
   if (pCursorRun->type == diRun) {
     ME_DisplayItem *row = ME_FindItemBack(pCursorRun, diStartRowOrParagraph);
@@ -126,7 +175,7 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
       HDC hDC = GetDC(editor->hWnd);
       ME_Context c;
       ME_DisplayItem *run = pCursorRun;
-      ME_DisplayItem *para;
+      ME_DisplayItem *para = NULL;
       SIZE sz = {0, 0};
     
       ME_InitContext(&c, editor, hDC);
@@ -134,19 +183,25 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
       if (!pCursor->nOffset && !editor->bCaretAtEnd)
       {
         ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrStartRow);
+        assert(prev);
         if (prev->type == diRun)
           pSizeRun = prev;
       }
       assert(row->type == diStartRow); /* paragraph -> run without start row ?*/
       para = ME_FindItemBack(row, diParagraph);
+      assert(para);
+      assert(para->type == diParagraph);
       if (editor->bCaretAtEnd && !pCursor->nOffset && 
           run == ME_FindItemFwd(row, diRun))
       {
         ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph);
+        assert(tmp);
         if (tmp->type == diRun)
         {
           row = ME_FindItemBack(tmp, diStartRow);
           pSizeRun = run = tmp;
+          assert(run);
+          assert(run->type == diRun);
           sz = ME_GetRunSize(&c, &para->member.para, &run->member.run, ME_StrLen(run->member.run.strText));
         }
       }
@@ -174,22 +229,31 @@ ME_MoveCaret(ME_TextEditor *editor)
 {
   int x, y, height;
 
+  if (ME_WrapMarkedParagraphs(editor))
+    ME_UpdateScrollBar(editor);
   ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height);
-  CreateCaret(editor->hWnd, NULL, 0, height);
-  SetCaretPos(x, y);
+  if(editor->bHaveFocus)
+  {
+    CreateCaret(editor->hWnd, NULL, 0, height);
+    SetCaretPos(x, y);
+  }
 }
 
 
 void ME_ShowCaret(ME_TextEditor *ed)
 {
   ME_MoveCaret(ed);
-  ShowCaret(ed->hWnd);
+  if(ed->bHaveFocus)
+    ShowCaret(ed->hWnd);
 }
 
 void ME_HideCaret(ME_TextEditor *ed)
 {
-  HideCaret(ed->hWnd);
-  DestroyCaret();
+  if(ed->bHaveFocus)
+  {
+    HideCaret(ed->hWnd);
+    DestroyCaret();
+  }
 }
 
 void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, 
@@ -309,6 +373,8 @@ void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor,
   int nChars)
 {  
   assert(nCursor>=0 && nCursor<editor->nCursors);
+  /* text operations set modified state */
+  editor->nModifyStep = 1;
   ME_InternalDeleteText(editor, ME_GetCursorOfs(editor, nCursor), nChars);
 }
 
@@ -374,16 +440,29 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
 {
   const WCHAR *pos;
   ME_Cursor *p = NULL;
-
-  assert(style);
+  int oldLen;
 
   /* FIXME really HERE ? */
   if (ME_IsSelection(editor))
     ME_DeleteSelection(editor);
 
+  /* FIXME: is this too slow? */
+  /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */
+  oldLen = ME_GetTextLength(editor);
+
+  /* text operations set modified state */
+  editor->nModifyStep = 1;
+
+  assert(style);
+
   assert(nCursor>=0 && nCursor<editor->nCursors);
   if (len == -1)
     len = lstrlenW(str);
+
+  /* grow the text limit to fit our text */
+  if(editor->nTextLimit < oldLen +len)
+    editor->nTextLimit = oldLen + len;
+
   while (len)
   {
     pos = str;
@@ -405,6 +484,22 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
         continue;
       }
     }
+    /* handle special \r\r\n sequence (richedit 2.x and higher only) */
+    if (!editor->bEmulateVersion10 && pos-str < len-2 && pos[0] == '\r' && pos[1] == '\r' && pos[2] == '\n') {
+      WCHAR space = ' ';
+
+      if (pos!=str)
+        ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
+
+      ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0);
+
+      pos+=3;
+      if(pos-str <= len) {
+        len -= pos - str;
+        str = pos;
+        continue;
+      }
+    }
     if (pos-str < len) {   /* handle EOLs */
       ME_DisplayItem *tp, *end_run;
       ME_Style *tmp_style;
@@ -605,107 +700,87 @@ ME_SelectWord(ME_TextEditor *editor)
 int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
 {
   ME_Cursor *pCursor = &editor->pCursors[nCursor];
-  
   return ME_GetParagraph(pCursor->pRun)->member.para.nCharOfs
     + pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
 }
 
-int ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
+static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
 {
   ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para;
+  ME_DisplayItem *last = NULL;
   int rx = 0;
-  
+
   if (is_eol)
     *is_eol = 0;
 
-  while(p != editor->pBuffer->pLast)
+  /* find paragraph */
+  for (; p != editor->pBuffer->pLast; p = p->member.para.next_para)
   {
-    if (p->type == diParagraph)
+    assert(p->type == diParagraph);
+    if (y < p->member.para.nYPos + p->member.para.nHeight)
     {
-      int ry = y - p->member.para.nYPos;
-      if (ry < 0)
-      {
-        result->pRun = ME_FindItemFwd(p, diRun);
-        result->nOffset = 0;
-        return 0;
-      }
-      if (ry >= p->member.para.nHeight)
-      {
-        p = p->member.para.next_para;
-        continue;
-      }
+      y -= p->member.para.nYPos;
       p = ME_FindItemFwd(p, diStartRow);
-      y = ry;
-      continue;
+      break;
     }
-    if (p->type == diStartRow)
+  }
+  /* find row */
+  for (; p != editor->pBuffer->pLast; )
+  {
+    ME_DisplayItem *pp;
+    assert(p->type == diStartRow);
+    if (y < p->member.row.nYPos + p->member.row.nHeight)
     {
-      int ry = y - p->member.row.nYPos;
-      if (ry < 0)
-        return 0;
-      if (ry >= p->member.row.nHeight)
-      {
-        p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
-        if (p->type != diStartRow)
-          return 0;
-        continue;
-      }
-      p = ME_FindItemFwd(p, diRun);
-      continue;
+        p = ME_FindItemFwd(p, diRun);
+        break;
     }
-    if (p->type == diRun)
+    pp = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
+    if (pp->type != diStartRow)
     {
-      ME_DisplayItem *pp;
+        p = ME_FindItemFwd(p, diRun);
+        break;
+    }
+    p = pp;
+  }
+  for (; p != editor->pBuffer->pLast; p = p->next)
+  {
+    switch (p->type)
+    {
+    case diRun:
       rx = x - p->member.run.pt.x;
-      if (rx < 0)
-        rx = 0;
-      if (rx >= p->member.run.nWidth) /* not this run yet... find next item */
-      {
-        pp = p;
-        do {
-          p = p->next;
-          if (p->type == diRun)
-          {
-            rx = x - p->member.run.pt.x;
-            goto continue_search;
-          }
-          if (p->type == diStartRow)
-          {
-            p = ME_FindItemFwd(p, diRun);
-            if (is_eol)
-              *is_eol = 1;
-            rx = 0; /* FIXME not sure */
-            goto found_here;
-          }
-          if (p->type == diParagraph || p->type == diTextEnd)
-          {
-            rx = 0; /* FIXME not sure */
-            p = pp;
-            goto found_here;
-          }
-        } while(1);
-        continue;
-      }
-    found_here:
-      if (p->member.run.nFlags & MERF_ENDPARA)
-        rx = 0;
-      result->pRun = p;
-      result->nOffset = ME_CharFromPointCursor(editor, rx, &p->member.run);
-      if (editor->pCursors[0].nOffset == p->member.run.strText->nLen && rx)
+      if (rx < p->member.run.nWidth)
       {
-        result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
-        result->nOffset = 0;
+      found_here:
+        assert(p->type == diRun);
+        if ((p->member.run.nFlags & MERF_ENDPARA) || rx < 0)
+          rx = 0;
+        result->pRun = p;
+        result->nOffset = ME_CharFromPointCursor(editor, rx, &p->member.run);
+        if (editor->pCursors[0].nOffset == p->member.run.strText->nLen && rx)
+        {
+          result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
+          result->nOffset = 0;
+        }
+        return;
       }
-      return 1;
+      break;
+    case diStartRow:
+      p = ME_FindItemFwd(p, diRun);
+      if (is_eol) *is_eol = 1;
+      rx = 0; /* FIXME not sure */
+      goto found_here;
+    case diParagraph:
+    case diTextEnd:
+      rx = 0; /* FIXME not sure */
+      p = last;
+      goto found_here;
+    default: assert(0);
     }
-    assert(0);
-  continue_search:
-    ;
+    last = p;
   }
   result->pRun = ME_FindItemBack(p, diRun);
   result->nOffset = 0;
   assert(result->pRun->member.run.nFlags & MERF_ENDPARA);
-  return 0;
 }
 
 
@@ -737,25 +812,64 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
   tmp_cursor = editor->pCursors[0];
   is_selection = ME_IsSelection(editor);
 
-  ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
-  
-  if (GetKeyState(VK_SHIFT)>=0)
+  if (x >= editor->selofs)
   {
-    editor->pCursors[1] = editor->pCursors[0];
+    ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
+    if (GetKeyState(VK_SHIFT)>=0)
+    {
+      editor->pCursors[1] = editor->pCursors[0];
+    }
+    else if (!is_selection) {
+      editor->pCursors[1] = tmp_cursor;
+      is_selection = 1;
+    }
+
+    ME_InvalidateSelection(editor);
+    HideCaret(editor->hWnd);
+    ME_MoveCaret(editor);
+    ShowCaret(editor->hWnd);
+    ME_ClearTempStyle(editor);
+    ME_SendSelChange(editor);
   }
   else
   {
-    if (!is_selection) {
-      editor->pCursors[1] = tmp_cursor;
-      is_selection = 1;
+    ME_DisplayItem *pRow;
+
+    editor->linesel = 1;
+    editor->sely = y;
+    /* Set pCursors[0] to beginning of line */
+    ME_FindPixelPos(editor, x, y, &editor->pCursors[1], &editor->bCaretAtEnd);
+    /* Set pCursors[1] to end of line */
+    pRow = ME_FindItemFwd(editor->pCursors[1].pRun, diStartRowOrParagraphOrEnd);
+    assert(pRow);
+    /* pCursor[0] is the position where the cursor will be drawn,
+     * pCursor[1] is the other end of the selection range
+     * pCursor[2] and [3] are backups of [0] and [1] so I
+     * don't have to look them up again
+     */
+
+    if (pRow->type == diStartRow) {
+      /* FIXME WTF was I thinking about here ? */
+      ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
+      assert(pRun);
+      editor->pCursors[0].pRun = pRun;
+      editor->pCursors[0].nOffset = 0;
+      editor->bCaretAtEnd = 1;
+    } else {
+      editor->pCursors[0].pRun = ME_FindItemBack(pRow, diRun);
+      assert(editor->pCursors[0].pRun && editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA);
+      editor->pCursors[0].nOffset = 0;
+      editor->bCaretAtEnd = 0;
     }
+    editor->pCursors[2] = editor->pCursors[0];
+    editor->pCursors[3] = editor->pCursors[1];
+    ME_InvalidateSelection(editor);
+    HideCaret(editor->hWnd);
+    ME_MoveCaret(editor);
+    ShowCaret(editor->hWnd);
+    ME_ClearTempStyle(editor);
+    ME_SendSelChange(editor);
   }
-  ME_InvalidateSelection(editor);
-  HideCaret(editor->hWnd);
-  ME_MoveCaret(editor);
-  ShowCaret(editor->hWnd);
-  ME_ClearTempStyle(editor);
-  ME_SendSelChange(editor);
 }
 
 void ME_MouseMove(ME_TextEditor *editor, int x, int y)
@@ -765,15 +879,34 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
   y += ME_GetYScrollPos(editor);
 
   tmp_cursor = editor->pCursors[0];
-  if (!ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd))
-    /* return */;
-  
-  if (tmp_cursor.pRun == editor->pCursors[0].pRun && 
-      tmp_cursor.nOffset == editor->pCursors[0].nOffset)
+  /* FIXME: do something with the return value of ME_FindPixelPos */
+  if (!editor->linesel)
+    ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd);
+  else ME_FindPixelPos(editor, (y > editor->sely) * editor->rcFormat.right, y, &tmp_cursor, &editor->bCaretAtEnd);
+
+  if (!memcmp(&tmp_cursor, editor->pCursors, sizeof(tmp_cursor)))
     return;
-  
+
   ME_InvalidateSelection(editor);
-  editor->pCursors[0] = tmp_cursor;
+  if (!editor->linesel)
+    editor->pCursors[0] = tmp_cursor;
+  else if (!memcmp(&tmp_cursor, editor->pCursors+2, sizeof(tmp_cursor)) ||
+           !memcmp(&tmp_cursor, editor->pCursors+3, sizeof(tmp_cursor)))
+  {
+    editor->pCursors[0] = editor->pCursors[2];
+    editor->pCursors[1] = editor->pCursors[3];
+  }
+  else if (y < editor->sely)
+  {
+    editor->pCursors[0] = tmp_cursor;
+    editor->pCursors[1] = editor->pCursors[2];
+  }
+  else
+  {
+    editor->pCursors[0] = tmp_cursor;
+    editor->pCursors[1] = editor->pCursors[3];
+  }
+
   HideCaret(editor->hWnd);
   ME_MoveCaret(editor);
   ME_InvalidateSelection(editor);
@@ -927,9 +1060,9 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
     ME_EnsureVisible(editor, ME_FindItemFwd(editor->pBuffer->pFirst, diRun));
     ME_Repaint(editor);
   }
-  else {
-    ME_Scroll(editor, 0, ys-yprev);
-    ME_Repaint(editor);
+  else 
+  {
+    ME_ScrollUp(editor, ys-yprev);
   }
   assert(pCursor->pRun);
   assert(pCursor->pRun->type == diRun);
@@ -980,9 +1113,9 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
     ME_EnsureVisible(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun));
     ME_Repaint(editor);
   }
-  else {
-    ME_Scroll(editor, 0, ys-yprev);
-    ME_Repaint(editor);
+  else 
+  {
+    ME_ScrollUp(editor,ys-yprev);
   }
   assert(pCursor->pRun);
   assert(pCursor->pRun->type == diRun);
@@ -991,6 +1124,10 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
 static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
 {
   ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
+  /* bCaretAtEnd doesn't make sense if the cursor isn't set at the
+  first character of the next row */
+  assert(!editor->bCaretAtEnd || !pCursor->nOffset);
+  ME_WrapMarkedParagraphs(editor);
   if (pRow) {
     ME_DisplayItem *pRun;
     if (editor->bCaretAtEnd && !pCursor->nOffset) {
@@ -1069,8 +1206,8 @@ static int ME_GetSelCursor(ME_TextEditor *editor, int dir)
   else
     return 1;
 }
-      
-BOOL ME_UpdateSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
+
+BOOL ME_UpdateSelection(ME_TextEditor *editor, const ME_Cursor *pTempCursor)
 {
   ME_Cursor old_anchor = editor->pCursors[1];
   
@@ -1107,11 +1244,11 @@ ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
 {
   ME_Style *style;
   int from, to;
-  ME_Cursor c;
-  
+
   ME_GetSelection(editor, &from, &to);
-  ME_CursorFromCharOfs(editor, from, &c);
   if (from != to) {
+    ME_Cursor c;
+    ME_CursorFromCharOfs(editor, from, &c);
     style = c.pRun->member.run.style;
     ME_AddRefStyle(style); /* ME_GetInsertStyle has already done that */
   }
@@ -1141,7 +1278,6 @@ void ME_SendSelChange(ME_TextEditor *editor)
   SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
 }
 
-
 BOOL
 ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
 {
@@ -1149,10 +1285,8 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
   ME_Cursor *p = &editor->pCursors[nCursor];
   ME_Cursor tmp_curs = *p;
   BOOL success = FALSE;
-
-  if (ME_IsSelection(editor) && !extend)
-    ME_InvalidateSelection(editor);
   
+  ME_CheckCharOffsets(editor);
   editor->nUDArrowX = -1;
   switch(nVKey) {
     case VK_LEFT:
@@ -1201,8 +1335,8 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
     editor->pCursors[1] = tmp_curs;
   *p = tmp_curs;
   
-  if (ME_IsSelection(editor))
-    ME_InvalidateSelection(editor);
+  ME_InvalidateSelection(editor);
+  ME_Repaint(editor);
   HideCaret(editor->hWnd);
   ME_EnsureVisible(editor, tmp_curs.pRun); 
   ME_ShowCaret(editor);