Index: calctool.h
===================================================================
--- calctool.h	(revision 1709)
+++ calctool.h	(working copy)
@@ -287,6 +287,11 @@
 struct exprm_state {       /* Expression mode state */
     struct button button;  /* Current button/character pressed. */
     int ans[MP_SIZE];      /* Previously calculated answer */
+    int trunkated_ans[MP_SIZE];
+    struct {
+      int showing_answer;
+    } flags;
+    char *ans_tag;
     char *expression;      /* Expression entered by user */
 };
 
Index: functions.c
===================================================================
--- functions.c	(revision 1709)
+++ functions.c	(working copy)
@@ -138,6 +138,7 @@
 {
     memcpy(dst, src, sizeof(struct exprm_state));
     dst->expression = gc_strdup(src->expression);
+    dst->ans_tag = gc_strdup(src->ans_tag);
 }
 
 void
@@ -149,7 +150,9 @@
 	do {
 	    i = ((i + 1) % UNDO_HISTORY_LENGTH);
 	    free(v->h.e[i].expression);
+	    free(v->h.e[i].ans_tag);
 	    v->h.e[i].expression = NULL;
+	    v->h.e[i].ans_tag = NULL;
 	} while (i != v->h.end);
     }
 
@@ -168,13 +171,28 @@
     if (v->h.current == v->h.begin) {
 	free(v->h.e[v->h.begin].expression);
 	v->h.e[v->h.begin].expression = NULL;
+	free(v->h.e[v->h.begin].ans_tag);
+	v->h.e[v->h.begin].ans_tag = NULL;
 	v->h.begin = ((v->h.begin + 1) % UNDO_HISTORY_LENGTH);
     }
 
     copy_state(&(v->h.e[v->h.current]), &(v->h.e[c]));
+
+    struct exprm_state *e = get_state();
+    e->flags.showing_answer = 0;
+
     update_undo_redo_button_sensitivity();
 }
 
+struct exprm_state *
+peek_previous_state()
+{
+    if (v->h.current != v->h.begin) {
+      return &(v->h.e[((v->h.current - 1) % UNDO_HISTORY_LENGTH)]);
+    } else {
+      return NULL;
+    }
+}
 
 void
 perform_undo(void)
@@ -251,7 +269,32 @@
     show_display(v->MPdisp_val);
 }
 
+void 
+str_append(char **source, char *text)
+{
+    char *buf;
+    int orig_len, dest_len;
 
+    if (!text || !source) {
+        return;
+    }
+	
+    orig_len = (*source) ? strlen(*source) : 0;
+    dest_len = orig_len + strlen(text) +1;
+    buf = malloc(dest_len);
+    assert(buf);
+    if (*source) {
+        if (snprintf(buf, dest_len, "%s%s", *source, text) < 0) {
+            assert(0);
+        }
+    } else {
+        STRCPY(buf, text);
+    }
+    free(*source);
+    *source = buf;
+}
+
+
 void 
 exp_append(char *text)
 {
@@ -295,6 +338,13 @@
     get_expr_from_display();
 }
 
+void
+exp_backspace()
+{
+    delete_from_cursor();
+    get_expr_from_display();
+}
+
 void 
 exp_del() 
 {
@@ -320,7 +370,7 @@
     return ret;
 }
 
-
+#if 0
 static void
 exp_del_char(char **expr, int amount) 
 {
@@ -344,8 +394,8 @@
     free(*expr);
     *expr = e;
 }
+#endif
 
-
 void
 exp_replace(char *text)
 {
@@ -490,17 +540,33 @@
 }
 
 
