Fixed StyledtextContentAdapter to overwrite existing content properly 80/3980/1
authorTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Mon, 9 Mar 2020 16:11:02 +0000 (18:11 +0200)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Mon, 9 Mar 2020 16:11:02 +0000 (18:11 +0200)
gitlab #492

Change-Id: I58e4feb40b13f8a9c6b0619776cf496d5f21a80b

bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/assist/StyledTextContentAdapter.java

index dd71e323b0b2a500d6c67452df72dad99d4079e5..899b9e731dd7800d7447e32988abbf588120edae 100644 (file)
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.simantics.scl.ui.assist;
 
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
 import org.eclipse.jface.fieldassist.IControlContentAdapter;
 import org.eclipse.jface.fieldassist.IControlContentAdapter2;
 import org.eclipse.swt.custom.StyledText;
@@ -69,26 +70,51 @@ public class StyledTextContentAdapter implements IControlContentAdapter, IContro
        public void insertControlContents(Control control, String contents, int cursorPosition) {
                StyledText text = ((StyledText)control);
                cursorPosition = Math.min(cursorPosition, contents.length());
-               int caretEndRange = text.getCaretOffset();
+
+               int caretOffset = text.getCaretOffset();
                String currentText = text.getText();
-               
-               int offset = caretEndRange;
-        int length = currentText.length();
-        while (--offset >= 0 && (Character.isJavaIdentifierPart(currentText.charAt(offset)) && !Character.isWhitespace(currentText.charAt(offset))))
-            length--;
-               
-               int nameSpaceBeginRange = currentText.lastIndexOf(".", caretEndRange - 1); //$NON-NLS-1$
-               if (nameSpaceBeginRange > length)
-                   length = nameSpaceBeginRange;
-               int endRange = currentText.length();
-               if (caretEndRange < endRange)
-                   endRange = caretEndRange;
-               text.setSelection(length, endRange);
+               int replacementOffset = findPrefixMatchOffset(currentText, caretOffset, contents);
+
+//             System.out.println("text: " + currentText);
+//             System.out.println("proposal to fill: " + contents);
+//             System.out.format("longest match of proposed contents found from text @ offset %d: \"%s[%s]%s\"%n",
+//                             replacementOffset,
+//                             currentText.substring(0, replacementOffset),
+//                             currentText.substring(replacementOffset, caretOffset),
+//                             currentText.substring(caretOffset));
+
+               // The text between [replaceOffset, caretOffset) will be replaced with `contents`
+               text.setSelection(replacementOffset, caretOffset);
                text.insert(contents);
-               // calculate the initial count of letters that was typed when the proposal was accepted to insert the caret
-               // at the right position
-               int proposalFirstLettersCount = endRange - (length);
-               text.setCaretOffset(caretEndRange + cursorPosition - proposalFirstLettersCount);
+               text.setSelection(replacementOffset + contents.length());
+       }
+
+       /**
+        * Find offset of longest prefix match of <code>match</code> in
+        * <code>text</code> ending at offset <code>endOffset</code>.
+        * 
+        * Example:
+        * <pre>
+        * ...  res (=text)
+        * resource (=match)
+        *  resourc
+        *   resour
+        *    resou
+        *     reso
+        *      res match! return endOffset - 3
+        * </pre>
+        * 
+        * @param text the text from which to find the match
+        * @param endOffset endOffset until which to search for the longest match
+        * @param match the text to prefix-match
+        * @return
+        */
+       private static int findPrefixMatchOffset(String text, int endOffset, String match) {
+               for (int i = match.length(); i >= 0; --i) {
+                       if (text.regionMatches(true, endOffset - i, match, 0, i))
+                               return endOffset - i;
+               }
+               return 0;
        }
 
        /*