@@ -98,6 +98,49 @@ protected void onPostExecute(@Nonnull EditorState state) {
9898 }
9999 }
100100
101+ private class SplitText {
102+ public int selectionStart = 0 ;
103+ public int selectionEnd = 0 ;
104+ public int selectionLength = 0 ;
105+ public int insertionPos = 0 ;
106+ public boolean textSelected = false ;
107+ public String textLeft = "" ;
108+ public String textMid = "" ;
109+ public String textRight = "" ;
110+ public String text = "" ;
111+
112+ public SplitText (String text , int cursorPos ) {
113+ this .text = text ;
114+ selectionStart = view .getSelectionStart ();
115+ selectionEnd = view .getSelectionEnd ();
116+ selectionLength = selectionEnd - selectionStart ;
117+ textSelected = selectionLength != 0 ;
118+ insertionPos = textSelected ?
119+ clamp (selectionStart , text )
120+ : clamp (cursorPos , text );
121+ textLeft = text .substring (0 , insertionPos );
122+ textMid = text .substring (selectionStart , selectionEnd );
123+ textRight = text .substring (insertionPos + selectionLength , text .length ());
124+ }
125+
126+ public String getTextMid (boolean deleteSelection ) {
127+ return deleteSelection ? "" : this .textMid ;
128+ }
129+
130+ public String getDelTextLeft () {
131+ MathType type = MathType .getType (text , insertionPos - 1 , false , engine ).type ;
132+ return this .textSelected ?
133+ this .textLeft
134+ : type == MathType .grouping_separator ?
135+ this .textLeft .substring (0 ,this .textLeft .length ()-2 )
136+ : this .textLeft .substring (0 ,this .textLeft .length ()-1 );
137+ }
138+ public int getDelPos () {
139+ return this .getDelTextLeft ().length ();
140+ }
141+ }
142+
143+
101144 @ VisibleForTesting
102145 @ Nullable
103146 EditorTextProcessor textProcessor ;
@@ -240,20 +283,17 @@ public EditorState moveCursorRight() {
240283
241284 public boolean erase () {
242285 Check .isMainThread ();
243- final int selection = state .selection ;
286+ final int delPos = state .selection ;
244287 final String text = state .getTextString ();
245- if (selection <= 0 || text .length () <= 0 || selection > text .length ()) {
288+ final SplitText st = new SplitText (text , delPos );
289+
290+ if (delPos <= 0 || text .length () <= 0 || delPos > text .length ()) {
246291 return false ;
247292 }
248- int removeStart = selection - 1 ;
249- if (MathType .getType (text , selection - 1 , false , engine ).type == MathType .grouping_separator ) {
250- // we shouldn't remove just separator as it will be re-added after the evaluation is done. Remove the digit
251- // before
252- removeStart -= 1 ;
253- }
254293
255- final String newText = text .substring (0 , removeStart ) + text .substring (selection , text .length ());
256- onTextChanged (EditorState .create (newText , removeStart ));
294+ final String newText = st .getDelTextLeft () + st .getTextMid (true ) + st .textRight ;
295+ onTextChanged (EditorState .create (newText , st .getDelPos ()));
296+
257297 return !newText .isEmpty ();
258298 }
259299
@@ -277,16 +317,36 @@ public void insert(@Nonnull String text) {
277317 insert (text , 0 );
278318 }
279319
280- public void insert (@ Nonnull String text , int selectionOffset ) {
320+ public void insert (@ Nonnull String textToInsert , int selectionOffset ) {
281321 Check .isMainThread ();
282- if (TextUtils .isEmpty (text ) && selectionOffset == 0 ) {
322+ if (TextUtils .isEmpty (textToInsert ) && selectionOffset == 0 ) {
283323 return ;
284324 }
285325 final String oldText = state .getTextString ();
286- final int selection = clamp (state .selection , oldText );
287- final int newTextLength = text .length () + oldText .length ();
288- final int newSelection = clamp (text .length () + selection + selectionOffset , newTextLength );
289- final String newText = oldText .substring (0 , selection ) + text + oldText .substring (selection );
326+ final MathType type = MathType .getType (textToInsert , 0 , false , engine ).type ;
327+ final SplitText st = new SplitText (oldText , state .selection );
328+
329+ boolean deleteSelection = false ;
330+ if (st .textSelected && type == MathType .digit ) {
331+ deleteSelection = true ;
332+ }
333+
334+ if (st .textSelected && type == MathType .binary_operation ) {
335+ textToInsert = "()" + textToInsert ;
336+ selectionOffset = -textToInsert .length () + 1 ;
337+ }
338+
339+ final int insertedTextLength = textToInsert .length ();
340+ final int newTextLength = insertedTextLength + oldText .length ();
341+
342+ final int pluginPos = insertedTextLength + selectionOffset ;
343+ final String insertLeft = textToInsert .substring (0 , pluginPos );
344+ final String insertRight = textToInsert .substring (pluginPos , insertedTextLength );
345+ final String newText = st .textLeft + insertLeft + st .getTextMid (deleteSelection ) + insertRight + st .textRight ;
346+ int newSelection = st .textLeft .length () + insertLeft .length () + st .textMid .length ();
347+ if (st .textSelected ) newSelection += insertRight .length ();
348+ newSelection = clamp (newSelection , newText );
349+
290350 onTextChanged (EditorState .create (newText , newSelection ));
291351 }
292352
0 commit comments