+void give_ans() {
+    struct exprm_state *e = get_state();
+    char *ans = make_number(e->ans, v->base, FALSE);
+    MPstr_to_num(ans, v->base, e->trunkated_ans);
+    if (!mpeq(e->ans, e->trunkated_ans)) { 
+	e->ans_tag = gc_strdup(make_number(e->ans, v->base, FALSE));
+	str_append(&(e->ans_tag), "..");
+	exp_replace(e->ans_tag);
+    } else {
+	exp_replace(ans);
+    }
+    e->flags.showing_answer = 1;
+}
+  
 void
 do_expression()
 {
     int update_display = 0; // Update whole display. Looses cursor position.
     char *btext = NULL;
-    struct exprm_state *e;
+    struct exprm_state *e, *ex;
     int non_empty_expression;
 
     update_statusbar("", "");
 
     e = get_state();
+    ex = peek_previous_state();
+
     if (e->button.flags & dpoint) {
 	btext = get_localized_numeric_point();
     } else {
@@ -512,7 +578,7 @@
     non_empty_expression = !!(e->expression && strlen(e->expression));
 
     if (non_empty_expression) {
-	if (!strcmp(e->expression, "Ans")) {
+      if (e->ans_tag && !strcmp(e->expression, e->ans_tag)) {
 	    if (e->button.flags & number) {
 		exp_del(); 
                 update_display = 1;
@@ -530,9 +596,10 @@
 
     if ((e->button.flags & (prefixop | func)) 
 	&& e->expression
-	&& !strcmp(e->expression, "Ans")) {
+	&& ex
+	&& ex->flags.showing_answer) {
 	    char buf[1024];
-	    snprintf(buf, 128, "%s(Ans)", btext);
+	    snprintf(buf, 128, "%s(%s)", btext, e->expression);
 	    exp_replace(buf);
             update_display = 1;
     } else if (e->button.flags & clear) {
@@ -544,38 +611,13 @@
         int i = char_val(e->button.value[0]);
         char reg[3];
         int n = '0' +  i;
-
         snprintf(reg, 3, "R%c", n);
         exp_insert(reg);
     } else if (e->button.flags & con) {
         int *MPval = v->MPcon_vals[char_val(e->button.value[0])];
-
         exp_insert(make_number(MPval, v->base, FALSE));
     } else if (e->button.flags & bsp) {
-        if (exp_has_postfix(e->expression, "Ans")) { 
-            char *ans = make_number(e->ans, v->base, FALSE);   
-
-            str_replace(&e->expression, "Ans", ans);
-        } else {
-            char reg[3];
-            int n = '0';
-            int i;
-
-            for (i = 0; i < 10; i++) {
-                snprintf(reg, 3, "R%c", n+i);
-                if (exp_has_postfix(e->expression, reg)) {
-                    int MP_reg[MP_SIZE];
-                    char *reg_val;
-
-                    do_rcl_reg(i, MP_reg);
-                    reg_val = make_number(MP_reg, v->base, FALSE);
-                    /* Remove "Rx" postfix. */
-                    exp_del_char(&e->expression, 2);
-                    exp_insert(reg_val);
-                }
-            }
-        }
-        delete_from_cursor();
+        exp_backspace();
     } else if (e->button.flags & neg) {
         exp_negate();
         update_display = 1;
@@ -584,17 +626,15 @@
         update_display = 1;
     } else if (e->button.flags & enter) {
 	  if (e->expression) {
-	    if (strcmp(e->expression, "Ans")) {
+	    if (!ex || !(ex->flags.showing_answer)) {
 		  int MPval[MP_SIZE];
 		  int ret = ce_parse(e->expression, MPval);
-
 		  if (!ret) {
-			mpstr(MPval, e->ans);
-			exp_replace("Ans");
-                        update_display = 1;
+		    mpstr(MPval, e->ans);
+		    give_ans();
+		    update_display = 1;
 		  } else {
 			char *message = NULL;
-
 			switch (ret) {
 			    case -PARSER_ERR_INVALID_BASE:
 			        message = _("Invalid number for the current base");
@@ -855,7 +895,7 @@
 			     "gtk-dialog-error");
 	} else if (!v->ghost_zero) {
 	    mpstr(MP, e->ans);
-	    exp_replace("Ans");
+	    give_ans();
 	    make_registers();
 	}
 	clear_undo_history();
@@ -959,7 +999,7 @@
                   mpstr(v->MPmvals[n], MPtemp);
                   mpstr(MPexpr, v->MPmvals[n]);
                   mpstr(MPtemp, e->ans);	      
-                  exp_replace("Ans");
+		  give_ans();
                   refresh_display();
                   make_registers();
 	      }
@@ -1236,7 +1276,7 @@
                              "gtk-dialog-error");
         } else if (!v->ghost_zero) {
             mpstr(MP, e->ans);
-            exp_replace("Ans");
+	    give_ans();
             make_registers();
         }
 	clear_undo_history();
@@ -1547,8 +1587,7 @@
 
             dir = (mtype == M_LSHF) ? left : right;
             calc_rshift(MPval, e->ans, n, dir);
-
-	    exp_replace("Ans");
+	    give_ans();
         }
         break;
 
Index: ce_tokeniser.l
===================================================================
--- ce_tokeniser.l	(revision 1709)
+++ ce_tokeniser.l	(working copy)
@@ -99,6 +99,7 @@
 return tREG;
 }
 
+".." {return tTWODOTS;}
 
 {DEC_NUM}{EXP}{DEC_NUM} {
 if (v->base == HEX) REJECT;
Index: gtk.c
===================================================================
--- gtk.c	(revision 1709)
+++ gtk.c	(working copy)
@@ -2856,21 +2856,21 @@
  */
 
     switch (v->syntax) {
-        case npa:
-            if (v->old_cal_value == '?' ||
-                IS_KEY(v->old_cal_value, KEY_EQ.value[0])) {
-                complete = 1;    /* Calculation is complete. */
-            }
-            break;
-
-	    case exprs: {
-		  	struct exprm_state *e = get_state();
-            if (!e->expression || !strcmp(e->expression, "Ans")) {
-                complete = 1;   /* Calculation is complete. */
-            }
-	}
-            break;
+    case npa:
+      if (v->old_cal_value == '?' ||
+	  IS_KEY(v->old_cal_value, KEY_EQ.value[0])) {
+	complete = 1;    /* Calculation is complete. */
+      }
+      break;
+      
+    case exprs: {
+      struct exprm_state *e = get_state();
+      if (!e->expression || e->flags.showing_answer) {
+	complete = 1;   /* Calculation is complete. */
+      }
     }
+      break;
+    }
 
     if (complete) {
         if ((v->modetype != SCIENTIFIC) ||
Index: ce_parser.y
===================================================================
--- ce_parser.y	(revision 1709)
+++ ce_parser.y	(working copy)
@@ -85,6 +85,8 @@
 %token tXNOR
 %token tXOR
 
+%token tTWODOTS
+
 %token <int_t> tNUMBER
 %token <integer> tREG
 
@@ -272,6 +274,14 @@
   struct exprm_state *e = get_state();
   cp(e->ans, $$);
 }
+| tNUMBER tTWODOTS {
+    struct exprm_state *e = get_state();
+    if (mpeq(e->trunkated_ans, $1)) {
+	cp(e->ans, $$);
+    } else {
+	parser_state.error = -EINVAL; // TODO: more specific error    
+    }
+}
 ;
 
 %%
